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

Unified Diff: webkit/media/crypto/decoders/ffmpeg_video_decoder.cc

Issue 10899021: Add CDM video decoder. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 4 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: webkit/media/crypto/decoders/ffmpeg_video_decoder.cc
diff --git a/webkit/media/crypto/decoders/ffmpeg_video_decoder.cc b/webkit/media/crypto/decoders/ffmpeg_video_decoder.cc
new file mode 100644
index 0000000000000000000000000000000000000000..d16976b61b8ce97807b45bb40ee3bdc8e261455a
--- /dev/null
+++ b/webkit/media/crypto/decoders/ffmpeg_video_decoder.cc
@@ -0,0 +1,127 @@
+// Copyright (c) 2012 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/logging.h"
+#include "base/memory/ref_counted.h"
+#include "media/base/limits.h"
+#include "media/ffmpeg/ffmpeg_common.h"
+#include "webkit/media/crypto/decoders/ffmpeg_util.h"
+#include "webkit/media/crypto/decoders/ffmpeg_video_decoder.h"
+#include "webkit/media/crypto/ppapi/content_decryption_module.h"
+
+namespace webkit_media {
+
+using cdm::VideoDecoderConfig;
+using cdm::VideoFrame;
+
+static int GetVideoBufferImpl(AVCodecContext* s, AVFrame* frame) {
+ FFmpegVideoDecoder* vd = static_cast<FFmpegVideoDecoder*>(s->opaque);
+ return vd->GetVideoBuffer(s, frame);
+}
+
+static void ReleaseVideoBufferImpl(AVCodecContext* s, AVFrame* frame) {
+ scoped_refptr<VideoFrame> video_frame;
+ video_frame.swap(reinterpret_cast<VideoFrame**>(&frame->opaque));
+
+ // The FFmpeg API expects us to zero the data pointers in
+ // this callback
+ memset(frame->data, 0, sizeof(frame->data));
+ frame->opaque = NULL;
+}
+
+FFmpegVideoDecoder::FFmpegVideoDecoder()
+ : codec_context_(NULL),
+ av_frame_(NULL) {
+}
+
+FFmpegVideoDecoder::~FFmpegVideoDecoder() {
+}
+
+bool FFmpegVideoDecoder::Initialize(const VideoDecoderConfig& config) {
+ return false;
+}
+
+bool FFmpegVideoDecoder::DecodeFrame(const VideoFrame& compressed_frame,
+ VideoFrame* decompressed_frame) {
+ return false;
+}
+
+int FFmpegVideoDecoder::GetVideoBuffer(AVCodecContext* codec_context,
+ AVFrame* frame) {
+ // Don't use |codec_context_| here! With threaded decoding,
+ // it will contain unsynchronized width/height/pix_fmt values,
+ // whereas |codec_context| contains the current threads's
+ // updated width/height/pix_fmt, which can change for adaptive
+ // content.
+ VideoFrame::Format format = PixelFormatToVideoFormat(codec_context->pix_fmt);
+ if (format == VideoFrame::INVALID)
+ return AVERROR(EINVAL);
+ DCHECK(format == VideoFrame::YV12 || format == VideoFrame::YV16);
+
+ gfx::Size size(codec_context->width, codec_context->height);
+ int ret;
+ if ((ret = av_image_check_size(size.width(), size.height(), 0, NULL)) < 0)
+ return ret;
+
+ gfx::Size natural_size;
+ if (codec_context->sample_aspect_ratio.num > 0) {
+ natural_size = GetNaturalSize(size,
+ codec_context->sample_aspect_ratio.num,
+ codec_context->sample_aspect_ratio.den);
+ } else {
+ natural_size = demuxer_stream_->video_decoder_config().natural_size();
+ }
+
+ if (!VideoFrame::IsValidConfig(format, size, natural_size))
+ return AVERROR(EINVAL);
+
+ scoped_refptr<VideoFrame> video_frame =
+ VideoFrame::CreateFrame(format, size, natural_size, kNoTimestamp());
+
+ for (int i = 0; i < 3; i++) {
+ frame->base[i] = video_frame->data(i);
+ frame->data[i] = video_frame->data(i);
+ frame->linesize[i] = video_frame->stride(i);
+ }
+
+ frame->opaque = NULL;
+ video_frame.swap(reinterpret_cast<VideoFrame**>(&frame->opaque));
+ frame->type = FF_BUFFER_TYPE_USER;
+ frame->pkt_pts = codec_context->pkt ? codec_context->pkt->pts :
+ AV_NOPTS_VALUE;
+ frame->width = codec_context->width;
+ frame->height = codec_context->height;
+ frame->format = codec_context->pix_fmt;
+
+ return 0;
+}
+
+// static
+bool VideoFrame::IsValidConfig(VideoFrame::Format format,
+ const Size& data_size) {
+ return (format != VideoFrame::INVALID &&
+ data_size.width() > 0 && data_size.height() > 0 &&
+ data_size.width() <= limits::kMaxDimension &&
+ data_size.height() <= limits::kMaxDimension &&
+ data_size.width() * data_size.height() <= limits::kMaxCanvas &&
+ natural_size.width() > 0 && natural_size.height() > 0 &&
+ natural_size.width() <= limits::kMaxDimension &&
+ natural_size.height() <= limits::kMaxDimension &&
+ natural_size.width() * natural_size.height() <= limits::kMaxCanvas);
+}
+
+void FFmpegVideoDecoder::ReleaseFFmpegResources() {
+ if (codec_context_) {
+ av_free(codec_context_->extradata);
+ avcodec_close(codec_context_);
+ av_free(codec_context_);
+ codec_context_ = NULL;
+ }
+ if (av_frame_) {
+ av_free(av_frame_);
+ av_frame_ = NULL;
+ }
+}
+
+} // namespace webkit_media

Powered by Google App Engine
This is Rietveld 408576698