5 #include "packager/media/formats/wvm/wvm_media_parser.h" 11 #include "packager/base/strings/string_number_conversions.h" 12 #include "packager/media/base/aes_decryptor.h" 13 #include "packager/media/base/audio_stream_info.h" 14 #include "packager/media/base/key_source.h" 15 #include "packager/media/base/media_sample.h" 16 #include "packager/media/base/video_stream_info.h" 17 #include "packager/media/codecs/aac_audio_specific_config.h" 18 #include "packager/media/codecs/avc_decoder_configuration_record.h" 19 #include "packager/media/codecs/es_descriptor.h" 20 #include "packager/media/formats/mp2t/adts_header.h" 21 #include "packager/status.h" 23 #define HAS_HEADER_EXTENSION(x) ((x != 0xBC) && (x != 0xBE) && (x != 0xBF) \ 24 && (x != 0xF0) && (x != 0xF2) && (x != 0xF8) \ 28 const uint32_t kMpeg2ClockRate = 90000;
29 const uint32_t kPesOptPts = 0x80;
30 const uint32_t kPesOptDts = 0x40;
31 const uint32_t kPesOptAlign = 0x04;
32 const uint32_t kPsmStreamId = 0xBC;
33 const uint32_t kPaddingStreamId = 0xBE;
34 const uint32_t kIndexMagic = 0x49444d69;
35 const uint32_t kIndexStreamId = 0xBF;
36 const uint32_t kIndexVersion4HeaderSize = 12;
37 const uint32_t kEcmStreamId = 0xF0;
38 const uint32_t kV2MetadataStreamId = 0xF1;
39 const uint32_t kScramblingBitsMask = 0x30;
40 const uint32_t kStartCode1 = 0x00;
41 const uint32_t kStartCode2 = 0x00;
42 const uint32_t kStartCode3 = 0x01;
43 const uint32_t kStartCode4Pack = 0xBA;
44 const uint32_t kStartCode4System = 0xBB;
45 const uint32_t kStartCode4ProgramEnd = 0xB9;
46 const uint32_t kPesStreamIdVideoMask = 0xF0;
47 const uint32_t kPesStreamIdVideo = 0xE0;
48 const uint32_t kPesStreamIdAudioMask = 0xE0;
49 const uint32_t kPesStreamIdAudio = 0xC0;
50 const uint32_t kVersion4 = 4;
51 const uint8_t kAacSampleSizeBits = 16;
53 const uint8_t kNaluLengthSize = 4;
56 const uint32_t kDefaultSamplingFrequency = 100;
57 const uint16_t kEcmSizeBytes = 80;
58 const uint32_t kInitializationVectorSizeBytes = 16;
60 const uint32_t kEcmContentKeySizeBytes = 16;
61 const uint32_t kEcmDCPFlagsSizeBytes = 3;
62 const uint32_t kEcmCCIFlagsSizeBytes = 1;
63 const uint32_t kEcmFlagsSizeBytes =
64 kEcmCCIFlagsSizeBytes + kEcmDCPFlagsSizeBytes;
65 const uint32_t kEcmPaddingSizeBytes = 12;
66 const uint32_t kAssetKeySizeBytes = 16;
68 const uint8_t kDefaultAudioStreamId = kPesStreamIdAudio;
69 const uint8_t kDefaultVideoStreamId = kPesStreamIdVideo;
90 WvmMediaParser::WvmMediaParser()
91 : is_initialized_(false),
92 parse_state_(StartCode1),
94 metadata_is_complete_(false),
95 current_program_id_(0),
97 prev_pes_stream_id_(0),
101 prev_pes_flags_1_(0),
102 pes_header_data_bytes_(0),
106 index_program_id_(0),
108 crypto_unit_start_pos_(0),
110 decryption_key_source_(NULL) {}
112 WvmMediaParser::~WvmMediaParser() {}
114 void WvmMediaParser::Init(
const InitCB& init_cb,
115 const NewSampleCB& new_sample_cb,
117 DCHECK(!is_initialized_);
118 DCHECK(!init_cb.is_null());
119 DCHECK(!new_sample_cb.is_null());
120 decryption_key_source_ = decryption_key_source;
122 new_sample_cb_ = new_sample_cb;
125 bool WvmMediaParser::Parse(
const uint8_t* buf,
int size) {
126 size_t num_bytes = 0;
127 size_t prev_size = 0;
128 const uint8_t* read_ptr = buf;
129 const uint8_t* end = read_ptr + size;
131 while (read_ptr < end) {
132 switch (parse_state_) {
134 if (*read_ptr == kStartCode1) {
135 parse_state_ = StartCode2;
139 if (*read_ptr == kStartCode2) {
140 parse_state_ = StartCode3;
142 parse_state_ = StartCode1;
146 if (*read_ptr == kStartCode3) {
147 parse_state_ = StartCode4;
149 parse_state_ = StartCode1;
154 case kStartCode4Pack:
155 parse_state_ = PackHeader1;
157 case kStartCode4System:
158 parse_state_ = SystemHeader1;
160 case kStartCode4ProgramEnd:
161 parse_state_ = ProgramEnd;
164 parse_state_ = PesStreamId;
169 parse_state_ = PackHeader2;
172 parse_state_ = PackHeader3;
175 parse_state_ = PackHeader4;
178 parse_state_ = PackHeader5;
181 parse_state_ = PackHeader6;
184 parse_state_ = PackHeader7;
187 parse_state_ = PackHeader8;
190 parse_state_ = PackHeader9;
193 parse_state_ = PackHeader10;
196 skip_bytes_ = *read_ptr & 0x07;
197 parse_state_ = PackHeaderStuffingSkip;
200 skip_bytes_ = *read_ptr;
202 parse_state_ = SystemHeader2;
205 skip_bytes_ |= *read_ptr;
206 parse_state_ = SystemHeaderSkip;
208 case PackHeaderStuffingSkip:
209 if (end >= skip_bytes_ + read_ptr) {
210 read_ptr += skip_bytes_;
212 parse_state_ = StartCode1;
214 skip_bytes_ -= (end - read_ptr);
218 case SystemHeaderSkip:
219 if (end >= skip_bytes_ + read_ptr) {
220 read_ptr += skip_bytes_;
222 parse_state_ = StartCode1;
224 uint32_t remaining_size = end - read_ptr;
225 skip_bytes_ -= remaining_size;
230 pes_stream_id_ = *read_ptr;
231 if (!metadata_is_complete_ &&
232 (pes_stream_id_ != kPsmStreamId) &&
233 (pes_stream_id_ != kIndexStreamId) &&
234 (pes_stream_id_ != kEcmStreamId) &&
235 (pes_stream_id_ != kV2MetadataStreamId) &&
236 (pes_stream_id_ != kPaddingStreamId)) {
237 metadata_is_complete_ =
true;
239 parse_state_ = PesPacketLength1;
241 case PesPacketLength1:
242 pes_packet_bytes_ = *read_ptr;
243 pes_packet_bytes_ <<= 8;
244 parse_state_ = PesPacketLength2;
246 case PesPacketLength2:
247 pes_packet_bytes_ |= *read_ptr;
248 if (HAS_HEADER_EXTENSION(pes_stream_id_)) {
249 parse_state_ = PesExtension1;
251 prev_pes_flags_1_ = pes_flags_1_;
252 pes_flags_1_ = pes_flags_2_ = 0;
253 pes_header_data_bytes_ = 0;
254 parse_state_ = PesPayload;
258 prev_pes_flags_1_ = pes_flags_1_;
259 pes_flags_1_ = *read_ptr;
261 parse_state_ = PesExtension2;
264 pes_flags_2_ = *read_ptr;
266 parse_state_ = PesExtension3;
269 pes_header_data_bytes_ = *read_ptr;
271 if (pes_flags_2_ & kPesOptPts) {
274 parse_state_ = PesHeaderData;
278 timestamp_ = (*read_ptr & 0x0E);
279 --pes_header_data_bytes_;
285 timestamp_ |= *read_ptr;
286 --pes_header_data_bytes_;
292 timestamp_ |= *read_ptr >> 1;
293 --pes_header_data_bytes_;
299 timestamp_ |= *read_ptr;
300 --pes_header_data_bytes_;
306 timestamp_ |= *read_ptr >> 1;
308 --pes_header_data_bytes_;
310 if (pes_flags_2_ & kPesOptDts) {
314 parse_state_ = PesHeaderData;
318 timestamp_ = (*read_ptr & 0x0E);
319 --pes_header_data_bytes_;
325 timestamp_ |= *read_ptr;
326 --pes_header_data_bytes_;
332 timestamp_ |= *read_ptr >> 1;
333 --pes_header_data_bytes_;
339 timestamp_ |= *read_ptr;
340 --pes_header_data_bytes_;
346 timestamp_ |= *read_ptr >> 1;
348 --pes_header_data_bytes_;
350 parse_state_ = PesHeaderData;
353 num_bytes = end - read_ptr;
354 if (num_bytes >= pes_header_data_bytes_) {
355 num_bytes = pes_header_data_bytes_;
356 parse_state_ = PesPayload;
358 pes_header_data_bytes_ -= num_bytes;
359 pes_packet_bytes_ -= num_bytes;
360 read_ptr += num_bytes;
363 switch (pes_stream_id_) {
366 parse_state_ = PsmPayload;
368 case kPaddingStreamId:
369 parse_state_ = Padding;
373 parse_state_ = EcmPayload;
376 parse_state_ = IndexPayload;
379 if (!DemuxNextPes(
false)) {
382 parse_state_ = EsPayload;
386 num_bytes = end - read_ptr;
387 if (num_bytes >= pes_packet_bytes_) {
388 num_bytes = pes_packet_bytes_;
389 parse_state_ = StartCode1;
392 pes_packet_bytes_ -= num_bytes;
393 prev_size = psm_data_.size();
394 psm_data_.resize(prev_size + num_bytes);
395 memcpy(&psm_data_[prev_size], read_ptr, num_bytes);
397 read_ptr += num_bytes;
400 num_bytes = end - read_ptr;
401 if (num_bytes >= pes_packet_bytes_) {
402 num_bytes = pes_packet_bytes_;
403 parse_state_ = StartCode1;
406 pes_packet_bytes_ -= num_bytes;
407 prev_size = ecm_.size();
408 ecm_.resize(prev_size + num_bytes);
409 memcpy(&ecm_[prev_size], read_ptr, num_bytes);
411 if ((pes_packet_bytes_ == 0) && !ecm_.empty()) {
416 read_ptr += num_bytes;
419 num_bytes = end - read_ptr;
420 if (num_bytes >= pes_packet_bytes_) {
421 num_bytes = pes_packet_bytes_;
422 parse_state_ = StartCode1;
425 pes_packet_bytes_ -= num_bytes;
426 prev_size = index_data_.size();
427 index_data_.resize(prev_size + num_bytes);
428 memcpy(&index_data_[prev_size], read_ptr, num_bytes);
430 if (pes_packet_bytes_ == 0 && !index_data_.empty()) {
431 if (!metadata_is_complete_) {
432 if (!ParseIndexEntry()) {
437 read_ptr += num_bytes;
440 num_bytes = end - read_ptr;
441 if (num_bytes >= pes_packet_bytes_) {
442 num_bytes = pes_packet_bytes_;
443 parse_state_ = StartCode1;
445 pes_packet_bytes_ -= num_bytes;
446 if (pes_stream_id_ != kV2MetadataStreamId) {
447 sample_data_.resize(sample_data_.size() + num_bytes);
448 memcpy(&sample_data_[sample_data_.size() - num_bytes], read_ptr,
451 prev_pes_stream_id_ = pes_stream_id_;
452 read_ptr += num_bytes;
455 num_bytes = end - read_ptr;
456 if (num_bytes >= pes_packet_bytes_) {
457 num_bytes = pes_packet_bytes_;
458 parse_state_ = StartCode1;
460 pes_packet_bytes_ -= num_bytes;
461 read_ptr += num_bytes;
464 parse_state_ = StartCode1;
465 metadata_is_complete_ =
true;
466 if (!DemuxNextPes(
true)) {
474 parse_state_ = StartCode1;
475 prev_media_sample_data_.Reset();
476 current_program_id_++;
489 bool WvmMediaParser::EmitLastSample(
491 const std::shared_ptr<MediaSample>& new_sample) {
492 std::string key = base::UintToString(current_program_id_)
494 .append(base::UintToString(stream_id));
495 std::map<std::string, uint32_t>::iterator it =
496 program_demux_stream_map_.find(key);
497 if (it == program_demux_stream_map_.end())
499 return EmitSample(stream_id, (*it).second, new_sample,
true);
502 bool WvmMediaParser::EmitPendingSamples() {
504 while (!media_sample_queue_.empty()) {
506 media_sample_queue_.front();
507 if (!EmitSample(demux_stream_media_sample.parsed_audio_or_video_stream_id,
508 demux_stream_media_sample.demux_stream_id,
509 demux_stream_media_sample.media_sample,
513 media_sample_queue_.pop_front();
518 bool WvmMediaParser::Flush() {
521 if (prev_media_sample_data_.audio_sample != NULL) {
522 if (!EmitLastSample(prev_pes_stream_id_,
523 prev_media_sample_data_.audio_sample)) {
524 LOG(ERROR) <<
"Did not emit last sample for audio stream with ID = " 525 << prev_pes_stream_id_;
529 if (prev_media_sample_data_.video_sample != NULL) {
530 if (!EmitLastSample(prev_pes_stream_id_,
531 prev_media_sample_data_.video_sample)) {
532 LOG(ERROR) <<
"Did not emit last sample for video stream with ID = " 533 << prev_pes_stream_id_;
540 bool WvmMediaParser::ParseIndexEntry() {
543 if (current_program_id_ > 0) {
546 uint32_t index_size = 0;
547 if (index_data_.size() < kIndexVersion4HeaderSize) {
551 const uint8_t* read_ptr = index_data_.data();
552 if (ntohlFromBuffer(read_ptr) != kIndexMagic) {
558 uint32_t version = ntohlFromBuffer(read_ptr);
560 if (version == kVersion4) {
561 index_size = kIndexVersion4HeaderSize + ntohlFromBuffer(read_ptr);
562 if (index_data_.size() < index_size) {
566 read_ptr +=
sizeof(uint32_t);
569 uint32_t index_metadata_max_size = index_size - kIndexVersion4HeaderSize;
570 if (index_metadata_max_size <
sizeof(uint8_t)) {
575 uint64_t track_duration = 0;
576 uint32_t trick_play_factor = 0;
577 uint32_t sampling_frequency = kDefaultSamplingFrequency;
578 uint32_t time_scale = kMpeg2ClockRate;
579 uint16_t video_width = 0;
580 uint16_t video_height = 0;
581 uint32_t pixel_width = 0;
582 uint32_t pixel_height = 0;
583 uint8_t nalu_length_size = kNaluLengthSize;
584 uint8_t num_channels = 0;
585 int audio_pes_stream_id = 0;
586 int video_pes_stream_id = 0;
587 bool has_video =
false;
588 bool has_audio =
false;
589 std::vector<uint8_t> audio_codec_config;
590 std::vector<uint8_t> video_codec_config;
591 uint8_t num_index_entries = *read_ptr;
593 --index_metadata_max_size;
595 for (uint8_t idx = 0; idx < num_index_entries; ++idx) {
596 if (index_metadata_max_size < (2 *
sizeof(uint8_t)) +
sizeof(uint32_t)) {
599 uint8_t tag = *read_ptr;
601 uint8_t type = *read_ptr;
603 uint32_t length = ntohlFromBuffer(read_ptr);
604 read_ptr +=
sizeof(uint32_t);
605 index_metadata_max_size -= (2 *
sizeof(uint8_t)) +
sizeof(uint32_t);
606 if (index_metadata_max_size < length) {
611 std::vector<uint8_t> binary_data;
612 switch (Type(type)) {
614 if (length ==
sizeof(uint8_t)) {
615 tagtype = GetTag(tag, length, read_ptr, &value);
621 if (length ==
sizeof(int8_t)) {
622 tagtype = GetTag(tag, length, read_ptr, &value);
628 if (length ==
sizeof(uint16_t)) {
629 tagtype = GetTag(tag, length, read_ptr, &value);
635 if (length ==
sizeof(int16_t)) {
636 tagtype = GetTag(tag, length, read_ptr, &value);
642 if (length ==
sizeof(uint32_t)) {
643 tagtype = GetTag(tag, length, read_ptr, &value);
649 if (length ==
sizeof(int32_t)) {
650 tagtype = GetTag(tag, length, read_ptr, &value);
656 if (length ==
sizeof(uint64_t)) {
657 tagtype = GetTag(tag, length, read_ptr, &value);
663 if (length ==
sizeof(int64_t)) {
664 tagtype = GetTag(tag, length, read_ptr, &value);
670 case Type_BinaryData:
671 binary_data.assign(read_ptr, read_ptr + length);
680 track_duration = value;
682 case TrackTrickPlayFactor:
683 trick_play_factor = value;
686 video_pes_stream_id = value;
689 audio_pes_stream_id = value;
692 video_width = (uint16_t)value;
695 video_height = (uint16_t)value;
697 case AudioNumChannels:
698 num_channels = (uint8_t)value;
706 case VideoPixelWidth:
707 pixel_width =
static_cast<uint32_t
>(value);
709 case VideoPixelHeight:
710 pixel_height =
static_cast<uint32_t
>(value);
712 case Audio_EsDescriptor: {
714 if (!descriptor.
Parse(binary_data)) {
716 "Could not extract AudioSpecificConfig from ES_Descriptor";
719 audio_codec_config = descriptor.decoder_config_descriptor()
720 .decoder_specific_info_descriptor()
724 case Audio_EC3SpecificData:
725 case Audio_DtsSpecificData:
726 case Audio_AC3SpecificData:
727 LOG(ERROR) <<
"Audio type not supported.";
729 case Video_AVCDecoderConfigurationRecord:
730 video_codec_config = binary_data;
737 index_metadata_max_size -= length;
740 index_size = read_ptr - index_data_.data();
744 stream_id_count_, time_scale, track_duration, kCodecH264,
745 byte_to_unit_stream_converter_.stream_format(), std::string(),
746 video_codec_config.data(), video_codec_config.size(), video_width,
747 video_height, pixel_width, pixel_height,
748 0 , trick_play_factor, nalu_length_size,
749 std::string(), decryption_key_source_ ? false :
true));
750 program_demux_stream_map_[base::UintToString(index_program_id_) +
":" +
753 ? video_pes_stream_id
754 : kDefaultVideoStreamId)] =
758 const Codec audio_codec = kCodecAAC;
761 stream_id_count_, time_scale, track_duration, audio_codec,
762 std::string(), audio_codec_config.data(), audio_codec_config.size(),
763 kAacSampleSizeBits, num_channels, sampling_frequency,
766 decryption_key_source_ ? false :
true));
767 program_demux_stream_map_[base::UintToString(index_program_id_) +
":" +
770 ? audio_pes_stream_id
771 : kDefaultAudioStreamId)] =
781 bool WvmMediaParser::DemuxNextPes(
bool is_program_end) {
782 bool output_encrypted_sample =
false;
783 if (!sample_data_.empty() && (prev_pes_flags_1_ & kScramblingBitsMask)) {
785 if (!content_decryptor_) {
786 output_encrypted_sample =
true;
788 content_decryptor_->Crypt(&sample_data_[crypto_unit_start_pos_],
789 sample_data_.size() - crypto_unit_start_pos_,
790 &sample_data_[crypto_unit_start_pos_]);
795 if ((pes_flags_2_ & kPesOptPts) || is_program_end) {
796 if (!sample_data_.empty()) {
797 if (!Output(output_encrypted_sample)) {
801 StartMediaSampleDemux();
804 crypto_unit_start_pos_ = sample_data_.size();
808 void WvmMediaParser::StartMediaSampleDemux() {
809 bool is_key_frame = ((pes_flags_1_ & kPesOptAlign) != 0);
811 media_sample_->set_dts(dts_);
812 media_sample_->set_pts(pts_);
813 media_sample_->set_is_key_frame(is_key_frame);
815 sample_data_.clear();
818 bool WvmMediaParser::Output(
bool output_encrypted_sample) {
819 if (output_encrypted_sample) {
820 media_sample_->SetData(sample_data_.data(), sample_data_.size());
821 media_sample_->set_is_encrypted(
true);
823 if ((prev_pes_stream_id_ & kPesStreamIdVideoMask) == kPesStreamIdVideo) {
825 std::vector<uint8_t> nal_unit_stream;
826 if (!byte_to_unit_stream_converter_.ConvertByteStreamToNalUnitStream(
827 sample_data_.data(), sample_data_.size(), &nal_unit_stream)) {
828 LOG(ERROR) <<
"Could not convert h.264 byte stream sample";
831 media_sample_->SetData(nal_unit_stream.data(), nal_unit_stream.size());
832 if (!is_initialized_) {
835 std::vector<uint8_t> decoder_config_record;
836 byte_to_unit_stream_converter_.GetDecoderConfigurationRecord(
837 &decoder_config_record);
838 for (uint32_t i = 0; i < stream_infos_.size(); i++) {
839 if (stream_infos_[i]->stream_type() == kStreamVideo &&
840 stream_infos_[i]->codec_string().empty()) {
841 const std::vector<uint8_t>* stream_config;
842 if (stream_infos_[i]->codec_config().empty()) {
845 stream_infos_[i]->set_codec_config(decoder_config_record);
846 stream_config = &decoder_config_record;
849 stream_config = &stream_infos_[i]->codec_config();
851 DCHECK(stream_config);
856 if (!avc_config.
Parse(*stream_config)) {
857 LOG(WARNING) <<
"Failed to parse AVCDecoderConfigurationRecord. " 858 "Using computed configuration record instead.";
859 video_stream_info->set_codec_config(decoder_config_record);
860 if (!avc_config.
Parse(decoder_config_record)) {
861 LOG(ERROR) <<
"Failed to parse AVCDecoderConfigurationRecord.";
865 const FourCC codec_fourcc =
866 byte_to_unit_stream_converter_.stream_format() ==
867 H26xStreamFormat::kNalUnitStreamWithParameterSetNalus
870 video_stream_info->set_codec_string(
873 if (avc_config.pixel_width() != video_stream_info->
pixel_width() ||
874 avc_config.pixel_height() !=
876 LOG_IF(WARNING, video_stream_info->
pixel_width() != 0 ||
878 <<
"Pixel aspect ratio in WVM metadata (" 881 <<
") does not match with SAR in " 882 "AVCDecoderConfigurationRecord (" 883 << avc_config.pixel_width() <<
"," 884 << avc_config.pixel_height()
885 <<
"). Use AVCDecoderConfigurationRecord.";
886 video_stream_info->set_pixel_width(avc_config.pixel_width());
887 video_stream_info->set_pixel_height(avc_config.pixel_height());
889 if (avc_config.coded_width() != video_stream_info->width() ||
890 avc_config.coded_height() != video_stream_info->height()) {
891 LOG(WARNING) <<
"Resolution in WVM metadata (" 892 << video_stream_info->width() <<
"," 893 << video_stream_info->height()
894 <<
") does not match with resolution in " 895 "AVCDecoderConfigurationRecord (" 896 << avc_config.coded_width() <<
"," 897 << avc_config.coded_height()
898 <<
"). Use AVCDecoderConfigurationRecord.";
899 video_stream_info->set_width(avc_config.coded_width());
900 video_stream_info->set_height(avc_config.coded_height());
905 }
else if ((prev_pes_stream_id_ & kPesStreamIdAudioMask) ==
909 const uint8_t* frame_ptr = sample_data_.data();
910 if (!adts_header.
Parse(frame_ptr, sample_data_.size())) {
911 LOG(ERROR) <<
"Could not parse ADTS header";
914 media_sample_->SetData(
917 if (!is_initialized_) {
918 for (uint32_t i = 0; i < stream_infos_.size(); i++) {
919 if (stream_infos_[i]->stream_type() == kStreamAudio &&
920 stream_infos_[i]->codec_string().empty()) {
923 if (audio_stream_info->codec_config().empty()) {
926 audio_stream_info->set_sampling_frequency(
928 std::vector<uint8_t> audio_specific_config;
930 audio_stream_info->set_codec_config(audio_specific_config);
931 audio_stream_info->set_codec_string(
938 if (!aac_config.
Parse(stream_infos_[i]->codec_config())) {
939 LOG(ERROR) <<
"Could not parse AACAudioSpecificconfig";
942 audio_stream_info->set_sampling_frequency(
944 audio_stream_info->set_codec_string(
954 if (!is_initialized_) {
955 bool all_streams_have_config =
true;
957 for (uint32_t i = 0; i < stream_infos_.size(); i++) {
958 if (stream_infos_[i]->codec_string().empty()) {
959 all_streams_have_config =
false;
963 if (all_streams_have_config) {
964 init_cb_.Run(stream_infos_);
965 is_initialized_ =
true;
969 DCHECK_GT(media_sample_->data_size(), 0UL);
970 std::string key = base::UintToString(current_program_id_).append(
":")
971 .append(base::UintToString(prev_pes_stream_id_));
972 std::map<std::string, uint32_t>::iterator it =
973 program_demux_stream_map_.find(key);
974 if (it == program_demux_stream_map_.end()) {
980 demux_stream_media_sample.parsed_audio_or_video_stream_id =
982 demux_stream_media_sample.demux_stream_id = (*it).second;
983 demux_stream_media_sample.media_sample = media_sample_;
985 if (!is_initialized_) {
986 media_sample_queue_.push_back(demux_stream_media_sample);
989 while (!media_sample_queue_.empty()) {
990 if (!EmitPendingSamples())
994 if (!EmitSample(prev_pes_stream_id_, (*it).second, media_sample_,
false))
1000 bool WvmMediaParser::EmitSample(uint32_t parsed_audio_or_video_stream_id,
1002 const std::shared_ptr<MediaSample>& new_sample,
1003 bool isLastSample) {
1006 if ((parsed_audio_or_video_stream_id & kPesStreamIdVideoMask) ==
1007 kPesStreamIdVideo) {
1008 new_sample->set_duration(prev_media_sample_data_.video_sample_duration);
1009 }
else if ((parsed_audio_or_video_stream_id & kPesStreamIdAudioMask) ==
1010 kPesStreamIdAudio) {
1011 new_sample->set_duration(prev_media_sample_data_.audio_sample_duration);
1013 if (!new_sample_cb_.Run(stream_id, new_sample)) {
1014 LOG(ERROR) <<
"Failed to process the last sample.";
1022 if ((parsed_audio_or_video_stream_id & kPesStreamIdVideoMask) ==
1023 kPesStreamIdVideo) {
1024 if (prev_media_sample_data_.video_sample == NULL) {
1025 prev_media_sample_data_.video_sample = new_sample;
1026 prev_media_sample_data_.video_stream_id = stream_id;
1029 prev_media_sample_data_.video_sample->set_duration(
1030 new_sample->dts() - prev_media_sample_data_.video_sample->dts());
1031 prev_media_sample_data_.video_sample_duration =
1032 prev_media_sample_data_.video_sample->duration();
1033 if (!new_sample_cb_.Run(prev_media_sample_data_.video_stream_id,
1034 prev_media_sample_data_.video_sample)) {
1035 LOG(ERROR) <<
"Failed to process the video sample.";
1038 prev_media_sample_data_.video_sample = new_sample;
1039 prev_media_sample_data_.video_stream_id = stream_id;
1040 }
else if ((parsed_audio_or_video_stream_id & kPesStreamIdAudioMask) ==
1041 kPesStreamIdAudio) {
1042 if (prev_media_sample_data_.audio_sample == NULL) {
1043 prev_media_sample_data_.audio_sample = new_sample;
1044 prev_media_sample_data_.audio_stream_id = stream_id;
1047 prev_media_sample_data_.audio_sample->set_duration(
1048 new_sample->dts() - prev_media_sample_data_.audio_sample->dts());
1049 prev_media_sample_data_.audio_sample_duration =
1050 prev_media_sample_data_.audio_sample->duration();
1051 if (!new_sample_cb_.Run(prev_media_sample_data_.audio_stream_id,
1052 prev_media_sample_data_.audio_sample)) {
1053 LOG(ERROR) <<
"Failed to process the audio sample.";
1056 prev_media_sample_data_.audio_sample = new_sample;
1057 prev_media_sample_data_.audio_stream_id = stream_id;
1062 bool WvmMediaParser::GetAssetKey(
const uint8_t* asset_id,
1064 DCHECK(decryption_key_source_);
1065 Status status = decryption_key_source_->FetchKeys(
1066 EmeInitDataType::WIDEVINE_CLASSIC,
1067 std::vector<uint8_t>(asset_id, asset_id +
sizeof(uint32_t)));
1069 LOG(ERROR) <<
"Fetch Key(s) failed for AssetID = " 1070 << ntohlFromBuffer(asset_id) <<
", error = " << status;
1074 const char kHdStreamLabel[] =
"HD";
1075 status = decryption_key_source_->GetKey(kHdStreamLabel, encryption_key);
1077 LOG(ERROR) <<
"Fetch Key(s) failed for AssetID = " 1078 << ntohlFromBuffer(asset_id) <<
", error = " << status;
1085 bool WvmMediaParser::ProcessEcm() {
1087 if (!decryption_key_source_)
1090 if (current_program_id_ > 0) {
1093 if (ecm_.size() != kEcmSizeBytes) {
1094 LOG(ERROR) <<
"Unexpected ECM size = " << ecm_.size()
1095 <<
", expected size = " << kEcmSizeBytes;
1098 const uint8_t* ecm_data = ecm_.data();
1100 ecm_data +=
sizeof(uint32_t);
1101 ecm_data +=
sizeof(uint32_t);
1102 ecm_data +=
sizeof(uint32_t);
1104 if (!GetAssetKey(ecm_data, &encryption_key)) {
1107 if (encryption_key.key.size() < kAssetKeySizeBytes) {
1108 LOG(ERROR) <<
"Asset Key size of " << encryption_key.key.size()
1109 <<
" for AssetID = " << ntohlFromBuffer(ecm_data)
1110 <<
" is less than minimum asset key size.";
1113 ecm_data +=
sizeof(uint32_t);
1117 std::vector<uint8_t> asset_key(
1118 encryption_key.key.begin(),
1119 encryption_key.key.begin() + kAssetKeySizeBytes);
1121 std::vector<uint8_t> zero_iv(kInitializationVectorSizeBytes, 0);
1122 AesCbcDecryptor asset_decryptor(kCtsPadding, AesCryptor::kUseConstantIv);
1124 LOG(ERROR) <<
"Failed to initialize asset_decryptor.";
1128 const size_t content_key_buffer_size =
1129 kEcmFlagsSizeBytes + kEcmContentKeySizeBytes +
1130 kEcmPaddingSizeBytes;
1131 std::vector<uint8_t> content_key_buffer(content_key_buffer_size);
1132 CHECK(asset_decryptor.Crypt(ecm_data, content_key_buffer_size,
1133 content_key_buffer.data()));
1135 std::vector<uint8_t> decrypted_content_key_vec(
1136 content_key_buffer.begin() + 4,
1137 content_key_buffer.begin() + 20);
1138 std::unique_ptr<AesCbcDecryptor> content_decryptor(
1140 if (!content_decryptor->InitializeWithIv(decrypted_content_key_vec,
1142 LOG(ERROR) <<
"Failed to initialize content decryptor.";
1146 content_decryptor_ = std::move(content_decryptor);
1150 DemuxStreamIdMediaSample::DemuxStreamIdMediaSample() :
1152 parsed_audio_or_video_stream_id(0) {}
1154 DemuxStreamIdMediaSample::~DemuxStreamIdMediaSample() {}
1156 PrevSampleData::PrevSampleData() {
1160 PrevSampleData::~PrevSampleData() {}
1162 void PrevSampleData::Reset() {
1163 audio_sample = NULL;
1164 video_sample = NULL;
1165 audio_stream_id = 0;
1166 video_stream_id = 0;
1167 audio_sample_duration = 0;
1168 video_sample_duration = 0;
All the methods that are virtual are virtual for mocking.