Index: chrome/renderer/media/ipc_video_decoder.cc |
=================================================================== |
--- chrome/renderer/media/ipc_video_decoder.cc (revision 78386) |
+++ chrome/renderer/media/ipc_video_decoder.cc (working copy) |
@@ -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)); |
-} |