5 #include "packager/media/formats/wvm/wvm_media_parser.h"
11 #include "packager/base/stl_util.h"
12 #include "packager/base/strings/string_number_conversions.h"
13 #include "packager/media/base/aes_encryptor.h"
14 #include "packager/media/base/audio_stream_info.h"
15 #include "packager/media/base/key_source.h"
16 #include "packager/media/base/media_sample.h"
17 #include "packager/media/base/status.h"
18 #include "packager/media/base/video_stream_info.h"
19 #include "packager/media/filters/h264_parser.h"
20 #include "packager/media/formats/mp2t/adts_header.h"
21 #include "packager/media/formats/mp4/aac_audio_specific_config.h"
22 #include "packager/media/formats/mp4/es_descriptor.h"
24 #define HAS_HEADER_EXTENSION(x) ((x != 0xBC) && (x != 0xBE) && (x != 0xBF) \
25 && (x != 0xF0) && (x != 0xF2) && (x != 0xF8) \
29 const uint32_t kMpeg2ClockRate = 90000;
30 const uint32_t kPesOptPts = 0x80;
31 const uint32_t kPesOptDts = 0x40;
32 const uint32_t kPesOptAlign = 0x04;
33 const uint32_t kPsmStreamId = 0xBC;
34 const uint32_t kPaddingStreamId = 0xBE;
35 const uint32_t kIndexMagic = 0x49444d69;
36 const uint32_t kIndexStreamId = 0xBF;
37 const uint32_t kIndexVersion4HeaderSize = 12;
38 const uint32_t kEcmStreamId = 0xF0;
39 const uint32_t kV2MetadataStreamId = 0xF1;
40 const uint32_t kScramblingBitsMask = 0x30;
41 const uint32_t kStartCode1 = 0x00;
42 const uint32_t kStartCode2 = 0x00;
43 const uint32_t kStartCode3 = 0x01;
44 const uint32_t kStartCode4Pack = 0xBA;
45 const uint32_t kStartCode4System = 0xBB;
46 const uint32_t kStartCode4ProgramEnd = 0xB9;
47 const uint32_t kPesStreamIdVideoMask = 0xF0;
48 const uint32_t kPesStreamIdVideo = 0xE0;
49 const uint32_t kPesStreamIdAudioMask = 0xE0;
50 const uint32_t kPesStreamIdAudio = 0xC0;
51 const uint32_t kVersion4 = 4;
52 const int kAdtsHeaderMinSize = 7;
53 const uint8_t kAacSampleSizeBits = 16;
55 const uint8_t kNaluLengthSize = 4;
58 const uint32_t kDefaultSamplingFrequency = 100;
59 const uint16_t kEcmSizeBytes = 80;
60 const uint32_t kInitializationVectorSizeBytes = 16;
62 const uint32_t kEcmContentKeySizeBytes = 16;
63 const uint32_t kEcmDCPFlagsSizeBytes = 3;
64 const uint32_t kEcmCCIFlagsSizeBytes = 1;
65 const uint32_t kEcmFlagsSizeBytes =
66 kEcmCCIFlagsSizeBytes + kEcmDCPFlagsSizeBytes;
67 const uint32_t kEcmPaddingSizeBytes = 12;
68 const uint32_t kAssetKeySizeBytes = 16;
70 const uint8_t kDefaultAudioStreamId = kPesStreamIdAudio;
71 const uint8_t kDefaultVideoStreamId = kPesStreamIdVideo;
88 namespace edash_packager {
92 WvmMediaParser::WvmMediaParser()
93 : is_initialized_(false),
94 parse_state_(StartCode1),
97 metadata_is_complete_(false),
98 current_program_id_(0),
100 prev_pes_stream_id_(0),
101 pes_packet_bytes_(0),
104 prev_pes_flags_1_(0),
105 pes_header_data_bytes_(0),
109 index_program_id_(0),
111 crypto_unit_start_pos_(0),
113 decryption_key_source_(NULL) {
116 WvmMediaParser::~WvmMediaParser() {}
118 void WvmMediaParser::Init(
const InitCB& init_cb,
119 const NewSampleCB& new_sample_cb,
121 DCHECK(!is_initialized_);
122 DCHECK(!init_cb.is_null());
123 DCHECK(!new_sample_cb.is_null());
124 decryption_key_source_ = decryption_key_source;
126 new_sample_cb_ = new_sample_cb;
129 bool WvmMediaParser::Parse(
const uint8_t* buf,
int size) {
130 uint32_t num_bytes, prev_size;
131 num_bytes = prev_size = 0;
132 uint8_t* read_ptr = (uint8_t*)(&buf[0]);
133 uint8_t* end = read_ptr + size;
135 while (read_ptr < end) {
136 switch(parse_state_) {
138 if (*read_ptr == kStartCode1) {
139 parse_state_ = StartCode2;
143 if (*read_ptr == kStartCode2) {
144 parse_state_ = StartCode3;
146 parse_state_ = StartCode1;
150 if (*read_ptr == kStartCode3) {
151 parse_state_ = StartCode4;
153 parse_state_ = StartCode1;
158 case kStartCode4Pack:
159 parse_state_ = PackHeader1;
161 case kStartCode4System:
162 parse_state_ = SystemHeader1;
164 case kStartCode4ProgramEnd:
165 parse_state_ = ProgramEnd;
168 parse_state_ = PesStreamId;
173 parse_state_ = PackHeader2;
176 parse_state_ = PackHeader3;
179 parse_state_ = PackHeader4;
182 parse_state_ = PackHeader5;
185 parse_state_ = PackHeader6;
188 parse_state_ = PackHeader7;
191 parse_state_ = PackHeader8;
194 parse_state_ = PackHeader9;
197 parse_state_ = PackHeader10;
200 skip_bytes_ = *read_ptr & 0x07;
201 parse_state_ = PackHeaderStuffingSkip;
204 skip_bytes_ = *read_ptr;
206 parse_state_ = SystemHeader2;
209 skip_bytes_ |= *read_ptr;
210 parse_state_ = SystemHeaderSkip;
212 case PackHeaderStuffingSkip:
213 if ((end - read_ptr) >= (int32_t)skip_bytes_) {
214 read_ptr += skip_bytes_;
216 parse_state_ = StartCode1;
218 skip_bytes_ -= (end - read_ptr);
222 case SystemHeaderSkip:
223 if ((end - read_ptr) >= (int32_t)skip_bytes_) {
224 read_ptr += skip_bytes_;
226 parse_state_ = StartCode1;
228 uint32_t remaining_size = end - read_ptr;
229 skip_bytes_ -= remaining_size;
234 pes_stream_id_ = *read_ptr;
235 if (!metadata_is_complete_ &&
236 (pes_stream_id_ != kPsmStreamId) &&
237 (pes_stream_id_ != kIndexStreamId) &&
238 (pes_stream_id_ != kEcmStreamId) &&
239 (pes_stream_id_ != kV2MetadataStreamId) &&
240 (pes_stream_id_ != kPaddingStreamId)) {
241 metadata_is_complete_ =
true;
243 parse_state_ = PesPacketLength1;
245 case PesPacketLength1:
246 pes_packet_bytes_ = *read_ptr;
247 pes_packet_bytes_ <<= 8;
248 parse_state_ = PesPacketLength2;
250 case PesPacketLength2:
251 pes_packet_bytes_ |= *read_ptr;
252 if (HAS_HEADER_EXTENSION(pes_stream_id_)) {
253 parse_state_ = PesExtension1;
255 pes_flags_1_ = pes_flags_2_ = 0;
256 pes_header_data_bytes_ = 0;
257 parse_state_ = PesPayload;
261 prev_pes_flags_1_ = pes_flags_1_;
262 pes_flags_1_ = *read_ptr;
263 *read_ptr &= ~kScramblingBitsMask;
265 parse_state_ = PesExtension2;
268 pes_flags_2_ = *read_ptr;
270 parse_state_ = PesExtension3;
273 pes_header_data_bytes_ = *read_ptr;
275 if (pes_flags_2_ & kPesOptPts) {
278 parse_state_ = PesHeaderData;
282 timestamp_ = (*read_ptr & 0x0E);
283 --pes_header_data_bytes_;
289 timestamp_ |= *read_ptr;
290 --pes_header_data_bytes_;
296 timestamp_ |= *read_ptr >> 1;
297 --pes_header_data_bytes_;
303 timestamp_ |= *read_ptr;
304 --pes_header_data_bytes_;
310 timestamp_ |= *read_ptr >> 1;
312 --pes_header_data_bytes_;
314 if (pes_flags_2_ & kPesOptDts) {
318 parse_state_ = PesHeaderData;
322 timestamp_ = (*read_ptr & 0x0E);
323 --pes_header_data_bytes_;
329 timestamp_ |= *read_ptr;
330 --pes_header_data_bytes_;
336 timestamp_ |= *read_ptr >> 1;
337 --pes_header_data_bytes_;
343 timestamp_ |= *read_ptr;
344 --pes_header_data_bytes_;
350 timestamp_ |= *read_ptr >> 1;
352 --pes_header_data_bytes_;
354 parse_state_ = PesHeaderData;
357 num_bytes = end - read_ptr;
358 if (num_bytes >= pes_header_data_bytes_) {
359 num_bytes = pes_header_data_bytes_;
360 parse_state_ = PesPayload;
362 pes_header_data_bytes_ -= num_bytes;
363 pes_packet_bytes_ -= num_bytes;
364 read_ptr += num_bytes;
367 switch (pes_stream_id_) {
370 parse_state_ = PsmPayload;
372 case kPaddingStreamId:
373 parse_state_ = Padding;
377 parse_state_ = EcmPayload;
380 parse_state_ = IndexPayload;
383 if (!DemuxNextPes(
false)) {
386 parse_state_ = EsPayload;
390 num_bytes = end - read_ptr;
391 if (num_bytes >= pes_packet_bytes_) {
392 num_bytes = pes_packet_bytes_;
393 parse_state_ = StartCode1;
396 pes_packet_bytes_ -= num_bytes;
397 prev_size = psm_data_.size();
398 psm_data_.resize(prev_size + num_bytes);
399 memcpy(&psm_data_[prev_size], read_ptr, num_bytes);
401 read_ptr += num_bytes;
404 num_bytes = end - read_ptr;
405 if (num_bytes >= pes_packet_bytes_) {
406 num_bytes = pes_packet_bytes_;
407 parse_state_ = StartCode1;
410 pes_packet_bytes_ -= num_bytes;
411 prev_size = ecm_.size();
412 ecm_.resize(prev_size + num_bytes);
413 memcpy(&ecm_[prev_size], read_ptr, num_bytes);
415 if ((pes_packet_bytes_ == 0) && !ecm_.empty()) {
420 read_ptr += num_bytes;
423 num_bytes = end - read_ptr;
424 if (num_bytes >= pes_packet_bytes_) {
425 num_bytes = pes_packet_bytes_;
426 parse_state_ = StartCode1;
429 pes_packet_bytes_ -= num_bytes;
430 prev_size = index_data_.size();
431 index_data_.resize(prev_size + num_bytes);
432 memcpy(&index_data_[prev_size], read_ptr, num_bytes);
434 if (pes_packet_bytes_ == 0 && !index_data_.empty()) {
435 if (!metadata_is_complete_) {
436 if (!ParseIndexEntry()) {
441 read_ptr += num_bytes;
444 num_bytes = end - read_ptr;
445 if (num_bytes >= pes_packet_bytes_) {
446 num_bytes = pes_packet_bytes_;
447 parse_state_ = StartCode1;
449 pes_packet_bytes_ -= num_bytes;
450 if (pes_stream_id_ != kV2MetadataStreamId) {
451 sample_data_.resize(sample_data_.size() + num_bytes);
452 memcpy(&sample_data_[sample_data_.size() - num_bytes], read_ptr,
455 prev_pes_stream_id_ = pes_stream_id_;
456 read_ptr += num_bytes;
459 num_bytes = end - read_ptr;
460 if (num_bytes >= pes_packet_bytes_) {
461 num_bytes = pes_packet_bytes_;
462 parse_state_ = StartCode1;
464 pes_packet_bytes_ -= num_bytes;
465 read_ptr += num_bytes;
468 parse_state_ = StartCode1;
469 metadata_is_complete_ =
true;
470 if (!DemuxNextPes(
true)) {
476 parse_state_ = StartCode1;
477 prev_media_sample_data_.Reset();
478 current_program_id_++;
491 bool WvmMediaParser::EmitLastSample(uint32_t stream_id,
492 scoped_refptr<MediaSample>& new_sample) {
493 std::string key = base::UintToString(current_program_id_)
495 .append(base::UintToString(stream_id));
496 std::map<std::string, uint32_t>::iterator it =
497 program_demux_stream_map_.find(key);
498 if (it == program_demux_stream_map_.end())
500 return EmitSample(stream_id, (*it).second, new_sample,
true);
503 bool WvmMediaParser::EmitPendingSamples() {
505 while (!media_sample_queue_.empty()) {
506 DemuxStreamIdMediaSample& demux_stream_media_sample =
507 media_sample_queue_.front();
508 if (!EmitSample(demux_stream_media_sample.parsed_audio_or_video_stream_id,
509 demux_stream_media_sample.demux_stream_id,
510 demux_stream_media_sample.media_sample,
514 media_sample_queue_.pop_front();
519 void WvmMediaParser::Flush() {
522 if (prev_media_sample_data_.audio_sample != NULL) {
523 if (!EmitLastSample(prev_pes_stream_id_,
524 prev_media_sample_data_.audio_sample)) {
525 LOG(ERROR) <<
"Did not emit last sample for audio stream with ID = "
526 << 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_;
538 bool WvmMediaParser::ParseIndexEntry() {
541 if (current_program_id_ > 0) {
544 uint32_t index_size = 0;
545 if (index_data_.size() < kIndexVersion4HeaderSize) {
549 const uint8_t* read_ptr = vector_as_array(&index_data_);
550 if (ntohlFromBuffer(read_ptr) != kIndexMagic) {
556 uint32_t version = ntohlFromBuffer(read_ptr);
558 if (version == kVersion4) {
559 index_size = kIndexVersion4HeaderSize + ntohlFromBuffer(read_ptr);
560 if (index_data_.size() < index_size) {
564 read_ptr +=
sizeof(uint32_t);
567 uint32_t index_metadata_max_size = index_size - kIndexVersion4HeaderSize;
568 if (index_metadata_max_size <
sizeof(uint8_t)) {
573 uint64_t track_duration = 0;
574 int16_t trick_play_rate = 0;
575 uint32_t sampling_frequency = kDefaultSamplingFrequency;
576 uint32_t time_scale = kMpeg2ClockRate;
577 uint16_t video_width = 0;
578 uint16_t video_height = 0;
579 uint32_t pixel_width = 0;
580 uint32_t pixel_height = 0;
581 uint8_t nalu_length_size = kNaluLengthSize;
582 uint8_t num_channels = 0;
583 int audio_pes_stream_id = 0;
584 int video_pes_stream_id = 0;
585 bool has_video =
false;
586 bool has_audio =
false;
587 std::vector<uint8_t> audio_codec_config;
588 std::vector<uint8_t> video_codec_config;
589 uint8_t num_index_entries = *read_ptr;
591 --index_metadata_max_size;
593 for (uint8_t idx = 0; idx < num_index_entries; ++idx) {
594 if (index_metadata_max_size < (2 *
sizeof(uint8_t)) +
sizeof(uint32_t)) {
597 uint8_t tag = *read_ptr;
599 uint8_t type = *read_ptr;
601 uint32_t length = ntohlFromBuffer(read_ptr);
602 read_ptr +=
sizeof(uint32_t);
603 index_metadata_max_size -= (2 *
sizeof(uint8_t)) +
sizeof(uint32_t);
604 if (index_metadata_max_size < length) {
609 std::vector<uint8_t> binary_data;
610 switch (Type(type)) {
612 if (length ==
sizeof(uint8_t)) {
613 tagtype = GetTag(tag, length, read_ptr, &value);
619 if (length ==
sizeof(int8_t)) {
620 tagtype = GetTag(tag, length, read_ptr, &value);
626 if (length ==
sizeof(uint16_t)) {
627 tagtype = GetTag(tag, length, read_ptr, &value);
633 if (length ==
sizeof(int16_t)) {
634 tagtype = GetTag(tag, length, read_ptr, &value);
640 if (length ==
sizeof(uint32_t)) {
641 tagtype = GetTag(tag, length, read_ptr, &value);
647 if (length ==
sizeof(int32_t)) {
648 tagtype = GetTag(tag, length, read_ptr, &value);
654 if (length ==
sizeof(uint64_t)) {
655 tagtype = GetTag(tag, length, read_ptr, &value);
661 if (length ==
sizeof(int64_t)) {
662 tagtype = GetTag(tag, length, read_ptr, &value);
668 case Type_BinaryData:
669 binary_data.assign(read_ptr, read_ptr + length);
678 track_duration = value;
680 case TrackTrickPlayRate:
681 trick_play_rate = value;
684 video_pes_stream_id = value;
687 audio_pes_stream_id = value;
690 video_width = (uint16_t)value;
693 video_height = (uint16_t)value;
695 case AudioNumChannels:
696 num_channels = (uint8_t)value;
704 case VideoPixelWidth:
705 pixel_width =
static_cast<uint32_t
>(value);
707 case VideoPixelHeight:
708 pixel_height =
static_cast<uint32_t
>(value);
710 case Audio_EsDescriptor: {
711 mp4::ESDescriptor descriptor;
712 if (!descriptor.Parse(binary_data)) {
714 "Could not extract AudioSpecificConfig from ES_Descriptor";
717 audio_codec_config = descriptor.decoder_specific_info();
720 case Audio_EC3SpecificData:
721 case Audio_DtsSpecificData:
722 case Audio_AC3SpecificData:
723 LOG(ERROR) <<
"Audio type not supported.";
725 case AVCDecoderConfigurationRecord:
726 video_codec_config = binary_data;
733 index_metadata_max_size -= length;
736 index_size = read_ptr - vector_as_array(&index_data_);
739 VideoCodec video_codec = kCodecH264;
740 stream_infos_.push_back(
new VideoStreamInfo(
741 stream_id_count_, time_scale, track_duration, video_codec,
742 std::string(), std::string(), video_width, video_height,
743 pixel_width, pixel_height, trick_play_rate, nalu_length_size,
744 vector_as_array(&video_codec_config), video_codec_config.size(),
746 program_demux_stream_map_[base::UintToString(index_program_id_) +
":" +
747 base::UintToString(video_pes_stream_id ?
748 video_pes_stream_id :
749 kDefaultVideoStreamId)] =
753 AudioCodec audio_codec = kCodecAAC;
754 stream_infos_.push_back(
new AudioStreamInfo(
755 stream_id_count_, time_scale, track_duration, audio_codec,
756 std::string(), std::string(), kAacSampleSizeBits, num_channels,
757 sampling_frequency, vector_as_array(&audio_codec_config),
758 audio_codec_config.size(),
true));
759 program_demux_stream_map_[base::UintToString(index_program_id_) +
":" +
760 base::UintToString(audio_pes_stream_id ?
761 audio_pes_stream_id :
762 kDefaultAudioStreamId)] =
772 bool WvmMediaParser::DemuxNextPes(
bool is_program_end) {
773 bool output_encrypted_sample =
false;
774 if (!sample_data_.empty() && (prev_pes_flags_1_ & kScramblingBitsMask)) {
776 if (!content_decryptor_) {
777 output_encrypted_sample =
true;
779 content_decryptor_->Decrypt(&sample_data_[crypto_unit_start_pos_],
780 sample_data_.size() - crypto_unit_start_pos_,
781 &sample_data_[crypto_unit_start_pos_]);
786 if ((pes_flags_2_ & kPesOptPts) || is_program_end) {
787 if (!sample_data_.empty()) {
788 if (!Output(output_encrypted_sample)) {
792 StartMediaSampleDemux();
795 crypto_unit_start_pos_ = sample_data_.size();
799 void WvmMediaParser::StartMediaSampleDemux() {
800 bool is_key_frame = ((pes_flags_1_ & kPesOptAlign) != 0);
802 media_sample_->set_dts(dts_);
803 media_sample_->set_pts(pts_);
804 media_sample_->set_is_key_frame(is_key_frame);
806 sample_data_.clear();
809 bool WvmMediaParser::Output(
bool output_encrypted_sample) {
810 if (output_encrypted_sample) {
811 media_sample_->set_data(vector_as_array(&sample_data_),
812 sample_data_.size());
813 media_sample_->set_is_encrypted(
true);
815 if ((prev_pes_stream_id_ & kPesStreamIdVideoMask) == kPesStreamIdVideo) {
817 std::vector<uint8_t> nal_unit_stream;
818 if (!byte_to_unit_stream_converter_.ConvertByteStreamToNalUnitStream(
819 vector_as_array(&sample_data_), sample_data_.size(),
821 LOG(ERROR) <<
"Could not convert h.264 byte stream sample";
824 media_sample_->set_data(nal_unit_stream.data(), nal_unit_stream.size());
825 if (!is_initialized_) {
828 std::vector<uint8_t> decoder_config_record;
829 byte_to_unit_stream_converter_.GetAVCDecoderConfigurationRecord(
830 &decoder_config_record);
831 for (uint32_t i = 0; i < stream_infos_.size(); i++) {
832 if (stream_infos_[i]->stream_type() == media::kStreamVideo &&
833 stream_infos_[i]->codec_string().empty()) {
834 const std::vector<uint8_t>* stream_config;
835 if (stream_infos_[i]->extra_data().empty()) {
838 stream_infos_[i]->set_extra_data(decoder_config_record);
839 stream_config = &decoder_config_record;
842 stream_config = &stream_infos_[i]->extra_data();
844 DCHECK(stream_config);
846 kCodecH264, (*stream_config)[1], (*stream_config)[2],
847 (*stream_config)[3]));
849 VideoStreamInfo* video_stream_info =
850 reinterpret_cast<VideoStreamInfo*
>(stream_infos_[i].get());
851 uint32_t coded_width = 0;
852 uint32_t coded_height = 0;
853 uint32_t pixel_width = 0;
854 uint32_t pixel_height = 0;
855 if (!ExtractResolutionFromDecoderConfig(
856 vector_as_array(stream_config), stream_config->size(),
857 &coded_width, &coded_height, &pixel_width, &pixel_height)) {
858 LOG(WARNING) <<
"Failed to parse AVCDecoderConfigurationRecord. "
859 "Using computed configuration record instead.";
860 video_stream_info->set_extra_data(decoder_config_record);
861 if (!ExtractResolutionFromDecoderConfig(
862 vector_as_array(&decoder_config_record),
863 decoder_config_record.size(),
864 &coded_width, &coded_height, &pixel_width, &pixel_height)) {
865 LOG(ERROR) <<
"Failed to parse AVCDecoderConfigurationRecord.";
869 if (pixel_width != video_stream_info->pixel_width() ||
870 pixel_height != video_stream_info->pixel_height()) {
871 LOG_IF(WARNING, video_stream_info->pixel_width() != 0 ||
872 video_stream_info->pixel_height() != 0)
873 <<
"Pixel aspect ratio in WVM metadata ("
874 << video_stream_info->pixel_width() <<
","
875 << video_stream_info->pixel_height()
876 <<
") does not match with SAR in "
877 "AVCDecoderConfigurationRecord ("
878 << pixel_width <<
"," << pixel_height
879 <<
"). Use AVCDecoderConfigurationRecord.";
880 video_stream_info->set_pixel_width(pixel_width);
881 video_stream_info->set_pixel_height(pixel_height);
883 if (coded_width != video_stream_info->width() ||
884 coded_height != video_stream_info->height()) {
885 LOG(WARNING) <<
"Resolution in WVM metadata ("
886 << video_stream_info->width() <<
","
887 << video_stream_info->height()
888 <<
") does not match with resolution in "
889 "AVCDecoderConfigurationRecord ("
890 << coded_width <<
"," << coded_height
891 <<
"). Use AVCDecoderConfigurationRecord.";
892 video_stream_info->set_width(coded_width);
893 video_stream_info->set_height(coded_height);
898 }
else if ((prev_pes_stream_id_ & kPesStreamIdAudioMask) ==
902 vector_as_array(&sample_data_), kAdtsHeaderMinSize);
903 media::mp2t::AdtsHeader adts_header;
904 const uint8_t* frame_ptr = vector_as_array(&sample_data_);
905 if (!adts_header.Parse(frame_ptr, frame_size)) {
906 LOG(ERROR) <<
"Could not parse ADTS header";
909 size_t header_size = adts_header.GetAdtsHeaderSize(frame_ptr,
911 media_sample_->set_data(frame_ptr + header_size,
912 frame_size - header_size);
913 if (!is_initialized_) {
914 for (uint32_t i = 0; i < stream_infos_.size(); i++) {
915 if (stream_infos_[i]->stream_type() == media::kStreamAudio &&
916 stream_infos_[i]->codec_string().empty()) {
917 AudioStreamInfo* audio_stream_info =
918 reinterpret_cast<AudioStreamInfo*
>(stream_infos_[i].get());
919 if (audio_stream_info->extra_data().empty()) {
922 audio_stream_info->set_sampling_frequency(
923 adts_header.GetSamplingFrequency());
924 std::vector<uint8_t> audio_specific_config;
925 if (!adts_header.GetAudioSpecificConfig(&audio_specific_config)) {
926 LOG(ERROR) <<
"Could not compute AACaudiospecificconfig";
929 audio_stream_info->set_extra_data(audio_specific_config);
930 audio_stream_info->set_codec_string(
932 kCodecAAC, adts_header.GetObjectType()));
936 mp4::AACAudioSpecificConfig aac_config;
937 if (!aac_config.Parse(stream_infos_[i]->extra_data())) {
938 LOG(ERROR) <<
"Could not parse AACAudioSpecificconfig";
941 audio_stream_info->set_sampling_frequency(aac_config.frequency());
942 audio_stream_info->set_codec_string(
944 kCodecAAC, aac_config.audio_object_type()));
952 if (!is_initialized_) {
953 bool all_streams_have_config =
true;
955 for (uint32_t i = 0; i < stream_infos_.size(); i++) {
956 if (stream_infos_[i]->codec_string().empty()) {
957 all_streams_have_config =
false;
961 if (all_streams_have_config) {
962 init_cb_.Run(stream_infos_);
963 is_initialized_ =
true;
967 DCHECK_GT(media_sample_->data_size(), 0UL);
968 std::string key = base::UintToString(current_program_id_).append(
":")
969 .append(base::UintToString(prev_pes_stream_id_));
970 std::map<std::string, uint32_t>::iterator it =
971 program_demux_stream_map_.find(key);
972 if (it == program_demux_stream_map_.end()) {
977 DemuxStreamIdMediaSample demux_stream_media_sample;
978 demux_stream_media_sample.parsed_audio_or_video_stream_id =
980 demux_stream_media_sample.demux_stream_id = (*it).second;
981 demux_stream_media_sample.media_sample = media_sample_;
983 if (!is_initialized_) {
984 media_sample_queue_.push_back(demux_stream_media_sample);
987 while (!media_sample_queue_.empty()) {
988 if (!EmitPendingSamples())
992 if (!EmitSample(prev_pes_stream_id_, (*it).second, media_sample_,
false))
998 bool WvmMediaParser::EmitSample(uint32_t parsed_audio_or_video_stream_id,
1000 scoped_refptr<MediaSample>& new_sample,
1001 bool isLastSample) {
1004 if ((parsed_audio_or_video_stream_id & kPesStreamIdVideoMask) ==
1005 kPesStreamIdVideo) {
1006 new_sample->set_duration(prev_media_sample_data_.video_sample_duration);
1007 }
else if ((parsed_audio_or_video_stream_id & kPesStreamIdAudioMask) ==
1008 kPesStreamIdAudio) {
1009 new_sample->set_duration(prev_media_sample_data_.audio_sample_duration);
1011 if (!new_sample_cb_.Run(stream_id, new_sample)) {
1012 LOG(ERROR) <<
"Failed to process the last sample.";
1020 if ((parsed_audio_or_video_stream_id & kPesStreamIdVideoMask) ==
1021 kPesStreamIdVideo) {
1022 if (prev_media_sample_data_.video_sample == NULL) {
1023 prev_media_sample_data_.video_sample = new_sample;
1024 prev_media_sample_data_.video_stream_id = stream_id;
1027 prev_media_sample_data_.video_sample->set_duration(
1028 new_sample->dts() - prev_media_sample_data_.video_sample->dts());
1029 prev_media_sample_data_.video_sample_duration =
1030 prev_media_sample_data_.video_sample->duration();
1031 if (!new_sample_cb_.Run(prev_media_sample_data_.video_stream_id,
1032 prev_media_sample_data_.video_sample)) {
1033 LOG(ERROR) <<
"Failed to process the video sample.";
1036 prev_media_sample_data_.video_sample = new_sample;
1037 prev_media_sample_data_.video_stream_id = stream_id;
1038 }
else if ((parsed_audio_or_video_stream_id & kPesStreamIdAudioMask) ==
1039 kPesStreamIdAudio) {
1040 if (prev_media_sample_data_.audio_sample == NULL) {
1041 prev_media_sample_data_.audio_sample = new_sample;
1042 prev_media_sample_data_.audio_stream_id = stream_id;
1045 prev_media_sample_data_.audio_sample->set_duration(
1046 new_sample->dts() - prev_media_sample_data_.audio_sample->dts());
1047 prev_media_sample_data_.audio_sample_duration =
1048 prev_media_sample_data_.audio_sample->duration();
1049 if (!new_sample_cb_.Run(prev_media_sample_data_.audio_stream_id,
1050 prev_media_sample_data_.audio_sample)) {
1051 LOG(ERROR) <<
"Failed to process the audio sample.";
1054 prev_media_sample_data_.audio_sample = new_sample;
1055 prev_media_sample_data_.audio_stream_id = stream_id;
1060 bool WvmMediaParser::GetAssetKey(
const uint32_t asset_id,
1061 EncryptionKey* encryption_key) {
1062 DCHECK(decryption_key_source_);
1063 Status status = decryption_key_source_->FetchKeys(asset_id);
1065 LOG(ERROR) <<
"Fetch Key(s) failed for AssetID = " << asset_id
1066 <<
", error = " << status;
1070 status = decryption_key_source_->GetKey(KeySource::TRACK_TYPE_HD,
1073 LOG(ERROR) <<
"Fetch Key(s) failed for AssetID = " << asset_id
1074 <<
", error = " << status;
1081 bool WvmMediaParser::ProcessEcm() {
1083 if (!decryption_key_source_)
1086 if (current_program_id_ > 0) {
1089 if (ecm_.size() != kEcmSizeBytes) {
1090 LOG(ERROR) <<
"Unexpected ECM size = " << ecm_.size()
1091 <<
", expected size = " << kEcmSizeBytes;
1094 const uint8_t* ecm_data = ecm_.data();
1096 ecm_data +=
sizeof(uint32_t);
1097 ecm_data +=
sizeof(uint32_t);
1098 ecm_data +=
sizeof(uint32_t);
1099 uint32_t asset_id = ntohlFromBuffer(ecm_data);
1100 if (asset_id == 0) {
1101 LOG(ERROR) <<
"AssetID in ECM is not valid.";
1104 ecm_data +=
sizeof(uint32_t);
1105 EncryptionKey encryption_key;
1106 if (!GetAssetKey(asset_id, &encryption_key)) {
1109 if (encryption_key.key.size() < kAssetKeySizeBytes) {
1110 LOG(ERROR) <<
"Asset Key size of " << encryption_key.key.size()
1111 <<
" for AssetID = " << asset_id
1112 <<
" is less than minimum asset key size.";
1118 std::vector<uint8_t> asset_key(
1119 encryption_key.key.begin(),
1120 encryption_key.key.begin() + kAssetKeySizeBytes);
1121 std::vector<uint8_t> iv(kInitializationVectorSizeBytes);
1122 AesCbcCtsDecryptor asset_decryptor;
1123 if (!asset_decryptor.InitializeWithIv(asset_key, iv)) {
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 asset_decryptor.Decrypt(
1133 ecm_data, content_key_buffer_size, vector_as_array(&content_key_buffer));
1135 std::vector<uint8_t> decrypted_content_key_vec(
1136 content_key_buffer.begin() + 4,
1137 content_key_buffer.begin() + 20);
1138 scoped_ptr<AesCbcCtsDecryptor> content_decryptor(
new AesCbcCtsDecryptor);
1139 if (!content_decryptor->InitializeWithIv(decrypted_content_key_vec, iv)) {
1140 LOG(ERROR) <<
"Failed to initialize content decryptor.";
1144 content_decryptor_ = content_decryptor.Pass();
1148 DemuxStreamIdMediaSample::DemuxStreamIdMediaSample() :
1150 parsed_audio_or_video_stream_id(0) {}
1152 DemuxStreamIdMediaSample::~DemuxStreamIdMediaSample() {}
1154 PrevSampleData::PrevSampleData() {
1158 PrevSampleData::~PrevSampleData() {}
1160 void PrevSampleData::Reset() {
1161 audio_sample = NULL;
1162 video_sample = NULL;
1163 audio_stream_id = 0;
1164 video_stream_id = 0;
1165 audio_sample_duration = 0;
1166 video_sample_duration = 0;