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 3// found in the LICENSE file. 4 5#include "media/formats/mp2t/mp2t_stream_parser.h" 6 7#include "base/bind.h" 8#include "base/callback_helpers.h" 9#include "base/memory/scoped_ptr.h" 10#include "base/stl_util.h" 11#include "media/base/audio_decoder_config.h" 12#include "media/base/buffers.h" 13#include "media/base/stream_parser_buffer.h" 14#include "media/base/text_track_config.h" 15#include "media/base/video_decoder_config.h" 16#include "media/formats/mp2t/es_parser.h" 17#include "media/formats/mp2t/es_parser_adts.h" 18#include "media/formats/mp2t/es_parser_h264.h" 19#include "media/formats/mp2t/es_parser_mpeg1audio.h" 20#include "media/formats/mp2t/mp2t_common.h" 21#include "media/formats/mp2t/ts_packet.h" 22#include "media/formats/mp2t/ts_section.h" 23#include "media/formats/mp2t/ts_section_pat.h" 24#include "media/formats/mp2t/ts_section_pes.h" 25#include "media/formats/mp2t/ts_section_pmt.h" 26 27namespace media { 28namespace mp2t { 29 30enum StreamType { 31 // ISO-13818.1 / ITU H.222 Table 2.34 "Stream type assignments" 32 kStreamTypeMpeg1Audio = 0x3, 33 kStreamTypeAAC = 0xf, 34 kStreamTypeAVC = 0x1b, 35}; 36 37class PidState { 38 public: 39 enum PidType { 40 kPidPat, 41 kPidPmt, 42 kPidAudioPes, 43 kPidVideoPes, 44 }; 45 46 PidState(int pid, PidType pid_tyoe, 47 scoped_ptr<TsSection> section_parser); 48 49 // Extract the content of the TS packet and parse it. 50 // Return true if successful. 51 bool PushTsPacket(const TsPacket& ts_packet); 52 53 // Flush the PID state (possibly emitting some pending frames) 54 // and reset its state. 55 void Flush(); 56 57 // Enable/disable the PID. 58 // Disabling a PID will reset its state and ignore any further incoming TS 59 // packets. 60 void Enable(); 61 void Disable(); 62 bool IsEnabled() const; 63 64 PidType pid_type() const { return pid_type_; } 65 66 private: 67 void ResetState(); 68 69 int pid_; 70 PidType pid_type_; 71 scoped_ptr<TsSection> section_parser_; 72 73 bool enable_; 74 75 int continuity_counter_; 76}; 77 78PidState::PidState(int pid, PidType pid_type, 79 scoped_ptr<TsSection> section_parser) 80 : pid_(pid), 81 pid_type_(pid_type), 82 section_parser_(section_parser.Pass()), 83 enable_(false), 84 continuity_counter_(-1) { 85 DCHECK(section_parser_); 86} 87 88bool PidState::PushTsPacket(const TsPacket& ts_packet) { 89 DCHECK_EQ(ts_packet.pid(), pid_); 90 91 // The current PID is not part of the PID filter, 92 // just discard the incoming TS packet. 93 if (!enable_) 94 return true; 95 96 int expected_continuity_counter = (continuity_counter_ + 1) % 16; 97 if (continuity_counter_ >= 0 && 98 ts_packet.continuity_counter() != expected_continuity_counter) { 99 DVLOG(1) << "TS discontinuity detected for pid: " << pid_; 100 return false; 101 } 102 103 bool status = section_parser_->Parse( 104 ts_packet.payload_unit_start_indicator(), 105 ts_packet.payload(), 106 ts_packet.payload_size()); 107 108 // At the minimum, when parsing failed, auto reset the section parser. 109 // Components that use the StreamParser can take further action if needed. 110 if (!status) { 111 DVLOG(1) << "Parsing failed for pid = " << pid_; 112 ResetState(); 113 } 114 115 return status; 116} 117 118void PidState::Flush() { 119 section_parser_->Flush(); 120 ResetState(); 121} 122 123void PidState::Enable() { 124 enable_ = true; 125} 126 127void PidState::Disable() { 128 if (!enable_) 129 return; 130 131 ResetState(); 132 enable_ = false; 133} 134 135bool PidState::IsEnabled() const { 136 return enable_; 137} 138 139void PidState::ResetState() { 140 section_parser_->Reset(); 141 continuity_counter_ = -1; 142} 143 144Mp2tStreamParser::BufferQueueWithConfig::BufferQueueWithConfig( 145 bool is_cfg_sent, 146 const AudioDecoderConfig& audio_cfg, 147 const VideoDecoderConfig& video_cfg) 148 : is_config_sent(is_cfg_sent), 149 audio_config(audio_cfg), 150 video_config(video_cfg) { 151} 152 153Mp2tStreamParser::BufferQueueWithConfig::~BufferQueueWithConfig() { 154} 155 156Mp2tStreamParser::Mp2tStreamParser(bool sbr_in_mimetype) 157 : sbr_in_mimetype_(sbr_in_mimetype), 158 selected_audio_pid_(-1), 159 selected_video_pid_(-1), 160 is_initialized_(false), 161 segment_started_(false) { 162} 163 164Mp2tStreamParser::~Mp2tStreamParser() { 165 STLDeleteValues(&pids_); 166} 167 168void Mp2tStreamParser::Init( 169 const InitCB& init_cb, 170 const NewConfigCB& config_cb, 171 const NewBuffersCB& new_buffers_cb, 172 bool /* ignore_text_tracks */ , 173 const NeedKeyCB& need_key_cb, 174 const NewMediaSegmentCB& new_segment_cb, 175 const base::Closure& end_of_segment_cb, 176 const LogCB& log_cb) { 177 DCHECK(!is_initialized_); 178 DCHECK(init_cb_.is_null()); 179 DCHECK(!init_cb.is_null()); 180 DCHECK(!config_cb.is_null()); 181 DCHECK(!new_buffers_cb.is_null()); 182 DCHECK(!need_key_cb.is_null()); 183 DCHECK(!end_of_segment_cb.is_null()); 184 185 init_cb_ = init_cb; 186 config_cb_ = config_cb; 187 new_buffers_cb_ = new_buffers_cb; 188 need_key_cb_ = need_key_cb; 189 new_segment_cb_ = new_segment_cb; 190 end_of_segment_cb_ = end_of_segment_cb; 191 log_cb_ = log_cb; 192} 193 194void Mp2tStreamParser::Flush() { 195 DVLOG(1) << "Mp2tStreamParser::Flush"; 196 197 // Flush the buffers and reset the pids. 198 for (std::map<int, PidState*>::iterator it = pids_.begin(); 199 it != pids_.end(); ++it) { 200 DVLOG(1) << "Flushing PID: " << it->first; 201 PidState* pid_state = it->second; 202 pid_state->Flush(); 203 delete pid_state; 204 } 205 pids_.clear(); 206 EmitRemainingBuffers(); 207 buffer_queue_chain_.clear(); 208 209 // End of the segment. 210 // Note: does not need to invoke |end_of_segment_cb_| since flushing the 211 // stream parser already involves the end of the current segment. 212 segment_started_ = false; 213 214 // Remove any bytes left in the TS buffer. 215 // (i.e. any partial TS packet => less than 188 bytes). 216 ts_byte_queue_.Reset(); 217 218 // Reset the selected PIDs. 219 selected_audio_pid_ = -1; 220 selected_video_pid_ = -1; 221 222 // Reset the timestamp unroller. 223 timestamp_unroller_.Reset(); 224} 225 226bool Mp2tStreamParser::Parse(const uint8* buf, int size) { 227 DVLOG(1) << "Mp2tStreamParser::Parse size=" << size; 228 229 // Add the data to the parser state. 230 ts_byte_queue_.Push(buf, size); 231 232 while (true) { 233 const uint8* ts_buffer; 234 int ts_buffer_size; 235 ts_byte_queue_.Peek(&ts_buffer, &ts_buffer_size); 236 if (ts_buffer_size < TsPacket::kPacketSize) 237 break; 238 239 // Synchronization. 240 int skipped_bytes = TsPacket::Sync(ts_buffer, ts_buffer_size); 241 if (skipped_bytes > 0) { 242 DVLOG(1) << "Packet not aligned on a TS syncword:" 243 << " skipped_bytes=" << skipped_bytes; 244 ts_byte_queue_.Pop(skipped_bytes); 245 continue; 246 } 247 248 // Parse the TS header, skipping 1 byte if the header is invalid. 249 scoped_ptr<TsPacket> ts_packet(TsPacket::Parse(ts_buffer, ts_buffer_size)); 250 if (!ts_packet) { 251 DVLOG(1) << "Error: invalid TS packet"; 252 ts_byte_queue_.Pop(1); 253 continue; 254 } 255 DVLOG(LOG_LEVEL_TS) 256 << "Processing PID=" << ts_packet->pid() 257 << " start_unit=" << ts_packet->payload_unit_start_indicator(); 258 259 // Parse the section. 260 std::map<int, PidState*>::iterator it = pids_.find(ts_packet->pid()); 261 if (it == pids_.end() && 262 ts_packet->pid() == TsSection::kPidPat) { 263 // Create the PAT state here if needed. 264 scoped_ptr<TsSection> pat_section_parser( 265 new TsSectionPat( 266 base::Bind(&Mp2tStreamParser::RegisterPmt, 267 base::Unretained(this)))); 268 scoped_ptr<PidState> pat_pid_state( 269 new PidState(ts_packet->pid(), PidState::kPidPat, 270 pat_section_parser.Pass())); 271 pat_pid_state->Enable(); 272 it = pids_.insert( 273 std::pair<int, PidState*>(ts_packet->pid(), 274 pat_pid_state.release())).first; 275 } 276 277 if (it != pids_.end()) { 278 if (!it->second->PushTsPacket(*ts_packet)) 279 return false; 280 } else { 281 DVLOG(LOG_LEVEL_TS) << "Ignoring TS packet for pid: " << ts_packet->pid(); 282 } 283 284 // Go to the next packet. 285 ts_byte_queue_.Pop(TsPacket::kPacketSize); 286 } 287 288 RCHECK(FinishInitializationIfNeeded()); 289 290 // Emit the A/V buffers that kept accumulating during TS parsing. 291 return EmitRemainingBuffers(); 292} 293 294void Mp2tStreamParser::RegisterPmt(int program_number, int pmt_pid) { 295 DVLOG(1) << "RegisterPmt:" 296 << " program_number=" << program_number 297 << " pmt_pid=" << pmt_pid; 298 299 // Only one TS program is allowed. Ignore the incoming program map table, 300 // if there is already one registered. 301 for (std::map<int, PidState*>::iterator it = pids_.begin(); 302 it != pids_.end(); ++it) { 303 PidState* pid_state = it->second; 304 if (pid_state->pid_type() == PidState::kPidPmt) { 305 DVLOG_IF(1, pmt_pid != it->first) << "More than one program is defined"; 306 return; 307 } 308 } 309 310 // Create the PMT state here if needed. 311 DVLOG(1) << "Create a new PMT parser"; 312 scoped_ptr<TsSection> pmt_section_parser( 313 new TsSectionPmt( 314 base::Bind(&Mp2tStreamParser::RegisterPes, 315 base::Unretained(this), pmt_pid))); 316 scoped_ptr<PidState> pmt_pid_state( 317 new PidState(pmt_pid, PidState::kPidPmt, pmt_section_parser.Pass())); 318 pmt_pid_state->Enable(); 319 pids_.insert(std::pair<int, PidState*>(pmt_pid, pmt_pid_state.release())); 320} 321 322void Mp2tStreamParser::RegisterPes(int pmt_pid, 323 int pes_pid, 324 int stream_type) { 325 // TODO(damienv): check there is no mismatch if the entry already exists. 326 DVLOG(1) << "RegisterPes:" 327 << " pes_pid=" << pes_pid 328 << " stream_type=" << std::hex << stream_type << std::dec; 329 std::map<int, PidState*>::iterator it = pids_.find(pes_pid); 330 if (it != pids_.end()) 331 return; 332 333 // Create a stream parser corresponding to the stream type. 334 bool is_audio = false; 335 scoped_ptr<EsParser> es_parser; 336 if (stream_type == kStreamTypeAVC) { 337 es_parser.reset( 338 new EsParserH264( 339 base::Bind(&Mp2tStreamParser::OnVideoConfigChanged, 340 base::Unretained(this), 341 pes_pid), 342 base::Bind(&Mp2tStreamParser::OnEmitVideoBuffer, 343 base::Unretained(this), 344 pes_pid))); 345 } else if (stream_type == kStreamTypeAAC) { 346 es_parser.reset( 347 new EsParserAdts( 348 base::Bind(&Mp2tStreamParser::OnAudioConfigChanged, 349 base::Unretained(this), 350 pes_pid), 351 base::Bind(&Mp2tStreamParser::OnEmitAudioBuffer, 352 base::Unretained(this), 353 pes_pid), 354 sbr_in_mimetype_)); 355 is_audio = true; 356 } else if (stream_type == kStreamTypeMpeg1Audio) { 357 es_parser.reset( 358 new EsParserMpeg1Audio( 359 base::Bind(&Mp2tStreamParser::OnAudioConfigChanged, 360 base::Unretained(this), 361 pes_pid), 362 base::Bind(&Mp2tStreamParser::OnEmitAudioBuffer, 363 base::Unretained(this), 364 pes_pid), 365 log_cb_)); 366 is_audio = true; 367 } else { 368 return; 369 } 370 371 // Create the PES state here. 372 DVLOG(1) << "Create a new PES state"; 373 scoped_ptr<TsSection> pes_section_parser( 374 new TsSectionPes(es_parser.Pass(), ×tamp_unroller_)); 375 PidState::PidType pid_type = 376 is_audio ? PidState::kPidAudioPes : PidState::kPidVideoPes; 377 scoped_ptr<PidState> pes_pid_state( 378 new PidState(pes_pid, pid_type, pes_section_parser.Pass())); 379 pids_.insert(std::pair<int, PidState*>(pes_pid, pes_pid_state.release())); 380 381 // A new PES pid has been added, the PID filter might change. 382 UpdatePidFilter(); 383} 384 385void Mp2tStreamParser::UpdatePidFilter() { 386 // Applies the HLS rule to select the default audio/video PIDs: 387 // select the audio/video streams with the lowest PID. 388 // TODO(damienv): this can be changed when the StreamParser interface 389 // supports multiple audio/video streams. 390 PidMap::iterator lowest_audio_pid = pids_.end(); 391 PidMap::iterator lowest_video_pid = pids_.end(); 392 for (PidMap::iterator it = pids_.begin(); it != pids_.end(); ++it) { 393 int pid = it->first; 394 PidState* pid_state = it->second; 395 if (pid_state->pid_type() == PidState::kPidAudioPes && 396 (lowest_audio_pid == pids_.end() || pid < lowest_audio_pid->first)) 397 lowest_audio_pid = it; 398 if (pid_state->pid_type() == PidState::kPidVideoPes && 399 (lowest_video_pid == pids_.end() || pid < lowest_video_pid->first)) 400 lowest_video_pid = it; 401 } 402 403 // Enable both the lowest audio and video PIDs. 404 if (lowest_audio_pid != pids_.end()) { 405 DVLOG(1) << "Enable audio pid: " << lowest_audio_pid->first; 406 lowest_audio_pid->second->Enable(); 407 selected_audio_pid_ = lowest_audio_pid->first; 408 } 409 if (lowest_video_pid != pids_.end()) { 410 DVLOG(1) << "Enable video pid: " << lowest_video_pid->first; 411 lowest_video_pid->second->Enable(); 412 selected_video_pid_ = lowest_video_pid->first; 413 } 414 415 // Disable all the other audio and video PIDs. 416 for (PidMap::iterator it = pids_.begin(); it != pids_.end(); ++it) { 417 PidState* pid_state = it->second; 418 if (it != lowest_audio_pid && it != lowest_video_pid && 419 (pid_state->pid_type() == PidState::kPidAudioPes || 420 pid_state->pid_type() == PidState::kPidVideoPes)) 421 pid_state->Disable(); 422 } 423} 424 425void Mp2tStreamParser::OnVideoConfigChanged( 426 int pes_pid, 427 const VideoDecoderConfig& video_decoder_config) { 428 DVLOG(1) << "OnVideoConfigChanged for pid=" << pes_pid; 429 DCHECK_EQ(pes_pid, selected_video_pid_); 430 DCHECK(video_decoder_config.IsValidConfig()); 431 432 if (!buffer_queue_chain_.empty() && 433 !buffer_queue_chain_.back().video_config.IsValidConfig()) { 434 // No video has been received so far, can reuse the existing video queue. 435 DCHECK(buffer_queue_chain_.back().video_queue.empty()); 436 buffer_queue_chain_.back().video_config = video_decoder_config; 437 } else { 438 // Create a new entry in |buffer_queue_chain_| with the updated configs. 439 BufferQueueWithConfig buffer_queue_with_config( 440 false, 441 buffer_queue_chain_.empty() 442 ? AudioDecoderConfig() : buffer_queue_chain_.back().audio_config, 443 video_decoder_config); 444 buffer_queue_chain_.push_back(buffer_queue_with_config); 445 } 446 447 // Replace any non valid config with the 1st valid entry. 448 // This might happen if there was no available config before. 449 for (std::list<BufferQueueWithConfig>::iterator it = 450 buffer_queue_chain_.begin(); it != buffer_queue_chain_.end(); ++it) { 451 if (it->video_config.IsValidConfig()) 452 break; 453 it->video_config = video_decoder_config; 454 } 455} 456 457void Mp2tStreamParser::OnAudioConfigChanged( 458 int pes_pid, 459 const AudioDecoderConfig& audio_decoder_config) { 460 DVLOG(1) << "OnAudioConfigChanged for pid=" << pes_pid; 461 DCHECK_EQ(pes_pid, selected_audio_pid_); 462 DCHECK(audio_decoder_config.IsValidConfig()); 463 464 if (!buffer_queue_chain_.empty() && 465 !buffer_queue_chain_.back().audio_config.IsValidConfig()) { 466 // No audio has been received so far, can reuse the existing audio queue. 467 DCHECK(buffer_queue_chain_.back().audio_queue.empty()); 468 buffer_queue_chain_.back().audio_config = audio_decoder_config; 469 } else { 470 // Create a new entry in |buffer_queue_chain_| with the updated configs. 471 BufferQueueWithConfig buffer_queue_with_config( 472 false, 473 audio_decoder_config, 474 buffer_queue_chain_.empty() 475 ? VideoDecoderConfig() : buffer_queue_chain_.back().video_config); 476 buffer_queue_chain_.push_back(buffer_queue_with_config); 477 } 478 479 // Replace any non valid config with the 1st valid entry. 480 // This might happen if there was no available config before. 481 for (std::list<BufferQueueWithConfig>::iterator it = 482 buffer_queue_chain_.begin(); it != buffer_queue_chain_.end(); ++it) { 483 if (it->audio_config.IsValidConfig()) 484 break; 485 it->audio_config = audio_decoder_config; 486 } 487} 488 489bool Mp2tStreamParser::FinishInitializationIfNeeded() { 490 // Nothing to be done if already initialized. 491 if (is_initialized_) 492 return true; 493 494 // Wait for more data to come to finish initialization. 495 if (buffer_queue_chain_.empty()) 496 return true; 497 498 // Wait for more data to come if one of the config is not available. 499 BufferQueueWithConfig& queue_with_config = buffer_queue_chain_.front(); 500 if (selected_audio_pid_ > 0 && 501 !queue_with_config.audio_config.IsValidConfig()) 502 return true; 503 if (selected_video_pid_ > 0 && 504 !queue_with_config.video_config.IsValidConfig()) 505 return true; 506 507 // Pass the config before invoking the initialization callback. 508 RCHECK(config_cb_.Run(queue_with_config.audio_config, 509 queue_with_config.video_config, 510 TextTrackConfigMap())); 511 queue_with_config.is_config_sent = true; 512 513 // For Mpeg2 TS, the duration is not known. 514 DVLOG(1) << "Mpeg2TS stream parser initialization done"; 515 base::ResetAndReturn(&init_cb_) 516 .Run(true, InitParameters(kInfiniteDuration())); 517 is_initialized_ = true; 518 519 return true; 520} 521 522void Mp2tStreamParser::OnEmitAudioBuffer( 523 int pes_pid, 524 scoped_refptr<StreamParserBuffer> stream_parser_buffer) { 525 DCHECK_EQ(pes_pid, selected_audio_pid_); 526 527 DVLOG(LOG_LEVEL_ES) 528 << "OnEmitAudioBuffer: " 529 << " size=" 530 << stream_parser_buffer->data_size() 531 << " dts=" 532 << stream_parser_buffer->GetDecodeTimestamp().InMilliseconds() 533 << " pts=" 534 << stream_parser_buffer->timestamp().InMilliseconds() 535 << " dur=" 536 << stream_parser_buffer->duration().InMilliseconds(); 537 538 // Ignore the incoming buffer if it is not associated with any config. 539 if (buffer_queue_chain_.empty()) { 540 NOTREACHED() << "Cannot provide buffers before configs"; 541 return; 542 } 543 544 buffer_queue_chain_.back().audio_queue.push_back(stream_parser_buffer); 545} 546 547void Mp2tStreamParser::OnEmitVideoBuffer( 548 int pes_pid, 549 scoped_refptr<StreamParserBuffer> stream_parser_buffer) { 550 DCHECK_EQ(pes_pid, selected_video_pid_); 551 552 DVLOG(LOG_LEVEL_ES) 553 << "OnEmitVideoBuffer" 554 << " size=" 555 << stream_parser_buffer->data_size() 556 << " dts=" 557 << stream_parser_buffer->GetDecodeTimestamp().InMilliseconds() 558 << " pts=" 559 << stream_parser_buffer->timestamp().InMilliseconds() 560 << " dur=" 561 << stream_parser_buffer->duration().InMilliseconds() 562 << " IsKeyframe=" 563 << stream_parser_buffer->IsKeyframe(); 564 565 // Ignore the incoming buffer if it is not associated with any config. 566 if (buffer_queue_chain_.empty()) { 567 NOTREACHED() << "Cannot provide buffers before configs"; 568 return; 569 } 570 571 buffer_queue_chain_.back().video_queue.push_back(stream_parser_buffer); 572} 573 574bool Mp2tStreamParser::EmitRemainingBuffers() { 575 DVLOG(LOG_LEVEL_ES) << "Mp2tStreamParser::EmitRemainingBuffers"; 576 577 // No buffer should be sent until fully initialized. 578 if (!is_initialized_) 579 return true; 580 581 if (buffer_queue_chain_.empty()) 582 return true; 583 584 // Keep track of the last audio and video config sent. 585 AudioDecoderConfig last_audio_config = 586 buffer_queue_chain_.back().audio_config; 587 VideoDecoderConfig last_video_config = 588 buffer_queue_chain_.back().video_config; 589 590 // Do not have all the configs, need more data. 591 if (selected_audio_pid_ >= 0 && !last_audio_config.IsValidConfig()) 592 return true; 593 if (selected_video_pid_ >= 0 && !last_video_config.IsValidConfig()) 594 return true; 595 596 // Buffer emission. 597 while (!buffer_queue_chain_.empty()) { 598 // Start a segment if needed. 599 if (!segment_started_) { 600 DVLOG(1) << "Starting a new segment"; 601 segment_started_ = true; 602 new_segment_cb_.Run(); 603 } 604 605 // Update the audio and video config if needed. 606 BufferQueueWithConfig& queue_with_config = buffer_queue_chain_.front(); 607 if (!queue_with_config.is_config_sent) { 608 if (!config_cb_.Run(queue_with_config.audio_config, 609 queue_with_config.video_config, 610 TextTrackConfigMap())) 611 return false; 612 queue_with_config.is_config_sent = true; 613 } 614 615 // Add buffers. 616 TextBufferQueueMap empty_text_map; 617 if (!queue_with_config.audio_queue.empty() || 618 !queue_with_config.video_queue.empty()) { 619 if (!new_buffers_cb_.Run(queue_with_config.audio_queue, 620 queue_with_config.video_queue, 621 empty_text_map)) { 622 return false; 623 } 624 } 625 626 buffer_queue_chain_.pop_front(); 627 } 628 629 // Push an empty queue with the last audio/video config 630 // so that buffers with the same config can be added later on. 631 BufferQueueWithConfig queue_with_config( 632 true, last_audio_config, last_video_config); 633 buffer_queue_chain_.push_back(queue_with_config); 634 635 return true; 636} 637 638} // namespace mp2t 639} // namespace media 640