annotate ffmpeg/libavcodec/libvpxdec.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * Copyright (c) 2010, Google, Inc.
yading@10 3 *
yading@10 4 * This file is part of FFmpeg.
yading@10 5 *
yading@10 6 * FFmpeg is free software; you can redistribute it and/or
yading@10 7 * modify it under the terms of the GNU Lesser General Public
yading@10 8 * License as published by the Free Software Foundation; either
yading@10 9 * version 2.1 of the License, or (at your option) any later version.
yading@10 10 *
yading@10 11 * FFmpeg is distributed in the hope that it will be useful,
yading@10 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 14 * Lesser General Public License for more details.
yading@10 15 *
yading@10 16 * You should have received a copy of the GNU Lesser General Public
yading@10 17 * License along with FFmpeg; if not, write to the Free Software
yading@10 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 19 */
yading@10 20
yading@10 21 /**
yading@10 22 * @file
yading@10 23 * VP8 decoder support via libvpx
yading@10 24 */
yading@10 25
yading@10 26 #define VPX_CODEC_DISABLE_COMPAT 1
yading@10 27 #include <vpx/vpx_decoder.h>
yading@10 28 #include <vpx/vp8dx.h>
yading@10 29
yading@10 30 #include "libavutil/common.h"
yading@10 31 #include "libavutil/imgutils.h"
yading@10 32 #include "avcodec.h"
yading@10 33 #include "internal.h"
yading@10 34
yading@10 35 typedef struct VP8DecoderContext {
yading@10 36 struct vpx_codec_ctx decoder;
yading@10 37 } VP8Context;
yading@10 38
yading@10 39 static av_cold int vpx_init(AVCodecContext *avctx,
yading@10 40 const struct vpx_codec_iface *iface)
yading@10 41 {
yading@10 42 VP8Context *ctx = avctx->priv_data;
yading@10 43 struct vpx_codec_dec_cfg deccfg = {
yading@10 44 /* token partitions+1 would be a decent choice */
yading@10 45 .threads = FFMIN(avctx->thread_count, 16)
yading@10 46 };
yading@10 47
yading@10 48 av_log(avctx, AV_LOG_INFO, "%s\n", vpx_codec_version_str());
yading@10 49 av_log(avctx, AV_LOG_VERBOSE, "%s\n", vpx_codec_build_config());
yading@10 50
yading@10 51 if (vpx_codec_dec_init(&ctx->decoder, iface, &deccfg, 0) != VPX_CODEC_OK) {
yading@10 52 const char *error = vpx_codec_error(&ctx->decoder);
yading@10 53 av_log(avctx, AV_LOG_ERROR, "Failed to initialize decoder: %s\n",
yading@10 54 error);
yading@10 55 return AVERROR(EINVAL);
yading@10 56 }
yading@10 57
yading@10 58 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
yading@10 59 return 0;
yading@10 60 }
yading@10 61
yading@10 62 static int vp8_decode(AVCodecContext *avctx,
yading@10 63 void *data, int *got_frame, AVPacket *avpkt)
yading@10 64 {
yading@10 65 VP8Context *ctx = avctx->priv_data;
yading@10 66 AVFrame *picture = data;
yading@10 67 const void *iter = NULL;
yading@10 68 struct vpx_image *img;
yading@10 69 int ret;
yading@10 70
yading@10 71 if (vpx_codec_decode(&ctx->decoder, avpkt->data, avpkt->size, NULL, 0) !=
yading@10 72 VPX_CODEC_OK) {
yading@10 73 const char *error = vpx_codec_error(&ctx->decoder);
yading@10 74 const char *detail = vpx_codec_error_detail(&ctx->decoder);
yading@10 75
yading@10 76 av_log(avctx, AV_LOG_ERROR, "Failed to decode frame: %s\n", error);
yading@10 77 if (detail)
yading@10 78 av_log(avctx, AV_LOG_ERROR, " Additional information: %s\n",
yading@10 79 detail);
yading@10 80 return AVERROR_INVALIDDATA;
yading@10 81 }
yading@10 82
yading@10 83 if ((img = vpx_codec_get_frame(&ctx->decoder, &iter))) {
yading@10 84 if (img->fmt != VPX_IMG_FMT_I420) {
yading@10 85 av_log(avctx, AV_LOG_ERROR, "Unsupported output colorspace (%d)\n",
yading@10 86 img->fmt);
yading@10 87 return AVERROR_INVALIDDATA;
yading@10 88 }
yading@10 89
yading@10 90 if ((int) img->d_w != avctx->width || (int) img->d_h != avctx->height) {
yading@10 91 av_log(avctx, AV_LOG_INFO, "dimension change! %dx%d -> %dx%d\n",
yading@10 92 avctx->width, avctx->height, img->d_w, img->d_h);
yading@10 93 if (av_image_check_size(img->d_w, img->d_h, 0, avctx))
yading@10 94 return AVERROR_INVALIDDATA;
yading@10 95 avcodec_set_dimensions(avctx, img->d_w, img->d_h);
yading@10 96 }
yading@10 97 if ((ret = ff_get_buffer(avctx, picture, 0)) < 0)
yading@10 98 return ret;
yading@10 99 av_image_copy(picture->data, picture->linesize, img->planes,
yading@10 100 img->stride, avctx->pix_fmt, img->d_w, img->d_h);
yading@10 101 *got_frame = 1;
yading@10 102 }
yading@10 103 return avpkt->size;
yading@10 104 }
yading@10 105
yading@10 106 static av_cold int vp8_free(AVCodecContext *avctx)
yading@10 107 {
yading@10 108 VP8Context *ctx = avctx->priv_data;
yading@10 109 vpx_codec_destroy(&ctx->decoder);
yading@10 110 return 0;
yading@10 111 }
yading@10 112
yading@10 113 #if CONFIG_LIBVPX_VP8_DECODER
yading@10 114 static av_cold int vp8_init(AVCodecContext *avctx)
yading@10 115 {
yading@10 116 return vpx_init(avctx, &vpx_codec_vp8_dx_algo);
yading@10 117 }
yading@10 118
yading@10 119 AVCodec ff_libvpx_vp8_decoder = {
yading@10 120 .name = "libvpx",
yading@10 121 .type = AVMEDIA_TYPE_VIDEO,
yading@10 122 .id = AV_CODEC_ID_VP8,
yading@10 123 .priv_data_size = sizeof(VP8Context),
yading@10 124 .init = vp8_init,
yading@10 125 .close = vp8_free,
yading@10 126 .decode = vp8_decode,
yading@10 127 .capabilities = CODEC_CAP_AUTO_THREADS | CODEC_CAP_DR1,
yading@10 128 .long_name = NULL_IF_CONFIG_SMALL("libvpx VP8"),
yading@10 129 };
yading@10 130 #endif /* CONFIG_LIBVPX_VP8_DECODER */
yading@10 131
yading@10 132 #if CONFIG_LIBVPX_VP9_DECODER
yading@10 133 static av_cold int vp9_init(AVCodecContext *avctx)
yading@10 134 {
yading@10 135 return vpx_init(avctx, &vpx_codec_vp9_dx_algo);
yading@10 136 }
yading@10 137
yading@10 138 AVCodec ff_libvpx_vp9_decoder = {
yading@10 139 .name = "libvpx-vp9",
yading@10 140 .type = AVMEDIA_TYPE_VIDEO,
yading@10 141 .id = AV_CODEC_ID_VP9,
yading@10 142 .priv_data_size = sizeof(VP8Context),
yading@10 143 .init = vp9_init,
yading@10 144 .close = vp8_free,
yading@10 145 .decode = vp8_decode,
yading@10 146 .capabilities = CODEC_CAP_AUTO_THREADS | CODEC_CAP_EXPERIMENTAL,
yading@10 147 .long_name = NULL_IF_CONFIG_SMALL("libvpx VP9"),
yading@10 148 };
yading@10 149 #endif /* CONFIG_LIBVPX_VP9_DECODER */