Fix avc3 codec string problem
- Added wvm decryption and demuxing test - Added avc3 test (not strip parameter set nal units) Change-Id: I28ff4d7f9ef539eafe45cfadfc0912cd11c72b05
This commit is contained in:
parent
59f393779c
commit
4a47268f3d
|
@ -354,6 +354,34 @@ class PackagerAppTest(unittest.TestCase):
|
||||||
self._VerifyDecryption(self.output[0], 'bear-320x240-opus-golden.mp4')
|
self._VerifyDecryption(self.output[0], 'bear-320x240-opus-golden.mp4')
|
||||||
self._VerifyDecryption(self.output[1], 'bear-320x240-vp9-golden.mp4')
|
self._VerifyDecryption(self.output[1], 'bear-320x240-vp9-golden.mp4')
|
||||||
|
|
||||||
|
def testPackageWvmInput(self):
|
||||||
|
self.packager.Package(
|
||||||
|
self._GetStreams(
|
||||||
|
['0', '1', '2', '3'], test_files=['bear-multi-configs.wvm']),
|
||||||
|
self._GetFlags(
|
||||||
|
decryption=True, encryption_key='9248d245390e0a49d483ba9b43fc69c3'))
|
||||||
|
# Output timescale is 90000.
|
||||||
|
self._DiffGold(self.output[0], 'bear-320x180-v-wvm-golden.mp4')
|
||||||
|
self._DiffGold(self.output[1], 'bear-320x180-a-wvm-golden.mp4')
|
||||||
|
self._DiffGold(self.output[2], 'bear-640x360-v-wvm-golden.mp4')
|
||||||
|
self._DiffGold(self.output[3], 'bear-640x360-a-wvm-golden.mp4')
|
||||||
|
self._DiffGold(self.mpd_output, 'bear-wvm-golden.mpd')
|
||||||
|
|
||||||
|
def testPackageWvmInputWithoutStrippingParameterSetNalus(self):
|
||||||
|
self.packager.Package(
|
||||||
|
self._GetStreams(
|
||||||
|
['0', '1', '2', '3'], test_files=['bear-multi-configs.wvm']),
|
||||||
|
self._GetFlags(
|
||||||
|
strip_parameter_set_nalus=False,
|
||||||
|
decryption=True,
|
||||||
|
encryption_key='9248d245390e0a49d483ba9b43fc69c3'))
|
||||||
|
# Output timescale is 90000.
|
||||||
|
self._DiffGold(self.output[0], 'bear-320x180-avc3-wvm-golden.mp4')
|
||||||
|
self._DiffGold(self.output[1], 'bear-320x180-a-wvm-golden.mp4')
|
||||||
|
self._DiffGold(self.output[2], 'bear-640x360-avc3-wvm-golden.mp4')
|
||||||
|
self._DiffGold(self.output[3], 'bear-640x360-a-wvm-golden.mp4')
|
||||||
|
self._DiffGold(self.mpd_output, 'bear-avc3-wvm-golden.mpd')
|
||||||
|
|
||||||
def testPackageWithEncryptionAndRandomIv(self):
|
def testPackageWithEncryptionAndRandomIv(self):
|
||||||
self.packager.Package(
|
self.packager.Package(
|
||||||
self._GetStreams(['audio', 'video']),
|
self._GetStreams(['audio', 'video']),
|
||||||
|
@ -582,6 +610,7 @@ class PackagerAppTest(unittest.TestCase):
|
||||||
return 'mp4'
|
return 'mp4'
|
||||||
|
|
||||||
def _GetFlags(self,
|
def _GetFlags(self,
|
||||||
|
strip_parameter_set_nalus=True,
|
||||||
encryption=False,
|
encryption=False,
|
||||||
protection_scheme=None,
|
protection_scheme=None,
|
||||||
vp9_subsample_encryption=True,
|
vp9_subsample_encryption=True,
|
||||||
|
@ -598,6 +627,10 @@ class PackagerAppTest(unittest.TestCase):
|
||||||
generate_static_mpd=False,
|
generate_static_mpd=False,
|
||||||
use_fake_clock=True):
|
use_fake_clock=True):
|
||||||
flags = []
|
flags = []
|
||||||
|
|
||||||
|
if not strip_parameter_set_nalus:
|
||||||
|
flags += ['--strip_parameter_set_nalus=false']
|
||||||
|
|
||||||
if widevine_encryption:
|
if widevine_encryption:
|
||||||
widevine_server_url = ('https://license.uat.widevine.com/cenc'
|
widevine_server_url = ('https://license.uat.widevine.com/cenc'
|
||||||
'/getcontentkey/widevine_test')
|
'/getcontentkey/widevine_test')
|
||||||
|
@ -624,7 +657,7 @@ class PackagerAppTest(unittest.TestCase):
|
||||||
if decryption:
|
if decryption:
|
||||||
flags += ['--enable_fixed_key_decryption',
|
flags += ['--enable_fixed_key_decryption',
|
||||||
'--key_id=31323334353637383930313233343536',
|
'--key_id=31323334353637383930313233343536',
|
||||||
'--key=32333435363738393021323334353637']
|
'--key=' + encryption_key]
|
||||||
|
|
||||||
if key_rotation:
|
if key_rotation:
|
||||||
flags.append('--crypto_period_duration=1')
|
flags.append('--crypto_period_duration=1')
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,36 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
||||||
|
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.73607S">
|
||||||
|
<Period id="0">
|
||||||
|
<AdaptationSet id="0" contentType="video" maxWidth="640" maxHeight="360" frameRate="90000/3003" subsegmentAlignment="true" par="16:9">
|
||||||
|
<Representation id="0" bandwidth="354240" codecs="avc3.64000d" mimeType="video/mp4" sar="1:1" width="320" height="180">
|
||||||
|
<BaseURL>output_0.mp4</BaseURL>
|
||||||
|
<SegmentBase indexRange="818-885" timescale="90000">
|
||||||
|
<Initialization range="0-817"/>
|
||||||
|
</SegmentBase>
|
||||||
|
</Representation>
|
||||||
|
<Representation id="2" bandwidth="888442" codecs="avc3.64001e" mimeType="video/mp4" sar="1:1" width="640" height="360">
|
||||||
|
<BaseURL>output_2.mp4</BaseURL>
|
||||||
|
<SegmentBase indexRange="819-886" timescale="90000">
|
||||||
|
<Initialization range="0-818"/>
|
||||||
|
</SegmentBase>
|
||||||
|
</Representation>
|
||||||
|
</AdaptationSet>
|
||||||
|
<AdaptationSet id="1" contentType="audio" subsegmentAlignment="true">
|
||||||
|
<Representation id="1" bandwidth="132362" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
|
||||||
|
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
|
||||||
|
<BaseURL>output_1.mp4</BaseURL>
|
||||||
|
<SegmentBase indexRange="757-824" timescale="90000">
|
||||||
|
<Initialization range="0-756"/>
|
||||||
|
</SegmentBase>
|
||||||
|
</Representation>
|
||||||
|
<Representation id="3" bandwidth="136806" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
|
||||||
|
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
|
||||||
|
<BaseURL>output_3.mp4</BaseURL>
|
||||||
|
<SegmentBase indexRange="757-824" timescale="90000">
|
||||||
|
<Initialization range="0-756"/>
|
||||||
|
</SegmentBase>
|
||||||
|
</Representation>
|
||||||
|
</AdaptationSet>
|
||||||
|
</Period>
|
||||||
|
</MPD>
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
||||||
|
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.73607S">
|
||||||
|
<Period id="0">
|
||||||
|
<AdaptationSet id="0" contentType="video" maxWidth="640" maxHeight="360" frameRate="90000/3003" subsegmentAlignment="true" par="16:9">
|
||||||
|
<Representation id="0" bandwidth="353919" codecs="avc1.64000d" mimeType="video/mp4" sar="1:1" width="320" height="180">
|
||||||
|
<BaseURL>output_0.mp4</BaseURL>
|
||||||
|
<SegmentBase indexRange="822-889" timescale="90000">
|
||||||
|
<Initialization range="0-821"/>
|
||||||
|
</SegmentBase>
|
||||||
|
</Representation>
|
||||||
|
<Representation id="2" bandwidth="888108" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1" width="640" height="360">
|
||||||
|
<BaseURL>output_2.mp4</BaseURL>
|
||||||
|
<SegmentBase indexRange="823-890" timescale="90000">
|
||||||
|
<Initialization range="0-822"/>
|
||||||
|
</SegmentBase>
|
||||||
|
</Representation>
|
||||||
|
</AdaptationSet>
|
||||||
|
<AdaptationSet id="1" contentType="audio" subsegmentAlignment="true">
|
||||||
|
<Representation id="1" bandwidth="132362" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
|
||||||
|
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
|
||||||
|
<BaseURL>output_1.mp4</BaseURL>
|
||||||
|
<SegmentBase indexRange="757-824" timescale="90000">
|
||||||
|
<Initialization range="0-756"/>
|
||||||
|
</SegmentBase>
|
||||||
|
</Representation>
|
||||||
|
<Representation id="3" bandwidth="136806" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
|
||||||
|
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
|
||||||
|
<BaseURL>output_3.mp4</BaseURL>
|
||||||
|
<SegmentBase indexRange="757-824" timescale="90000">
|
||||||
|
<Initialization range="0-756"/>
|
||||||
|
</SegmentBase>
|
||||||
|
</Representation>
|
||||||
|
</AdaptationSet>
|
||||||
|
</Period>
|
||||||
|
</MPD>
|
|
@ -88,18 +88,21 @@ bool AVCDecoderConfigurationRecord::ParseInternal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string AVCDecoderConfigurationRecord::GetCodecString() const {
|
std::string AVCDecoderConfigurationRecord::GetCodecString(
|
||||||
return GetCodecString(profile_indication_, profile_compatibility_,
|
FourCC codec_fourcc) const {
|
||||||
avc_level_);
|
return GetCodecString(codec_fourcc, profile_indication_,
|
||||||
|
profile_compatibility_, avc_level_);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string AVCDecoderConfigurationRecord::GetCodecString(
|
std::string AVCDecoderConfigurationRecord::GetCodecString(
|
||||||
|
FourCC codec_fourcc,
|
||||||
uint8_t profile_indication,
|
uint8_t profile_indication,
|
||||||
uint8_t profile_compatibility,
|
uint8_t profile_compatibility,
|
||||||
uint8_t avc_level) {
|
uint8_t avc_level) {
|
||||||
const uint8_t bytes[] = {profile_indication, profile_compatibility,
|
const uint8_t bytes[] = {profile_indication, profile_compatibility,
|
||||||
avc_level};
|
avc_level};
|
||||||
return "avc1." + base::ToLowerASCII(base::HexEncode(bytes, arraysize(bytes)));
|
return FourCCToString(codec_fourcc) + "." +
|
||||||
|
base::ToLowerASCII(base::HexEncode(bytes, arraysize(bytes)));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace media
|
} // namespace media
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "packager/base/macros.h"
|
#include "packager/base/macros.h"
|
||||||
|
#include "packager/media/base/fourccs.h"
|
||||||
#include "packager/media/codecs/decoder_configuration_record.h"
|
#include "packager/media/codecs/decoder_configuration_record.h"
|
||||||
|
|
||||||
namespace shaka {
|
namespace shaka {
|
||||||
|
@ -24,7 +25,7 @@ class AVCDecoderConfigurationRecord : public DecoderConfigurationRecord {
|
||||||
~AVCDecoderConfigurationRecord() override;
|
~AVCDecoderConfigurationRecord() override;
|
||||||
|
|
||||||
/// @return The codec string.
|
/// @return The codec string.
|
||||||
std::string GetCodecString() const;
|
std::string GetCodecString(FourCC codec_fourcc) const;
|
||||||
|
|
||||||
uint8_t version() const { return version_; }
|
uint8_t version() const { return version_; }
|
||||||
uint8_t profile_indication() const { return profile_indication_; }
|
uint8_t profile_indication() const { return profile_indication_; }
|
||||||
|
@ -37,7 +38,8 @@ class AVCDecoderConfigurationRecord : public DecoderConfigurationRecord {
|
||||||
|
|
||||||
/// Static version of GetCodecString.
|
/// Static version of GetCodecString.
|
||||||
/// @return The codec string.
|
/// @return The codec string.
|
||||||
static std::string GetCodecString(uint8_t profile_indication,
|
static std::string GetCodecString(FourCC codec_fourcc,
|
||||||
|
uint8_t profile_indication,
|
||||||
uint8_t profile_compatibility,
|
uint8_t profile_compatibility,
|
||||||
uint8_t avc_level);
|
uint8_t avc_level);
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,8 @@ TEST(AVCDecoderConfigurationRecordTest, Success) {
|
||||||
EXPECT_EQ(8u, avc_config.pixel_width());
|
EXPECT_EQ(8u, avc_config.pixel_width());
|
||||||
EXPECT_EQ(9u, avc_config.pixel_height());
|
EXPECT_EQ(9u, avc_config.pixel_height());
|
||||||
|
|
||||||
EXPECT_EQ("avc1.64001e", avc_config.GetCodecString());
|
EXPECT_EQ("avc1.64001e", avc_config.GetCodecString(FOURCC_avc1));
|
||||||
|
EXPECT_EQ("avc3.64001e", avc_config.GetCodecString(FOURCC_avc3));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(AVCDecoderConfigurationRecordTest, FailsOnInvalidNaluLengthSize) {
|
TEST(AVCDecoderConfigurationRecordTest, FailsOnInvalidNaluLengthSize) {
|
||||||
|
@ -56,8 +57,8 @@ TEST(AVCDecoderConfigurationRecordTest, FailOnInsufficientData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(AVCDecoderConfigurationRecordTest, GetCodecString) {
|
TEST(AVCDecoderConfigurationRecordTest, GetCodecString) {
|
||||||
EXPECT_EQ("avc1.123456",
|
EXPECT_EQ("avc1.123456", AVCDecoderConfigurationRecord::GetCodecString(
|
||||||
AVCDecoderConfigurationRecord::GetCodecString(0x12, 0x34, 0x56));
|
FOURCC_avc1, 0x12, 0x34, 0x56));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace media
|
} // namespace media
|
||||||
|
|
|
@ -148,11 +148,15 @@ bool EsParserH264::UpdateVideoDecoderConfig(int pps_id) {
|
||||||
|
|
||||||
const uint8_t nalu_length_size =
|
const uint8_t nalu_length_size =
|
||||||
H26xByteToUnitStreamConverter::kUnitStreamNaluLengthSize;
|
H26xByteToUnitStreamConverter::kUnitStreamNaluLengthSize;
|
||||||
|
const H26xStreamFormat stream_format = stream_converter()->stream_format();
|
||||||
|
const FourCC codec_fourcc =
|
||||||
|
stream_format == H26xStreamFormat::kNalUnitStreamWithParameterSetNalus
|
||||||
|
? FOURCC_avc3
|
||||||
|
: FOURCC_avc1;
|
||||||
last_video_decoder_config_ = std::make_shared<VideoStreamInfo>(
|
last_video_decoder_config_ = std::make_shared<VideoStreamInfo>(
|
||||||
pid(), kMpeg2Timescale, kInfiniteDuration, kCodecH264,
|
pid(), kMpeg2Timescale, kInfiniteDuration, kCodecH264, stream_format,
|
||||||
stream_converter()->stream_format(),
|
AVCDecoderConfigurationRecord::GetCodecString(
|
||||||
AVCDecoderConfigurationRecord::GetCodecString(decoder_config_record[1],
|
codec_fourcc, decoder_config_record[1], decoder_config_record[2],
|
||||||
decoder_config_record[2],
|
|
||||||
decoder_config_record[3]),
|
decoder_config_record[3]),
|
||||||
decoder_config_record.data(), decoder_config_record.size(), coded_width,
|
decoder_config_record.data(), decoder_config_record.size(), coded_width,
|
||||||
coded_height, pixel_width, pixel_height, 0, nalu_length_size,
|
coded_height, pixel_width, pixel_height, 0, nalu_length_size,
|
||||||
|
|
|
@ -520,7 +520,7 @@ bool MP4MediaParser::ParseMoov(BoxReader* reader) {
|
||||||
LOG(ERROR) << "Failed to parse avcc.";
|
LOG(ERROR) << "Failed to parse avcc.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
codec_string = avc_config.GetCodecString();
|
codec_string = avc_config.GetCodecString(actual_format);
|
||||||
nalu_length_size = avc_config.nalu_length_size();
|
nalu_length_size = avc_config.nalu_length_size();
|
||||||
|
|
||||||
if (coded_width != avc_config.coded_width() ||
|
if (coded_width != avc_config.coded_width() ||
|
||||||
|
|
|
@ -861,7 +861,13 @@ bool WvmMediaParser::Output(bool output_encrypted_sample) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
video_stream_info->set_codec_string(avc_config.GetCodecString());
|
const FourCC codec_fourcc =
|
||||||
|
byte_to_unit_stream_converter_.stream_format() ==
|
||||||
|
H26xStreamFormat::kNalUnitStreamWithParameterSetNalus
|
||||||
|
? FOURCC_avc3
|
||||||
|
: FOURCC_avc1;
|
||||||
|
video_stream_info->set_codec_string(
|
||||||
|
avc_config.GetCodecString(codec_fourcc));
|
||||||
|
|
||||||
if (avc_config.pixel_width() != video_stream_info->pixel_width() ||
|
if (avc_config.pixel_width() != video_stream_info->pixel_width() ||
|
||||||
avc_config.pixel_height() !=
|
avc_config.pixel_height() !=
|
||||||
|
|
|
@ -215,7 +215,7 @@ TEST_F(WvmMediaParserTest, ParseMultiConfigWvm) {
|
||||||
EXPECT_CALL(*key_source_, GetKey(_, _))
|
EXPECT_CALL(*key_source_, GetKey(_, _))
|
||||||
.WillOnce(DoAll(SetArgPointee<1>(encryption_key_), Return(Status::OK)));
|
.WillOnce(DoAll(SetArgPointee<1>(encryption_key_), Return(Status::OK)));
|
||||||
Parse(kMultiConfigWvmFile);
|
Parse(kMultiConfigWvmFile);
|
||||||
EXPECT_EQ(6u, stream_map_.size());
|
ASSERT_EQ(4u, stream_map_.size());
|
||||||
|
|
||||||
ASSERT_EQ(kStreamVideo, stream_map_[0]->stream_type());
|
ASSERT_EQ(kStreamVideo, stream_map_[0]->stream_type());
|
||||||
VideoStreamInfo* video_info = reinterpret_cast<VideoStreamInfo*>(
|
VideoStreamInfo* video_info = reinterpret_cast<VideoStreamInfo*>(
|
||||||
|
@ -242,18 +242,6 @@ TEST_F(WvmMediaParserTest, ParseMultiConfigWvm) {
|
||||||
EXPECT_EQ("mp4a.40.2", audio_info->codec_string());
|
EXPECT_EQ("mp4a.40.2", audio_info->codec_string());
|
||||||
EXPECT_EQ(2u, audio_info->num_channels());
|
EXPECT_EQ(2u, audio_info->num_channels());
|
||||||
EXPECT_EQ(44100u, audio_info->sampling_frequency());
|
EXPECT_EQ(44100u, audio_info->sampling_frequency());
|
||||||
|
|
||||||
ASSERT_EQ(kStreamVideo, stream_map_[4]->stream_type());
|
|
||||||
video_info = reinterpret_cast<VideoStreamInfo*>(stream_map_[4].get());
|
|
||||||
EXPECT_EQ("avc1.64001f", video_info->codec_string());
|
|
||||||
EXPECT_EQ(1280u, video_info->width());
|
|
||||||
EXPECT_EQ(720u, video_info->height());
|
|
||||||
|
|
||||||
ASSERT_EQ(kStreamAudio, stream_map_[5]->stream_type());
|
|
||||||
audio_info = reinterpret_cast<AudioStreamInfo*>(stream_map_[5].get());
|
|
||||||
EXPECT_EQ("mp4a.40.2", audio_info->codec_string());
|
|
||||||
EXPECT_EQ(2u, audio_info->num_channels());
|
|
||||||
EXPECT_EQ(48000u, audio_info->sampling_frequency());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace wvm
|
} // namespace wvm
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue