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/mojo/services/mojo_demuxer_stream_adapter.h" 6 7 #include "base/bind.h" 8 #include "base/callback_helpers.h" 9 #include "media/base/decoder_buffer.h" 10 #include "media/mojo/services/media_type_converters.h" 11 12 namespace media { 13 MojoDemuxerStreamAdapter(mojo::DemuxerStreamPtr demuxer_stream,const base::Closure & stream_ready_cb)14MojoDemuxerStreamAdapter::MojoDemuxerStreamAdapter( 15 mojo::DemuxerStreamPtr demuxer_stream, 16 const base::Closure& stream_ready_cb) 17 : demuxer_stream_(demuxer_stream.Pass()), 18 stream_ready_cb_(stream_ready_cb), 19 weak_factory_(this) { 20 demuxer_stream_.set_client(this); 21 } 22 ~MojoDemuxerStreamAdapter()23MojoDemuxerStreamAdapter::~MojoDemuxerStreamAdapter() { 24 } 25 Read(const DemuxerStream::ReadCB & read_cb)26void MojoDemuxerStreamAdapter::Read(const DemuxerStream::ReadCB& read_cb) { 27 // We shouldn't be holding on to a previous callback if a new Read() came in. 28 DCHECK(read_cb_.is_null()); 29 read_cb_ = read_cb; 30 demuxer_stream_->Read(base::Bind(&MojoDemuxerStreamAdapter::OnBufferReady, 31 weak_factory_.GetWeakPtr())); 32 } 33 audio_decoder_config()34AudioDecoderConfig MojoDemuxerStreamAdapter::audio_decoder_config() { 35 DCHECK(!config_queue_.empty()); 36 return config_queue_.front(); 37 } 38 video_decoder_config()39VideoDecoderConfig MojoDemuxerStreamAdapter::video_decoder_config() { 40 NOTREACHED(); 41 return VideoDecoderConfig(); 42 } 43 type()44media::DemuxerStream::Type MojoDemuxerStreamAdapter::type() { 45 return media::DemuxerStream::AUDIO; 46 } 47 EnableBitstreamConverter()48void MojoDemuxerStreamAdapter::EnableBitstreamConverter() { 49 NOTREACHED(); 50 } 51 SupportsConfigChanges()52bool MojoDemuxerStreamAdapter::SupportsConfigChanges() { 53 return true; 54 } 55 video_rotation()56VideoRotation MojoDemuxerStreamAdapter::video_rotation() { 57 NOTIMPLEMENTED(); 58 return VIDEO_ROTATION_0; 59 } 60 OnStreamReady(mojo::ScopedDataPipeConsumerHandle pipe)61void MojoDemuxerStreamAdapter::OnStreamReady( 62 mojo::ScopedDataPipeConsumerHandle pipe) { 63 // TODO(tim): We don't support pipe streaming yet. 64 DCHECK(!pipe.is_valid()); 65 DCHECK(!config_queue_.empty()); 66 stream_ready_cb_.Run(); 67 } 68 OnAudioDecoderConfigChanged(mojo::AudioDecoderConfigPtr config)69void MojoDemuxerStreamAdapter::OnAudioDecoderConfigChanged( 70 mojo::AudioDecoderConfigPtr config) { 71 config_queue_.push(config.To<media::AudioDecoderConfig>()); 72 73 if (!read_cb_.is_null()) { 74 read_cb_.Run(media::DemuxerStream::Status::kConfigChanged, NULL); 75 read_cb_.Reset(); 76 } 77 } 78 OnBufferReady(mojo::DemuxerStream::Status status,mojo::MediaDecoderBufferPtr buffer)79void MojoDemuxerStreamAdapter::OnBufferReady( 80 mojo::DemuxerStream::Status status, 81 mojo::MediaDecoderBufferPtr buffer) { 82 DCHECK(!read_cb_.is_null()); 83 DCHECK(!config_queue_.empty()); 84 85 media::DemuxerStream::Status media_status( 86 static_cast<media::DemuxerStream::Status>(status)); 87 scoped_refptr<media::DecoderBuffer> media_buffer( 88 buffer.To<scoped_refptr<media::DecoderBuffer> >()); 89 90 if (status == mojo::DemuxerStream::STATUS_CONFIG_CHANGED) { 91 DCHECK(!media_buffer.get()); 92 config_queue_.pop(); 93 94 // If the |config_queue_| is empty we need to wait for 95 // OnAudioDecoderConfigChanged before invoking |read_cb|. 96 if (config_queue_.empty()) 97 return; 98 } 99 read_cb_.Run(media_status, media_buffer); 100 read_cb_.Reset(); 101 } 102 103 } // namespace media 104