diff options
Diffstat (limited to 'chrome/renderer/media')
-rw-r--r-- | chrome/renderer/media/ipc_video_decoder.cc | 344 | ||||
-rw-r--r-- | chrome/renderer/media/ipc_video_decoder.h | 100 |
2 files changed, 0 insertions, 444 deletions
diff --git a/chrome/renderer/media/ipc_video_decoder.cc b/chrome/renderer/media/ipc_video_decoder.cc deleted file mode 100644 index 9d47260..0000000 --- a/chrome/renderer/media/ipc_video_decoder.cc +++ /dev/null @@ -1,344 +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/ipc_video_decoder.h" - -#include "base/task.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/ffmpeg/ffmpeg_util.h" -#include "media/filters/ffmpeg_interfaces.h" - -namespace media { - -IpcVideoDecoder::IpcVideoDecoder(MessageLoop* message_loop) - : width_(0), - height_(0), - state_(kUnInitialized), - pending_reads_(0), - pending_requests_(0), - renderer_thread_message_loop_(message_loop) { -} - -IpcVideoDecoder::~IpcVideoDecoder() { -} - -void IpcVideoDecoder::Initialize(DemuxerStream* demuxer_stream, - FilterCallback* callback) { - if (MessageLoop::current() != renderer_thread_message_loop_) { - renderer_thread_message_loop_->PostTask( - FROM_HERE, - NewRunnableMethod(this, - &IpcVideoDecoder::Initialize, - demuxer_stream, - callback)); - return; - } - - CHECK(!demuxer_stream_); - demuxer_stream_ = demuxer_stream; - initialize_callback_.reset(callback); - - // Get the AVStream by querying for the provider interface. - AVStreamProvider* av_stream_provider; - if (!demuxer_stream->QueryInterface(&av_stream_provider)) { - GpuVideoDecoderInitDoneParam param; - OnInitializeDone(false, param); - return; - } - - AVStream* av_stream = av_stream_provider->GetAVStream(); - width_ = av_stream->codec->width; - height_ = av_stream->codec->height; - - // Create hardware decoder instance. - GpuVideoServiceHost* gpu_video_service_host = GpuVideoServiceHost::get(); - gpu_video_decoder_host_ = gpu_video_service_host->CreateVideoDecoder(this); - - // Initialize hardware decoder. - GpuVideoDecoderInitParam param; - param.width_ = width_; - param.height_ = height_; - if (!gpu_video_decoder_host_->Initialize(param)) { - GpuVideoDecoderInitDoneParam param; - OnInitializeDone(false, param); - } -} - -void IpcVideoDecoder::OnInitializeDone( - bool success, const GpuVideoDecoderInitDoneParam& param) { - if (MessageLoop::current() != renderer_thread_message_loop_) { - renderer_thread_message_loop_->PostTask( - FROM_HERE, - NewRunnableMethod(this, - &IpcVideoDecoder::OnInitializeDone, - success, - param)); - return; - } - - AutoCallbackRunner done_runner(initialize_callback_.release()); - - if (success) { - media_format_.SetAsString(MediaFormat::kMimeType, - mime_type::kUncompressedVideo); - media_format_.SetAsInteger(MediaFormat::kWidth, width_); - media_format_.SetAsInteger(MediaFormat::kHeight, height_); - media_format_.SetAsInteger(MediaFormat::kSurfaceType, - static_cast<int>(param.surface_type_)); - media_format_.SetAsInteger(MediaFormat::kSurfaceFormat, - static_cast<int>(param.format_)); - state_ = kPlaying; - } else { - LOG(ERROR) << "IpcVideoDecoder initialization failed!"; - host()->SetError(PIPELINE_ERROR_DECODE); - } -} - -void IpcVideoDecoder::Stop(FilterCallback* callback) { - if (MessageLoop::current() != renderer_thread_message_loop_) { - renderer_thread_message_loop_->PostTask( - FROM_HERE, - NewRunnableMethod(this, - &IpcVideoDecoder::Stop, - callback)); - return; - } - - stop_callback_.reset(callback); - if (!gpu_video_decoder_host_->Uninitialize()) { - LOG(ERROR) << "gpu video decoder destroy failed"; - IpcVideoDecoder::OnUninitializeDone(); - } -} - -void IpcVideoDecoder::OnUninitializeDone() { - if (MessageLoop::current() != renderer_thread_message_loop_) { - renderer_thread_message_loop_->PostTask( - FROM_HERE, - NewRunnableMethod(this, - &IpcVideoDecoder::OnUninitializeDone)); - return; - } - - AutoCallbackRunner done_runner(stop_callback_.release()); - - state_ = kStopped; -} - -void IpcVideoDecoder::Pause(FilterCallback* callback) { - Flush(callback); // TODO(jiesun): move this to flush(). -} - -void IpcVideoDecoder::Flush(FilterCallback* callback) { - if (MessageLoop::current() != renderer_thread_message_loop_) { - renderer_thread_message_loop_->PostTask( - FROM_HERE, - NewRunnableMethod(this, - &IpcVideoDecoder::Flush, - callback)); - return; - } - - state_ = kFlushing; - - flush_callback_.reset(callback); - - if (!gpu_video_decoder_host_->Flush()) { - LOG(ERROR) << "gpu video decoder flush failed"; - OnFlushDone(); - } -} - -void IpcVideoDecoder::OnFlushDone() { - if (MessageLoop::current() != renderer_thread_message_loop_) { - renderer_thread_message_loop_->PostTask( - FROM_HERE, - NewRunnableMethod(this, - &IpcVideoDecoder::OnFlushDone)); - return; - } - - if (pending_reads_ == 0 && pending_requests_ == 0 && flush_callback_.get()) { - flush_callback_->Run(); - flush_callback_.reset(); - } -} - -void IpcVideoDecoder::Seek(base::TimeDelta time, FilterCallback* callback) { - if (MessageLoop::current() != renderer_thread_message_loop_) { - renderer_thread_message_loop_->PostTask( - FROM_HERE, - NewRunnableMethod(this, - &IpcVideoDecoder::Seek, - time, - callback)); - return; - } - - OnSeekComplete(callback); -} - -void IpcVideoDecoder::OnSeekComplete(FilterCallback* callback) { - if (MessageLoop::current() != renderer_thread_message_loop_) { - renderer_thread_message_loop_->PostTask( - FROM_HERE, - NewRunnableMethod(this, - &IpcVideoDecoder::OnSeekComplete, - callback)); - return; - } - - AutoCallbackRunner done_runner(callback); - - state_ = kPlaying; - - for (int i = 0; i < 20; ++i) { - demuxer_stream_->Read( - NewCallback(this, - &IpcVideoDecoder::OnReadComplete)); - ++pending_reads_; - } -} - -void IpcVideoDecoder::OnReadComplete(Buffer* buffer) { - scoped_refptr<Buffer> buffer_ref = buffer; - ReadCompleteTask(buffer_ref); -} - -void IpcVideoDecoder::ReadCompleteTask(scoped_refptr<Buffer> buffer) { - if (MessageLoop::current() != renderer_thread_message_loop_) { - renderer_thread_message_loop_->PostTask( - FROM_HERE, - NewRunnableMethod(this, - &IpcVideoDecoder::ReadCompleteTask, - buffer)); - return; - } - - DCHECK_GT(pending_reads_, 0u); - --pending_reads_; - - if (state_ == kStopped || state_ == kEnded) { - // Just discard the input buffers - return; - } - - if (state_ == kFlushing) { - if (pending_reads_ == 0 && pending_requests_ == 0) { - CHECK(flush_callback_.get()); - flush_callback_->Run(); - flush_callback_.reset(); - state_ = kPlaying; - } - return; - } - // Transition to kFlushCodec on the first end of input stream buffer. - if (state_ == kPlaying && buffer->IsEndOfStream()) { - state_ = kFlushCodec; - } - - gpu_video_decoder_host_->EmptyThisBuffer(buffer); -} - -void IpcVideoDecoder::FillThisBuffer(scoped_refptr<VideoFrame> video_frame) { - if (MessageLoop::current() != renderer_thread_message_loop_) { - renderer_thread_message_loop_->PostTask( - FROM_HERE, - NewRunnableMethod(this, - &IpcVideoDecoder::FillThisBuffer, - video_frame)); - return; - } - - // Synchronized flushing before stop should prevent this. - CHECK_NE(state_, kStopped); - - // Notify decode engine the available of new frame. - ++pending_requests_; - gpu_video_decoder_host_->FillThisBuffer(video_frame); -} - -void IpcVideoDecoder::OnFillBufferDone(scoped_refptr<VideoFrame> video_frame) { - if (MessageLoop::current() != renderer_thread_message_loop_) { - renderer_thread_message_loop_->PostTask( - FROM_HERE, - NewRunnableMethod(this, - &IpcVideoDecoder::OnFillBufferDone, - video_frame)); - return; - } - - if (video_frame.get()) { - --pending_requests_; - fill_buffer_done_callback()->Run(video_frame); - if (state_ == kFlushing && pending_reads_ == 0 && pending_requests_ == 0) { - CHECK(flush_callback_.get()); - flush_callback_->Run(); - flush_callback_.reset(); - state_ = kPlaying; - } - - } else { - if (state_ == kFlushCodec) { - // When in kFlushCodec, any errored decode, or a 0-lengthed frame, - // is taken as a signal to stop decoding. - state_ = kEnded; - scoped_refptr<VideoFrame> video_frame; - VideoFrame::CreateEmptyFrame(&video_frame); - fill_buffer_done_callback()->Run(video_frame); - } - } -} - -void IpcVideoDecoder::OnEmptyBufferDone(scoped_refptr<Buffer> buffer) { - if (MessageLoop::current() != renderer_thread_message_loop_) { - renderer_thread_message_loop_->PostTask( - FROM_HERE, - NewRunnableMethod(this, - &IpcVideoDecoder::OnEmptyBufferDone, - buffer)); - return; - } - - // TODO(jiesun): We haven't recycle input buffer yet. - demuxer_stream_->Read(NewCallback(this, &IpcVideoDecoder::OnReadComplete)); - ++pending_reads_; -} - -void IpcVideoDecoder::OnDeviceError() { - host()->SetError(PIPELINE_ERROR_DECODE); -} - -bool IpcVideoDecoder::ProvidesBuffer() { - return true; -} - -// static -FilterFactory* IpcVideoDecoder::CreateFactory(MessageLoop* message_loop) { - return new FilterFactoryImpl1<IpcVideoDecoder, MessageLoop*>(message_loop); -} - -// static -bool IpcVideoDecoder::IsMediaFormatSupported(const MediaFormat& format) { - std::string mime_type; - if (!format.GetAsString(MediaFormat::kMimeType, &mime_type) && - mime_type::kFFmpegVideo != mime_type) - return false; - - // TODO(jiesun): Although we current only support H264 hardware decoding, - // in the future, we should query GpuVideoService for capabilities. - int codec_id; - return format.GetAsInteger(MediaFormat::kFFmpegCodecID, &codec_id) && - codec_id == CODEC_ID_H264; -} - -} // namespace media - diff --git a/chrome/renderer/media/ipc_video_decoder.h b/chrome/renderer/media/ipc_video_decoder.h deleted file mode 100644 index 40a8098..0000000 --- a/chrome/renderer/media/ipc_video_decoder.h +++ /dev/null @@ -1,100 +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_IPC_VIDEO_DECODER_H_ -#define CHROME_RENDERER_MEDIA_IPC_VIDEO_DECODER_H_ - -#include "base/time.h" -#include "chrome/renderer/gpu_video_service_host.h" -#include "media/base/pts_heap.h" -#include "media/base/video_frame.h" -#include "media/filters/decoder_base.h" - -struct AVRational; - -namespace media { - -class VideoDecodeEngine; - -class IpcVideoDecoder : public VideoDecoder, - public GpuVideoDecoderHost::EventHandler { - public: - explicit IpcVideoDecoder(MessageLoop* message_loop); - virtual ~IpcVideoDecoder(); - - static FilterFactory* CreateFactory(MessageLoop* message_loop); - static bool IsMediaFormatSupported(const MediaFormat& media_format); - - // MediaFilter implementation. - virtual void Stop(FilterCallback* callback); - virtual void Seek(base::TimeDelta time, FilterCallback* callback); - virtual void Pause(FilterCallback* callback); - virtual void Flush(FilterCallback* callback); - - // Decoder implementation. - virtual void Initialize(DemuxerStream* demuxer_stream, - FilterCallback* callback); - virtual const MediaFormat& media_format() { return media_format_; } - virtual void FillThisBuffer(scoped_refptr<VideoFrame> video_frame); - - // GpuVideoDecoderHost::EventHandler. - virtual void OnInitializeDone(bool success, - const GpuVideoDecoderInitDoneParam& param); - virtual void OnUninitializeDone(); - virtual void OnFlushDone(); - virtual void OnEmptyBufferDone(scoped_refptr<Buffer> buffer); - virtual void OnFillBufferDone(scoped_refptr<VideoFrame> frame); - virtual void OnDeviceError(); - - virtual bool ProvidesBuffer(); - - private: - void OnSeekComplete(FilterCallback* callback); - void OnReadComplete(Buffer* buffer); - void ReadCompleteTask(scoped_refptr<Buffer> buffer); - - private: - friend class FilterFactoryImpl2<IpcVideoDecoder, - VideoDecodeEngine*, - MessageLoop*>; - - private: - int32 width_; - int32 height_; - MediaFormat media_format_; - - scoped_ptr<FilterCallback> flush_callback_; - scoped_ptr<FilterCallback> initialize_callback_; - scoped_ptr<FilterCallback> stop_callback_; - - enum DecoderState { - kUnInitialized, - kPlaying, - kFlushing, - kPausing, - kFlushCodec, - kEnded, - kStopped, - }; - DecoderState state_; - - // Tracks the number of asynchronous reads issued to |demuxer_stream_|. - // Using size_t since it is always compared against deque::size(). - size_t pending_reads_; - // Tracks the number of asynchronous reads issued from renderer. - size_t pending_requests_; - - // Pointer to the demuxer stream that will feed us compressed buffers. - scoped_refptr<DemuxerStream> demuxer_stream_; - - MessageLoop* renderer_thread_message_loop_; - scoped_refptr<GpuVideoDecoderHost> gpu_video_decoder_host_; - - DISALLOW_COPY_AND_ASSIGN(IpcVideoDecoder); -}; - -} // namespace media - -#endif // CHROME_RENDERER_MEDIA_IPC_VIDEO_DECODER_H_ - |