5#include <packager/media/formats/wvm/wvm_media_parser.h>
16#include <absl/base/internal/endian.h>
17#include <absl/log/check.h>
18#include <absl/log/log.h>
19#include <absl/strings/str_format.h>
21#include <packager/media/base/aes_cryptor.h>
22#include <packager/media/base/aes_decryptor.h>
23#include <packager/media/base/aes_encryptor.h>
24#include <packager/media/base/audio_stream_info.h>
25#include <packager/media/base/fourccs.h>
26#include <packager/media/base/key_source.h>
27#include <packager/media/base/media_sample.h>
28#include <packager/media/base/stream_info.h>
29#include <packager/media/base/video_stream_info.h>
30#include <packager/media/codecs/aac_audio_specific_config.h>
31#include <packager/media/codecs/avc_decoder_configuration_record.h>
32#include <packager/media/codecs/es_descriptor.h>
33#include <packager/media/formats/mp2t/adts_header.h>
34#include <packager/status.h>
36#define HAS_HEADER_EXTENSION(x) \
37 ((x != 0xBC) && (x != 0xBE) && (x != 0xBF) && (x != 0xF0) && (x != 0xF2) && \
38 (x != 0xF8) && (x != 0xFF))
41const uint32_t kMpeg2ClockRate = 90000;
42const uint32_t kPesOptPts = 0x80;
43const uint32_t kPesOptDts = 0x40;
44const uint32_t kPesOptAlign = 0x04;
45const uint32_t kPsmStreamId = 0xBC;
46const uint32_t kPaddingStreamId = 0xBE;
47const uint32_t kIndexMagic = 0x49444d69;
48const uint32_t kIndexStreamId = 0xBF;
49const uint32_t kIndexVersion4HeaderSize = 12;
50const uint32_t kEcmStreamId = 0xF0;
51const uint32_t kV2MetadataStreamId = 0xF1;
52const uint32_t kScramblingBitsMask = 0x30;
53const uint32_t kStartCode1 = 0x00;
54const uint32_t kStartCode2 = 0x00;
55const uint32_t kStartCode3 = 0x01;
56const uint32_t kStartCode4Pack = 0xBA;
57const uint32_t kStartCode4System = 0xBB;
58const uint32_t kStartCode4ProgramEnd = 0xB9;
59const uint32_t kPesStreamIdVideoMask = 0xF0;
60const uint32_t kPesStreamIdVideo = 0xE0;
61const uint32_t kPesStreamIdAudioMask = 0xE0;
62const uint32_t kPesStreamIdAudio = 0xC0;
63const uint32_t kVersion4 = 4;
64const uint8_t kAacSampleSizeBits = 16;
66const uint8_t kNaluLengthSize = 4;
69const uint32_t kDefaultSamplingFrequency = 100;
70const uint16_t kEcmSizeBytes = 80;
71const uint32_t kInitializationVectorSizeBytes = 16;
73const uint32_t kEcmContentKeySizeBytes = 16;
74const uint32_t kEcmDCPFlagsSizeBytes = 3;
75const uint32_t kEcmCCIFlagsSizeBytes = 1;
76const uint32_t kEcmFlagsSizeBytes =
77 kEcmCCIFlagsSizeBytes + kEcmDCPFlagsSizeBytes;
78const uint32_t kEcmPaddingSizeBytes = 12;
79const uint32_t kAssetKeySizeBytes = 16;
81const uint8_t kDefaultAudioStreamId = kPesStreamIdAudio;
82const uint8_t kDefaultVideoStreamId = kPesStreamIdVideo;
103WvmMediaParser::WvmMediaParser()
104 : is_initialized_(false),
105 parse_state_(StartCode1),
107 metadata_is_complete_(false),
108 current_program_id_(0),
110 prev_pes_stream_id_(0),
111 pes_packet_bytes_(0),
114 prev_pes_flags_1_(0),
115 pes_header_data_bytes_(0),
119 index_program_id_(0),
121 crypto_unit_start_pos_(0),
123 decryption_key_source_(NULL) {}
125WvmMediaParser::~WvmMediaParser() {}
127void WvmMediaParser::Init(
const InitCB& init_cb,
131 DCHECK(!is_initialized_);
132 DCHECK(init_cb !=
nullptr);
133 DCHECK(new_media_sample_cb !=
nullptr);
134 decryption_key_source_ = decryption_key_source;
136 new_sample_cb_ = new_media_sample_cb;
139bool WvmMediaParser::Parse(
const uint8_t* buf,
int size) {
140 size_t num_bytes = 0;
141 size_t prev_size = 0;
142 const uint8_t* read_ptr = buf;
143 const uint8_t* end = read_ptr + size;
145 while (read_ptr < end) {
146 switch (parse_state_) {
148 if (*read_ptr == kStartCode1) {
149 parse_state_ = StartCode2;
153 if (*read_ptr == kStartCode2) {
154 parse_state_ = StartCode3;
156 parse_state_ = StartCode1;
160 if (*read_ptr == kStartCode3) {
161 parse_state_ = StartCode4;
163 parse_state_ = StartCode1;
168 case kStartCode4Pack:
169 parse_state_ = PackHeader1;
171 case kStartCode4System:
172 parse_state_ = SystemHeader1;
174 case kStartCode4ProgramEnd:
175 parse_state_ = ProgramEnd;
178 parse_state_ = PesStreamId;
183 parse_state_ = PackHeader2;
186 parse_state_ = PackHeader3;
189 parse_state_ = PackHeader4;
192 parse_state_ = PackHeader5;
195 parse_state_ = PackHeader6;
198 parse_state_ = PackHeader7;
201 parse_state_ = PackHeader8;
204 parse_state_ = PackHeader9;
207 parse_state_ = PackHeader10;
210 skip_bytes_ = *read_ptr & 0x07;
211 parse_state_ = PackHeaderStuffingSkip;
214 skip_bytes_ = *read_ptr;
216 parse_state_ = SystemHeader2;
219 skip_bytes_ |= *read_ptr;
220 parse_state_ = SystemHeaderSkip;
222 case PackHeaderStuffingSkip:
223 if (end >= skip_bytes_ + read_ptr) {
224 read_ptr += skip_bytes_;
226 parse_state_ = StartCode1;
228 skip_bytes_ -= (end - read_ptr);
232 case SystemHeaderSkip:
233 if (end >= skip_bytes_ + read_ptr) {
234 read_ptr += skip_bytes_;
236 parse_state_ = StartCode1;
238 uint32_t remaining_size = end - read_ptr;
239 skip_bytes_ -= remaining_size;
244 pes_stream_id_ = *read_ptr;
245 if (!metadata_is_complete_ && (pes_stream_id_ != kPsmStreamId) &&
246 (pes_stream_id_ != kIndexStreamId) &&
247 (pes_stream_id_ != kEcmStreamId) &&
248 (pes_stream_id_ != kV2MetadataStreamId) &&
249 (pes_stream_id_ != kPaddingStreamId)) {
250 metadata_is_complete_ =
true;
252 parse_state_ = PesPacketLength1;
254 case PesPacketLength1:
255 pes_packet_bytes_ = *read_ptr;
256 pes_packet_bytes_ <<= 8;
257 parse_state_ = PesPacketLength2;
259 case PesPacketLength2:
260 pes_packet_bytes_ |= *read_ptr;
261 if (HAS_HEADER_EXTENSION(pes_stream_id_)) {
262 parse_state_ = PesExtension1;
264 prev_pes_flags_1_ = pes_flags_1_;
265 pes_flags_1_ = pes_flags_2_ = 0;
266 pes_header_data_bytes_ = 0;
267 parse_state_ = PesPayload;
271 prev_pes_flags_1_ = pes_flags_1_;
272 pes_flags_1_ = *read_ptr;
274 parse_state_ = PesExtension2;
277 pes_flags_2_ = *read_ptr;
279 parse_state_ = PesExtension3;
282 pes_header_data_bytes_ = *read_ptr;
284 if (pes_flags_2_ & kPesOptPts) {
287 parse_state_ = PesHeaderData;
291 timestamp_ = (*read_ptr & 0x0E);
292 --pes_header_data_bytes_;
298 timestamp_ |= *read_ptr;
299 --pes_header_data_bytes_;
305 timestamp_ |= *read_ptr >> 1;
306 --pes_header_data_bytes_;
312 timestamp_ |= *read_ptr;
313 --pes_header_data_bytes_;
319 timestamp_ |= *read_ptr >> 1;
321 --pes_header_data_bytes_;
323 if (pes_flags_2_ & kPesOptDts) {
327 parse_state_ = PesHeaderData;
331 timestamp_ = (*read_ptr & 0x0E);
332 --pes_header_data_bytes_;
338 timestamp_ |= *read_ptr;
339 --pes_header_data_bytes_;
345 timestamp_ |= *read_ptr >> 1;
346 --pes_header_data_bytes_;
352 timestamp_ |= *read_ptr;
353 --pes_header_data_bytes_;
359 timestamp_ |= *read_ptr >> 1;
361 --pes_header_data_bytes_;
363 parse_state_ = PesHeaderData;
366 num_bytes = end - read_ptr;
367 if (num_bytes >= pes_header_data_bytes_) {
368 num_bytes = pes_header_data_bytes_;
369 parse_state_ = PesPayload;
371 pes_header_data_bytes_ -= num_bytes;
372 pes_packet_bytes_ -= num_bytes;
373 read_ptr += num_bytes;
376 switch (pes_stream_id_) {
379 parse_state_ = PsmPayload;
381 case kPaddingStreamId:
382 parse_state_ = Padding;
386 parse_state_ = EcmPayload;
389 parse_state_ = IndexPayload;
392 if (!DemuxNextPes(
false)) {
395 parse_state_ = EsPayload;
399 num_bytes = end - read_ptr;
400 if (num_bytes >= pes_packet_bytes_) {
401 num_bytes = pes_packet_bytes_;
402 parse_state_ = StartCode1;
405 pes_packet_bytes_ -= num_bytes;
406 prev_size = psm_data_.size();
407 psm_data_.resize(prev_size + num_bytes);
408 memcpy(&psm_data_[prev_size], read_ptr, num_bytes);
410 read_ptr += num_bytes;
413 num_bytes = end - read_ptr;
414 if (num_bytes >= pes_packet_bytes_) {
415 num_bytes = pes_packet_bytes_;
416 parse_state_ = StartCode1;
419 pes_packet_bytes_ -= num_bytes;
420 prev_size = ecm_.size();
421 ecm_.resize(prev_size + num_bytes);
422 memcpy(&ecm_[prev_size], read_ptr, num_bytes);
424 if ((pes_packet_bytes_ == 0) && !ecm_.empty()) {
429 read_ptr += num_bytes;
432 num_bytes = end - read_ptr;
433 if (num_bytes >= pes_packet_bytes_) {
434 num_bytes = pes_packet_bytes_;
435 parse_state_ = StartCode1;
438 pes_packet_bytes_ -= num_bytes;
439 prev_size = index_data_.size();
440 index_data_.resize(prev_size + num_bytes);
441 memcpy(&index_data_[prev_size], read_ptr, num_bytes);
443 if (pes_packet_bytes_ == 0 && !index_data_.empty()) {
444 if (!metadata_is_complete_) {
445 if (!ParseIndexEntry()) {
450 read_ptr += num_bytes;
453 num_bytes = end - read_ptr;
454 if (num_bytes >= pes_packet_bytes_) {
455 num_bytes = pes_packet_bytes_;
456 parse_state_ = StartCode1;
458 pes_packet_bytes_ -= num_bytes;
459 if (pes_stream_id_ != kV2MetadataStreamId) {
460 sample_data_.resize(sample_data_.size() + num_bytes);
461 memcpy(&sample_data_[sample_data_.size() - num_bytes], read_ptr,
464 prev_pes_stream_id_ = pes_stream_id_;
465 read_ptr += num_bytes;
468 num_bytes = end - read_ptr;
469 if (num_bytes >= pes_packet_bytes_) {
470 num_bytes = pes_packet_bytes_;
471 parse_state_ = StartCode1;
473 pes_packet_bytes_ -= num_bytes;
474 read_ptr += num_bytes;
477 parse_state_ = StartCode1;
478 metadata_is_complete_ =
true;
479 if (!DemuxNextPes(
true)) {
487 parse_state_ = StartCode1;
488 prev_media_sample_data_.Reset();
489 current_program_id_++;
502bool WvmMediaParser::EmitLastSample(
504 const std::shared_ptr<MediaSample>& new_sample) {
505 std::string key = absl::StrFormat(
"%u:%u", current_program_id_, stream_id);
506 std::map<std::string, uint32_t>::iterator it =
507 program_demux_stream_map_.find(key);
508 if (it == program_demux_stream_map_.end())
510 return EmitSample(stream_id, (*it).second, new_sample,
true);
513bool WvmMediaParser::EmitPendingSamples() {
515 while (!media_sample_queue_.empty()) {
516 DemuxStreamIdMediaSample& demux_stream_media_sample =
517 media_sample_queue_.front();
518 if (!EmitSample(demux_stream_media_sample.parsed_audio_or_video_stream_id,
519 demux_stream_media_sample.demux_stream_id,
520 demux_stream_media_sample.media_sample,
false)) {
523 media_sample_queue_.pop_front();
528bool WvmMediaParser::Flush() {
531 if (prev_media_sample_data_.audio_sample != NULL) {
532 if (!EmitLastSample(prev_pes_stream_id_,
533 prev_media_sample_data_.audio_sample)) {
534 LOG(ERROR) <<
"Did not emit last sample for audio stream with ID = "
535 << prev_pes_stream_id_;
539 if (prev_media_sample_data_.video_sample != NULL) {
540 if (!EmitLastSample(prev_pes_stream_id_,
541 prev_media_sample_data_.video_sample)) {
542 LOG(ERROR) <<
"Did not emit last sample for video stream with ID = "
543 << prev_pes_stream_id_;
550bool WvmMediaParser::ParseIndexEntry() {
553 if (current_program_id_ > 0) {
556 uint32_t index_size = 0;
557 if (index_data_.size() < kIndexVersion4HeaderSize) {
561 const uint8_t* read_ptr = index_data_.data();
562 if (absl::big_endian::Load32(read_ptr) != kIndexMagic) {
568 uint32_t version = absl::big_endian::Load32(read_ptr);
570 if (version == kVersion4) {
571 index_size = kIndexVersion4HeaderSize + absl::big_endian::Load32(read_ptr);
572 if (index_data_.size() < index_size) {
576 read_ptr +=
sizeof(uint32_t);
579 uint32_t index_metadata_max_size = index_size - kIndexVersion4HeaderSize;
580 if (index_metadata_max_size <
sizeof(uint8_t)) {
585 int64_t track_duration = 0;
586 uint32_t trick_play_factor = 0;
587 uint32_t sampling_frequency = kDefaultSamplingFrequency;
588 int32_t time_scale = kMpeg2ClockRate;
589 uint16_t video_width = 0;
590 uint16_t video_height = 0;
591 uint32_t pixel_width = 0;
592 uint32_t pixel_height = 0;
593 uint8_t nalu_length_size = kNaluLengthSize;
594 uint8_t num_channels = 0;
595 int audio_pes_stream_id = 0;
596 int video_pes_stream_id = 0;
597 bool has_video =
false;
598 bool has_audio =
false;
599 std::vector<uint8_t> audio_codec_config;
600 std::vector<uint8_t> video_codec_config;
601 uint8_t num_index_entries = *read_ptr;
603 --index_metadata_max_size;
605 for (uint8_t idx = 0; idx < num_index_entries; ++idx) {
606 if (index_metadata_max_size < (2 *
sizeof(uint8_t)) +
sizeof(uint32_t)) {
609 uint8_t tag = *read_ptr;
611 uint8_t type = *read_ptr;
613 uint32_t length = absl::big_endian::Load32(read_ptr);
614 read_ptr +=
sizeof(uint32_t);
615 index_metadata_max_size -= (2 *
sizeof(uint8_t)) +
sizeof(uint32_t);
616 if (index_metadata_max_size < length) {
621 std::vector<uint8_t> binary_data;
622 switch (Type(type)) {
624 if (length ==
sizeof(uint8_t)) {
625 tagtype = GetTag(tag, length, read_ptr, &value);
631 if (length ==
sizeof(int8_t)) {
632 tagtype = GetTag(tag, length, read_ptr, &value);
638 if (length ==
sizeof(uint16_t)) {
639 tagtype = GetTag(tag, length, read_ptr, &value);
645 if (length ==
sizeof(int16_t)) {
646 tagtype = GetTag(tag, length, read_ptr, &value);
652 if (length ==
sizeof(uint32_t)) {
653 tagtype = GetTag(tag, length, read_ptr, &value);
659 if (length ==
sizeof(int32_t)) {
660 tagtype = GetTag(tag, length, read_ptr, &value);
666 if (length ==
sizeof(uint64_t)) {
667 tagtype = GetTag(tag, length, read_ptr, &value);
673 if (length ==
sizeof(int64_t)) {
674 tagtype = GetTag(tag, length, read_ptr, &value);
680 case Type_BinaryData:
681 binary_data.assign(read_ptr, read_ptr + length);
690 track_duration = value;
692 case TrackTrickPlayFactor:
693 trick_play_factor = value;
696 video_pes_stream_id = value;
699 audio_pes_stream_id = value;
702 video_width = (uint16_t)value;
705 video_height = (uint16_t)value;
707 case AudioNumChannels:
708 num_channels = (uint8_t)value;
716 case VideoPixelWidth:
717 pixel_width =
static_cast<uint32_t
>(value);
719 case VideoPixelHeight:
720 pixel_height =
static_cast<uint32_t
>(value);
722 case Audio_EsDescriptor: {
723 ESDescriptor descriptor;
724 if (!descriptor.Parse(binary_data)) {
726 <<
"Could not extract AudioSpecificConfig from ES_Descriptor";
729 audio_codec_config = descriptor.decoder_config_descriptor()
730 .decoder_specific_info_descriptor()
734 case Audio_EC3SpecificData:
735 case Audio_DtsSpecificData:
736 case Audio_AC3SpecificData:
737 LOG(ERROR) <<
"Audio type not supported.";
739 case Video_AVCDecoderConfigurationRecord:
740 video_codec_config = binary_data;
747 index_metadata_max_size -= length;
750 index_size = read_ptr - index_data_.data();
753 stream_infos_.emplace_back(
new VideoStreamInfo(
754 stream_id_count_, time_scale, track_duration, kCodecH264,
755 byte_to_unit_stream_converter_.stream_format(), std::string(),
756 video_codec_config.data(), video_codec_config.size(), video_width,
757 video_height, pixel_width, pixel_height, 0 ,
759 trick_play_factor, nalu_length_size, std::string(),
760 decryption_key_source_ ?
false : true));
761 program_demux_stream_map_[absl::StrFormat(
762 "%u:%u", index_program_id_,
763 video_pes_stream_id ? video_pes_stream_id : kDefaultVideoStreamId)] =
767 const Codec audio_codec = kCodecAAC;
769 stream_infos_.emplace_back(
new AudioStreamInfo(
770 stream_id_count_, time_scale, track_duration, audio_codec,
771 std::string(), audio_codec_config.data(), audio_codec_config.size(),
772 kAacSampleSizeBits, num_channels, sampling_frequency,
775 decryption_key_source_ ?
false : true));
776 program_demux_stream_map_[absl::StrFormat(
777 "%u:%u", index_program_id_,
778 audio_pes_stream_id ? audio_pes_stream_id : kDefaultAudioStreamId)] =
788bool WvmMediaParser::DemuxNextPes(
bool is_program_end) {
789 bool output_encrypted_sample =
false;
790 if (!sample_data_.empty() && (prev_pes_flags_1_ & kScramblingBitsMask)) {
792 if (!content_decryptor_) {
793 output_encrypted_sample =
true;
795 size_t output_size = content_decryptor_->RequiredOutputSize(
796 sample_data_.size() - crypto_unit_start_pos_);
797 content_decryptor_->Crypt(&sample_data_[crypto_unit_start_pos_],
798 sample_data_.size() - crypto_unit_start_pos_,
799 &sample_data_[crypto_unit_start_pos_],
805 if ((pes_flags_2_ & kPesOptPts) || is_program_end) {
806 if (!sample_data_.empty()) {
807 if (!Output(output_encrypted_sample)) {
811 StartMediaSampleDemux();
814 crypto_unit_start_pos_ = sample_data_.size();
818void WvmMediaParser::StartMediaSampleDemux() {
819 bool is_key_frame = ((pes_flags_1_ & kPesOptAlign) != 0);
820 media_sample_ = MediaSample::CreateEmptyMediaSample();
821 media_sample_->set_dts(dts_);
822 media_sample_->set_pts(pts_);
823 media_sample_->set_is_key_frame(is_key_frame);
825 sample_data_.clear();
828bool WvmMediaParser::Output(
bool output_encrypted_sample) {
829 if (output_encrypted_sample) {
830 media_sample_->SetData(sample_data_.data(), sample_data_.size());
831 media_sample_->set_is_encrypted(
true);
833 if ((prev_pes_stream_id_ & kPesStreamIdVideoMask) == kPesStreamIdVideo) {
835 std::vector<uint8_t> nal_unit_stream;
836 if (!byte_to_unit_stream_converter_.ConvertByteStreamToNalUnitStream(
837 sample_data_.data(), sample_data_.size(), &nal_unit_stream)) {
838 LOG(ERROR) <<
"Could not convert h.264 byte stream sample";
841 media_sample_->SetData(nal_unit_stream.data(), nal_unit_stream.size());
842 if (!is_initialized_) {
845 std::vector<uint8_t> decoder_config_record;
846 byte_to_unit_stream_converter_.GetDecoderConfigurationRecord(
847 &decoder_config_record);
848 for (uint32_t i = 0; i < stream_infos_.size(); i++) {
849 if (stream_infos_[i]->stream_type() == kStreamVideo &&
850 stream_infos_[i]->codec_string().empty()) {
851 const std::vector<uint8_t>* stream_config;
852 if (stream_infos_[i]->codec_config().empty()) {
855 stream_infos_[i]->set_codec_config(decoder_config_record);
856 stream_config = &decoder_config_record;
859 stream_config = &stream_infos_[i]->codec_config();
861 DCHECK(stream_config);
863 VideoStreamInfo* video_stream_info =
864 reinterpret_cast<VideoStreamInfo*
>(stream_infos_[i].get());
865 AVCDecoderConfigurationRecord avc_config;
866 if (!avc_config.Parse(*stream_config)) {
867 LOG(WARNING) <<
"Failed to parse AVCDecoderConfigurationRecord. "
868 "Using computed configuration record instead.";
869 video_stream_info->set_codec_config(decoder_config_record);
870 if (!avc_config.Parse(decoder_config_record)) {
871 LOG(ERROR) <<
"Failed to parse AVCDecoderConfigurationRecord.";
875 const FourCC codec_fourcc =
876 byte_to_unit_stream_converter_.stream_format() ==
877 H26xStreamFormat::kNalUnitStreamWithParameterSetNalus
880 video_stream_info->set_codec_string(
881 avc_config.GetCodecString(codec_fourcc));
883 if (avc_config.pixel_width() != video_stream_info->pixel_width() ||
884 avc_config.pixel_height() !=
885 video_stream_info->pixel_height()) {
886 LOG_IF(WARNING, video_stream_info->pixel_width() != 0 ||
887 video_stream_info->pixel_height() != 0)
888 <<
"Pixel aspect ratio in WVM metadata ("
889 << video_stream_info->pixel_width() <<
","
890 << video_stream_info->pixel_height()
891 <<
") does not match with SAR in "
892 "AVCDecoderConfigurationRecord ("
893 << avc_config.pixel_width() <<
","
894 << avc_config.pixel_height()
895 <<
"). Use AVCDecoderConfigurationRecord.";
896 video_stream_info->set_pixel_width(avc_config.pixel_width());
897 video_stream_info->set_pixel_height(avc_config.pixel_height());
899 if (avc_config.coded_width() != video_stream_info->width() ||
900 avc_config.coded_height() != video_stream_info->height()) {
901 LOG(WARNING) <<
"Resolution in WVM metadata ("
902 << video_stream_info->width() <<
","
903 << video_stream_info->height()
904 <<
") does not match with resolution in "
905 "AVCDecoderConfigurationRecord ("
906 << avc_config.coded_width() <<
","
907 << avc_config.coded_height()
908 <<
"). Use AVCDecoderConfigurationRecord.";
909 video_stream_info->set_width(avc_config.coded_width());
910 video_stream_info->set_height(avc_config.coded_height());
915 }
else if ((prev_pes_stream_id_ & kPesStreamIdAudioMask) ==
918 mp2t::AdtsHeader adts_header;
919 const uint8_t* frame_ptr = sample_data_.data();
920 if (!adts_header.Parse(frame_ptr, sample_data_.size())) {
921 LOG(ERROR) <<
"Could not parse ADTS header";
924 media_sample_->SetData(
925 frame_ptr + adts_header.GetHeaderSize(),
926 adts_header.GetFrameSize() - adts_header.GetHeaderSize());
927 if (!is_initialized_) {
928 for (uint32_t i = 0; i < stream_infos_.size(); i++) {
929 if (stream_infos_[i]->stream_type() == kStreamAudio &&
930 stream_infos_[i]->codec_string().empty()) {
931 AudioStreamInfo* audio_stream_info =
932 reinterpret_cast<AudioStreamInfo*
>(stream_infos_[i].get());
933 if (audio_stream_info->codec_config().empty()) {
936 audio_stream_info->set_sampling_frequency(
937 adts_header.GetSamplingFrequency());
938 std::vector<uint8_t> audio_specific_config;
939 adts_header.GetAudioSpecificConfig(&audio_specific_config);
940 audio_stream_info->set_codec_config(audio_specific_config);
941 audio_stream_info->set_codec_string(
942 AudioStreamInfo::GetCodecString(kCodecAAC,
943 adts_header.GetObjectType()));
947 AACAudioSpecificConfig aac_config;
948 if (!aac_config.Parse(stream_infos_[i]->codec_config())) {
949 LOG(ERROR) <<
"Could not parse AACAudioSpecificconfig";
952 audio_stream_info->set_sampling_frequency(
953 aac_config.GetSamplesPerSecond());
954 audio_stream_info->set_codec_string(
955 AudioStreamInfo::GetCodecString(
956 kCodecAAC, aac_config.GetAudioObjectType()));
964 if (!is_initialized_) {
965 bool all_streams_have_config =
true;
967 for (uint32_t i = 0; i < stream_infos_.size(); i++) {
968 if (stream_infos_[i]->codec_string().empty()) {
969 all_streams_have_config =
false;
973 if (all_streams_have_config) {
974 init_cb_(stream_infos_);
975 is_initialized_ =
true;
979 DCHECK_GT(media_sample_->data_size(), 0UL);
981 absl::StrFormat(
"%u:%u", current_program_id_, prev_pes_stream_id_);
982 std::map<std::string, uint32_t>::iterator it =
983 program_demux_stream_map_.find(key);
984 if (it == program_demux_stream_map_.end()) {
989 DemuxStreamIdMediaSample demux_stream_media_sample;
990 demux_stream_media_sample.parsed_audio_or_video_stream_id =
992 demux_stream_media_sample.demux_stream_id = (*it).second;
993 demux_stream_media_sample.media_sample = media_sample_;
995 if (!is_initialized_) {
996 media_sample_queue_.push_back(demux_stream_media_sample);
999 while (!media_sample_queue_.empty()) {
1000 if (!EmitPendingSamples())
1004 if (!EmitSample(prev_pes_stream_id_, (*it).second, media_sample_,
false))
1010bool WvmMediaParser::EmitSample(uint32_t parsed_audio_or_video_stream_id,
1012 const std::shared_ptr<MediaSample>& new_sample,
1013 bool isLastSample) {
1016 if ((parsed_audio_or_video_stream_id & kPesStreamIdVideoMask) ==
1017 kPesStreamIdVideo) {
1018 new_sample->set_duration(prev_media_sample_data_.video_sample_duration);
1019 }
else if ((parsed_audio_or_video_stream_id & kPesStreamIdAudioMask) ==
1020 kPesStreamIdAudio) {
1021 new_sample->set_duration(prev_media_sample_data_.audio_sample_duration);
1023 if (!new_sample_cb_(stream_id, new_sample)) {
1024 LOG(ERROR) <<
"Failed to process the last sample.";
1032 if ((parsed_audio_or_video_stream_id & kPesStreamIdVideoMask) ==
1033 kPesStreamIdVideo) {
1034 if (prev_media_sample_data_.video_sample == NULL) {
1035 prev_media_sample_data_.video_sample = new_sample;
1036 prev_media_sample_data_.video_stream_id = stream_id;
1039 prev_media_sample_data_.video_sample->set_duration(
1040 new_sample->dts() - prev_media_sample_data_.video_sample->dts());
1041 prev_media_sample_data_.video_sample_duration =
1042 prev_media_sample_data_.video_sample->duration();
1043 if (!new_sample_cb_(prev_media_sample_data_.video_stream_id,
1044 prev_media_sample_data_.video_sample)) {
1045 LOG(ERROR) <<
"Failed to process the video sample.";
1048 prev_media_sample_data_.video_sample = new_sample;
1049 prev_media_sample_data_.video_stream_id = stream_id;
1050 }
else if ((parsed_audio_or_video_stream_id & kPesStreamIdAudioMask) ==
1051 kPesStreamIdAudio) {
1052 if (prev_media_sample_data_.audio_sample == NULL) {
1053 prev_media_sample_data_.audio_sample = new_sample;
1054 prev_media_sample_data_.audio_stream_id = stream_id;
1057 prev_media_sample_data_.audio_sample->set_duration(
1058 new_sample->dts() - prev_media_sample_data_.audio_sample->dts());
1059 prev_media_sample_data_.audio_sample_duration =
1060 prev_media_sample_data_.audio_sample->duration();
1061 if (!new_sample_cb_(prev_media_sample_data_.audio_stream_id,
1062 prev_media_sample_data_.audio_sample)) {
1063 LOG(ERROR) <<
"Failed to process the audio sample.";
1066 prev_media_sample_data_.audio_sample = new_sample;
1067 prev_media_sample_data_.audio_stream_id = stream_id;
1072bool WvmMediaParser::GetAssetKey(
const uint8_t* asset_id,
1073 EncryptionKey* encryption_key) {
1074 DCHECK(decryption_key_source_);
1075 Status status = decryption_key_source_->FetchKeys(
1076 EmeInitDataType::WIDEVINE_CLASSIC,
1077 std::vector<uint8_t>(asset_id, asset_id +
sizeof(uint32_t)));
1079 LOG(ERROR) <<
"Fetch Key(s) failed for AssetID = "
1080 << absl::big_endian::Load32(asset_id) <<
", error = " << status;
1084 const char kHdStreamLabel[] =
"HD";
1085 status = decryption_key_source_->GetKey(kHdStreamLabel, encryption_key);
1087 LOG(ERROR) <<
"Fetch Key(s) failed for AssetID = "
1088 << absl::big_endian::Load32(asset_id) <<
", error = " << status;
1095bool WvmMediaParser::ProcessEcm() {
1097 if (!decryption_key_source_)
1100 if (current_program_id_ > 0) {
1103 if (ecm_.size() != kEcmSizeBytes) {
1104 LOG(ERROR) <<
"Unexpected ECM size = " << ecm_.size()
1105 <<
", expected size = " << kEcmSizeBytes;
1108 const uint8_t* ecm_data = ecm_.data();
1110 ecm_data +=
sizeof(uint32_t);
1111 ecm_data +=
sizeof(uint32_t);
1112 ecm_data +=
sizeof(uint32_t);
1113 EncryptionKey encryption_key;
1114 if (!GetAssetKey(ecm_data, &encryption_key)) {
1117 if (encryption_key.key.size() < kAssetKeySizeBytes) {
1118 LOG(ERROR) <<
"Asset Key size of " << encryption_key.key.size()
1119 <<
" for AssetID = " << absl::big_endian::Load32(ecm_data)
1120 <<
" is less than minimum asset key size.";
1123 ecm_data +=
sizeof(uint32_t);
1127 std::vector<uint8_t> asset_key(
1128 encryption_key.key.begin(),
1129 encryption_key.key.begin() + kAssetKeySizeBytes);
1131 std::vector<uint8_t> zero_iv(kInitializationVectorSizeBytes, 0);
1132 AesCbcDecryptor asset_decryptor(kCtsPadding, AesCryptor::kUseConstantIv);
1133 if (!asset_decryptor.InitializeWithIv(asset_key, zero_iv)) {
1134 LOG(ERROR) <<
"Failed to initialize asset_decryptor.";
1138 const size_t content_key_buffer_size =
1139 kEcmFlagsSizeBytes + kEcmContentKeySizeBytes +
1140 kEcmPaddingSizeBytes;
1142 size_t output_size =
1143 asset_decryptor.RequiredOutputSize(content_key_buffer_size);
1144 std::vector<uint8_t> content_key_buffer(output_size);
1145 CHECK(asset_decryptor.Crypt(ecm_data, content_key_buffer_size,
1146 content_key_buffer.data(), &output_size));
1148 std::vector<uint8_t> decrypted_content_key_vec(
1149 content_key_buffer.begin() + 4, content_key_buffer.begin() + 20);
1150 std::unique_ptr<AesCbcDecryptor> content_decryptor(
1151 new AesCbcDecryptor(kCtsPadding, AesCryptor::kUseConstantIv));
1152 if (!content_decryptor->InitializeWithIv(decrypted_content_key_vec,
1154 LOG(ERROR) <<
"Failed to initialize content decryptor.";
1158 content_decryptor_ = std::move(content_decryptor);
1162DemuxStreamIdMediaSample::DemuxStreamIdMediaSample()
1163 : demux_stream_id(0), parsed_audio_or_video_stream_id(0) {}
1165DemuxStreamIdMediaSample::~DemuxStreamIdMediaSample() {}
1167PrevSampleData::PrevSampleData() {
1171PrevSampleData::~PrevSampleData() {}
1173void PrevSampleData::Reset() {
1174 audio_sample = NULL;
1175 video_sample = NULL;
1176 audio_stream_id = 0;
1177 video_stream_id = 0;
1178 audio_sample_duration = 0;
1179 video_sample_duration = 0;
All the methods that are virtual are virtual for mocking.