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 "third_party/mojo/src/mojo/public/cpp/system/data_pipe.h"
15 MojoDemuxerStreamAdapter::MojoDemuxerStreamAdapter(
16 interfaces::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_
->Initialize(base::Bind(
24 &MojoDemuxerStreamAdapter::OnStreamReady
, weak_factory_
.GetWeakPtr()));
27 MojoDemuxerStreamAdapter::~MojoDemuxerStreamAdapter() {
28 DVLOG(1) << __FUNCTION__
;
31 void MojoDemuxerStreamAdapter::Read(const DemuxerStream::ReadCB
& read_cb
) {
32 DVLOG(3) << __FUNCTION__
;
33 // We shouldn't be holding on to a previous callback if a new Read() came in.
34 DCHECK(read_cb_
.is_null());
36 DCHECK(stream_pipe_
.is_valid());
38 demuxer_stream_
->Read(base::Bind(&MojoDemuxerStreamAdapter::OnBufferReady
,
39 weak_factory_
.GetWeakPtr()));
42 AudioDecoderConfig
MojoDemuxerStreamAdapter::audio_decoder_config() {
43 DCHECK_EQ(type_
, DemuxerStream::AUDIO
);
47 VideoDecoderConfig
MojoDemuxerStreamAdapter::video_decoder_config() {
48 DCHECK_EQ(type_
, DemuxerStream::VIDEO
);
52 DemuxerStream::Type
MojoDemuxerStreamAdapter::type() const {
56 void MojoDemuxerStreamAdapter::EnableBitstreamConverter() {
60 bool MojoDemuxerStreamAdapter::SupportsConfigChanges() {
64 VideoRotation
MojoDemuxerStreamAdapter::video_rotation() {
66 return VIDEO_ROTATION_0
;
69 // TODO(xhwang): Pass liveness here.
70 void MojoDemuxerStreamAdapter::OnStreamReady(
71 interfaces::DemuxerStream::Type type
,
72 mojo::ScopedDataPipeConsumerHandle pipe
,
73 interfaces::AudioDecoderConfigPtr audio_config
,
74 interfaces::VideoDecoderConfigPtr video_config
) {
75 DVLOG(1) << __FUNCTION__
;
76 DCHECK(pipe
.is_valid());
77 DCHECK_EQ(DemuxerStream::UNKNOWN
, type_
);
79 type_
= static_cast<DemuxerStream::Type
>(type
);
80 stream_pipe_
= pipe
.Pass();
81 UpdateConfig(audio_config
.Pass(), video_config
.Pass());
83 stream_ready_cb_
.Run();
86 void MojoDemuxerStreamAdapter::OnBufferReady(
87 interfaces::DemuxerStream::Status status
,
88 interfaces::DecoderBufferPtr buffer
,
89 interfaces::AudioDecoderConfigPtr audio_config
,
90 interfaces::VideoDecoderConfigPtr video_config
) {
91 DVLOG(3) << __FUNCTION__
;
92 DCHECK(!read_cb_
.is_null());
93 DCHECK_NE(type_
, DemuxerStream::UNKNOWN
);
94 DCHECK(stream_pipe_
.is_valid());
96 if (status
== interfaces::DemuxerStream::STATUS_CONFIG_CHANGED
) {
97 UpdateConfig(audio_config
.Pass(), video_config
.Pass());
98 base::ResetAndReturn(&read_cb_
).Run(DemuxerStream::kConfigChanged
, nullptr);
102 if (status
== interfaces::DemuxerStream::STATUS_ABORTED
) {
103 base::ResetAndReturn(&read_cb_
).Run(DemuxerStream::kAborted
, nullptr);
107 DCHECK_EQ(status
, interfaces::DemuxerStream::STATUS_OK
);
108 scoped_refptr
<DecoderBuffer
> media_buffer(
109 buffer
.To
<scoped_refptr
<DecoderBuffer
>>());
111 if (!media_buffer
->end_of_stream()) {
112 DCHECK_GT(media_buffer
->data_size(), 0);
114 // Read the inner data for the DecoderBuffer from our DataPipe.
115 uint32_t num_bytes
= media_buffer
->data_size();
116 CHECK_EQ(ReadDataRaw(stream_pipe_
.get(), media_buffer
->writable_data(),
117 &num_bytes
, MOJO_READ_DATA_FLAG_ALL_OR_NONE
),
119 CHECK_EQ(num_bytes
, static_cast<uint32_t>(media_buffer
->data_size()));
122 base::ResetAndReturn(&read_cb_
).Run(DemuxerStream::kOk
, media_buffer
);
125 void MojoDemuxerStreamAdapter::UpdateConfig(
126 interfaces::AudioDecoderConfigPtr audio_config
,
127 interfaces::VideoDecoderConfigPtr video_config
) {
128 DCHECK_NE(type_
, DemuxerStream::UNKNOWN
);
131 case DemuxerStream::AUDIO
:
132 DCHECK(audio_config
&& !video_config
);
133 audio_config_
= audio_config
.To
<AudioDecoderConfig
>();
135 case DemuxerStream::VIDEO
:
136 DCHECK(video_config
&& !audio_config
);
137 video_config_
= video_config
.To
<VideoDecoderConfig
>();