Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/formats/mp2t/mp2t_stream_parser.h" | 5 #include "media/formats/mp2t/mp2t_stream_parser.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/callback_helpers.h" | 11 #include "base/callback_helpers.h" |
| 12 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
| 13 #include "media/base/media_tracks.h" | 13 #include "media/base/media_tracks.h" |
| 14 #include "media/base/stream_parser_buffer.h" | 14 #include "media/base/stream_parser_buffer.h" |
| 15 #include "media/base/text_track_config.h" | 15 #include "media/base/text_track_config.h" |
| 16 #include "media/base/timestamp_constants.h" | 16 #include "media/base/timestamp_constants.h" |
| 17 #include "media/formats/mp2t/es_parser.h" | 17 #include "media/formats/mp2t/es_parser.h" |
| 18 #include "media/formats/mp2t/es_parser_adts.h" | 18 #include "media/formats/mp2t/es_parser_adts.h" |
| 19 #include "media/formats/mp2t/es_parser_h264.h" | 19 #include "media/formats/mp2t/es_parser_h264.h" |
| 20 #include "media/formats/mp2t/es_parser_mpeg1audio.h" | 20 #include "media/formats/mp2t/es_parser_mpeg1audio.h" |
| 21 #include "media/formats/mp2t/mp2t_common.h" | 21 #include "media/formats/mp2t/mp2t_common.h" |
| 22 #include "media/formats/mp2t/ts_packet.h" | 22 #include "media/formats/mp2t/ts_packet.h" |
| 23 #include "media/formats/mp2t/ts_section.h" | 23 #include "media/formats/mp2t/ts_section.h" |
| 24 #include "media/formats/mp2t/ts_section_pat.h" | 24 #include "media/formats/mp2t/ts_section_pat.h" |
| 25 #include "media/formats/mp2t/ts_section_pes.h" | 25 #include "media/formats/mp2t/ts_section_pes.h" |
| 26 #include "media/formats/mp2t/ts_section_pmt.h" | 26 #include "media/formats/mp2t/ts_section_pmt.h" |
| 27 | 27 |
| 28 #if BUILDFLAG(ENABLE_HLS_SAMPLE_AES) | |
| 29 #include "media/formats/mp2t/ts_section_cat.h" | |
| 30 #include "media/formats/mp2t/ts_section_cets_ecm.h" | |
| 31 #include "media/formats/mp2t/ts_section_cets_pssh.h" | |
| 32 #endif | |
| 33 | |
| 28 namespace media { | 34 namespace media { |
| 29 namespace mp2t { | 35 namespace mp2t { |
| 30 | 36 |
| 37 namespace { | |
| 38 | |
| 39 #if BUILDFLAG(ENABLE_HLS_SAMPLE_AES) | |
| 40 const int64_t kSampleAESPrivateDataIndicatorAVC = 0x7a617663; | |
| 41 const int64_t kSampleAESPrivateDataIndicatorAAC = 0x61616364; | |
| 42 // TODO(dougsteed). Consider adding support for the following: | |
| 43 // const int64_t kSampleAESPrivateDataIndicatorAC3 = 0x61633364; | |
| 44 // const int64_t kSampleAESPrivateDataIndicatorEAC3 = 0x65633364; | |
| 45 #endif | |
| 46 | |
| 47 } // namespace | |
| 48 | |
| 31 enum StreamType { | 49 enum StreamType { |
| 32 // ISO-13818.1 / ITU H.222 Table 2.34 "Stream type assignments" | 50 // ISO-13818.1 / ITU H.222 Table 2.34 "Stream type assignments" |
| 33 kStreamTypeMpeg1Audio = 0x3, | 51 kStreamTypeMpeg1Audio = 0x3, |
| 34 kStreamTypeAAC = 0xf, | 52 kStreamTypeAAC = 0xf, |
| 35 kStreamTypeAVC = 0x1b, | 53 kStreamTypeAVC = 0x1b, |
| 54 #if BUILDFLAG(ENABLE_HLS_SAMPLE_AES) | |
| 55 kStreamTypeAACWithSampleAES = 0xcf, | |
| 56 kStreamTypeAVCWithSampleAES = 0xdb, | |
| 57 // TODO(dougsteed). Consider adding support for the following: | |
| 58 // kStreamTypeAC3WithSampleAES = 0xc1, | |
| 59 // kStreamTypeEAC3WithSampleAES = 0xc2, | |
| 60 #endif | |
| 36 }; | 61 }; |
| 37 | 62 |
| 38 class PidState { | 63 class PidState { |
| 39 public: | 64 public: |
| 40 enum PidType { | 65 enum PidType { |
| 41 kPidPat, | 66 kPidPat, |
| 42 kPidPmt, | 67 kPidPmt, |
| 43 kPidAudioPes, | 68 kPidAudioPes, |
| 44 kPidVideoPes, | 69 kPidVideoPes, |
| 70 #if BUILDFLAG(ENABLE_HLS_SAMPLE_AES) | |
| 71 kPidCat, | |
| 72 kPidCetsEcm, | |
| 73 kPidCetsPssh, | |
| 74 #endif | |
| 45 }; | 75 }; |
| 46 | 76 |
| 47 PidState(int pid, | 77 PidState(int pid, |
| 48 PidType pid_tyoe, | 78 PidType pid_tyoe, |
| 49 std::unique_ptr<TsSection> section_parser); | 79 std::unique_ptr<TsSection> section_parser); |
| 50 | 80 |
| 51 // Extract the content of the TS packet and parse it. | 81 // Extract the content of the TS packet and parse it. |
| 52 // Return true if successful. | 82 // Return true if successful. |
| 53 bool PushTsPacket(const TsPacket& ts_packet); | 83 bool PushTsPacket(const TsPacket& ts_packet); |
| 54 | 84 |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 195 encrypted_media_init_data_cb_ = encrypted_media_init_data_cb; | 225 encrypted_media_init_data_cb_ = encrypted_media_init_data_cb; |
| 196 new_segment_cb_ = new_segment_cb; | 226 new_segment_cb_ = new_segment_cb; |
| 197 end_of_segment_cb_ = end_of_segment_cb; | 227 end_of_segment_cb_ = end_of_segment_cb; |
| 198 media_log_ = media_log; | 228 media_log_ = media_log; |
| 199 } | 229 } |
| 200 | 230 |
| 201 void Mp2tStreamParser::Flush() { | 231 void Mp2tStreamParser::Flush() { |
| 202 DVLOG(1) << "Mp2tStreamParser::Flush"; | 232 DVLOG(1) << "Mp2tStreamParser::Flush"; |
| 203 | 233 |
| 204 // Flush the buffers and reset the pids. | 234 // Flush the buffers and reset the pids. |
| 205 for (std::map<int, PidState*>::iterator it = pids_.begin(); | 235 for (const auto& pid : pids_) { |
| 206 it != pids_.end(); ++it) { | 236 DVLOG(1) << "Flushing PID: " << pid.first; |
| 207 DVLOG(1) << "Flushing PID: " << it->first; | 237 PidState* pid_state = pid.second; |
| 208 PidState* pid_state = it->second; | |
| 209 pid_state->Flush(); | 238 pid_state->Flush(); |
| 210 delete pid_state; | 239 delete pid_state; |
| 211 } | 240 } |
| 212 pids_.clear(); | 241 pids_.clear(); |
| 213 | 242 |
| 214 // Flush is invoked from SourceBuffer.abort/SourceState::ResetParserState, and | 243 // Flush is invoked from SourceBuffer.abort/SourceState::ResetParserState, and |
| 215 // MSE spec prohibits emitting new configs in ResetParserState algorithm (see | 244 // MSE spec prohibits emitting new configs in ResetParserState algorithm (see |
| 216 // https://w3c.github.io/media-source/#sourcebuffer-reset-parser-state, | 245 // https://w3c.github.io/media-source/#sourcebuffer-reset-parser-state, |
| 217 // 3.5.2 Reset Parser State states that new frames might be processed only in | 246 // 3.5.2 Reset Parser State states that new frames might be processed only in |
| 218 // PARSING_MEDIA_SEGMENT and therefore doesn't allow emitting new configs, | 247 // PARSING_MEDIA_SEGMENT and therefore doesn't allow emitting new configs, |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 277 if (!ts_packet) { | 306 if (!ts_packet) { |
| 278 DVLOG(1) << "Error: invalid TS packet"; | 307 DVLOG(1) << "Error: invalid TS packet"; |
| 279 ts_byte_queue_.Pop(1); | 308 ts_byte_queue_.Pop(1); |
| 280 continue; | 309 continue; |
| 281 } | 310 } |
| 282 DVLOG(LOG_LEVEL_TS) | 311 DVLOG(LOG_LEVEL_TS) |
| 283 << "Processing PID=" << ts_packet->pid() | 312 << "Processing PID=" << ts_packet->pid() |
| 284 << " start_unit=" << ts_packet->payload_unit_start_indicator(); | 313 << " start_unit=" << ts_packet->payload_unit_start_indicator(); |
| 285 | 314 |
| 286 // Parse the section. | 315 // Parse the section. |
| 287 std::map<int, PidState*>::iterator it = pids_.find(ts_packet->pid()); | 316 auto it = pids_.find(ts_packet->pid()); |
| 288 if (it == pids_.end() && | 317 if (it == pids_.end() && |
| 289 ts_packet->pid() == TsSection::kPidPat) { | 318 ts_packet->pid() == TsSection::kPidPat) { |
| 290 // Create the PAT state here if needed. | 319 // Create the PAT state here if needed. |
| 291 std::unique_ptr<TsSection> pat_section_parser(new TsSectionPat( | 320 std::unique_ptr<TsSection> pat_section_parser(new TsSectionPat( |
| 292 base::Bind(&Mp2tStreamParser::RegisterPmt, base::Unretained(this)))); | 321 base::Bind(&Mp2tStreamParser::RegisterPmt, base::Unretained(this)))); |
| 293 std::unique_ptr<PidState> pat_pid_state(new PidState( | 322 std::unique_ptr<PidState> pat_pid_state(new PidState( |
| 294 ts_packet->pid(), PidState::kPidPat, std::move(pat_section_parser))); | 323 ts_packet->pid(), PidState::kPidPat, std::move(pat_section_parser))); |
| 295 pat_pid_state->Enable(); | 324 pat_pid_state->Enable(); |
| 296 it = pids_.insert( | 325 it = |
| 297 std::pair<int, PidState*>(ts_packet->pid(), | 326 pids_.insert(PidMapElement(ts_packet->pid(), pat_pid_state.release())) |
| 298 pat_pid_state.release())).first; | 327 .first; |
| 299 } | 328 } |
| 329 #if BUILDFLAG(ENABLE_HLS_SAMPLE_AES) | |
| 330 // We allow a CAT to appear as the first packet in the TS. This allows us to | |
| 331 // specify encryption metadata for HLS by injecting it as an extra TS packet | |
| 332 // at the front of the stream. | |
| 333 else if (it == pids_.end() && ts_packet->pid() == TsSection::kPidCat) { | |
| 334 it = RegisterCat(); | |
| 335 } | |
| 336 #endif | |
| 300 | 337 |
| 301 if (it != pids_.end()) { | 338 if (it != pids_.end()) { |
| 302 if (!it->second->PushTsPacket(*ts_packet)) | 339 if (!it->second->PushTsPacket(*ts_packet)) |
| 303 return false; | 340 return false; |
| 304 } else { | 341 } else { |
| 305 DVLOG(LOG_LEVEL_TS) << "Ignoring TS packet for pid: " << ts_packet->pid(); | 342 DVLOG(LOG_LEVEL_TS) << "Ignoring TS packet for pid: " << ts_packet->pid(); |
| 306 } | 343 } |
| 307 | 344 |
| 308 // Go to the next packet. | 345 // Go to the next packet. |
| 309 ts_byte_queue_.Pop(TsPacket::kPacketSize); | 346 ts_byte_queue_.Pop(TsPacket::kPacketSize); |
| 310 } | 347 } |
| 311 | 348 |
| 312 RCHECK(FinishInitializationIfNeeded()); | 349 RCHECK(FinishInitializationIfNeeded()); |
| 313 | 350 |
| 314 // Emit the A/V buffers that kept accumulating during TS parsing. | 351 // Emit the A/V buffers that kept accumulating during TS parsing. |
| 315 return EmitRemainingBuffers(); | 352 return EmitRemainingBuffers(); |
| 316 } | 353 } |
| 317 | 354 |
| 318 void Mp2tStreamParser::RegisterPmt(int program_number, int pmt_pid) { | 355 void Mp2tStreamParser::RegisterPmt(int program_number, int pmt_pid) { |
| 319 DVLOG(1) << "RegisterPmt:" | 356 DVLOG(1) << "RegisterPmt:" |
| 320 << " program_number=" << program_number | 357 << " program_number=" << program_number |
| 321 << " pmt_pid=" << pmt_pid; | 358 << " pmt_pid=" << pmt_pid; |
| 322 | 359 |
| 323 // Only one TS program is allowed. Ignore the incoming program map table, | 360 // Only one TS program is allowed. Ignore the incoming program map table, |
| 324 // if there is already one registered. | 361 // if there is already one registered. |
| 325 for (std::map<int, PidState*>::iterator it = pids_.begin(); | 362 for (const auto& pid : pids_) { |
| 326 it != pids_.end(); ++it) { | 363 PidState* pid_state = pid.second; |
| 327 PidState* pid_state = it->second; | |
| 328 if (pid_state->pid_type() == PidState::kPidPmt) { | 364 if (pid_state->pid_type() == PidState::kPidPmt) { |
| 329 DVLOG_IF(1, pmt_pid != it->first) << "More than one program is defined"; | 365 DVLOG_IF(1, pmt_pid != pid.first) << "More than one program is defined"; |
| 330 return; | 366 return; |
| 331 } | 367 } |
| 332 } | 368 } |
| 333 | 369 |
| 334 // Create the PMT state here if needed. | 370 // Create the PMT state here if needed. |
| 335 DVLOG(1) << "Create a new PMT parser"; | 371 DVLOG(1) << "Create a new PMT parser"; |
| 336 std::unique_ptr<TsSection> pmt_section_parser(new TsSectionPmt(base::Bind( | 372 std::unique_ptr<TsSection> pmt_section_parser(new TsSectionPmt(base::Bind( |
| 337 &Mp2tStreamParser::RegisterPes, base::Unretained(this), pmt_pid))); | 373 &Mp2tStreamParser::RegisterPes, base::Unretained(this), pmt_pid))); |
| 338 std::unique_ptr<PidState> pmt_pid_state( | 374 std::unique_ptr<PidState> pmt_pid_state( |
| 339 new PidState(pmt_pid, PidState::kPidPmt, std::move(pmt_section_parser))); | 375 new PidState(pmt_pid, PidState::kPidPmt, std::move(pmt_section_parser))); |
| 340 pmt_pid_state->Enable(); | 376 pmt_pid_state->Enable(); |
| 341 pids_.insert(std::pair<int, PidState*>(pmt_pid, pmt_pid_state.release())); | 377 pids_.insert(std::pair<int, PidState*>(pmt_pid, pmt_pid_state.release())); |
| 378 | |
| 379 #if BUILDFLAG(ENABLE_HLS_SAMPLE_AES) | |
| 380 // Take the opportunity to clean up any PIDs that were involved in importing | |
| 381 // encryption metadata for HLS with SampleAES. This prevents the possibility | |
| 382 // of interference with actual PIDs that might be declared in the PMT. | |
| 383 // TODO(dougsteed): if in the future the appropriate PIDs are embedded in the | |
| 384 // source stream, this will not be necessary. | |
| 385 UnregisterCat(); | |
| 386 UnregisterCencPids(); | |
| 387 #endif | |
| 342 } | 388 } |
| 343 | 389 |
| 344 void Mp2tStreamParser::RegisterPes(int pmt_pid, | 390 void Mp2tStreamParser::RegisterPes(int pmt_pid, |
| 345 int pes_pid, | 391 int pes_pid, |
| 346 int stream_type) { | 392 int stream_type, |
| 393 const Descriptors& descriptors) { | |
| 347 // TODO(damienv): check there is no mismatch if the entry already exists. | 394 // TODO(damienv): check there is no mismatch if the entry already exists. |
| 348 DVLOG(1) << "RegisterPes:" | 395 DVLOG(1) << "RegisterPes:" |
| 349 << " pes_pid=" << pes_pid | 396 << " pes_pid=" << pes_pid |
| 350 << " stream_type=" << std::hex << stream_type << std::dec; | 397 << " stream_type=" << std::hex << stream_type << std::dec; |
| 351 std::map<int, PidState*>::iterator it = pids_.find(pes_pid); | 398 std::map<int, PidState*>::iterator it = pids_.find(pes_pid); |
| 352 if (it != pids_.end()) | 399 if (it != pids_.end()) |
| 353 return; | 400 return; |
| 354 | 401 |
| 355 // Create a stream parser corresponding to the stream type. | 402 // Create a stream parser corresponding to the stream type. |
| 356 bool is_audio = false; | 403 bool is_audio = false; |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 376 sbr_in_mimetype_)); | 423 sbr_in_mimetype_)); |
| 377 is_audio = true; | 424 is_audio = true; |
| 378 } else if (stream_type == kStreamTypeMpeg1Audio) { | 425 } else if (stream_type == kStreamTypeMpeg1Audio) { |
| 379 es_parser.reset(new EsParserMpeg1Audio( | 426 es_parser.reset(new EsParserMpeg1Audio( |
| 380 base::Bind(&Mp2tStreamParser::OnAudioConfigChanged, | 427 base::Bind(&Mp2tStreamParser::OnAudioConfigChanged, |
| 381 base::Unretained(this), pes_pid), | 428 base::Unretained(this), pes_pid), |
| 382 base::Bind(&Mp2tStreamParser::OnEmitAudioBuffer, base::Unretained(this), | 429 base::Bind(&Mp2tStreamParser::OnEmitAudioBuffer, base::Unretained(this), |
| 383 pes_pid), | 430 pes_pid), |
| 384 media_log_)); | 431 media_log_)); |
| 385 is_audio = true; | 432 is_audio = true; |
| 433 #if BUILDFLAG(ENABLE_HLS_SAMPLE_AES) | |
| 434 } else if (stream_type == kStreamTypeAVCWithSampleAES && | |
| 435 descriptors.HasPrivateDataIndicator( | |
| 436 kSampleAESPrivateDataIndicatorAVC)) { | |
| 437 es_parser.reset( | |
| 438 new EsParserH264(base::Bind(&Mp2tStreamParser::OnVideoConfigChanged, | |
| 439 base::Unretained(this), pes_pid), | |
| 440 base::Bind(&Mp2tStreamParser::OnEmitVideoBuffer, | |
| 441 base::Unretained(this), pes_pid), | |
| 442 true, base::Bind(&Mp2tStreamParser::GetDecryptConfig, | |
| 443 base::Unretained(this)))); | |
| 444 } else if (stream_type == kStreamTypeAACWithSampleAES && | |
| 445 descriptors.HasPrivateDataIndicator( | |
| 446 kSampleAESPrivateDataIndicatorAAC)) { | |
| 447 es_parser.reset(new EsParserAdts( | |
| 448 base::Bind(&Mp2tStreamParser::OnAudioConfigChanged, | |
| 449 base::Unretained(this), pes_pid), | |
| 450 base::Bind(&Mp2tStreamParser::OnEmitAudioBuffer, base::Unretained(this), | |
| 451 pes_pid), | |
| 452 sbr_in_mimetype_, true, base::Bind(&Mp2tStreamParser::GetDecryptConfig, | |
| 453 base::Unretained(this)))); | |
| 454 is_audio = true; | |
| 455 #endif | |
| 386 } else { | 456 } else { |
| 387 return; | 457 return; |
| 388 } | 458 } |
| 389 | 459 |
| 390 // Create the PES state here. | 460 // Create the PES state here. |
| 391 DVLOG(1) << "Create a new PES state"; | 461 DVLOG(1) << "Create a new PES state"; |
| 392 std::unique_ptr<TsSection> pes_section_parser( | 462 std::unique_ptr<TsSection> pes_section_parser( |
| 393 new TsSectionPes(std::move(es_parser), ×tamp_unroller_)); | 463 new TsSectionPes(std::move(es_parser), ×tamp_unroller_)); |
| 394 PidState::PidType pid_type = | 464 PidState::PidType pid_type = |
| 395 is_audio ? PidState::kPidAudioPes : PidState::kPidVideoPes; | 465 is_audio ? PidState::kPidAudioPes : PidState::kPidVideoPes; |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 670 | 740 |
| 671 // Push an empty queue with the last audio/video config | 741 // Push an empty queue with the last audio/video config |
| 672 // so that buffers with the same config can be added later on. | 742 // so that buffers with the same config can be added later on. |
| 673 BufferQueueWithConfig queue_with_config( | 743 BufferQueueWithConfig queue_with_config( |
| 674 true, last_audio_config, last_video_config); | 744 true, last_audio_config, last_video_config); |
| 675 buffer_queue_chain_.push_back(queue_with_config); | 745 buffer_queue_chain_.push_back(queue_with_config); |
| 676 | 746 |
| 677 return true; | 747 return true; |
| 678 } | 748 } |
| 679 | 749 |
| 750 #if BUILDFLAG(ENABLE_HLS_SAMPLE_AES) | |
| 751 std::map<int, PidState*>::iterator Mp2tStreamParser::RegisterCat() { | |
| 752 std::unique_ptr<TsSection> cat_section_parser(new TsSectionCat( | |
| 753 base::Bind(&Mp2tStreamParser::RegisterCencPids, base::Unretained(this)))); | |
| 754 std::unique_ptr<PidState> cat_pid_state(new PidState( | |
| 755 TsSection::kPidCat, PidState::kPidCat, std::move(cat_section_parser))); | |
| 756 cat_pid_state->Enable(); | |
| 757 return pids_ | |
| 758 .insert(PidMapElement(TsSection::kPidCat, cat_pid_state.release())) | |
|
yucliu1
2016/05/26 23:28:47
nit: Replace insert with emplace?
And I think pid
dougsteed
2016/09/25 21:52:29
Can't replace insert with emplace. Agree with the
| |
| 759 .first; | |
| 760 } | |
| 761 | |
| 762 void Mp2tStreamParser::UnregisterCat() { | |
| 763 for (auto& pid : pids_) { | |
| 764 if (pid.second->pid_type() == PidState::kPidCat) { | |
| 765 delete pid.second; | |
| 766 pids_.erase(pid.first); | |
| 767 break; | |
| 768 } | |
| 769 } | |
| 770 } | |
| 771 | |
| 772 void Mp2tStreamParser::RegisterCencPids(int ca_pid, int pssh_pid) { | |
| 773 std::unique_ptr<TsSectionCetsEcm> ecm_parser(new TsSectionCetsEcm(base::Bind( | |
| 774 &Mp2tStreamParser::RegisterDecryptConfig, base::Unretained(this)))); | |
| 775 std::unique_ptr<PidState> ecm_pid_state( | |
| 776 new PidState(ca_pid, PidState::kPidCetsEcm, std::move(ecm_parser))); | |
| 777 ecm_pid_state->Enable(); | |
| 778 pids_.insert(PidMapElement(ca_pid, ecm_pid_state.release())); | |
|
yucliu1
2016/05/26 23:28:47
ditto.
dougsteed
2016/09/25 21:52:29
ditto
| |
| 779 | |
| 780 std::unique_ptr<TsSectionCetsPssh> pssh_parser( | |
| 781 new TsSectionCetsPssh(base::Bind(&Mp2tStreamParser::RegisterPsshBoxes, | |
| 782 base::Unretained(this)))); | |
| 783 std::unique_ptr<PidState> pssh_pid_state( | |
| 784 new PidState(pssh_pid, PidState::kPidCetsPssh, std::move(pssh_parser))); | |
| 785 pssh_pid_state->Enable(); | |
| 786 pids_.insert(PidMapElement(pssh_pid, pssh_pid_state.release())); | |
|
yucliu1
2016/05/26 23:28:47
ditto.
dougsteed
2016/09/25 21:52:29
ditto
| |
| 787 } | |
| 788 | |
| 789 void Mp2tStreamParser::UnregisterCencPids() { | |
| 790 for (auto& pid : pids_) { | |
| 791 if (pid.second->pid_type() == PidState::kPidCetsEcm) { | |
| 792 delete pid.second; | |
| 793 pids_.erase(pid.first); | |
| 794 break; | |
| 795 } | |
| 796 } | |
| 797 for (auto& pid : pids_) { | |
| 798 if (pid.second->pid_type() == PidState::kPidCetsPssh) { | |
| 799 delete pid.second; | |
| 800 pids_.erase(pid.first); | |
| 801 break; | |
| 802 } | |
| 803 } | |
| 804 } | |
| 805 | |
| 806 void Mp2tStreamParser::RegisterDecryptConfig(const DecryptConfig& config) { | |
| 807 decrypt_config_.reset( | |
| 808 new DecryptConfig(config.key_id(), config.iv(), config.subsamples())); | |
| 809 } | |
| 810 | |
| 811 void Mp2tStreamParser::RegisterPsshBoxes( | |
| 812 const std::vector<uint8_t>& init_data) { | |
| 813 encrypted_media_init_data_cb_.Run(EmeInitDataType::CENC, init_data); | |
| 814 } | |
| 815 | |
| 816 #endif | |
| 817 | |
| 680 } // namespace mp2t | 818 } // namespace mp2t |
| 681 } // namespace media | 819 } // namespace media |
| OLD | NEW |