Change values for slice header attributes

- nalu_data points to the beginning of the nalu, instead of
  beginning of the slice header which excluded the nalu
  header.
- nalu_size is the size of the whole nalu.
- header_bit_size calculation is corrected. The size used to exclude
  emulation prevention bytes.

Change-Id: Ic00f42caeddf7b4701f3948e6ef8a3537fd7f770
This commit is contained in:
Rintaro Kuroiwa 2016-12-06 12:23:37 -08:00
parent 0c2ee4c844
commit 7a4a40acb8
5 changed files with 54 additions and 12 deletions

View File

@ -985,8 +985,8 @@ H264Parser::Result H264Parser::ParseSliceHeader(const Nalu& nalu,
shdr->idr_pic_flag = (nalu.type() == 5); shdr->idr_pic_flag = (nalu.type() == 5);
shdr->nal_ref_idc = nalu.ref_idc(); shdr->nal_ref_idc = nalu.ref_idc();
shdr->nalu_data = nalu.data() + nalu.header_size(); shdr->nalu_data = nalu.data();
shdr->nalu_size = nalu.payload_size(); shdr->nalu_size = nalu.header_size() + nalu.payload_size();
READ_UE_OR_RETURN(&shdr->first_mb_in_slice); READ_UE_OR_RETURN(&shdr->first_mb_in_slice);
READ_UE_OR_RETURN(&shdr->slice_type); READ_UE_OR_RETURN(&shdr->slice_type);
@ -1116,9 +1116,7 @@ H264Parser::Result H264Parser::ParseSliceHeader(const Nalu& nalu,
return kUnsupportedStream; return kUnsupportedStream;
} }
size_t epb = br->NumEmulationPreventionBytesRead(); shdr->header_bit_size = nalu.payload_size() * 8 - br->NumBitsLeft();
shdr->header_bit_size = (shdr->nalu_size - epb) * 8 - br->NumBitsLeft();
return kOk; return kOk;
} }

View File

@ -165,9 +165,17 @@ struct H264SliceHeader {
bool idr_pic_flag; // from NAL header bool idr_pic_flag; // from NAL header
int nal_ref_idc; // from NAL header int nal_ref_idc; // from NAL header
const uint8_t* nalu_data; // from NAL header // Points to the beginning of the nal unit.
off_t nalu_size; // from NAL header const uint8_t* nalu_data;
off_t header_bit_size; // calculated
// Size of whole nalu unit.
off_t nalu_size;
// This is the size of the slice header not including the nalu header byte.
// Sturcture: |NALU Header| Slice Header | Slice Data |
// Size: |<- 8bits ->|<- header_bit_size ->|<- Rest of nalu ->|
// Note that this is not a field in the H.264 spec.
off_t header_bit_size;
int first_mb_in_slice; int first_mb_in_slice;
int slice_type; int slice_type;

View File

@ -11,6 +11,22 @@
namespace shaka { namespace shaka {
namespace media { namespace media {
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
TEST(H264ParserTest, StreamFileParsing) { TEST(H264ParserTest, StreamFileParsing) {
std::vector<uint8_t> buffer = ReadTestDataFile("test-25fps.h264"); std::vector<uint8_t> buffer = ReadTestDataFile("test-25fps.h264");
@ -65,6 +81,25 @@ TEST(H264ParserTest, StreamFileParsing) {
} }
} }
// 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);
}
TEST(H264ParserTest, ExtractResolutionFromSpsData) { TEST(H264ParserTest, ExtractResolutionFromSpsData) {
const uint8_t kSps[] = {0x67, 0x64, 0x00, 0x1E, 0xAC, 0xD9, 0x40, 0xB4, const uint8_t kSps[] = {0x67, 0x64, 0x00, 0x1E, 0xAC, 0xD9, 0x40, 0xB4,
0x2F, 0xF9, 0x7F, 0xF0, 0x00, 0x80, 0x00, 0x91, 0x2F, 0xF9, 0x7F, 0xF0, 0x00, 0x80, 0x00, 0x91,

View File

@ -390,10 +390,7 @@ H265Parser::Result H265Parser::ParseSliceHeader(const Nalu& nalu,
TRUE_OR_RETURN(br->SkipBits(extension_length * 8)); TRUE_OR_RETURN(br->SkipBits(extension_length * 8));
} }
size_t epb = br->NumEmulationPreventionBytesRead(); slice_header->header_bit_size = nalu.payload_size() * 8 - br->NumBitsLeft();
slice_header->header_bit_size =
(nalu.payload_size() - epb) * 8 - br->NumBitsLeft();
return kOk; return kOk;
} }

View File

@ -218,6 +218,10 @@ struct H265SliceHeader {
// Many of the fields here are required when parsing so the default here may // Many of the fields here are required when parsing so the default here may
// not be valid. // not be valid.
// This is the size of the slice header not including the nalu header byte.
// Sturcture: |NALU Header | Slice Header | Slice Data |
// Size: |<- 16bits ->|<- header_bit_size ->|<- Rest of nalu ->|
// Note that this is not a field in the H.265 spec.
int header_bit_size = 0; int header_bit_size = 0;
bool first_slice_segment_in_pic_flag = false; bool first_slice_segment_in_pic_flag = false;