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.
5 #include "media/mojo/services/mojo_demuxer_stream_adapter.h"
8 #include "base/callback_helpers.h"
9 #include "media/base/decoder_buffer.h"
10 #include "media/mojo/services/media_type_converters.h"
11 #include "mojo/public/cpp/system/data_pipe.h"
15 MojoDemuxerStreamAdapter::MojoDemuxerStreamAdapter(
16 mojo::DemuxerStreamPtr demuxer_stream
,
17 const base::Closure
& stream_ready_cb
)
18 : demuxer_stream_(demuxer_stream
.Pass()),
19 stream_ready_cb_(stream_ready_cb
),
20 type_(DemuxerStream::UNKNOWN
),
22 DVLOG(1) << __FUNCTION__
;
23 demuxer_stream_
.set_client(this);
26 MojoDemuxerStreamAdapter::~MojoDemuxerStreamAdapter() {
27 DVLOG(1) << __FUNCTION__
;
30 void MojoDemuxerStreamAdapter::Read(const DemuxerStream::ReadCB
& read_cb
) {
31 DVLOG(3) << __FUNCTION__
;
32 // We shouldn't be holding on to a previous callback if a new Read() came in.
33 DCHECK(read_cb_
.is_null());
35 DCHECK(stream_pipe_
.is_valid());
37 demuxer_stream_
->Read(base::Bind(&MojoDemuxerStreamAdapter::OnBufferReady
,
38 weak_factory_
.GetWeakPtr()));
41 AudioDecoderConfig
MojoDemuxerStreamAdapter::audio_decoder_config() {
42 DCHECK_EQ(type_
, DemuxerStream::AUDIO
);
43 DCHECK(!audio_config_queue_
.empty());
44 return audio_config_queue_
.front();
47 VideoDecoderConfig
MojoDemuxerStreamAdapter::video_decoder_config() {
48 DCHECK_EQ(type_
, DemuxerStream::VIDEO
);
49 DCHECK(!video_config_queue_
.empty());
50 return video_config_queue_
.front();
53 DemuxerStream::Type
MojoDemuxerStreamAdapter::type() const {
57 void MojoDemuxerStreamAdapter::EnableBitstreamConverter() {
61 bool MojoDemuxerStreamAdapter::SupportsConfigChanges() {
65 VideoRotation
MojoDemuxerStreamAdapter::video_rotation() {
67 return VIDEO_ROTATION_0
;
70 // TODO(xhwang): Pass liveness here.
71 void MojoDemuxerStreamAdapter::OnStreamReady(
72 mojo::ScopedDataPipeConsumerHandle pipe
) {
73 DVLOG(1) << __FUNCTION__
;
74 DCHECK(pipe
.is_valid());
75 DCHECK_NE(type_
, DemuxerStream::UNKNOWN
);
76 stream_pipe_
= pipe
.Pass();
77 stream_ready_cb_
.Run();
80 void MojoDemuxerStreamAdapter::OnAudioDecoderConfigChanged(
81 mojo::AudioDecoderConfigPtr config
) {
82 DCHECK(type_
== DemuxerStream::UNKNOWN
|| type_
== DemuxerStream::AUDIO
)
84 type_
= DemuxerStream::AUDIO
;
86 audio_config_queue_
.push(config
.To
<AudioDecoderConfig
>());
89 void MojoDemuxerStreamAdapter::OnVideoDecoderConfigChanged(
90 mojo::VideoDecoderConfigPtr config
) {
91 DCHECK(type_
== DemuxerStream::UNKNOWN
|| type_
== DemuxerStream::VIDEO
)
93 type_
= DemuxerStream::VIDEO
;
95 video_config_queue_
.push(config
.To
<VideoDecoderConfig
>());
98 void MojoDemuxerStreamAdapter::OnBufferReady(
99 mojo::DemuxerStream::Status status
,
100 mojo::MediaDecoderBufferPtr buffer
) {
101 DVLOG(3) << __FUNCTION__
;
102 DCHECK(!read_cb_
.is_null());
103 DCHECK_NE(type_
, DemuxerStream::UNKNOWN
);
104 DCHECK(stream_pipe_
.is_valid());
106 if (status
== mojo::DemuxerStream::STATUS_CONFIG_CHANGED
) {
107 if (type_
== DemuxerStream::AUDIO
) {
108 audio_config_queue_
.pop();
109 DCHECK(!audio_config_queue_
.empty());
110 } else if (type_
== DemuxerStream::VIDEO
) {
111 video_config_queue_
.pop();
112 DCHECK(!video_config_queue_
.empty());
114 NOTREACHED() << "Unsupported config change encountered for type: "
118 base::ResetAndReturn(&read_cb_
).Run(DemuxerStream::kConfigChanged
, nullptr);
122 if (status
== mojo::DemuxerStream::STATUS_ABORTED
) {
123 base::ResetAndReturn(&read_cb_
).Run(DemuxerStream::kAborted
, nullptr);
127 DCHECK_EQ(status
, mojo::DemuxerStream::STATUS_OK
);
128 scoped_refptr
<DecoderBuffer
> media_buffer(
129 buffer
.To
<scoped_refptr
<DecoderBuffer
>>());
131 if (!media_buffer
->end_of_stream()) {
132 DCHECK_GT(media_buffer
->data_size(), 0);
134 // Read the inner data for the DecoderBuffer from our DataPipe.
135 uint32_t num_bytes
= media_buffer
->data_size();
136 CHECK_EQ(ReadDataRaw(stream_pipe_
.get(), media_buffer
->writable_data(),
137 &num_bytes
, MOJO_READ_DATA_FLAG_ALL_OR_NONE
),
139 CHECK_EQ(num_bytes
, static_cast<uint32_t>(media_buffer
->data_size()));
142 base::ResetAndReturn(&read_cb_
).Run(DemuxerStream::kOk
, media_buffer
);