Moved Nalu data pointer position.
Now the Nalu data pointer points to the start of the NALU header rather than pointing to the start code. Added a new method on NaluReader to check whether the stream starts with a start code. Change-Id: Ifaecbe0c911aa5cffdf0a966028e6cada8621cc3
This commit is contained in:
parent
96abd90ca2
commit
0d3951ff74
|
@ -49,7 +49,7 @@ bool AVCDecoderConfiguration::Parse(const std::vector<uint8_t>& data) {
|
||||||
H264Parser parser;
|
H264Parser parser;
|
||||||
int sps_id = 0;
|
int sps_id = 0;
|
||||||
Nalu nalu;
|
Nalu nalu;
|
||||||
RCHECK(nalu.InitializeFromH264(reader.data() + reader.pos(), sps_length, 0));
|
RCHECK(nalu.InitializeFromH264(reader.data() + reader.pos(), sps_length));
|
||||||
RCHECK(parser.ParseSPS(nalu, &sps_id) == H264Parser::kOk);
|
RCHECK(parser.ParseSPS(nalu, &sps_id) == H264Parser::kOk);
|
||||||
return ExtractResolutionFromSps(*parser.GetSPS(sps_id), &coded_width_,
|
return ExtractResolutionFromSps(*parser.GetSPS(sps_id), &coded_width_,
|
||||||
&coded_height_, &pixel_width_,
|
&coded_height_, &pixel_width_,
|
||||||
|
|
|
@ -34,26 +34,16 @@ bool H264ByteToUnitStreamConverter::ConvertByteStreamToNalUnitStream(
|
||||||
|
|
||||||
BufferWriter output_buffer(input_frame_size + kStreamConversionOverhead);
|
BufferWriter output_buffer(input_frame_size + kStreamConversionOverhead);
|
||||||
|
|
||||||
bool first_nalu(true);
|
|
||||||
Nalu nalu;
|
Nalu nalu;
|
||||||
NaluReader reader(kIsAnnexbByteStream, input_frame, input_frame_size);
|
NaluReader reader(kIsAnnexbByteStream, input_frame, input_frame_size);
|
||||||
while (reader.Advance(&nalu) == NaluReader::kOk) {
|
if (!reader.StartsWithStartCode()) {
|
||||||
if (first_nalu) {
|
|
||||||
if (nalu.data() != input_frame) {
|
|
||||||
LOG(ERROR) << "H.264 byte stream frame did not begin with start code.";
|
LOG(ERROR) << "H.264 byte stream frame did not begin with start code.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
first_nalu = false;
|
while (reader.Advance(&nalu) == NaluReader::kOk) {
|
||||||
}
|
|
||||||
|
|
||||||
ProcessNalu(nalu, &output_buffer);
|
ProcessNalu(nalu, &output_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (first_nalu) {
|
|
||||||
LOG(ERROR) << "H.264 byte stream frame did not contain start codes.";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
output_buffer.SwapBuffer(output_frame);
|
output_buffer.SwapBuffer(output_frame);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,12 +12,6 @@
|
||||||
namespace edash_packager {
|
namespace edash_packager {
|
||||||
namespace media {
|
namespace media {
|
||||||
|
|
||||||
namespace {
|
|
||||||
// The test data does not include a start code, the start of the data is the
|
|
||||||
// NALU header.
|
|
||||||
const uint8_t kStartCodeSize = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(H264ParserTest, StreamFileParsing) {
|
TEST(H264ParserTest, StreamFileParsing) {
|
||||||
std::vector<uint8_t> buffer = ReadTestDataFile("test-25fps.h264");
|
std::vector<uint8_t> buffer = ReadTestDataFile("test-25fps.h264");
|
||||||
|
|
||||||
|
@ -81,7 +75,7 @@ TEST(H264ParserTest, ExtractResolutionFromSpsData) {
|
||||||
H264Parser parser;
|
H264Parser parser;
|
||||||
int sps_id = 0;
|
int sps_id = 0;
|
||||||
Nalu nalu;
|
Nalu nalu;
|
||||||
ASSERT_TRUE(nalu.InitializeFromH264(kSps, arraysize(kSps), kStartCodeSize));
|
ASSERT_TRUE(nalu.InitializeFromH264(kSps, arraysize(kSps)));
|
||||||
ASSERT_EQ(H264Parser::kOk, parser.ParseSPS(nalu, &sps_id));
|
ASSERT_EQ(H264Parser::kOk, parser.ParseSPS(nalu, &sps_id));
|
||||||
|
|
||||||
uint32_t coded_width = 0;
|
uint32_t coded_width = 0;
|
||||||
|
@ -106,7 +100,7 @@ TEST(H264ParserTest, ExtractResolutionFromSpsDataWithCropping) {
|
||||||
H264Parser parser;
|
H264Parser parser;
|
||||||
int sps_id = 0;
|
int sps_id = 0;
|
||||||
Nalu nalu;
|
Nalu nalu;
|
||||||
ASSERT_TRUE(nalu.InitializeFromH264(kSps, arraysize(kSps), kStartCodeSize));
|
ASSERT_TRUE(nalu.InitializeFromH264(kSps, arraysize(kSps)));
|
||||||
ASSERT_EQ(H264Parser::kOk, parser.ParseSPS(nalu, &sps_id));
|
ASSERT_EQ(H264Parser::kOk, parser.ParseSPS(nalu, &sps_id));
|
||||||
|
|
||||||
uint32_t coded_width = 0;
|
uint32_t coded_width = 0;
|
||||||
|
|
|
@ -27,18 +27,16 @@ Nalu::Nalu()
|
||||||
type_(0),
|
type_(0),
|
||||||
is_video_slice_(false) {}
|
is_video_slice_(false) {}
|
||||||
|
|
||||||
bool Nalu::InitializeFromH264(const uint8_t* data,
|
bool Nalu::InitializeFromH264(const uint8_t* data, uint64_t size) {
|
||||||
uint64_t size,
|
|
||||||
uint8_t start_code_size) {
|
|
||||||
DCHECK(data);
|
DCHECK(data);
|
||||||
DCHECK_GT(size, start_code_size);
|
DCHECK_GT(size, 0u);
|
||||||
uint8_t header = data[start_code_size];
|
uint8_t header = data[0];
|
||||||
if ((header & 0x80) != 0)
|
if ((header & 0x80) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
data_ = data;
|
data_ = data;
|
||||||
header_size_ = start_code_size + 1;
|
header_size_ = 1;
|
||||||
data_size_ = size - start_code_size - 1;
|
data_size_ = size - 1;
|
||||||
ref_idc_ = (header >> 5) & 0x3;
|
ref_idc_ = (header >> 5) & 0x3;
|
||||||
type_ = header & 0x1F;
|
type_ = header & 0x1F;
|
||||||
is_video_slice_ = (type_ >= Nalu::H264_NonIDRSlice &&
|
is_video_slice_ = (type_ >= Nalu::H264_NonIDRSlice &&
|
||||||
|
@ -63,9 +61,10 @@ NaluReader::Result NaluReader::Advance(Nalu* nalu) {
|
||||||
return NaluReader::kEOStream;
|
return NaluReader::kEOStream;
|
||||||
|
|
||||||
uint8_t nalu_length_size_or_start_code_size;
|
uint8_t nalu_length_size_or_start_code_size;
|
||||||
uint64_t nalu_length_with_header;
|
uint64_t nalu_length;
|
||||||
if (format_ == kAnnexbByteStreamFormat) {
|
if (format_ == kAnnexbByteStreamFormat) {
|
||||||
// This will move |stream_| to the start code.
|
// This will move |stream_| to the start code.
|
||||||
|
uint64_t nalu_length_with_header;
|
||||||
if (!LocateNaluByStartCode(&nalu_length_with_header,
|
if (!LocateNaluByStartCode(&nalu_length_with_header,
|
||||||
&nalu_length_size_or_start_code_size)) {
|
&nalu_length_size_or_start_code_size)) {
|
||||||
LOG(ERROR) << "Could not find next NALU, bytes left in stream: "
|
LOG(ERROR) << "Could not find next NALU, bytes left in stream: "
|
||||||
|
@ -75,8 +74,8 @@ NaluReader::Result NaluReader::Advance(Nalu* nalu) {
|
||||||
// and there are no start codes in the stream.
|
// and there are no start codes in the stream.
|
||||||
return NaluReader::kInvalidStream;
|
return NaluReader::kInvalidStream;
|
||||||
}
|
}
|
||||||
|
nalu_length = nalu_length_with_header - nalu_length_size_or_start_code_size;
|
||||||
} else {
|
} else {
|
||||||
uint64_t nalu_length;
|
|
||||||
BufferReader reader(stream_, stream_size_);
|
BufferReader reader(stream_, stream_size_);
|
||||||
if (!reader.ReadNBytesInto8(&nalu_length, nalu_length_size_))
|
if (!reader.ReadNBytesInto8(&nalu_length, nalu_length_size_))
|
||||||
return NaluReader::kInvalidStream;
|
return NaluReader::kInvalidStream;
|
||||||
|
@ -91,17 +90,16 @@ NaluReader::Result NaluReader::Advance(Nalu* nalu) {
|
||||||
LOG(ERROR) << "NALU size 0";
|
LOG(ERROR) << "NALU size 0";
|
||||||
return NaluReader::kInvalidStream;
|
return NaluReader::kInvalidStream;
|
||||||
}
|
}
|
||||||
nalu_length_with_header = nalu_length + nalu_length_size_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nalu->InitializeFromH264(stream_, nalu_length_with_header,
|
const uint8_t* nalu_data = stream_ + nalu_length_size_or_start_code_size;
|
||||||
nalu_length_size_or_start_code_size))
|
if (!nalu->InitializeFromH264(nalu_data, nalu_length))
|
||||||
return NaluReader::kInvalidStream;
|
return NaluReader::kInvalidStream;
|
||||||
|
|
||||||
// Move parser state to after this NALU, so next time Advance
|
// Move parser state to after this NALU, so next time Advance
|
||||||
// is called, we will effectively be skipping it.
|
// is called, we will effectively be skipping it.
|
||||||
stream_ += nalu_length_with_header;
|
stream_ += nalu_length_size_or_start_code_size + nalu_length;
|
||||||
stream_size_ -= nalu_length_with_header;
|
stream_size_ -= nalu_length_size_or_start_code_size + nalu_length;
|
||||||
|
|
||||||
DVLOG(4) << "NALU type: " << static_cast<int>(nalu->type())
|
DVLOG(4) << "NALU type: " << static_cast<int>(nalu->type())
|
||||||
<< " at: " << reinterpret_cast<const void*>(nalu->data())
|
<< " at: " << reinterpret_cast<const void*>(nalu->data())
|
||||||
|
@ -111,6 +109,18 @@ NaluReader::Result NaluReader::Advance(Nalu* nalu) {
|
||||||
return NaluReader::kOk;
|
return NaluReader::kOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NaluReader::StartsWithStartCode() {
|
||||||
|
if (stream_size_ >= 3) {
|
||||||
|
if (IsStartCode(stream_))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (stream_size_ >= 4) {
|
||||||
|
if (stream_[0] == 0x00 && IsStartCode(stream_ + 1))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool NaluReader::FindStartCode(const uint8_t* data,
|
bool NaluReader::FindStartCode(const uint8_t* data,
|
||||||
uint64_t data_size,
|
uint64_t data_size,
|
||||||
|
|
|
@ -40,8 +40,7 @@ class Nalu {
|
||||||
Nalu();
|
Nalu();
|
||||||
|
|
||||||
bool InitializeFromH264(const uint8_t* data,
|
bool InitializeFromH264(const uint8_t* data,
|
||||||
uint64_t size,
|
uint64_t size) WARN_UNUSED_RESULT;
|
||||||
uint8_t start_code_size) WARN_UNUSED_RESULT;
|
|
||||||
|
|
||||||
const uint8_t* data() const { return data_; }
|
const uint8_t* data() const { return data_; }
|
||||||
uint64_t data_size() const { return data_size_; }
|
uint64_t data_size() const { return data_size_; }
|
||||||
|
@ -105,6 +104,9 @@ class NaluReader {
|
||||||
/// end-of-stream; kInvalidStream on error.
|
/// end-of-stream; kInvalidStream on error.
|
||||||
Result Advance(Nalu* nalu);
|
Result Advance(Nalu* nalu);
|
||||||
|
|
||||||
|
/// @returns true if the current position points to a start code.
|
||||||
|
bool StartsWithStartCode();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum Format {
|
enum Format {
|
||||||
kAnnexbByteStreamFormat,
|
kAnnexbByteStreamFormat,
|
||||||
|
|
|
@ -24,16 +24,16 @@ TEST(NaluReaderTest, StartCodeSearch) {
|
||||||
|
|
||||||
Nalu nalu;
|
Nalu nalu;
|
||||||
ASSERT_EQ(NaluReader::kOk, reader.Advance(&nalu));
|
ASSERT_EQ(NaluReader::kOk, reader.Advance(&nalu));
|
||||||
EXPECT_EQ(kNaluData + 6, nalu.data());
|
EXPECT_EQ(kNaluData + 9, nalu.data());
|
||||||
EXPECT_EQ(3u, nalu.data_size());
|
EXPECT_EQ(3u, nalu.data_size());
|
||||||
EXPECT_EQ(4u, nalu.header_size());
|
EXPECT_EQ(1u, nalu.header_size());
|
||||||
EXPECT_EQ(0, nalu.ref_idc());
|
EXPECT_EQ(0, nalu.ref_idc());
|
||||||
EXPECT_EQ(0x12, nalu.type());
|
EXPECT_EQ(0x12, nalu.type());
|
||||||
|
|
||||||
ASSERT_EQ(NaluReader::kOk, reader.Advance(&nalu));
|
ASSERT_EQ(NaluReader::kOk, reader.Advance(&nalu));
|
||||||
EXPECT_EQ(kNaluData + 13, nalu.data());
|
EXPECT_EQ(kNaluData + 17, nalu.data());
|
||||||
EXPECT_EQ(3u, nalu.data_size());
|
EXPECT_EQ(3u, nalu.data_size());
|
||||||
EXPECT_EQ(5u, nalu.header_size());
|
EXPECT_EQ(1u, nalu.header_size());
|
||||||
EXPECT_EQ(3, nalu.ref_idc());
|
EXPECT_EQ(3, nalu.ref_idc());
|
||||||
EXPECT_EQ(7, nalu.type());
|
EXPECT_EQ(7, nalu.type());
|
||||||
|
|
||||||
|
@ -52,44 +52,44 @@ TEST(NaluReaderTest, OneByteNaluLength) {
|
||||||
|
|
||||||
Nalu nalu;
|
Nalu nalu;
|
||||||
ASSERT_EQ(NaluReader::kOk, reader.Advance(&nalu));
|
ASSERT_EQ(NaluReader::kOk, reader.Advance(&nalu));
|
||||||
EXPECT_EQ(kNaluData, nalu.data());
|
EXPECT_EQ(kNaluData + 1, nalu.data());
|
||||||
EXPECT_EQ(4u, nalu.data_size());
|
EXPECT_EQ(4u, nalu.data_size());
|
||||||
EXPECT_EQ(2u, nalu.header_size());
|
EXPECT_EQ(1u, nalu.header_size());
|
||||||
EXPECT_EQ(0, nalu.ref_idc());
|
EXPECT_EQ(0, nalu.ref_idc());
|
||||||
EXPECT_EQ(8, nalu.type());
|
EXPECT_EQ(8, nalu.type());
|
||||||
|
|
||||||
ASSERT_EQ(NaluReader::kOk, reader.Advance(&nalu));
|
ASSERT_EQ(NaluReader::kOk, reader.Advance(&nalu));
|
||||||
EXPECT_EQ(kNaluData + 6, nalu.data());
|
EXPECT_EQ(kNaluData + 7, nalu.data());
|
||||||
EXPECT_EQ(5u, nalu.data_size());
|
EXPECT_EQ(5u, nalu.data_size());
|
||||||
EXPECT_EQ(2u, nalu.header_size());
|
EXPECT_EQ(1u, nalu.header_size());
|
||||||
EXPECT_EQ(3, nalu.ref_idc());
|
EXPECT_EQ(3, nalu.ref_idc());
|
||||||
EXPECT_EQ(7, nalu.type());
|
EXPECT_EQ(7, nalu.type());
|
||||||
|
|
||||||
EXPECT_EQ(NaluReader::kEOStream, reader.Advance(&nalu));
|
EXPECT_EQ(NaluReader::kEOStream, reader.Advance(&nalu));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(NaluReaderTest, ThreeByteNaluLength) {
|
TEST(NaluReaderTest, FourByteNaluLength) {
|
||||||
const uint8_t kNaluData[] = {
|
const uint8_t kNaluData[] = {
|
||||||
// First NALU
|
// First NALU
|
||||||
0x00, 0x00, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
|
0x00, 0x00, 0x00, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
|
||||||
// Second NALU
|
// Second NALU
|
||||||
0x00, 0x00, 0x03, 0x67, 0x0a, 0x0b
|
0x00, 0x00, 0x00, 0x03, 0x67, 0x0a, 0x0b
|
||||||
};
|
};
|
||||||
|
|
||||||
NaluReader reader(3, kNaluData, arraysize(kNaluData));
|
NaluReader reader(4, kNaluData, arraysize(kNaluData));
|
||||||
|
|
||||||
Nalu nalu;
|
Nalu nalu;
|
||||||
ASSERT_EQ(NaluReader::kOk, reader.Advance(&nalu));
|
ASSERT_EQ(NaluReader::kOk, reader.Advance(&nalu));
|
||||||
EXPECT_EQ(kNaluData, nalu.data());
|
EXPECT_EQ(kNaluData + 4, nalu.data());
|
||||||
EXPECT_EQ(6u, nalu.data_size());
|
EXPECT_EQ(6u, nalu.data_size());
|
||||||
EXPECT_EQ(4u, nalu.header_size());
|
EXPECT_EQ(1u, nalu.header_size());
|
||||||
EXPECT_EQ(0, nalu.ref_idc());
|
EXPECT_EQ(0, nalu.ref_idc());
|
||||||
EXPECT_EQ(8, nalu.type());
|
EXPECT_EQ(8, nalu.type());
|
||||||
|
|
||||||
ASSERT_EQ(NaluReader::kOk, reader.Advance(&nalu));
|
ASSERT_EQ(NaluReader::kOk, reader.Advance(&nalu));
|
||||||
EXPECT_EQ(kNaluData + 10, nalu.data());
|
EXPECT_EQ(kNaluData + 15, nalu.data());
|
||||||
EXPECT_EQ(2u, nalu.data_size());
|
EXPECT_EQ(2u, nalu.data_size());
|
||||||
EXPECT_EQ(4u, nalu.header_size());
|
EXPECT_EQ(1u, nalu.header_size());
|
||||||
EXPECT_EQ(3, nalu.ref_idc());
|
EXPECT_EQ(3, nalu.ref_idc());
|
||||||
EXPECT_EQ(7, nalu.type());
|
EXPECT_EQ(7, nalu.type());
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,15 @@ VideoCodec GetVideoCodec(const StreamInfo& stream_info) {
|
||||||
static_cast<const VideoStreamInfo&>(stream_info);
|
static_cast<const VideoStreamInfo&>(stream_info);
|
||||||
return video_stream_info.codec();
|
return video_stream_info.codec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t GetNaluLengthSize(const StreamInfo& stream_info) {
|
||||||
|
if (stream_info.stream_type() != kStreamVideo)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
const VideoStreamInfo& video_stream_info =
|
||||||
|
static_cast<const VideoStreamInfo&>(stream_info);
|
||||||
|
return video_stream_info.nalu_length_size();
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
EncryptingFragmenter::EncryptingFragmenter(
|
EncryptingFragmenter::EncryptingFragmenter(
|
||||||
|
@ -59,6 +68,7 @@ EncryptingFragmenter::EncryptingFragmenter(
|
||||||
: Fragmenter(traf),
|
: Fragmenter(traf),
|
||||||
info_(info),
|
info_(info),
|
||||||
encryption_key_(encryption_key.Pass()),
|
encryption_key_(encryption_key.Pass()),
|
||||||
|
nalu_length_size_(GetNaluLengthSize(*info)),
|
||||||
clear_time_(clear_time) {
|
clear_time_(clear_time) {
|
||||||
DCHECK(encryption_key_);
|
DCHECK(encryption_key_);
|
||||||
VideoCodec video_codec = GetVideoCodec(*info);
|
VideoCodec video_codec = GetVideoCodec(*info);
|
||||||
|
@ -213,7 +223,7 @@ Status EncryptingFragmenter::EncryptSample(scoped_refptr<MediaSample> sample) {
|
||||||
data += frame.frame_size;
|
data += frame.frame_size;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
NaluReader reader(GetNaluLengthSize(), data, sample->data_size());
|
NaluReader reader(nalu_length_size_, data, sample->data_size());
|
||||||
|
|
||||||
// Store the current length of clear data. This is used to squash
|
// Store the current length of clear data. This is used to squash
|
||||||
// multiple unencrypted NAL units into fewer subsample entries.
|
// multiple unencrypted NAL units into fewer subsample entries.
|
||||||
|
@ -231,14 +241,15 @@ Status EncryptingFragmenter::EncryptSample(scoped_refptr<MediaSample> sample) {
|
||||||
if (video_slice_header_size < 0)
|
if (video_slice_header_size < 0)
|
||||||
return Status(error::MUXER_FAILURE, "Failed to read slice header.");
|
return Status(error::MUXER_FAILURE, "Failed to read slice header.");
|
||||||
|
|
||||||
const uint64_t current_clear_bytes =
|
const uint64_t current_clear_bytes = nalu.header_size() +
|
||||||
nalu.header_size() + video_slice_header_size;
|
video_slice_header_size;
|
||||||
const uint64_t cipher_bytes =
|
const uint64_t cipher_bytes =
|
||||||
nalu.data_size() - video_slice_header_size;
|
nalu.data_size() - video_slice_header_size;
|
||||||
const uint8_t* nalu_data = nalu.data() + current_clear_bytes;
|
const uint8_t* nalu_data = nalu.data() + current_clear_bytes;
|
||||||
EncryptBytes(const_cast<uint8_t*>(nalu_data), cipher_bytes);
|
EncryptBytes(const_cast<uint8_t*>(nalu_data), cipher_bytes);
|
||||||
|
|
||||||
AddSubsamples(accumulated_clear_bytes + current_clear_bytes,
|
AddSubsamples(
|
||||||
|
accumulated_clear_bytes + nalu_length_size_ + current_clear_bytes,
|
||||||
cipher_bytes, &sample_encryption_entry.subsamples);
|
cipher_bytes, &sample_encryption_entry.subsamples);
|
||||||
accumulated_clear_bytes = 0;
|
accumulated_clear_bytes = 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -265,17 +276,8 @@ Status EncryptingFragmenter::EncryptSample(scoped_refptr<MediaSample> sample) {
|
||||||
return Status::OK;
|
return Status::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EncryptingFragmenter::GetNaluLengthSize() {
|
|
||||||
if (info_->stream_type() != kStreamVideo)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
const VideoStreamInfo& video_stream_info =
|
|
||||||
static_cast<const VideoStreamInfo&>(*info_);
|
|
||||||
return video_stream_info.nalu_length_size();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EncryptingFragmenter::IsSubsampleEncryptionRequired() {
|
bool EncryptingFragmenter::IsSubsampleEncryptionRequired() {
|
||||||
return vpx_parser_ || GetNaluLengthSize() != 0;
|
return vpx_parser_ || nalu_length_size_ != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace mp4
|
} // namespace mp4
|
||||||
|
|
|
@ -66,16 +66,16 @@ class EncryptingFragmenter : public Fragmenter {
|
||||||
void EncryptBytes(uint8_t* data, uint32_t size);
|
void EncryptBytes(uint8_t* data, uint32_t size);
|
||||||
Status EncryptSample(scoped_refptr<MediaSample> sample);
|
Status EncryptSample(scoped_refptr<MediaSample> sample);
|
||||||
|
|
||||||
// If this stream contains AVC, subsample encryption specifies that the size
|
|
||||||
// and type of NAL units remain unencrypted. This function returns the size of
|
|
||||||
// the size field in bytes. Can be 1, 2 or 4 bytes.
|
|
||||||
uint8_t GetNaluLengthSize();
|
|
||||||
// Should we enable subsample encryption?
|
// Should we enable subsample encryption?
|
||||||
bool IsSubsampleEncryptionRequired();
|
bool IsSubsampleEncryptionRequired();
|
||||||
|
|
||||||
scoped_refptr<StreamInfo> info_;
|
scoped_refptr<StreamInfo> info_;
|
||||||
scoped_ptr<EncryptionKey> encryption_key_;
|
scoped_ptr<EncryptionKey> encryption_key_;
|
||||||
scoped_ptr<AesCtrEncryptor> encryptor_;
|
scoped_ptr<AesCtrEncryptor> encryptor_;
|
||||||
|
// If this stream contains AVC, subsample encryption specifies that the size
|
||||||
|
// and type of NAL units remain unencrypted. This function returns the size of
|
||||||
|
// the size field in bytes. Can be 1, 2 or 4 bytes.
|
||||||
|
const uint8_t nalu_length_size_;
|
||||||
int64_t clear_time_;
|
int64_t clear_time_;
|
||||||
|
|
||||||
scoped_ptr<VPxParser> vpx_parser_;
|
scoped_ptr<VPxParser> vpx_parser_;
|
||||||
|
|
|
@ -13,10 +13,6 @@ namespace edash_packager {
|
||||||
namespace media {
|
namespace media {
|
||||||
namespace mp4 {
|
namespace mp4 {
|
||||||
|
|
||||||
namespace {
|
|
||||||
const uint8_t kStartCodeSize = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
H264VideoSliceHeaderParser::H264VideoSliceHeaderParser() {}
|
H264VideoSliceHeaderParser::H264VideoSliceHeaderParser() {}
|
||||||
H264VideoSliceHeaderParser::~H264VideoSliceHeaderParser() {}
|
H264VideoSliceHeaderParser::~H264VideoSliceHeaderParser() {}
|
||||||
|
|
||||||
|
@ -39,7 +35,7 @@ bool H264VideoSliceHeaderParser::Initialize(
|
||||||
|
|
||||||
int id;
|
int id;
|
||||||
Nalu nalu;
|
Nalu nalu;
|
||||||
RCHECK(nalu.InitializeFromH264(data, size, kStartCodeSize));
|
RCHECK(nalu.InitializeFromH264(data, size));
|
||||||
RCHECK(parser_.ParseSPS(nalu, &id) == H264Parser::kOk);
|
RCHECK(parser_.ParseSPS(nalu, &id) == H264Parser::kOk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +49,7 @@ bool H264VideoSliceHeaderParser::Initialize(
|
||||||
|
|
||||||
int id;
|
int id;
|
||||||
Nalu nalu;
|
Nalu nalu;
|
||||||
RCHECK(nalu.InitializeFromH264(data, size, kStartCodeSize));
|
RCHECK(nalu.InitializeFromH264(data, size));
|
||||||
RCHECK(parser_.ParsePPS(nalu, &id) == H264Parser::kOk);
|
RCHECK(parser_.ParsePPS(nalu, &id) == H264Parser::kOk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,6 @@ TEST(H264VideoSliceHeaderParserTest, BasicSupport) {
|
||||||
0x00, 0x06, // Size
|
0x00, 0x06, // Size
|
||||||
0x68, 0xeb, 0xe3, 0xcb, 0x22, 0xc0
|
0x68, 0xeb, 0xe3, 0xcb, 0x22, 0xc0
|
||||||
};
|
};
|
||||||
const uint8_t kStartCodeSize = 0;
|
|
||||||
const uint8_t kData[] = {
|
const uint8_t kData[] = {
|
||||||
// Incomplete data, but we only care about the header size.
|
// Incomplete data, but we only care about the header size.
|
||||||
0x65, 0x88, 0x84, 0x00, 0x21, 0xff, 0xcf, 0x73, 0xc7, 0x24,
|
0x65, 0x88, 0x84, 0x00, 0x21, 0xff, 0xcf, 0x73, 0xc7, 0x24,
|
||||||
|
@ -44,7 +43,7 @@ TEST(H264VideoSliceHeaderParserTest, BasicSupport) {
|
||||||
ASSERT_TRUE(parser.Initialize(extra_data));
|
ASSERT_TRUE(parser.Initialize(extra_data));
|
||||||
|
|
||||||
Nalu nalu;
|
Nalu nalu;
|
||||||
ASSERT_TRUE(nalu.InitializeFromH264(kData, arraysize(kData), kStartCodeSize));
|
ASSERT_TRUE(nalu.InitializeFromH264(kData, arraysize(kData)));
|
||||||
// Real header size is 34 bits, but we round up to 5 bytes.
|
// Real header size is 34 bits, but we round up to 5 bytes.
|
||||||
EXPECT_EQ(5, parser.GetHeaderSize(nalu));
|
EXPECT_EQ(5, parser.GetHeaderSize(nalu));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue