Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2016 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/filters/media_source_state.h" | 5 #include "media/filters/media_source_state.h" |
| 6 | 6 |
| 7 #include "base/callback_helpers.h" | 7 #include "base/callback_helpers.h" |
| 8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
| 9 #include "media/base/media_track.h" | 9 #include "media/base/media_track.h" |
| 10 #include "media/base/media_tracks.h" | 10 #include "media/base/media_tracks.h" |
| (...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 473 return false; | 473 return false; |
| 474 } | 474 } |
| 475 | 475 |
| 476 bool MediaSourceState::OnNewConfigs( | 476 bool MediaSourceState::OnNewConfigs( |
| 477 bool allow_audio, | 477 bool allow_audio, |
| 478 bool allow_video, | 478 bool allow_video, |
| 479 scoped_ptr<MediaTracks> tracks, | 479 scoped_ptr<MediaTracks> tracks, |
| 480 const StreamParser::TextTrackConfigMap& text_configs) { | 480 const StreamParser::TextTrackConfigMap& text_configs) { |
| 481 DCHECK_GE(state_, PENDING_PARSER_CONFIG); | 481 DCHECK_GE(state_, PENDING_PARSER_CONFIG); |
| 482 DCHECK(tracks.get()); | 482 DCHECK(tracks.get()); |
| 483 media_tracks_ = std::move(tracks); | 483 media_tracks_ = std::move(tracks); |
|
wolenetz
2016/04/15 22:47:18
minor nit: might we not want to replace our cache
servolk
2016/04/15 23:26:31
In fact it turns out that we don't need to store t
wolenetz
2016/04/15 23:52:17
Acknowledged.
| |
| 484 const AudioDecoderConfig& audio_config = media_tracks_->getFirstAudioConfig(); | 484 |
| 485 const VideoDecoderConfig& video_config = media_tracks_->getFirstVideoConfig(); | 485 const MediaTrack* audio_track = nullptr; |
| 486 const MediaTrack* video_track = nullptr; | |
| 487 AudioDecoderConfig audio_config; | |
| 488 VideoDecoderConfig video_config; | |
| 489 for (const auto& track : media_tracks_->tracks()) { | |
| 490 if (!audio_track && track->type() == MediaTrack::Audio && | |
| 491 media_tracks_->getAudioConfig(track->id()).IsValidConfig()) { | |
| 492 audio_config = media_tracks_->getAudioConfig(track->id()); | |
| 493 audio_track = track.get(); | |
| 494 } else if (!video_track && track->type() == MediaTrack::Video && | |
| 495 media_tracks_->getVideoConfig(track->id()).IsValidConfig()) { | |
| 496 video_config = media_tracks_->getVideoConfig(track->id()); | |
| 497 video_track = track.get(); | |
| 498 } | |
| 499 } | |
| 486 | 500 |
| 487 DVLOG(1) << "OnNewConfigs(" << allow_audio << ", " << allow_video << ", " | 501 DVLOG(1) << "OnNewConfigs(" << allow_audio << ", " << allow_video << ", " |
| 488 << audio_config.IsValidConfig() << ", " | 502 << audio_config.IsValidConfig() << ", " |
| 489 << video_config.IsValidConfig() << ")"; | 503 << video_config.IsValidConfig() << ")"; |
| 490 // MSE spec allows new configs to be emitted only during Append, but not | 504 // MSE spec allows new configs to be emitted only during Append, but not |
| 491 // during Flush or parser reset operations. | 505 // during Flush or parser reset operations. |
| 492 CHECK(append_in_progress_); | 506 CHECK(append_in_progress_); |
| 493 | 507 |
| 494 if (!audio_config.IsValidConfig() && !video_config.IsValidConfig()) { | 508 if (!audio_config.IsValidConfig() && !video_config.IsValidConfig()) { |
| 495 DVLOG(1) << "OnNewConfigs() : Audio & video config are not valid!"; | 509 DVLOG(1) << "OnNewConfigs() : Audio & video config are not valid!"; |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 523 if (!audio_) { | 537 if (!audio_) { |
| 524 media_log_->SetBooleanProperty("found_audio_stream", true); | 538 media_log_->SetBooleanProperty("found_audio_stream", true); |
| 525 } | 539 } |
| 526 if (!audio_ || | 540 if (!audio_ || |
| 527 audio_->audio_decoder_config().codec() != audio_config.codec()) { | 541 audio_->audio_decoder_config().codec() != audio_config.codec()) { |
| 528 media_log_->SetStringProperty("audio_codec_name", | 542 media_log_->SetStringProperty("audio_codec_name", |
| 529 GetCodecName(audio_config.codec())); | 543 GetCodecName(audio_config.codec())); |
| 530 } | 544 } |
| 531 | 545 |
| 532 if (!audio_) { | 546 if (!audio_) { |
| 533 audio_ = create_demuxer_stream_cb_.Run(DemuxerStream::AUDIO); | 547 DCHECK(audio_track); |
| 548 audio_ = create_demuxer_stream_cb_.Run(*audio_track); | |
| 534 | 549 |
| 535 if (!audio_) { | 550 if (!audio_) { |
| 536 DVLOG(1) << "Failed to create an audio stream."; | 551 DVLOG(1) << "Failed to create an audio stream."; |
| 537 return false; | 552 return false; |
| 538 } | 553 } |
| 539 | 554 |
| 540 if (!frame_processor_->AddTrack(FrameProcessor::kAudioTrackId, audio_)) { | 555 if (!frame_processor_->AddTrack(FrameProcessor::kAudioTrackId, audio_)) { |
| 541 DVLOG(1) << "Failed to add audio track to frame processor."; | 556 DVLOG(1) << "Failed to add audio track to frame processor."; |
| 542 return false; | 557 return false; |
| 543 } | 558 } |
| 544 } | 559 } |
| 545 | 560 |
| 546 frame_processor_->OnPossibleAudioConfigUpdate(audio_config); | 561 frame_processor_->OnPossibleAudioConfigUpdate(audio_config); |
| 547 success &= audio_->UpdateAudioConfig(audio_config, media_log_); | 562 success &= audio_->UpdateAudioConfig(audio_config, media_log_); |
| 548 } | 563 } |
| 549 | 564 |
| 550 if (video_config.IsValidConfig()) { | 565 if (video_config.IsValidConfig()) { |
| 551 if (!video_) { | 566 if (!video_) { |
| 552 media_log_->SetBooleanProperty("found_video_stream", true); | 567 media_log_->SetBooleanProperty("found_video_stream", true); |
| 553 } | 568 } |
| 554 if (!video_ || | 569 if (!video_ || |
| 555 video_->video_decoder_config().codec() != video_config.codec()) { | 570 video_->video_decoder_config().codec() != video_config.codec()) { |
| 556 media_log_->SetStringProperty("video_codec_name", | 571 media_log_->SetStringProperty("video_codec_name", |
| 557 GetCodecName(video_config.codec())); | 572 GetCodecName(video_config.codec())); |
| 558 } | 573 } |
| 559 | 574 |
| 560 if (!video_) { | 575 if (!video_) { |
| 561 video_ = create_demuxer_stream_cb_.Run(DemuxerStream::VIDEO); | 576 DCHECK(video_track); |
| 577 video_ = create_demuxer_stream_cb_.Run(*video_track); | |
| 562 | 578 |
| 563 if (!video_) { | 579 if (!video_) { |
| 564 DVLOG(1) << "Failed to create a video stream."; | 580 DVLOG(1) << "Failed to create a video stream."; |
| 565 return false; | 581 return false; |
| 566 } | 582 } |
| 567 | 583 |
| 568 if (!frame_processor_->AddTrack(FrameProcessor::kVideoTrackId, video_)) { | 584 if (!frame_processor_->AddTrack(FrameProcessor::kVideoTrackId, video_)) { |
| 569 DVLOG(1) << "Failed to add video track to frame processor."; | 585 DVLOG(1) << "Failed to add video track to frame processor."; |
| 570 return false; | 586 return false; |
| 571 } | 587 } |
| 572 } | 588 } |
| 573 | 589 |
| 574 success &= video_->UpdateVideoConfig(video_config, media_log_); | 590 success &= video_->UpdateVideoConfig(video_config, media_log_); |
| 575 } | 591 } |
| 576 | 592 |
| 577 typedef StreamParser::TextTrackConfigMap::const_iterator TextConfigItr; | 593 typedef StreamParser::TextTrackConfigMap::const_iterator TextConfigItr; |
| 578 if (text_stream_map_.empty()) { | 594 if (text_stream_map_.empty()) { |
| 579 for (TextConfigItr itr = text_configs.begin(); itr != text_configs.end(); | 595 for (TextConfigItr itr = text_configs.begin(); itr != text_configs.end(); |
| 580 ++itr) { | 596 ++itr) { |
| 597 // TODO(servolk): Look into unifying text tracks code path with audio and | |
| 598 // video track code paths. | |
| 599 MediaTrack dummy_text_track(MediaTrack::Text, "", "", "", ""); | |
| 581 ChunkDemuxerStream* const text_stream = | 600 ChunkDemuxerStream* const text_stream = |
| 582 create_demuxer_stream_cb_.Run(DemuxerStream::TEXT); | 601 create_demuxer_stream_cb_.Run(dummy_text_track); |
| 583 if (!frame_processor_->AddTrack(itr->first, text_stream)) { | 602 if (!frame_processor_->AddTrack(itr->first, text_stream)) { |
| 584 success &= false; | 603 success &= false; |
| 585 MEDIA_LOG(ERROR, media_log_) << "Failed to add text track ID " | 604 MEDIA_LOG(ERROR, media_log_) << "Failed to add text track ID " |
| 586 << itr->first << " to frame processor."; | 605 << itr->first << " to frame processor."; |
| 587 break; | 606 break; |
| 588 } | 607 } |
| 589 text_stream->UpdateTextConfig(itr->second, media_log_); | 608 text_stream->UpdateTextConfig(itr->second, media_log_); |
| 590 text_stream_map_[itr->first] = text_stream; | 609 text_stream_map_[itr->first] = text_stream; |
| 591 new_text_track_cb_.Run(text_stream, itr->second); | 610 new_text_track_cb_.Run(text_stream, itr->second); |
| 592 } | 611 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 644 << config_itr->first | 663 << config_itr->first |
| 645 << " does not match old one."; | 664 << " does not match old one."; |
| 646 break; | 665 break; |
| 647 } | 666 } |
| 648 } | 667 } |
| 649 } | 668 } |
| 650 } | 669 } |
| 651 | 670 |
| 652 frame_processor_->SetAllTrackBuffersNeedRandomAccessPoint(); | 671 frame_processor_->SetAllTrackBuffersNeedRandomAccessPoint(); |
| 653 | 672 |
| 673 if (audio_track) { | |
| 674 DCHECK(audio_); | |
| 675 media_tracks_->SetDemuxerStreamForMediaTrack(audio_track, audio_); | |
|
wolenetz
2016/04/15 22:47:18
I think this will now hit DCHECK on repeated init
servolk
2016/04/15 23:26:31
No, it's ok, because for each new init segment a n
wolenetz
2016/04/15 23:52:17
Acknowledged.
| |
| 676 } | |
| 677 if (video_track) { | |
| 678 DCHECK(video_); | |
| 679 media_tracks_->SetDemuxerStreamForMediaTrack(video_track, video_); | |
|
wolenetz
2016/04/15 22:47:18
ditto.
servolk
2016/04/15 23:26:31
Acknowledged.
| |
| 680 } | |
| 681 | |
| 654 DVLOG(1) << "OnNewConfigs() : " << (success ? "success" : "failed"); | 682 DVLOG(1) << "OnNewConfigs() : " << (success ? "success" : "failed"); |
| 655 if (success) { | 683 if (success) { |
| 656 if (state_ == PENDING_PARSER_CONFIG) | 684 if (state_ == PENDING_PARSER_CONFIG) |
| 657 state_ = PENDING_PARSER_INIT; | 685 state_ = PENDING_PARSER_INIT; |
| 658 DCHECK(!init_segment_received_cb_.is_null()); | 686 DCHECK(!init_segment_received_cb_.is_null()); |
| 659 init_segment_received_cb_.Run(std::move(media_tracks_)); | 687 init_segment_received_cb_.Run(std::move(media_tracks_)); |
| 660 } | 688 } |
| 661 | 689 |
| 662 return success; | 690 return success; |
| 663 } | 691 } |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 739 | 767 |
| 740 void MediaSourceState::OnSourceInitDone( | 768 void MediaSourceState::OnSourceInitDone( |
| 741 const StreamParser::InitParameters& params) { | 769 const StreamParser::InitParameters& params) { |
| 742 DCHECK_EQ(state_, PENDING_PARSER_INIT); | 770 DCHECK_EQ(state_, PENDING_PARSER_INIT); |
| 743 state_ = PARSER_INITIALIZED; | 771 state_ = PARSER_INITIALIZED; |
| 744 auto_update_timestamp_offset_ = params.auto_update_timestamp_offset; | 772 auto_update_timestamp_offset_ = params.auto_update_timestamp_offset; |
| 745 base::ResetAndReturn(&init_cb_).Run(params); | 773 base::ResetAndReturn(&init_cb_).Run(params); |
| 746 } | 774 } |
| 747 | 775 |
| 748 } // namespace media | 776 } // namespace media |
| OLD | NEW |