Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(124)

Unified Diff: media/cast/video_sender/external_video_encoder.cc

Issue 388663003: Cast: Reshuffle files under media/cast (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: missing includes Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: media/cast/video_sender/external_video_encoder.cc
diff --git a/media/cast/video_sender/external_video_encoder.cc b/media/cast/video_sender/external_video_encoder.cc
deleted file mode 100644
index 96ee51956fb597fe76e9e99ff5f010465db76ada..0000000000000000000000000000000000000000
--- a/media/cast/video_sender/external_video_encoder.cc
+++ /dev/null
@@ -1,434 +0,0 @@
-// Copyright 2014 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 "media/cast/video_sender/external_video_encoder.h"
-
-#include "base/bind.h"
-#include "base/logging.h"
-#include "base/memory/scoped_vector.h"
-#include "base/memory/shared_memory.h"
-#include "base/message_loop/message_loop.h"
-#include "media/base/video_frame.h"
-#include "media/base/video_util.h"
-#include "media/cast/cast_defines.h"
-#include "media/cast/logging/logging_defines.h"
-#include "media/cast/transport/cast_transport_config.h"
-#include "media/video/video_encode_accelerator.h"
-
-namespace media {
-namespace cast {
-class LocalVideoEncodeAcceleratorClient;
-} // namespace cast
-} // namespace media
-
-namespace {
-static const size_t kOutputBufferCount = 3;
-
-void LogFrameEncodedEvent(
- const scoped_refptr<media::cast::CastEnvironment>& cast_environment,
- base::TimeTicks event_time,
- media::cast::RtpTimestamp rtp_timestamp,
- uint32 frame_id) {
- cast_environment->Logging()->InsertFrameEvent(
- event_time, media::cast::FRAME_ENCODED, media::cast::VIDEO_EVENT,
- rtp_timestamp, frame_id);
-}
-
-// Proxy this call to ExternalVideoEncoder on the cast main thread.
-void ProxyCreateVideoEncodeAccelerator(
- const scoped_refptr<media::cast::CastEnvironment>& cast_environment,
- const base::WeakPtr<media::cast::ExternalVideoEncoder>& weak_ptr,
- const media::cast::CreateVideoEncodeMemoryCallback&
- create_video_encode_mem_cb,
- scoped_refptr<base::SingleThreadTaskRunner> encoder_task_runner,
- scoped_ptr<media::VideoEncodeAccelerator> vea) {
- cast_environment->PostTask(
- media::cast::CastEnvironment::MAIN,
- FROM_HERE,
- base::Bind(
- &media::cast::ExternalVideoEncoder::OnCreateVideoEncodeAccelerator,
- weak_ptr,
- create_video_encode_mem_cb,
- encoder_task_runner,
- base::Passed(&vea)));
-}
-} // namespace
-
-namespace media {
-namespace cast {
-
-// Container for the associated data of a video frame being processed.
-struct EncodedFrameReturnData {
- EncodedFrameReturnData(base::TimeTicks c_time,
- VideoEncoder::FrameEncodedCallback callback) {
- capture_time = c_time;
- frame_encoded_callback = callback;
- }
- base::TimeTicks capture_time;
- VideoEncoder::FrameEncodedCallback frame_encoded_callback;
-};
-
-// The ExternalVideoEncoder class can be deleted directly by cast, while
-// LocalVideoEncodeAcceleratorClient stays around long enough to properly shut
-// down the VideoEncodeAccelerator.
-class LocalVideoEncodeAcceleratorClient
- : public VideoEncodeAccelerator::Client,
- public base::RefCountedThreadSafe<LocalVideoEncodeAcceleratorClient> {
- public:
- LocalVideoEncodeAcceleratorClient(
- scoped_refptr<CastEnvironment> cast_environment,
- scoped_refptr<base::SingleThreadTaskRunner> encoder_task_runner,
- scoped_ptr<media::VideoEncodeAccelerator> vea,
- const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb,
- const base::WeakPtr<ExternalVideoEncoder>& weak_owner)
- : cast_environment_(cast_environment),
- encoder_task_runner_(encoder_task_runner),
- video_encode_accelerator_(vea.Pass()),
- create_video_encode_memory_cb_(create_video_encode_mem_cb),
- weak_owner_(weak_owner),
- last_encoded_frame_id_(kStartFrameId),
- key_frame_encountered_(false) {
- DCHECK(encoder_task_runner_);
- }
-
- // Initialize the real HW encoder.
- void Initialize(const VideoSenderConfig& video_config) {
- DCHECK(encoder_task_runner_);
- DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread());
-
- VideoCodecProfile output_profile = media::VIDEO_CODEC_PROFILE_UNKNOWN;
- switch (video_config.codec) {
- case transport::CODEC_VIDEO_VP8:
- output_profile = media::VP8PROFILE_MAIN;
- break;
- case transport::CODEC_VIDEO_H264:
- output_profile = media::H264PROFILE_MAIN;
- break;
- case transport::CODEC_VIDEO_FAKE:
- NOTREACHED() << "Fake software video encoder cannot be external";
- break;
- default:
- NOTREACHED() << "Video codec not specified or not supported";
- break;
- }
- max_frame_rate_ = video_config.max_frame_rate;
-
- if (!video_encode_accelerator_->Initialize(
- media::VideoFrame::I420,
- gfx::Size(video_config.width, video_config.height),
- output_profile,
- video_config.start_bitrate,
- this)) {
- NotifyError(VideoEncodeAccelerator::kInvalidArgumentError);
- return;
- }
-
- // Wait until shared memory is allocated to indicate that encoder is
- // initialized.
- }
-
- // Free the HW.
- void Destroy() {
- DCHECK(encoder_task_runner_);
- DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread());
-
- video_encode_accelerator_.reset();
- }
-
- void SetBitRate(uint32 bit_rate) {
- DCHECK(encoder_task_runner_);
- DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread());
-
- video_encode_accelerator_->RequestEncodingParametersChange(bit_rate,
- max_frame_rate_);
- }
-
- void EncodeVideoFrame(
- const scoped_refptr<media::VideoFrame>& video_frame,
- const base::TimeTicks& capture_time,
- bool key_frame_requested,
- const VideoEncoder::FrameEncodedCallback& frame_encoded_callback) {
- DCHECK(encoder_task_runner_);
- DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread());
-
- encoded_frame_data_storage_.push_back(
- EncodedFrameReturnData(capture_time, frame_encoded_callback));
-
- // BitstreamBufferReady will be called once the encoder is done.
- video_encode_accelerator_->Encode(video_frame, key_frame_requested);
- }
-
- protected:
- virtual void NotifyError(VideoEncodeAccelerator::Error error) OVERRIDE {
- DCHECK(encoder_task_runner_);
- DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread());
- VLOG(1) << "ExternalVideoEncoder NotifyError: " << error;
-
- video_encode_accelerator_.reset();
- cast_environment_->PostTask(
- CastEnvironment::MAIN,
- FROM_HERE,
- base::Bind(&ExternalVideoEncoder::EncoderError, weak_owner_));
- }
-
- // Called to allocate the input and output buffers.
- virtual void RequireBitstreamBuffers(unsigned int input_count,
- const gfx::Size& input_coded_size,
- size_t output_buffer_size) OVERRIDE {
- DCHECK(encoder_task_runner_);
- DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread());
- DCHECK(video_encode_accelerator_);
-
- for (size_t j = 0; j < kOutputBufferCount; ++j) {
- create_video_encode_memory_cb_.Run(
- output_buffer_size,
- base::Bind(&LocalVideoEncodeAcceleratorClient::OnCreateSharedMemory,
- this));
- }
- }
-
- // Encoder has encoded a frame and it's available in one of out output
- // buffers.
- virtual void BitstreamBufferReady(int32 bitstream_buffer_id,
- size_t payload_size,
- bool key_frame) OVERRIDE {
- DCHECK(encoder_task_runner_);
- DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread());
- if (bitstream_buffer_id < 0 ||
- bitstream_buffer_id >= static_cast<int32>(output_buffers_.size())) {
- NOTREACHED();
- VLOG(1) << "BitstreamBufferReady(): invalid bitstream_buffer_id="
- << bitstream_buffer_id;
- NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
- return;
- }
- base::SharedMemory* output_buffer = output_buffers_[bitstream_buffer_id];
- if (payload_size > output_buffer->mapped_size()) {
- NOTREACHED();
- VLOG(1) << "BitstreamBufferReady(): invalid payload_size = "
- << payload_size;
- NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
- return;
- }
- if (key_frame)
- key_frame_encountered_ = true;
- if (!key_frame_encountered_) {
- // Do not send video until we have encountered the first key frame.
- // Save the bitstream buffer in |stream_header_| to be sent later along
- // with the first key frame.
- stream_header_.append(static_cast<const char*>(output_buffer->memory()),
- payload_size);
- } else if (!encoded_frame_data_storage_.empty()) {
- scoped_ptr<transport::EncodedFrame> encoded_frame(
- new transport::EncodedFrame());
- encoded_frame->dependency = key_frame ? transport::EncodedFrame::KEY :
- transport::EncodedFrame::DEPENDENT;
- encoded_frame->frame_id = ++last_encoded_frame_id_;
- if (key_frame)
- encoded_frame->referenced_frame_id = encoded_frame->frame_id;
- else
- encoded_frame->referenced_frame_id = encoded_frame->frame_id - 1;
- encoded_frame->reference_time =
- encoded_frame_data_storage_.front().capture_time;
- encoded_frame->rtp_timestamp =
- GetVideoRtpTimestamp(encoded_frame->reference_time);
- if (!stream_header_.empty()) {
- encoded_frame->data = stream_header_;
- stream_header_.clear();
- }
- encoded_frame->data.append(
- static_cast<const char*>(output_buffer->memory()), payload_size);
-
- cast_environment_->PostTask(
- CastEnvironment::MAIN,
- FROM_HERE,
- base::Bind(&LogFrameEncodedEvent,
- cast_environment_,
- cast_environment_->Clock()->NowTicks(),
- encoded_frame->rtp_timestamp,
- encoded_frame->frame_id));
-
- cast_environment_->PostTask(
- CastEnvironment::MAIN,
- FROM_HERE,
- base::Bind(encoded_frame_data_storage_.front().frame_encoded_callback,
- base::Passed(&encoded_frame)));
-
- encoded_frame_data_storage_.pop_front();
- } else {
- VLOG(1) << "BitstreamBufferReady(): no encoded frame data available";
- }
-
- // We need to re-add the output buffer to the encoder after we are done
- // with it.
- video_encode_accelerator_->UseOutputBitstreamBuffer(media::BitstreamBuffer(
- bitstream_buffer_id,
- output_buffers_[bitstream_buffer_id]->handle(),
- output_buffers_[bitstream_buffer_id]->mapped_size()));
- }
-
- private:
- // Note: This method can be called on any thread.
- void OnCreateSharedMemory(scoped_ptr<base::SharedMemory> memory) {
- encoder_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&LocalVideoEncodeAcceleratorClient::ReceivedSharedMemory,
- this,
- base::Passed(&memory)));
- }
-
- void ReceivedSharedMemory(scoped_ptr<base::SharedMemory> memory) {
- DCHECK(encoder_task_runner_);
- DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread());
-
- output_buffers_.push_back(memory.release());
-
- // Wait until all requested buffers are received.
- if (output_buffers_.size() < kOutputBufferCount)
- return;
-
- // Immediately provide all output buffers to the VEA.
- for (size_t i = 0; i < output_buffers_.size(); ++i) {
- video_encode_accelerator_->UseOutputBitstreamBuffer(
- media::BitstreamBuffer(static_cast<int32>(i),
- output_buffers_[i]->handle(),
- output_buffers_[i]->mapped_size()));
- }
-
- cast_environment_->PostTask(
- CastEnvironment::MAIN,
- FROM_HERE,
- base::Bind(&ExternalVideoEncoder::EncoderInitialized, weak_owner_));
- }
-
- friend class base::RefCountedThreadSafe<LocalVideoEncodeAcceleratorClient>;
-
- virtual ~LocalVideoEncodeAcceleratorClient() {}
-
- const scoped_refptr<CastEnvironment> cast_environment_;
- scoped_refptr<base::SingleThreadTaskRunner> encoder_task_runner_;
- scoped_ptr<media::VideoEncodeAccelerator> video_encode_accelerator_;
- const CreateVideoEncodeMemoryCallback create_video_encode_memory_cb_;
- const base::WeakPtr<ExternalVideoEncoder> weak_owner_;
- int max_frame_rate_;
- uint32 last_encoded_frame_id_;
- bool key_frame_encountered_;
- std::string stream_header_;
-
- // Shared memory buffers for output with the VideoAccelerator.
- ScopedVector<base::SharedMemory> output_buffers_;
-
- // FIFO list.
- std::list<EncodedFrameReturnData> encoded_frame_data_storage_;
-
- DISALLOW_COPY_AND_ASSIGN(LocalVideoEncodeAcceleratorClient);
-};
-
-ExternalVideoEncoder::ExternalVideoEncoder(
- scoped_refptr<CastEnvironment> cast_environment,
- const VideoSenderConfig& video_config,
- const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
- const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb)
- : video_config_(video_config),
- cast_environment_(cast_environment),
- encoder_active_(false),
- key_frame_requested_(false),
- weak_factory_(this) {
- DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
-
- create_vea_cb.Run(base::Bind(&ProxyCreateVideoEncodeAccelerator,
- cast_environment,
- weak_factory_.GetWeakPtr(),
- create_video_encode_mem_cb));
-}
-
-ExternalVideoEncoder::~ExternalVideoEncoder() {
- encoder_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&LocalVideoEncodeAcceleratorClient::Destroy,
- video_accelerator_client_));
-}
-
-void ExternalVideoEncoder::EncoderInitialized() {
- DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
- encoder_active_ = true;
-}
-
-void ExternalVideoEncoder::EncoderError() {
- DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
- encoder_active_ = false;
-}
-
-void ExternalVideoEncoder::OnCreateVideoEncodeAccelerator(
- const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb,
- scoped_refptr<base::SingleThreadTaskRunner> encoder_task_runner,
- scoped_ptr<media::VideoEncodeAccelerator> vea) {
- DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
- encoder_task_runner_ = encoder_task_runner;
-
- video_accelerator_client_ =
- new LocalVideoEncodeAcceleratorClient(cast_environment_,
- encoder_task_runner,
- vea.Pass(),
- create_video_encode_mem_cb,
- weak_factory_.GetWeakPtr());
- encoder_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&LocalVideoEncodeAcceleratorClient::Initialize,
- video_accelerator_client_,
- video_config_));
-}
-
-bool ExternalVideoEncoder::EncodeVideoFrame(
- const scoped_refptr<media::VideoFrame>& video_frame,
- const base::TimeTicks& capture_time,
- const FrameEncodedCallback& frame_encoded_callback) {
- DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
-
- if (!encoder_active_)
- return false;
-
- encoder_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&LocalVideoEncodeAcceleratorClient::EncodeVideoFrame,
- video_accelerator_client_,
- video_frame,
- capture_time,
- key_frame_requested_,
- frame_encoded_callback));
-
- key_frame_requested_ = false;
- return true;
-}
-
-// Inform the encoder about the new target bit rate.
-void ExternalVideoEncoder::SetBitRate(int new_bit_rate) {
- if (!encoder_active_) {
- // If we receive SetBitRate() before VEA creation callback is invoked,
- // cache the new bit rate in the encoder config and use the new settings
- // to initialize VEA.
- video_config_.start_bitrate = new_bit_rate;
- return;
- }
-
- encoder_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&LocalVideoEncodeAcceleratorClient::SetBitRate,
- video_accelerator_client_,
- new_bit_rate));
-}
-
-// Inform the encoder to encode the next frame as a key frame.
-void ExternalVideoEncoder::GenerateKeyFrame() {
- DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
- key_frame_requested_ = true;
-}
-
-// Inform the encoder to only reference frames older or equal to frame_id;
-void ExternalVideoEncoder::LatestFrameIdToReference(uint32 /*frame_id*/) {
- // Do nothing not supported.
-}
-
-} // namespace cast
-} // namespace media
« no previous file with comments | « media/cast/video_sender/external_video_encoder.h ('k') | media/cast/video_sender/external_video_encoder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698