summaryrefslogtreecommitdiffstats
path: root/chrome/renderer/media
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-16 20:40:37 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-16 20:40:37 +0000
commitccc70d8efc4981925423ffa1390c0b4783ea1add (patch)
tree8cfe460075607074359b7f5556705c0ff173e7be /chrome/renderer/media
parent9dc1379851640ce5bd544862ce86f44258159ca9 (diff)
downloadchromium_src-ccc70d8efc4981925423ffa1390c0b4783ea1add.zip
chromium_src-ccc70d8efc4981925423ffa1390c0b4783ea1add.tar.gz
chromium_src-ccc70d8efc4981925423ffa1390c0b4783ea1add.tar.bz2
Move core renderer subdirectories to content.
TBR=avi Review URL: http://codereview.chromium.org/6673090 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@78422 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer/media')
-rw-r--r--chrome/renderer/media/audio_renderer_impl.cc362
-rw-r--r--chrome/renderer/media/audio_renderer_impl.h157
-rw-r--r--chrome/renderer/media/audio_renderer_impl_unittest.cc146
-rw-r--r--chrome/renderer/media/gles2_video_decode_context.cc122
-rw-r--r--chrome/renderer/media/gles2_video_decode_context.h113
-rw-r--r--chrome/renderer/media/ipc_video_decoder.cc207
-rw-r--r--chrome/renderer/media/ipc_video_decoder.h92
7 files changed, 0 insertions, 1199 deletions
diff --git a/chrome/renderer/media/audio_renderer_impl.cc b/chrome/renderer/media/audio_renderer_impl.cc
deleted file mode 100644
index de41c2a..0000000
--- a/chrome/renderer/media/audio_renderer_impl.cc
+++ /dev/null
@@ -1,362 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/renderer/media/audio_renderer_impl.h"
-
-#include <math.h>
-
-#include "chrome/common/render_messages.h"
-#include "chrome/common/render_messages_params.h"
-#include "chrome/renderer/audio_message_filter.h"
-#include "chrome/renderer/render_view.h"
-#include "chrome/renderer/render_thread.h"
-#include "media/base/filter_host.h"
-
-namespace {
-
-// We will try to fill 200 ms worth of audio samples in each packet. A round
-// trip latency for IPC messages are typically 10 ms, this should give us
-// plenty of time to avoid clicks.
-const int kMillisecondsPerPacket = 200;
-
-// We have at most 3 packets in browser, i.e. 600 ms. This is a reasonable
-// amount to avoid clicks.
-const int kPacketsInBuffer = 3;
-
-} // namespace
-
-AudioRendererImpl::AudioRendererImpl(AudioMessageFilter* filter)
- : AudioRendererBase(),
- bytes_per_second_(0),
- filter_(filter),
- stream_id_(0),
- shared_memory_(NULL),
- shared_memory_size_(0),
- io_loop_(filter->message_loop()),
- stopped_(false),
- pending_request_(false),
- prerolling_(false),
- preroll_bytes_(0) {
- DCHECK(io_loop_);
-}
-
-AudioRendererImpl::~AudioRendererImpl() {
-}
-
-base::TimeDelta AudioRendererImpl::ConvertToDuration(int bytes) {
- if (bytes_per_second_) {
- return base::TimeDelta::FromMicroseconds(
- base::Time::kMicrosecondsPerSecond * bytes / bytes_per_second_);
- }
- return base::TimeDelta();
-}
-
-bool AudioRendererImpl::OnInitialize(const media::MediaFormat& media_format) {
- // Parse integer values in MediaFormat.
- if (!ParseMediaFormat(media_format,
- &params_.channels,
- &params_.sample_rate,
- &params_.bits_per_sample)) {
- return false;
- }
- params_.format = AudioParameters::AUDIO_PCM_LINEAR;
-
- // Calculate the number of bytes per second using information of the stream.
- bytes_per_second_ = params_.sample_rate * params_.channels *
- params_.bits_per_sample / 8;
-
- io_loop_->PostTask(FROM_HERE,
- NewRunnableMethod(this, &AudioRendererImpl::CreateStreamTask, params_));
- return true;
-}
-
-void AudioRendererImpl::OnStop() {
- base::AutoLock auto_lock(lock_);
- if (stopped_)
- return;
- stopped_ = true;
-
- // We should never touch |io_loop_| after being stopped, so post our final
- // task to clean up.
- io_loop_->PostTask(FROM_HERE,
- NewRunnableMethod(this, &AudioRendererImpl::DestroyTask));
-}
-
-void AudioRendererImpl::ConsumeAudioSamples(
- scoped_refptr<media::Buffer> buffer_in) {
- base::AutoLock auto_lock(lock_);
- if (stopped_)
- return;
-
- // TODO(hclam): handle end of stream here.
-
- // Use the base class to queue the buffer.
- AudioRendererBase::ConsumeAudioSamples(buffer_in);
-
- // Post a task to render thread to notify a packet reception.
- io_loop_->PostTask(FROM_HERE,
- NewRunnableMethod(this, &AudioRendererImpl::NotifyPacketReadyTask));
-}
-
-void AudioRendererImpl::SetPlaybackRate(float rate) {
- DCHECK(rate >= 0.0f);
-
- base::AutoLock auto_lock(lock_);
- // Handle the case where we stopped due to |io_loop_| dying.
- if (stopped_) {
- AudioRendererBase::SetPlaybackRate(rate);
- return;
- }
-
- // We have two cases here:
- // Play: GetPlaybackRate() == 0.0 && rate != 0.0
- // Pause: GetPlaybackRate() != 0.0 && rate == 0.0
- if (GetPlaybackRate() == 0.0f && rate != 0.0f) {
- io_loop_->PostTask(FROM_HERE,
- NewRunnableMethod(this, &AudioRendererImpl::PlayTask));
- } else if (GetPlaybackRate() != 0.0f && rate == 0.0f) {
- // Pause is easy, we can always pause.
- io_loop_->PostTask(FROM_HERE,
- NewRunnableMethod(this, &AudioRendererImpl::PauseTask));
- }
- AudioRendererBase::SetPlaybackRate(rate);
-
- // If we are playing, give a kick to try fulfilling the packet request as
- // the previous packet request may be stalled by a pause.
- if (rate > 0.0f) {
- io_loop_->PostTask(
- FROM_HERE,
- NewRunnableMethod(this, &AudioRendererImpl::NotifyPacketReadyTask));
- }
-}
-
-void AudioRendererImpl::Pause(media::FilterCallback* callback) {
- AudioRendererBase::Pause(callback);
- base::AutoLock auto_lock(lock_);
- if (stopped_)
- return;
-
- io_loop_->PostTask(FROM_HERE,
- NewRunnableMethod(this, &AudioRendererImpl::PauseTask));
-}
-
-void AudioRendererImpl::Seek(base::TimeDelta time,
- media::FilterCallback* callback) {
- AudioRendererBase::Seek(time, callback);
- base::AutoLock auto_lock(lock_);
- if (stopped_)
- return;
-
- io_loop_->PostTask(FROM_HERE,
- NewRunnableMethod(this, &AudioRendererImpl::SeekTask));
-}
-
-
-void AudioRendererImpl::Play(media::FilterCallback* callback) {
- AudioRendererBase::Play(callback);
- base::AutoLock auto_lock(lock_);
- if (stopped_)
- return;
-
- if (GetPlaybackRate() != 0.0f) {
- io_loop_->PostTask(FROM_HERE,
- NewRunnableMethod(this, &AudioRendererImpl::PlayTask));
- } else {
- io_loop_->PostTask(FROM_HERE,
- NewRunnableMethod(this, &AudioRendererImpl::PauseTask));
- }
-}
-
-void AudioRendererImpl::SetVolume(float volume) {
- base::AutoLock auto_lock(lock_);
- if (stopped_)
- return;
- io_loop_->PostTask(FROM_HERE,
- NewRunnableMethod(
- this, &AudioRendererImpl::SetVolumeTask, volume));
-}
-
-void AudioRendererImpl::OnCreated(base::SharedMemoryHandle handle,
- uint32 length) {
- DCHECK(MessageLoop::current() == io_loop_);
-
- base::AutoLock auto_lock(lock_);
- if (stopped_)
- return;
-
- shared_memory_.reset(new base::SharedMemory(handle, false));
- shared_memory_->Map(length);
- shared_memory_size_ = length;
-}
-
-void AudioRendererImpl::OnLowLatencyCreated(base::SharedMemoryHandle,
- base::SyncSocket::Handle, uint32) {
- // AudioRenderer should not have a low-latency audio channel.
- NOTREACHED();
-}
-
-void AudioRendererImpl::OnRequestPacket(AudioBuffersState buffers_state) {
- DCHECK(MessageLoop::current() == io_loop_);
-
- {
- base::AutoLock auto_lock(lock_);
- DCHECK(!pending_request_);
- pending_request_ = true;
- request_buffers_state_ = buffers_state;
- }
-
- // Try to fill in the fulfill the packet request.
- NotifyPacketReadyTask();
-}
-
-void AudioRendererImpl::OnStateChanged(
- const ViewMsg_AudioStreamState_Params& state) {
- DCHECK(MessageLoop::current() == io_loop_);
-
- base::AutoLock auto_lock(lock_);
- if (stopped_)
- return;
-
- switch (state.state) {
- case ViewMsg_AudioStreamState_Params::kError:
- // We receive this error if we counter an hardware error on the browser
- // side. We can proceed with ignoring the audio stream.
- // TODO(hclam): We need more handling of these kind of error. For example
- // re-try creating the audio output stream on the browser side or fail
- // nicely and report to demuxer that the whole audio stream is discarded.
- host()->DisableAudioRenderer();
- break;
- // TODO(hclam): handle these events.
- case ViewMsg_AudioStreamState_Params::kPlaying:
- case ViewMsg_AudioStreamState_Params::kPaused:
- break;
- default:
- NOTREACHED();
- break;
- }
-}
-
-void AudioRendererImpl::OnVolume(double volume) {
- // TODO(hclam): decide whether we need to report the current volume to
- // pipeline.
-}
-
-void AudioRendererImpl::CreateStreamTask(const AudioParameters& audio_params) {
- DCHECK(MessageLoop::current() == io_loop_);
-
- base::AutoLock auto_lock(lock_);
- if (stopped_)
- return;
-
- // Make sure we don't call create more than once.
- DCHECK_EQ(0, stream_id_);
- stream_id_ = filter_->AddDelegate(this);
- io_loop_->AddDestructionObserver(this);
-
- ViewHostMsg_Audio_CreateStream_Params params;
- params.params = audio_params;
-
- // Let the browser choose packet size.
- params.params.samples_per_packet = 0;
-
- filter_->Send(new ViewHostMsg_CreateAudioStream(0, stream_id_, params,
- false));
-}
-
-void AudioRendererImpl::PlayTask() {
- DCHECK(MessageLoop::current() == io_loop_);
-
- filter_->Send(new ViewHostMsg_PlayAudioStream(0, stream_id_));
-}
-
-void AudioRendererImpl::PauseTask() {
- DCHECK(MessageLoop::current() == io_loop_);
-
- filter_->Send(new ViewHostMsg_PauseAudioStream(0, stream_id_));
-}
-
-void AudioRendererImpl::SeekTask() {
- DCHECK(MessageLoop::current() == io_loop_);
-
- // We have to pause the audio stream before we can flush.
- filter_->Send(new ViewHostMsg_PauseAudioStream(0, stream_id_));
- filter_->Send(new ViewHostMsg_FlushAudioStream(0, stream_id_));
-}
-
-void AudioRendererImpl::DestroyTask() {
- DCHECK(MessageLoop::current() == io_loop_);
-
- // Make sure we don't call destroy more than once.
- DCHECK_NE(0, stream_id_);
- filter_->RemoveDelegate(stream_id_);
- filter_->Send(new ViewHostMsg_CloseAudioStream(0, stream_id_));
- io_loop_->RemoveDestructionObserver(this);
- stream_id_ = 0;
-}
-
-void AudioRendererImpl::SetVolumeTask(double volume) {
- DCHECK(MessageLoop::current() == io_loop_);
-
- base::AutoLock auto_lock(lock_);
- if (stopped_)
- return;
- filter_->Send(new ViewHostMsg_SetAudioVolume(0, stream_id_, volume));
-}
-
-void AudioRendererImpl::NotifyPacketReadyTask() {
- DCHECK(MessageLoop::current() == io_loop_);
-
- base::AutoLock auto_lock(lock_);
- if (stopped_)
- return;
- if (pending_request_ && GetPlaybackRate() > 0.0f) {
- DCHECK(shared_memory_.get());
-
- // Adjust the playback delay.
- base::Time current_time = base::Time::Now();
-
- base::TimeDelta request_delay =
- ConvertToDuration(request_buffers_state_.total_bytes());
-
- // Add message delivery delay.
- if (current_time > request_buffers_state_.timestamp) {
- base::TimeDelta receive_latency =
- current_time - request_buffers_state_.timestamp;
-
- // If the receive latency is too much it may offset all the delay.
- if (receive_latency >= request_delay) {
- request_delay = base::TimeDelta();
- } else {
- request_delay -= receive_latency;
- }
- }
-
- // Finally we need to adjust the delay according to playback rate.
- if (GetPlaybackRate() != 1.0f) {
- request_delay = base::TimeDelta::FromMicroseconds(
- static_cast<int64>(ceil(request_delay.InMicroseconds() *
- GetPlaybackRate())));
- }
-
- uint32 filled = FillBuffer(static_cast<uint8*>(shared_memory_->memory()),
- shared_memory_size_, request_delay,
- request_buffers_state_.pending_bytes == 0);
- pending_request_ = false;
- // Then tell browser process we are done filling into the buffer.
- filter_->Send(
- new ViewHostMsg_NotifyAudioPacketReady(0, stream_id_, filled));
- }
-}
-
-void AudioRendererImpl::WillDestroyCurrentMessageLoop() {
- DCHECK(MessageLoop::current() == io_loop_);
-
- // We treat the IO loop going away the same as stopping.
- base::AutoLock auto_lock(lock_);
- if (stopped_)
- return;
-
- stopped_ = true;
- DestroyTask();
-}
diff --git a/chrome/renderer/media/audio_renderer_impl.h b/chrome/renderer/media/audio_renderer_impl.h
deleted file mode 100644
index 9e8b93d..0000000
--- a/chrome/renderer/media/audio_renderer_impl.h
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// Audio rendering unit utilizing audio output stream provided by browser
-// process through IPC.
-//
-// Relationship of classes.
-//
-// AudioRendererHost AudioRendererImpl
-// ^ ^
-// | |
-// v IPC v
-// RenderMessageFilter <---------> AudioMessageFilter
-//
-// Implementation of interface with audio device is in AudioRendererHost and
-// it provides services and entry points in RenderMessageFilter, allowing
-// usage of IPC calls to interact with audio device. AudioMessageFilter acts
-// as a portal for IPC calls and does no more than delegation.
-//
-// Transportation of audio buffer is done by using shared memory, after
-// OnCreateStream is executed, OnCreated would be called along with a
-// SharedMemoryHandle upon successful creation of audio output stream in the
-// browser process. The same piece of shared memory would be used during the
-// lifetime of this unit.
-//
-// This class lives inside three threads during it's lifetime, namely:
-// 1. IO thread.
-// The thread within which this class receives all the IPC messages and
-// IPC communications can only happen in this thread.
-// 2. Pipeline thread
-// Initialization of filter and proper stopping of filters happens here.
-// Properties of this filter is also set in this thread.
-// 3. Audio decoder thread (If there's one.)
-// Responsible for decoding audio data and gives raw PCM data to this object.
-
-#ifndef CHROME_RENDERER_MEDIA_AUDIO_RENDERER_IMPL_H_
-#define CHROME_RENDERER_MEDIA_AUDIO_RENDERER_IMPL_H_
-#pragma once
-
-#include "base/gtest_prod_util.h"
-#include "base/message_loop.h"
-#include "base/scoped_ptr.h"
-#include "base/shared_memory.h"
-#include "base/synchronization/lock.h"
-#include "chrome/renderer/audio_message_filter.h"
-#include "media/audio/audio_io.h"
-#include "media/audio/audio_manager.h"
-#include "media/base/filters.h"
-#include "media/filters/audio_renderer_base.h"
-
-class AudioMessageFilter;
-
-class AudioRendererImpl : public media::AudioRendererBase,
- public AudioMessageFilter::Delegate,
- public MessageLoop::DestructionObserver {
- public:
- // Methods called on Render thread ------------------------------------------
- explicit AudioRendererImpl(AudioMessageFilter* filter);
- virtual ~AudioRendererImpl();
-
- // Methods called on IO thread ----------------------------------------------
- // AudioMessageFilter::Delegate methods, called by AudioMessageFilter.
- virtual void OnRequestPacket(AudioBuffersState buffers_state);
- virtual void OnStateChanged(const ViewMsg_AudioStreamState_Params& state);
- virtual void OnCreated(base::SharedMemoryHandle handle, uint32 length);
- virtual void OnLowLatencyCreated(base::SharedMemoryHandle handle,
- base::SyncSocket::Handle socket_handle,
- uint32 length);
- virtual void OnVolume(double volume);
-
- // Methods called on pipeline thread ----------------------------------------
- // media::Filter implementation.
- virtual void SetPlaybackRate(float rate);
- virtual void Pause(media::FilterCallback* callback);
- virtual void Seek(base::TimeDelta time, media::FilterCallback* callback);
- virtual void Play(media::FilterCallback* callback);
-
- // media::AudioRenderer implementation.
- virtual void SetVolume(float volume);
-
- protected:
- // Methods called on audio renderer thread ----------------------------------
- // These methods are called from AudioRendererBase.
- virtual bool OnInitialize(const media::MediaFormat& media_format);
- virtual void OnStop();
-
- // Called when the decoder completes a Read().
- virtual void ConsumeAudioSamples(scoped_refptr<media::Buffer> buffer_in);
-
- private:
- // For access to constructor and IO thread methods.
- friend class AudioRendererImplTest;
- FRIEND_TEST_ALL_PREFIXES(AudioRendererImplTest, Stop);
- FRIEND_TEST_ALL_PREFIXES(AudioRendererImplTest,
- DestroyedMessageLoop_ConsumeAudioSamples);
- // Helper methods.
- // Convert number of bytes to duration of time using information about the
- // number of channels, sample rate and sample bits.
- base::TimeDelta ConvertToDuration(int bytes);
-
- // Methods call on IO thread ------------------------------------------------
- // The following methods are tasks posted on the IO thread that needs to
- // be executed on that thread. They interact with AudioMessageFilter and
- // sends IPC messages on that thread.
- void CreateStreamTask(const AudioParameters& params);
- void PlayTask();
- void PauseTask();
- void SeekTask();
- void SetVolumeTask(double volume);
- void NotifyPacketReadyTask();
- void DestroyTask();
-
- // Called on IO thread when message loop is dying.
- virtual void WillDestroyCurrentMessageLoop();
-
- // Information about the audio stream.
- AudioParameters params_;
- uint32 bytes_per_second_;
-
- scoped_refptr<AudioMessageFilter> filter_;
-
- // ID of the stream created in the browser process.
- int32 stream_id_;
-
- // Memory shared by the browser process for audio buffer.
- scoped_ptr<base::SharedMemory> shared_memory_;
- uint32 shared_memory_size_;
-
- // Message loop for the IO thread.
- MessageLoop* io_loop_;
-
- // Protects:
- // - |stopped_|
- // - |pending_request_|
- // - |request_buffers_state_|
- base::Lock lock_;
-
- // A flag that indicates this filter is called to stop.
- bool stopped_;
-
- // A flag that indicates an outstanding packet request.
- bool pending_request_;
-
- // State of the audio buffers at time of the last request.
- AudioBuffersState request_buffers_state_;
-
- // State variables for prerolling.
- bool prerolling_;
-
- // Remaining bytes for prerolling to complete.
- uint32 preroll_bytes_;
-
- DISALLOW_COPY_AND_ASSIGN(AudioRendererImpl);
-};
-
-#endif // CHROME_RENDERER_MEDIA_AUDIO_RENDERER_IMPL_H_
diff --git a/chrome/renderer/media/audio_renderer_impl_unittest.cc b/chrome/renderer/media/audio_renderer_impl_unittest.cc
deleted file mode 100644
index 754c60d..0000000
--- a/chrome/renderer/media/audio_renderer_impl_unittest.cc
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/process_util.h"
-#include "chrome/common/render_messages.h"
-#include "chrome/common/render_messages_params.h"
-#include "chrome/renderer/media/audio_renderer_impl.h"
-#include "media/base/data_buffer.h"
-#include "media/base/media_format.h"
-#include "media/base/mock_callback.h"
-#include "media/base/mock_filter_host.h"
-#include "media/base/mock_filters.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using ::testing::ReturnRef;
-
-class AudioRendererImplTest : public ::testing::Test {
- public:
- static const int kRouteId = 0;
- static const int kSize = 1024;
-
- AudioRendererImplTest() {
- message_loop_.reset(new MessageLoop(MessageLoop::TYPE_IO));
-
- // TODO(scherkus): use gmock with AudioMessageFilter to verify
- // AudioRendererImpl calls or doesn't call Send().
- filter_ = new AudioMessageFilter(kRouteId);
- filter_->message_loop_ = message_loop_.get();
-
- // Create temporary shared memory.
- CHECK(shared_mem_.CreateAnonymous(kSize));
-
- // Setup expectations for initialization.
- decoder_ = new media::MockAudioDecoder();
-
- // Associate media format with decoder
- decoder_media_format_.SetAsInteger(media::MediaFormat::kChannels, 2);
- decoder_media_format_.SetAsInteger(media::MediaFormat::kSampleRate, 48000);
- decoder_media_format_.SetAsInteger(media::MediaFormat::kSampleBits, 16);
- EXPECT_CALL(*decoder_, media_format())
- .WillRepeatedly(ReturnRef(decoder_media_format_));
-
- // Create and initialize audio renderer.
- renderer_ = new AudioRendererImpl(filter_);
- renderer_->set_host(&host_);
- renderer_->Initialize(decoder_, media::NewExpectedCallback());
-
- // Run pending tasks and simulate responding with a created audio stream.
- message_loop_->RunAllPending();
-
- // Duplicate the shared memory handle so both the test and the callee can
- // close their copy.
- base::SharedMemoryHandle duplicated_handle;
- EXPECT_TRUE(shared_mem_.ShareToProcess(base::GetCurrentProcessHandle(),
- &duplicated_handle));
-
- renderer_->OnCreated(duplicated_handle, kSize);
- }
-
- virtual ~AudioRendererImplTest() {
- }
-
- protected:
- // Fixtures.
- scoped_ptr<MessageLoop> message_loop_;
- scoped_refptr<AudioMessageFilter> filter_;
- base::SharedMemory shared_mem_;
- media::MockFilterHost host_;
- scoped_refptr<media::MockAudioDecoder> decoder_;
- scoped_refptr<AudioRendererImpl> renderer_;
- media::MediaFormat decoder_media_format_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(AudioRendererImplTest);
-};
-
-TEST_F(AudioRendererImplTest, SetPlaybackRate) {
- // Execute SetPlaybackRate() codepath to create an IPC message.
-
- // Toggle play/pause to generate some IPC messages.
- renderer_->SetPlaybackRate(0.0f);
- renderer_->SetPlaybackRate(1.0f);
- renderer_->SetPlaybackRate(0.0f);
-
- renderer_->Stop(media::NewExpectedCallback());
- message_loop_->RunAllPending();
-}
-
-TEST_F(AudioRendererImplTest, SetVolume) {
- // Execute SetVolume() codepath to create an IPC message.
- renderer_->SetVolume(0.5f);
- renderer_->Stop(media::NewExpectedCallback());
- message_loop_->RunAllPending();
-}
-
-TEST_F(AudioRendererImplTest, Stop) {
- // Declare some state messages.
- const ViewMsg_AudioStreamState_Params kError(
- ViewMsg_AudioStreamState_Params::kError);
- const ViewMsg_AudioStreamState_Params kPlaying(
- ViewMsg_AudioStreamState_Params::kPlaying);
- const ViewMsg_AudioStreamState_Params kPaused(
- ViewMsg_AudioStreamState_Params::kPaused);
-
- // Execute Stop() codepath to create an IPC message.
- renderer_->Stop(media::NewExpectedCallback());
- message_loop_->RunAllPending();
-
- // Run AudioMessageFilter::Delegate methods, which can be executed after being
- // stopped. AudioRendererImpl shouldn't create any messages.
- renderer_->OnRequestPacket(AudioBuffersState(kSize, 0));
- renderer_->OnStateChanged(kError);
- renderer_->OnStateChanged(kPlaying);
- renderer_->OnStateChanged(kPaused);
- renderer_->OnCreated(shared_mem_.handle(), kSize);
- renderer_->OnVolume(0.5);
-
- // It's possible that the upstream decoder replies right after being stopped.
- scoped_refptr<media::Buffer> buffer(new media::DataBuffer(kSize));
- renderer_->ConsumeAudioSamples(buffer);
-}
-
-TEST_F(AudioRendererImplTest, DestroyedMessageLoop_SetPlaybackRate) {
- // Kill the message loop and verify SetPlaybackRate() still works.
- message_loop_.reset();
- renderer_->SetPlaybackRate(0.0f);
- renderer_->SetPlaybackRate(1.0f);
- renderer_->SetPlaybackRate(0.0f);
- renderer_->Stop(media::NewExpectedCallback());
-}
-
-TEST_F(AudioRendererImplTest, DestroyedMessageLoop_SetVolume) {
- // Kill the message loop and verify SetVolume() still works.
- message_loop_.reset();
- renderer_->SetVolume(0.5f);
- renderer_->Stop(media::NewExpectedCallback());
-}
-
-TEST_F(AudioRendererImplTest, DestroyedMessageLoop_ConsumeAudioSamples) {
- // Kill the message loop and verify OnReadComplete() still works.
- message_loop_.reset();
- scoped_refptr<media::Buffer> buffer(new media::DataBuffer(kSize));
- renderer_->ConsumeAudioSamples(buffer);
- renderer_->Stop(media::NewExpectedCallback());
-}
diff --git a/chrome/renderer/media/gles2_video_decode_context.cc b/chrome/renderer/media/gles2_video_decode_context.cc
deleted file mode 100644
index 9712313..0000000
--- a/chrome/renderer/media/gles2_video_decode_context.cc
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <GLES2/gl2.h>
-
-#include "base/message_loop.h"
-#include "chrome/renderer/ggl/ggl.h"
-#include "chrome/renderer/media/gles2_video_decode_context.h"
-
-Gles2VideoDecodeContext::Gles2VideoDecodeContext(
- MessageLoop* message_loop, bool memory_mapped, ggl::Context* context)
- : message_loop_(message_loop),
- memory_mapped_(memory_mapped),
- context_(context) {
-}
-
-Gles2VideoDecodeContext::~Gles2VideoDecodeContext() {
-}
-
-void* Gles2VideoDecodeContext::GetDevice() {
- // This decode context is used inside the renderer and so hardware decoder
- // device handler should not be used.
- return NULL;
-}
-
-void Gles2VideoDecodeContext::AllocateVideoFrames(
- int num_frames, size_t width, size_t height,
- media::VideoFrame::Format format,
- std::vector<scoped_refptr<media::VideoFrame> >* frames_out, Task* task) {
- if (MessageLoop::current() != message_loop_) {
- message_loop_->PostTask(
- FROM_HERE,
- NewRunnableMethod(this, &Gles2VideoDecodeContext::AllocateVideoFrames,
- num_frames, width, height, format, frames_out,
- task));
- return;
- }
-
- // In this method we need to make the ggl context current and then generate
- // textures for each video frame. We also need to allocate memory for each
- // texture generated.
- bool ret = ggl::MakeCurrent(context_);
- CHECK(ret) << "Failed to switch context";
-
- frames_.resize(num_frames);
- for (int i = 0; i < num_frames; ++i) {
- int planes = media::VideoFrame::GetNumberOfPlanes(format);
- media::VideoFrame::GlTexture textures[media::VideoFrame::kMaxPlanes];
-
- // Set the color format of the textures.
- DCHECK(format == media::VideoFrame::RGBA ||
- format == media::VideoFrame::YV12);
- int gl_format = format == media::VideoFrame::RGBA ? GL_RGBA : GL_LUMINANCE;
-
- glGenTextures(planes, textures);
- for (int j = 0; j < planes; ++j) {
- glBindTexture(GL_TEXTURE_2D, textures[j]);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexImage2D(GL_TEXTURE_2D, 0, gl_format, width, height, 0, gl_format,
- GL_UNSIGNED_BYTE, NULL);
- }
- glFlush();
-
- scoped_refptr<media::VideoFrame> frame;
- media::VideoFrame::CreateFrameGlTexture(format, width, height, textures,
- &frame);
- frames_[i] = frame;
- }
- *frames_out = frames_;
-
- task->Run();
- delete task;
-}
-
-void Gles2VideoDecodeContext::ReleaseAllVideoFrames() {
- if (MessageLoop::current() != message_loop_) {
- message_loop_->PostTask(
- FROM_HERE,
- NewRunnableMethod(this,
- &Gles2VideoDecodeContext::ReleaseAllVideoFrames));
- return;
- }
-
- // Make the context current and then release the video frames.
- bool ret = ggl::MakeCurrent(context_);
- CHECK(ret) << "Failed to switch context";
-
- for (size_t i = 0; i < frames_.size(); ++i) {
- for (size_t j = 0; j < frames_[i]->planes(); ++j) {
- media::VideoFrame::GlTexture texture = frames_[i]->gl_texture(j);
- glDeleteTextures(1, &texture);
- }
- }
- frames_.clear();
-}
-
-void Gles2VideoDecodeContext::ConvertToVideoFrame(
- void* buffer, scoped_refptr<media::VideoFrame> frame, Task* task) {
- DCHECK(memory_mapped_);
- // TODO(hclam): Implement.
-}
-
-void Gles2VideoDecodeContext::Destroy(Task* task) {
- if (MessageLoop::current() != message_loop_) {
- message_loop_->PostTask(
- FROM_HERE,
- NewRunnableMethod(this, &Gles2VideoDecodeContext::Destroy, task));
- return;
- }
-
- ReleaseAllVideoFrames();
- DCHECK_EQ(0u, frames_.size());
-
- task->Run();
- delete task;
-}
-
-DISABLE_RUNNABLE_METHOD_REFCOUNT(Gles2VideoDecodeContext);
diff --git a/chrome/renderer/media/gles2_video_decode_context.h b/chrome/renderer/media/gles2_video_decode_context.h
deleted file mode 100644
index 3fe9889..0000000
--- a/chrome/renderer/media/gles2_video_decode_context.h
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_RENDERER_MEDIA_GLES2_VIDEO_DECODE_CONTEXT_H_
-#define CHROME_RENDERER_MEDIA_GLES2_VIDEO_DECODE_CONTEXT_H_
-
-#include <vector>
-
-#include "media/video/video_decode_context.h"
-
-class MessageLoop;
-
-namespace ggl {
-class Context;
-} // namespace ggl
-
-// FUNCTIONS
-//
-// This is a class that provides a video decode context using a ggl::Context
-// backend.
-//
-// It provides resources for a VideoDecodeEngine to store decoded video frames.
-//
-// This class is aware of the command buffer implementation of GLES2 inside the
-// Chrome renderer and keeps a reference of ggl::Context. It might use GLES2
-// commands specific to Chrome's renderer process to provide needed resources.
-//
-// There are two different kinds of video frame storage provided by this class:
-// 1. Memory mapped textures (aka software decoding mode).
-// Each texture is memory mapped and appears to the VideoDecodeEngine as
-// system memory.
-//
-// The usage of the textures is that the VideoDecodeEngine is performing
-// software video decoding and use them as if they are allocated in plain
-// system memory (in fact they are allocated in system memory and shared
-// bwith the GPU process). An additional step of uploading the content to
-// video memory is needed. Since VideoDecodeEngine is unaware of the video
-// memory, this upload operation is performed by calling
-// ConvertToVideoFrame().
-//
-// After the content is uploaded to video memory, WebKit will see the video
-// frame as textures and will perform the necessary operations for
-// rendering.
-//
-// 2. Opaque textures (aka hardware decoding mode).
-// In this mode of operation each video frame is backed by some opaque
-// textures. This is used only when hardware video decoding is used. The
-// textures needs to be generated and allocated inside the renderer process
-// first. This will establish a translation between texture ID in the
-// renderer process and the GPU process.
-//
-// The texture ID generated is used by IpcVideoDecodeEngine only to be sent
-// the GPU process. Inside the GPU process the texture ID is translated to
-// a real texture ID inside the actual context. The real texture ID is then
-// assigned to the hardware video decoder for storing the video frame.
-//
-// WebKit will see the video frame as a normal textures and perform
-// necessary render operations.
-//
-// In both operation modes, the objective is to have WebKit see the video frames
-// as regular textures.
-//
-// THREAD SEMANTICS
-//
-// All methods of this class can be called on any thread. GLES2 context and all
-// OpenGL method calls are accessed on the Render Thread. As as result all Tasks
-// given to this object are executed on the Render Thread.
-//
-// Since this class is not refcounted, it is important to destroy objects of
-// this class only when the Task given to Destroy() is called.
-//
-class Gles2VideoDecodeContext : public media::VideoDecodeContext {
- public:
- // |message_loop| is the message of the Render Thread.
- // |memory_mapped| determines if textures allocated are memory mapped.
- // |context| is the graphics context for generating textures.
- Gles2VideoDecodeContext(MessageLoop* message_loop,
- bool memory_mapped, ggl::Context* context);
- virtual ~Gles2VideoDecodeContext();
-
- // media::VideoDecodeContext implementation.
- virtual void* GetDevice();
- virtual void AllocateVideoFrames(
- int frames_num, size_t width, size_t height,
- media::VideoFrame::Format format,
- std::vector<scoped_refptr<media::VideoFrame> >* frames_out, Task* task);
- virtual void ReleaseAllVideoFrames();
- virtual void ConvertToVideoFrame(void* buffer,
- scoped_refptr<media::VideoFrame> frame,
- Task* task);
- virtual void Destroy(Task* task);
-
- // Accessor of the current mode of this decode context.
- bool IsMemoryMapped() const { return memory_mapped_; }
-
- private:
- // Message loop for Render Thread.
- MessageLoop* message_loop_;
-
- // Type of storage provided by this class.
- bool memory_mapped_;
-
- // Pointer to the GLES2 context.
- ggl::Context* context_;
-
- // VideoFrames allocated.
- std::vector<scoped_refptr<media::VideoFrame> > frames_;
-
- DISALLOW_COPY_AND_ASSIGN(Gles2VideoDecodeContext);
-};
-
-#endif // CHROME_RENDERER_MEDIA_GLES2_VIDEO_DECODE_CONTEXT_H_
diff --git a/chrome/renderer/media/ipc_video_decoder.cc b/chrome/renderer/media/ipc_video_decoder.cc
deleted file mode 100644
index 361642b..0000000
--- a/chrome/renderer/media/ipc_video_decoder.cc
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/renderer/media/ipc_video_decoder.h"
-
-#include "base/task.h"
-#include "chrome/renderer/ggl/ggl.h"
-#include "content/common/child_process.h"
-#include "media/base/callback.h"
-#include "media/base/filters.h"
-#include "media/base/filter_host.h"
-#include "media/base/limits.h"
-#include "media/base/media_format.h"
-#include "media/base/video_frame.h"
-#include "media/ffmpeg/ffmpeg_common.h"
-#include "media/filters/ffmpeg_interfaces.h"
-#include "media/video/video_decode_engine.h"
-
-IpcVideoDecoder::IpcVideoDecoder(MessageLoop* message_loop,
- ggl::Context* ggl_context)
- : decode_context_message_loop_(message_loop),
- ggl_context_(ggl_context) {
-}
-
-IpcVideoDecoder::~IpcVideoDecoder() {
-}
-
-void IpcVideoDecoder::Initialize(media::DemuxerStream* demuxer_stream,
- media::FilterCallback* callback,
- media::StatisticsCallback* statsCallback) {
- // It doesn't matter which thread we perform initialization because
- // all this method does is create objects and delegate the initialize
- // messsage.
-
- DCHECK(!demuxer_stream_);
- demuxer_stream_ = demuxer_stream;
- initialize_callback_.reset(callback);
- statistics_callback_.reset(statsCallback);
-
- // We require bit stream converter for hardware decoder.
- demuxer_stream->EnableBitstreamConverter();
-
- // Get the AVStream by querying for the provider interface.
- media::AVStreamProvider* av_stream_provider;
- if (!demuxer_stream->QueryInterface(&av_stream_provider)) {
- media::VideoCodecInfo info = {0};
- OnInitializeComplete(info);
- return;
- }
-
- AVStream* av_stream = av_stream_provider->GetAVStream();
-
- int width = av_stream->codec->coded_width;
- int height = av_stream->codec->coded_height;
- if (width > media::Limits::kMaxDimension ||
- height > media::Limits::kMaxDimension ||
- (width * height) > media::Limits::kMaxCanvas) {
- media::VideoCodecInfo info = {0};
- OnInitializeComplete(info);
- return;
- }
-
- // Create a video decode context that assocates with the graphics
- // context.
- decode_context_.reset(
- ggl::CreateVideoDecodeContext(
- ggl_context_, decode_context_message_loop_, true));
-
- // Create a hardware video decoder handle.
- decode_engine_.reset(ggl::CreateVideoDecodeEngine(ggl_context_));
-
- media::VideoCodecConfig config(
- media::CodecIDToVideoCodec(av_stream->codec->codec_id),
- width, height,
- av_stream->r_frame_rate.num,
- av_stream->r_frame_rate.den,
- av_stream->codec->extradata,
- av_stream->codec->extradata_size);
-
- // VideoDecodeEngine will perform initialization on the message loop
- // given to it so it doesn't matter on which thread we are calling this.
- decode_engine_->Initialize(ChildProcess::current()->io_message_loop(), this,
- decode_context_.get(), config);
-}
-
-const media::MediaFormat& IpcVideoDecoder::media_format() {
- return media_format_;
-}
-
-void IpcVideoDecoder::Stop(media::FilterCallback* callback) {
- stop_callback_.reset(callback);
- decode_engine_->Uninitialize();
-}
-
-void IpcVideoDecoder::Pause(media::FilterCallback* callback) {
- // TODO(hclam): It looks like that pause is not necessary so implement this
- // later.
- callback->Run();
- delete callback;
-}
-
-void IpcVideoDecoder::Flush(media::FilterCallback* callback) {
- flush_callback_.reset(callback);
- decode_engine_->Flush();
-}
-
-void IpcVideoDecoder::Seek(base::TimeDelta time,
- media::FilterCallback* callback) {
- seek_callback_.reset(callback);
- decode_engine_->Seek();
-}
-
-void IpcVideoDecoder::OnInitializeComplete(const media::VideoCodecInfo& info) {
- DCHECK_EQ(ChildProcess::current()->io_message_loop(), MessageLoop::current());
-
- if (info.success) {
- media_format_.SetAsInteger(media::MediaFormat::kSurfaceType,
- media::VideoFrame::TYPE_GL_TEXTURE);
- media_format_.SetAsInteger(media::MediaFormat::kSurfaceFormat,
- info.stream_info.surface_format);
- media_format_.SetAsInteger(media::MediaFormat::kWidth,
- info.stream_info.surface_width);
- media_format_.SetAsInteger(media::MediaFormat::kHeight,
- info.stream_info.surface_height);
- media_format_.SetAsInteger(
- media::MediaFormat::kSurfaceType,
- static_cast<int>(media::VideoFrame::TYPE_GL_TEXTURE));
- } else {
- LOG(ERROR) << "IpcVideoDecoder initialization failed!";
- host()->SetError(media::PIPELINE_ERROR_DECODE);
- }
-
- initialize_callback_->Run();
- initialize_callback_.reset();
-}
-
-void IpcVideoDecoder::OnUninitializeComplete() {
- DCHECK_EQ(ChildProcess::current()->io_message_loop(), MessageLoop::current());
-
- // After the decode engine is uninitialized we are safe to destroy the decode
- // context. The task will add a refcount to this object so don't need to worry
- // about objects lifetime.
- decode_context_->Destroy(
- NewRunnableMethod(this, &IpcVideoDecoder::OnDestroyComplete));
-
- // We don't need to wait for destruction of decode context to complete because
- // it can happen asynchronously. This object and decode context will live
- // until the destruction task is called.
- stop_callback_->Run();
- stop_callback_.reset();
-}
-
-void IpcVideoDecoder::OnFlushComplete() {
- DCHECK_EQ(ChildProcess::current()->io_message_loop(), MessageLoop::current());
- flush_callback_->Run();
- flush_callback_.reset();
-}
-
-void IpcVideoDecoder::OnSeekComplete() {
- DCHECK_EQ(ChildProcess::current()->io_message_loop(), MessageLoop::current());
- seek_callback_->Run();
- seek_callback_.reset();
-}
-
-void IpcVideoDecoder::OnError() {
- DCHECK_EQ(ChildProcess::current()->io_message_loop(), MessageLoop::current());
- host()->SetError(media::PIPELINE_ERROR_DECODE);
-}
-
-// This methid is called by Demuxer after a demuxed packet is produced.
-void IpcVideoDecoder::OnReadComplete(media::Buffer* buffer) {
- decode_engine_->ConsumeVideoSample(buffer);
-}
-
-void IpcVideoDecoder::OnDestroyComplete() {
- // We don't need to do anything in this method. Destruction of objects will
- // occur as soon as refcount goes to 0.
-}
-
-// This method is called by VideoRenderer. We delegate the method call to
-// VideoDecodeEngine.
-void IpcVideoDecoder::ProduceVideoFrame(
- scoped_refptr<media::VideoFrame> video_frame) {
- decode_engine_->ProduceVideoFrame(video_frame);
-}
-
-bool IpcVideoDecoder::ProvidesBuffer() {
- return true;
-}
-
-// This method is called by VideoDecodeEngine that a video frame is produced.
-// This is then passed to VideoRenderer.
-void IpcVideoDecoder::ConsumeVideoFrame(
- scoped_refptr<media::VideoFrame> video_frame,
- const media::PipelineStatistics& statistics) {
- DCHECK(video_frame);
- statistics_callback_->Run(statistics);
-
- VideoFrameReady(video_frame);
-}
-
-// This method is called by VideoDecodeEngine to request a video frame. The
-// request is passed to demuxer.
-void IpcVideoDecoder::ProduceVideoSample(scoped_refptr<media::Buffer> buffer) {
- demuxer_stream_->Read(NewCallback(this, &IpcVideoDecoder::OnReadComplete));
-}
diff --git a/chrome/renderer/media/ipc_video_decoder.h b/chrome/renderer/media/ipc_video_decoder.h
deleted file mode 100644
index 63702fa..0000000
--- a/chrome/renderer/media/ipc_video_decoder.h
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_RENDERER_MEDIA_IPC_VIDEO_DECODER_H_
-#define CHROME_RENDERER_MEDIA_IPC_VIDEO_DECODER_H_
-
-#include "base/time.h"
-#include "media/base/pts_heap.h"
-#include "media/base/video_frame.h"
-#include "media/filters/decoder_base.h"
-#include "media/video/video_decode_engine.h"
-#include "media/video/video_decode_context.h"
-
-struct AVRational;
-
-namespace ggl {
-class Context;
-} // namespace ggl
-
-class IpcVideoDecoder : public media::VideoDecoder,
- public media::VideoDecodeEngine::EventHandler {
- public:
- IpcVideoDecoder(MessageLoop* message_loop, ggl::Context* ggl_context);
- virtual ~IpcVideoDecoder();
-
- // media::Filter implementation.
- virtual void Stop(media::FilterCallback* callback);
- virtual void Seek(base::TimeDelta time, media::FilterCallback* callback);
- virtual void Pause(media::FilterCallback* callback);
- virtual void Flush(media::FilterCallback* callback);
-
- // media::VideoDecoder implementation.
- virtual void Initialize(media::DemuxerStream* demuxer_stream,
- media::FilterCallback* callback,
- media::StatisticsCallback* statsCallback);
- virtual const media::MediaFormat& media_format();
- virtual void ProduceVideoFrame(scoped_refptr<media::VideoFrame> video_frame);
-
- // TODO(hclam): Remove this method.
- virtual bool ProvidesBuffer();
-
- // media::VideoDecodeEngine::EventHandler implementation.
- virtual void OnInitializeComplete(const media::VideoCodecInfo& info);
- virtual void OnUninitializeComplete();
- virtual void OnFlushComplete();
- virtual void OnSeekComplete();
- virtual void OnError();
-
- // TODO(hclam): Remove this method.
- virtual void OnFormatChange(media::VideoStreamInfo stream_info) {}
- virtual void ProduceVideoSample(scoped_refptr<media::Buffer> buffer);
- virtual void ConsumeVideoFrame(scoped_refptr<media::VideoFrame> frame,
- const media::PipelineStatistics& statistics);
-
- private:
- void OnReadComplete(media::Buffer* buffer);
- void OnDestroyComplete();
-
- media::MediaFormat media_format_;
-
- scoped_ptr<media::FilterCallback> flush_callback_;
- scoped_ptr<media::FilterCallback> seek_callback_;
- scoped_ptr<media::FilterCallback> initialize_callback_;
- scoped_ptr<media::FilterCallback> stop_callback_;
- scoped_ptr<media::StatisticsCallback> statistics_callback_;
-
- // Pointer to the demuxer stream that will feed us compressed buffers.
- scoped_refptr<media::DemuxerStream> demuxer_stream_;
-
- // This is the message loop that we should assign to VideoDecodeContext.
- MessageLoop* decode_context_message_loop_;
-
- // A context for allocating textures and issuing GLES2 commands.
- // TODO(hclam): A ggl::Context lives on the Render Thread while this object
- // lives on the Video Decoder Thread, we need to take care of context lost
- // and destruction of the context.
- ggl::Context* ggl_context_;
-
- // This VideoDecodeEngine translate our requests to IPC commands to the
- // GPU process.
- // VideoDecodeEngine should run on IO Thread instead of Render Thread to
- // avoid dead lock during tear down of the media pipeline.
- scoped_ptr<media::VideoDecodeEngine> decode_engine_;
-
- // Decoding context to be used by VideoDecodeEngine.
- scoped_ptr<media::VideoDecodeContext> decode_context_;
-
- DISALLOW_COPY_AND_ASSIGN(IpcVideoDecoder);
-};
-
-#endif // CHROME_RENDERER_MEDIA_IPC_VIDEO_DECODER_H_