2014-04-01 01:34:59 +00:00
|
|
|
// Copyright 2014 The Chromium Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
2014-08-21 22:40:44 +00:00
|
|
|
#include <gtest/gtest.h>
|
|
|
|
|
2014-10-01 22:10:21 +00:00
|
|
|
#include "packager/base/logging.h"
|
2016-05-25 18:03:17 +00:00
|
|
|
#include "packager/media/codecs/h264_parser.h"
|
2014-10-01 22:10:21 +00:00
|
|
|
#include "packager/media/test/test_data_util.h"
|
2014-04-01 01:34:59 +00:00
|
|
|
|
2016-05-20 21:19:33 +00:00
|
|
|
namespace shaka {
|
2014-04-01 01:34:59 +00:00
|
|
|
namespace media {
|
|
|
|
|
2016-12-06 20:23:37 +00:00
|
|
|
namespace {
|
|
|
|
// SPS, PPS (for first slice), slice header from test-25fps.h264 file.
|
|
|
|
const uint8_t kSps[] = {
|
|
|
|
0x27, 0x4D, 0x40, 0x0D, 0xA9, 0x18, 0x28, 0x3E, 0x60, 0x0D,
|
|
|
|
0x41, 0x80, 0x41, 0xAD, 0xB0, 0xAD, 0x7B, 0xDF, 0x01,
|
|
|
|
};
|
|
|
|
const uint8_t kPps[] = {
|
|
|
|
0x28, 0xDE, 0x9, 0x88,
|
|
|
|
};
|
|
|
|
// This is the prefix of a video slice that only has the header.
|
|
|
|
// The actual slice header size is 30 bits (not including the nalu header).
|
|
|
|
const uint8_t kVideoSliceTrimmed[] = {
|
|
|
|
0x25, 0xB8, 0x20, 0x20, 0x63,
|
|
|
|
};
|
|
|
|
} // namespace
|
|
|
|
|
2014-04-01 01:34:59 +00:00
|
|
|
TEST(H264ParserTest, StreamFileParsing) {
|
2014-10-07 21:41:40 +00:00
|
|
|
std::vector<uint8_t> buffer = ReadTestDataFile("test-25fps.h264");
|
|
|
|
|
2014-04-01 01:34:59 +00:00
|
|
|
// Number of NALUs in the test stream to be parsed.
|
|
|
|
int num_nalus = 759;
|
|
|
|
|
|
|
|
H264Parser parser;
|
2016-04-21 20:35:49 +00:00
|
|
|
NaluReader reader(Nalu::kH264, kIsAnnexbByteStream, buffer.data(),
|
2016-02-26 22:34:14 +00:00
|
|
|
buffer.size());
|
2014-04-01 01:34:59 +00:00
|
|
|
|
|
|
|
// Parse until the end of stream/unsupported stream/error in stream is found.
|
|
|
|
int num_parsed_nalus = 0;
|
|
|
|
while (true) {
|
2014-04-01 21:18:11 +00:00
|
|
|
H264SliceHeader shdr;
|
|
|
|
H264SEIMessage sei_msg;
|
2016-02-05 19:08:07 +00:00
|
|
|
Nalu nalu;
|
|
|
|
NaluReader::Result res = reader.Advance(&nalu);
|
|
|
|
if (res == NaluReader::kEOStream) {
|
2014-04-01 01:34:59 +00:00
|
|
|
DVLOG(1) << "Number of successfully parsed NALUs before EOS: "
|
|
|
|
<< num_parsed_nalus;
|
|
|
|
ASSERT_EQ(num_nalus, num_parsed_nalus);
|
|
|
|
return;
|
|
|
|
}
|
2016-02-05 19:08:07 +00:00
|
|
|
ASSERT_EQ(res, NaluReader::kOk);
|
2014-04-01 01:34:59 +00:00
|
|
|
|
|
|
|
++num_parsed_nalus;
|
|
|
|
|
|
|
|
int id;
|
2016-02-05 19:08:07 +00:00
|
|
|
switch (nalu.type()) {
|
|
|
|
case Nalu::H264_IDRSlice:
|
|
|
|
case Nalu::H264_NonIDRSlice:
|
2014-04-01 01:34:59 +00:00
|
|
|
ASSERT_EQ(parser.ParseSliceHeader(nalu, &shdr), H264Parser::kOk);
|
|
|
|
break;
|
|
|
|
|
2016-02-05 19:08:07 +00:00
|
|
|
case Nalu::H264_SPS:
|
2016-03-14 19:09:26 +00:00
|
|
|
ASSERT_EQ(parser.ParseSps(nalu, &id), H264Parser::kOk);
|
2014-04-01 01:34:59 +00:00
|
|
|
break;
|
|
|
|
|
2016-02-05 19:08:07 +00:00
|
|
|
case Nalu::H264_PPS:
|
2016-03-14 19:09:26 +00:00
|
|
|
ASSERT_EQ(parser.ParsePps(nalu, &id), H264Parser::kOk);
|
2014-04-01 01:34:59 +00:00
|
|
|
break;
|
|
|
|
|
2016-02-05 19:08:07 +00:00
|
|
|
case Nalu::H264_SEIMessage:
|
|
|
|
ASSERT_EQ(parser.ParseSEI(nalu, &sei_msg), H264Parser::kOk);
|
2014-04-01 01:34:59 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
// Skip unsupported NALU.
|
|
|
|
DVLOG(4) << "Skipping unsupported NALU";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-06 20:23:37 +00:00
|
|
|
// Verify that SliceHeader::nalu_data points to the beginning of nal unit.
|
|
|
|
// Also verify that header_bit_size is set correctly.
|
|
|
|
TEST(H264ParserTest, SliceHeaderSize) {
|
|
|
|
H264Parser parser;
|
|
|
|
int unused_id;
|
|
|
|
Nalu nalu;
|
|
|
|
ASSERT_TRUE(nalu.Initialize(Nalu::kH264, kSps, arraysize(kSps)));
|
|
|
|
ASSERT_EQ(H264Parser::kOk, parser.ParseSps(nalu, &unused_id));
|
|
|
|
ASSERT_TRUE(nalu.Initialize(Nalu::kH264, kPps, arraysize(kPps)));
|
|
|
|
ASSERT_EQ(H264Parser::kOk, parser.ParsePps(nalu, &unused_id));
|
|
|
|
ASSERT_TRUE(nalu.Initialize(Nalu::kH264, kVideoSliceTrimmed,
|
|
|
|
arraysize(kVideoSliceTrimmed)));
|
|
|
|
|
|
|
|
H264SliceHeader slice_header;
|
|
|
|
ASSERT_EQ(H264Parser::kOk, parser.ParseSliceHeader(nalu, &slice_header));
|
|
|
|
EXPECT_EQ(nalu.data(), slice_header.nalu_data);
|
|
|
|
EXPECT_EQ(30u, slice_header.header_bit_size);
|
|
|
|
}
|
|
|
|
|
2015-09-16 22:22:22 +00:00
|
|
|
TEST(H264ParserTest, ExtractResolutionFromSpsData) {
|
2015-08-20 19:06:02 +00:00
|
|
|
const uint8_t kSps[] = {0x67, 0x64, 0x00, 0x1E, 0xAC, 0xD9, 0x40, 0xB4,
|
|
|
|
0x2F, 0xF9, 0x7F, 0xF0, 0x00, 0x80, 0x00, 0x91,
|
|
|
|
0x00, 0x00, 0x03, 0x03, 0xE9, 0x00, 0x00, 0xEA,
|
|
|
|
0x60, 0x0F, 0x16, 0x2D, 0x96};
|
|
|
|
|
2015-10-27 00:52:57 +00:00
|
|
|
H264Parser parser;
|
|
|
|
int sps_id = 0;
|
2016-02-05 19:08:07 +00:00
|
|
|
Nalu nalu;
|
2016-04-21 20:35:49 +00:00
|
|
|
ASSERT_TRUE(nalu.Initialize(Nalu::kH264, kSps, arraysize(kSps)));
|
2016-03-14 19:09:26 +00:00
|
|
|
ASSERT_EQ(H264Parser::kOk, parser.ParseSps(nalu, &sps_id));
|
2015-10-27 00:52:57 +00:00
|
|
|
|
2015-09-16 22:22:22 +00:00
|
|
|
uint32_t coded_width = 0;
|
|
|
|
uint32_t coded_height = 0;
|
2015-08-20 19:06:02 +00:00
|
|
|
uint32_t pixel_width = 0;
|
|
|
|
uint32_t pixel_height = 0;
|
2016-03-14 19:09:26 +00:00
|
|
|
ASSERT_TRUE(ExtractResolutionFromSps(*parser.GetSps(sps_id), &coded_width,
|
2015-10-27 00:52:57 +00:00
|
|
|
&coded_height, &pixel_width,
|
|
|
|
&pixel_height));
|
2015-09-16 22:22:22 +00:00
|
|
|
EXPECT_EQ(720u, coded_width);
|
|
|
|
EXPECT_EQ(360u, coded_height);
|
2015-08-20 19:06:02 +00:00
|
|
|
EXPECT_EQ(8u, pixel_width);
|
|
|
|
EXPECT_EQ(9u, pixel_height);
|
|
|
|
}
|
|
|
|
|
2015-09-16 22:22:22 +00:00
|
|
|
TEST(H264ParserTest, ExtractResolutionFromSpsDataWithCropping) {
|
|
|
|
// 320x192 with frame_crop_bottom_offset of 6.
|
|
|
|
const uint8_t kSps[] = {0x67, 0x64, 0x00, 0x0C, 0xAC, 0xD9, 0x41, 0x41, 0x9F,
|
|
|
|
0x9F, 0x01, 0x10, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00,
|
|
|
|
0x00, 0x03, 0x03, 0x00, 0xF1, 0x42, 0x99, 0x60};
|
|
|
|
|
2015-10-27 00:52:57 +00:00
|
|
|
H264Parser parser;
|
|
|
|
int sps_id = 0;
|
2016-02-05 19:08:07 +00:00
|
|
|
Nalu nalu;
|
2016-04-21 20:35:49 +00:00
|
|
|
ASSERT_TRUE(nalu.Initialize(Nalu::kH264, kSps, arraysize(kSps)));
|
2016-03-14 19:09:26 +00:00
|
|
|
ASSERT_EQ(H264Parser::kOk, parser.ParseSps(nalu, &sps_id));
|
2015-10-27 00:52:57 +00:00
|
|
|
|
2015-09-16 22:22:22 +00:00
|
|
|
uint32_t coded_width = 0;
|
|
|
|
uint32_t coded_height = 0;
|
|
|
|
uint32_t pixel_width = 0;
|
|
|
|
uint32_t pixel_height = 0;
|
2016-03-14 19:09:26 +00:00
|
|
|
ASSERT_TRUE(ExtractResolutionFromSps(*parser.GetSps(sps_id), &coded_width,
|
2015-10-27 00:52:57 +00:00
|
|
|
&coded_height, &pixel_width,
|
|
|
|
&pixel_height));
|
2015-09-16 22:22:22 +00:00
|
|
|
EXPECT_EQ(320u, coded_width);
|
|
|
|
EXPECT_EQ(180u, coded_height);
|
|
|
|
EXPECT_EQ(1u, pixel_width);
|
|
|
|
EXPECT_EQ(1u, pixel_height);
|
|
|
|
}
|
|
|
|
|
2014-04-01 01:34:59 +00:00
|
|
|
} // namespace media
|
2016-05-20 21:19:33 +00:00
|
|
|
} // namespace shaka
|