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 "chromecast/media/cma/ipc_streamer/coded_frame_provider_host.h"
8 #include "base/callback_helpers.h"
9 #include "chromecast/media/cma/base/decoder_buffer_base.h"
10 #include "chromecast/media/cma/ipc/media_message.h"
11 #include "chromecast/media/cma/ipc/media_message_fifo.h"
12 #include "chromecast/media/cma/ipc/media_message_type.h"
13 #include "chromecast/media/cma/ipc_streamer/audio_decoder_config_marshaller.h"
14 #include "chromecast/media/cma/ipc_streamer/decoder_buffer_base_marshaller.h"
15 #include "chromecast/media/cma/ipc_streamer/video_decoder_config_marshaller.h"
16 #include "media/base/buffers.h"
17 #include "media/base/decrypt_config.h"
19 namespace chromecast
{
22 CodedFrameProviderHost::CodedFrameProviderHost(
23 scoped_ptr
<MediaMessageFifo
> media_message_fifo
)
24 : fifo_(media_message_fifo
.Pass()),
26 weak_this_
= weak_factory_
.GetWeakPtr();
27 thread_checker_
.DetachFromThread();
30 CodedFrameProviderHost::~CodedFrameProviderHost() {
31 DCHECK(thread_checker_
.CalledOnValidThread());
34 void CodedFrameProviderHost::Read(const ReadCB
& read_cb
) {
35 DCHECK(thread_checker_
.CalledOnValidThread());
37 // Cannot be called if there is already a pending read.
38 DCHECK(read_cb_
.is_null());
44 void CodedFrameProviderHost::Flush(const base::Closure
& flush_cb
) {
45 DCHECK(thread_checker_
.CalledOnValidThread());
46 audio_config_
= ::media::AudioDecoderConfig();
47 video_config_
= ::media::VideoDecoderConfig();
53 void CodedFrameProviderHost::OnFifoWriteEvent() {
54 DCHECK(thread_checker_
.CalledOnValidThread());
58 base::Closure
CodedFrameProviderHost::GetFifoWriteEventCb() {
59 return base::Bind(&CodedFrameProviderHost::OnFifoWriteEvent
, weak_this_
);
62 void CodedFrameProviderHost::ReadMessages() {
63 // Read messages until a frame is provided (i.e. not just the audio/video
65 while (!read_cb_
.is_null()) {
66 scoped_ptr
<MediaMessage
> msg(fifo_
->Pop());
70 if (msg
->type() == PaddingMediaMsg
) {
71 // Ignore the message.
72 } else if (msg
->type() == AudioConfigMediaMsg
) {
73 audio_config_
= AudioDecoderConfigMarshaller::Read(msg
.get());
74 } else if (msg
->type() == VideoConfigMediaMsg
) {
75 video_config_
= VideoDecoderConfigMarshaller::Read(msg
.get());
76 } else if (msg
->type() == FrameMediaMsg
) {
77 scoped_refptr
<DecoderBufferBase
> buffer
=
78 DecoderBufferBaseMarshaller::Read(msg
.Pass());
79 base::ResetAndReturn(&read_cb_
).Run(
80 buffer
, audio_config_
, video_config_
);
81 audio_config_
= ::media::AudioDecoderConfig();
82 video_config_
= ::media::VideoDecoderConfig();
84 // Receiving an unexpected message.
85 // Possible use case (except software bugs): the renderer process has
86 // been compromised and an invalid message value has been written to
87 // the fifo. Crash the browser process in this case to avoid further
88 // security implications (so do not use NOTREACHED which crashes only
90 LOG(FATAL
) << "Unknown media message";
96 } // namespace chromecast