| 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/mojo/services/mojo_demuxer_stream_adapter.h" | 5 #include "media/mojo/services/mojo_demuxer_stream_adapter.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback_helpers.h" | 8 #include "base/callback_helpers.h" |
| 9 #include "media/base/decoder_buffer.h" | 9 #include "media/base/decoder_buffer.h" |
| 10 #include "media/mojo/services/media_type_converters.h" | 10 #include "media/mojo/services/media_type_converters.h" |
| 11 #include "third_party/mojo/src/mojo/public/cpp/system/data_pipe.h" | 11 #include "third_party/mojo/src/mojo/public/cpp/system/data_pipe.h" |
| 12 | 12 |
| 13 namespace media { | 13 namespace media { |
| 14 | 14 |
| 15 MojoDemuxerStreamAdapter::MojoDemuxerStreamAdapter( | 15 MojoDemuxerStreamAdapter::MojoDemuxerStreamAdapter( |
| 16 mojo::DemuxerStreamPtr demuxer_stream, | 16 mojo::DemuxerStreamPtr demuxer_stream, |
| 17 const base::Closure& stream_ready_cb) | 17 const base::Closure& stream_ready_cb) |
| 18 : demuxer_stream_(demuxer_stream.Pass()), | 18 : demuxer_stream_(demuxer_stream.Pass()), |
| 19 binding_(this), | |
| 20 stream_ready_cb_(stream_ready_cb), | 19 stream_ready_cb_(stream_ready_cb), |
| 21 type_(DemuxerStream::UNKNOWN), | 20 type_(DemuxerStream::UNKNOWN), |
| 22 weak_factory_(this) { | 21 weak_factory_(this) { |
| 23 DVLOG(1) << __FUNCTION__; | 22 DVLOG(1) << __FUNCTION__; |
| 24 mojo::DemuxerStreamObserverPtr observer_ptr; | 23 demuxer_stream_->Initialize(base::Bind( |
| 25 binding_.Bind(GetProxy(&observer_ptr)); | 24 &MojoDemuxerStreamAdapter::OnStreamReady, weak_factory_.GetWeakPtr())); |
| 26 demuxer_stream_->Initialize( | |
| 27 observer_ptr.Pass(), base::Bind(&MojoDemuxerStreamAdapter::OnStreamReady, | |
| 28 weak_factory_.GetWeakPtr())); | |
| 29 } | 25 } |
| 30 | 26 |
| 31 MojoDemuxerStreamAdapter::~MojoDemuxerStreamAdapter() { | 27 MojoDemuxerStreamAdapter::~MojoDemuxerStreamAdapter() { |
| 32 DVLOG(1) << __FUNCTION__; | 28 DVLOG(1) << __FUNCTION__; |
| 33 } | 29 } |
| 34 | 30 |
| 35 void MojoDemuxerStreamAdapter::Read(const DemuxerStream::ReadCB& read_cb) { | 31 void MojoDemuxerStreamAdapter::Read(const DemuxerStream::ReadCB& read_cb) { |
| 36 DVLOG(3) << __FUNCTION__; | 32 DVLOG(3) << __FUNCTION__; |
| 37 // We shouldn't be holding on to a previous callback if a new Read() came in. | 33 // We shouldn't be holding on to a previous callback if a new Read() came in. |
| 38 DCHECK(read_cb_.is_null()); | 34 DCHECK(read_cb_.is_null()); |
| 39 | 35 |
| 40 DCHECK(stream_pipe_.is_valid()); | 36 DCHECK(stream_pipe_.is_valid()); |
| 41 read_cb_ = read_cb; | 37 read_cb_ = read_cb; |
| 42 demuxer_stream_->Read(base::Bind(&MojoDemuxerStreamAdapter::OnBufferReady, | 38 demuxer_stream_->Read(base::Bind(&MojoDemuxerStreamAdapter::OnBufferReady, |
| 43 weak_factory_.GetWeakPtr())); | 39 weak_factory_.GetWeakPtr())); |
| 44 } | 40 } |
| 45 | 41 |
| 46 AudioDecoderConfig MojoDemuxerStreamAdapter::audio_decoder_config() { | 42 AudioDecoderConfig MojoDemuxerStreamAdapter::audio_decoder_config() { |
| 47 DCHECK_EQ(type_, DemuxerStream::AUDIO); | 43 DCHECK_EQ(type_, DemuxerStream::AUDIO); |
| 48 DCHECK(!audio_config_queue_.empty()); | 44 return audio_config_; |
| 49 return audio_config_queue_.front(); | |
| 50 } | 45 } |
| 51 | 46 |
| 52 VideoDecoderConfig MojoDemuxerStreamAdapter::video_decoder_config() { | 47 VideoDecoderConfig MojoDemuxerStreamAdapter::video_decoder_config() { |
| 53 DCHECK_EQ(type_, DemuxerStream::VIDEO); | 48 DCHECK_EQ(type_, DemuxerStream::VIDEO); |
| 54 DCHECK(!video_config_queue_.empty()); | 49 return video_config_; |
| 55 return video_config_queue_.front(); | |
| 56 } | 50 } |
| 57 | 51 |
| 58 DemuxerStream::Type MojoDemuxerStreamAdapter::type() const { | 52 DemuxerStream::Type MojoDemuxerStreamAdapter::type() const { |
| 59 return type_; | 53 return type_; |
| 60 } | 54 } |
| 61 | 55 |
| 62 void MojoDemuxerStreamAdapter::EnableBitstreamConverter() { | 56 void MojoDemuxerStreamAdapter::EnableBitstreamConverter() { |
| 63 NOTIMPLEMENTED(); | 57 NOTIMPLEMENTED(); |
| 64 } | 58 } |
| 65 | 59 |
| 66 bool MojoDemuxerStreamAdapter::SupportsConfigChanges() { | 60 bool MojoDemuxerStreamAdapter::SupportsConfigChanges() { |
| 67 return true; | 61 return true; |
| 68 } | 62 } |
| 69 | 63 |
| 70 VideoRotation MojoDemuxerStreamAdapter::video_rotation() { | 64 VideoRotation MojoDemuxerStreamAdapter::video_rotation() { |
| 71 NOTIMPLEMENTED(); | 65 NOTIMPLEMENTED(); |
| 72 return VIDEO_ROTATION_0; | 66 return VIDEO_ROTATION_0; |
| 73 } | 67 } |
| 74 | 68 |
| 75 // TODO(xhwang): Pass liveness here. | 69 // TODO(xhwang): Pass liveness here. |
| 76 void MojoDemuxerStreamAdapter::OnStreamReady( | 70 void MojoDemuxerStreamAdapter::OnStreamReady( |
| 77 mojo::ScopedDataPipeConsumerHandle pipe) { | 71 mojo::DemuxerStream::Type type, |
| 72 mojo::ScopedDataPipeConsumerHandle pipe, |
| 73 mojo::AudioDecoderConfigPtr audio_config, |
| 74 mojo::VideoDecoderConfigPtr video_config) { |
| 78 DVLOG(1) << __FUNCTION__; | 75 DVLOG(1) << __FUNCTION__; |
| 79 DCHECK(pipe.is_valid()); | 76 DCHECK(pipe.is_valid()); |
| 80 DCHECK_NE(type_, DemuxerStream::UNKNOWN); | 77 DCHECK_EQ(DemuxerStream::UNKNOWN, type_); |
| 78 |
| 79 type_ = static_cast<DemuxerStream::Type>(type); |
| 81 stream_pipe_ = pipe.Pass(); | 80 stream_pipe_ = pipe.Pass(); |
| 81 UpdateConfig(audio_config.Pass(), video_config.Pass()); |
| 82 |
| 82 stream_ready_cb_.Run(); | 83 stream_ready_cb_.Run(); |
| 83 } | 84 } |
| 84 | 85 |
| 85 void MojoDemuxerStreamAdapter::OnAudioDecoderConfigChanged( | |
| 86 mojo::AudioDecoderConfigPtr config) { | |
| 87 DCHECK(type_ == DemuxerStream::UNKNOWN || type_ == DemuxerStream::AUDIO) | |
| 88 << type_; | |
| 89 type_ = DemuxerStream::AUDIO; | |
| 90 | |
| 91 audio_config_queue_.push(config.To<AudioDecoderConfig>()); | |
| 92 } | |
| 93 | |
| 94 void MojoDemuxerStreamAdapter::OnVideoDecoderConfigChanged( | |
| 95 mojo::VideoDecoderConfigPtr config) { | |
| 96 DCHECK(type_ == DemuxerStream::UNKNOWN || type_ == DemuxerStream::VIDEO) | |
| 97 << type_; | |
| 98 type_ = DemuxerStream::VIDEO; | |
| 99 | |
| 100 video_config_queue_.push(config.To<VideoDecoderConfig>()); | |
| 101 } | |
| 102 | |
| 103 void MojoDemuxerStreamAdapter::OnBufferReady( | 86 void MojoDemuxerStreamAdapter::OnBufferReady( |
| 104 mojo::DemuxerStream::Status status, | 87 mojo::DemuxerStream::Status status, |
| 105 mojo::MediaDecoderBufferPtr buffer) { | 88 mojo::MediaDecoderBufferPtr buffer, |
| 89 mojo::AudioDecoderConfigPtr audio_config, |
| 90 mojo::VideoDecoderConfigPtr video_config) { |
| 106 DVLOG(3) << __FUNCTION__; | 91 DVLOG(3) << __FUNCTION__; |
| 107 DCHECK(!read_cb_.is_null()); | 92 DCHECK(!read_cb_.is_null()); |
| 108 DCHECK_NE(type_, DemuxerStream::UNKNOWN); | 93 DCHECK_NE(type_, DemuxerStream::UNKNOWN); |
| 109 DCHECK(stream_pipe_.is_valid()); | 94 DCHECK(stream_pipe_.is_valid()); |
| 110 | 95 |
| 111 if (status == mojo::DemuxerStream::STATUS_CONFIG_CHANGED) { | 96 if (status == mojo::DemuxerStream::STATUS_CONFIG_CHANGED) { |
| 112 if (type_ == DemuxerStream::AUDIO) { | 97 UpdateConfig(audio_config.Pass(), video_config.Pass()); |
| 113 audio_config_queue_.pop(); | |
| 114 DCHECK(!audio_config_queue_.empty()); | |
| 115 } else if (type_ == DemuxerStream::VIDEO) { | |
| 116 video_config_queue_.pop(); | |
| 117 DCHECK(!video_config_queue_.empty()); | |
| 118 } else { | |
| 119 NOTREACHED() << "Unsupported config change encountered for type: " | |
| 120 << type_; | |
| 121 } | |
| 122 | |
| 123 base::ResetAndReturn(&read_cb_).Run(DemuxerStream::kConfigChanged, nullptr); | 98 base::ResetAndReturn(&read_cb_).Run(DemuxerStream::kConfigChanged, nullptr); |
| 124 return; | 99 return; |
| 125 } | 100 } |
| 126 | 101 |
| 127 if (status == mojo::DemuxerStream::STATUS_ABORTED) { | 102 if (status == mojo::DemuxerStream::STATUS_ABORTED) { |
| 128 base::ResetAndReturn(&read_cb_).Run(DemuxerStream::kAborted, nullptr); | 103 base::ResetAndReturn(&read_cb_).Run(DemuxerStream::kAborted, nullptr); |
| 129 return; | 104 return; |
| 130 } | 105 } |
| 131 | 106 |
| 132 DCHECK_EQ(status, mojo::DemuxerStream::STATUS_OK); | 107 DCHECK_EQ(status, mojo::DemuxerStream::STATUS_OK); |
| 133 scoped_refptr<DecoderBuffer> media_buffer( | 108 scoped_refptr<DecoderBuffer> media_buffer( |
| 134 buffer.To<scoped_refptr<DecoderBuffer>>()); | 109 buffer.To<scoped_refptr<DecoderBuffer>>()); |
| 135 | 110 |
| 136 if (!media_buffer->end_of_stream()) { | 111 if (!media_buffer->end_of_stream()) { |
| 137 DCHECK_GT(media_buffer->data_size(), 0); | 112 DCHECK_GT(media_buffer->data_size(), 0); |
| 138 | 113 |
| 139 // Read the inner data for the DecoderBuffer from our DataPipe. | 114 // Read the inner data for the DecoderBuffer from our DataPipe. |
| 140 uint32_t num_bytes = media_buffer->data_size(); | 115 uint32_t num_bytes = media_buffer->data_size(); |
| 141 CHECK_EQ(ReadDataRaw(stream_pipe_.get(), media_buffer->writable_data(), | 116 CHECK_EQ(ReadDataRaw(stream_pipe_.get(), media_buffer->writable_data(), |
| 142 &num_bytes, MOJO_READ_DATA_FLAG_ALL_OR_NONE), | 117 &num_bytes, MOJO_READ_DATA_FLAG_ALL_OR_NONE), |
| 143 MOJO_RESULT_OK); | 118 MOJO_RESULT_OK); |
| 144 CHECK_EQ(num_bytes, static_cast<uint32_t>(media_buffer->data_size())); | 119 CHECK_EQ(num_bytes, static_cast<uint32_t>(media_buffer->data_size())); |
| 145 } | 120 } |
| 146 | 121 |
| 147 base::ResetAndReturn(&read_cb_).Run(DemuxerStream::kOk, media_buffer); | 122 base::ResetAndReturn(&read_cb_).Run(DemuxerStream::kOk, media_buffer); |
| 148 } | 123 } |
| 149 | 124 |
| 125 void MojoDemuxerStreamAdapter::UpdateConfig( |
| 126 mojo::AudioDecoderConfigPtr audio_config, |
| 127 mojo::VideoDecoderConfigPtr video_config) { |
| 128 DCHECK_NE(type_, DemuxerStream::UNKNOWN); |
| 129 |
| 130 switch(type_) { |
| 131 case DemuxerStream::AUDIO: |
| 132 DCHECK(audio_config && !video_config); |
| 133 audio_config_ = audio_config.To<AudioDecoderConfig>(); |
| 134 break; |
| 135 case DemuxerStream::VIDEO: |
| 136 DCHECK(video_config && !audio_config); |
| 137 video_config_ = video_config.To<VideoDecoderConfig>(); |
| 138 break; |
| 139 default: |
| 140 NOTREACHED(); |
| 141 } |
| 142 } |
| 143 |
| 150 } // namespace media | 144 } // namespace media |
| OLD | NEW |