Libav 0.7.1
|
00001 /* 00002 * Copyright (c) 2010, Google, Inc. 00003 * 00004 * This file is part of Libav. 00005 * 00006 * Libav is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * Libav is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with Libav; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 00026 #define VPX_CODEC_DISABLE_COMPAT 1 00027 #include <vpx/vpx_decoder.h> 00028 #include <vpx/vp8dx.h> 00029 00030 #include "libavutil/imgutils.h" 00031 #include "avcodec.h" 00032 00033 typedef struct VP8DecoderContext { 00034 struct vpx_codec_ctx decoder; 00035 } VP8Context; 00036 00037 static av_cold int vp8_init(AVCodecContext *avctx) 00038 { 00039 VP8Context *ctx = avctx->priv_data; 00040 const struct vpx_codec_iface *iface = &vpx_codec_vp8_dx_algo; 00041 struct vpx_codec_dec_cfg deccfg = { 00042 /* token partitions+1 would be a decent choice */ 00043 .threads = FFMIN(avctx->thread_count, 16) 00044 }; 00045 00046 av_log(avctx, AV_LOG_INFO, "%s\n", vpx_codec_version_str()); 00047 av_log(avctx, AV_LOG_VERBOSE, "%s\n", vpx_codec_build_config()); 00048 00049 if (vpx_codec_dec_init(&ctx->decoder, iface, &deccfg, 0) != VPX_CODEC_OK) { 00050 const char *error = vpx_codec_error(&ctx->decoder); 00051 av_log(avctx, AV_LOG_ERROR, "Failed to initialize decoder: %s\n", 00052 error); 00053 return AVERROR(EINVAL); 00054 } 00055 00056 avctx->pix_fmt = PIX_FMT_YUV420P; 00057 return 0; 00058 } 00059 00060 static int vp8_decode(AVCodecContext *avctx, 00061 void *data, int *data_size, AVPacket *avpkt) 00062 { 00063 VP8Context *ctx = avctx->priv_data; 00064 AVFrame *picture = data; 00065 const void *iter = NULL; 00066 struct vpx_image *img; 00067 00068 if (vpx_codec_decode(&ctx->decoder, avpkt->data, avpkt->size, NULL, 0) != 00069 VPX_CODEC_OK) { 00070 const char *error = vpx_codec_error(&ctx->decoder); 00071 const char *detail = vpx_codec_error_detail(&ctx->decoder); 00072 00073 av_log(avctx, AV_LOG_ERROR, "Failed to decode frame: %s\n", error); 00074 if (detail) 00075 av_log(avctx, AV_LOG_ERROR, " Additional information: %s\n", 00076 detail); 00077 return AVERROR_INVALIDDATA; 00078 } 00079 00080 if ((img = vpx_codec_get_frame(&ctx->decoder, &iter))) { 00081 if (img->fmt != VPX_IMG_FMT_I420) { 00082 av_log(avctx, AV_LOG_ERROR, "Unsupported output colorspace (%d)\n", 00083 img->fmt); 00084 return AVERROR_INVALIDDATA; 00085 } 00086 00087 if ((int) img->d_w != avctx->width || (int) img->d_h != avctx->height) { 00088 av_log(avctx, AV_LOG_INFO, "dimension change! %dx%d -> %dx%d\n", 00089 avctx->width, avctx->height, img->d_w, img->d_h); 00090 if (av_image_check_size(img->d_w, img->d_h, 0, avctx)) 00091 return AVERROR_INVALIDDATA; 00092 avcodec_set_dimensions(avctx, img->d_w, img->d_h); 00093 } 00094 picture->data[0] = img->planes[0]; 00095 picture->data[1] = img->planes[1]; 00096 picture->data[2] = img->planes[2]; 00097 picture->data[3] = NULL; 00098 picture->linesize[0] = img->stride[0]; 00099 picture->linesize[1] = img->stride[1]; 00100 picture->linesize[2] = img->stride[2]; 00101 picture->linesize[3] = 0; 00102 *data_size = sizeof(AVPicture); 00103 } 00104 return avpkt->size; 00105 } 00106 00107 static av_cold int vp8_free(AVCodecContext *avctx) 00108 { 00109 VP8Context *ctx = avctx->priv_data; 00110 vpx_codec_destroy(&ctx->decoder); 00111 return 0; 00112 } 00113 00114 AVCodec ff_libvpx_decoder = { 00115 "libvpx", 00116 AVMEDIA_TYPE_VIDEO, 00117 CODEC_ID_VP8, 00118 sizeof(VP8Context), 00119 vp8_init, 00120 NULL, /* encode */ 00121 vp8_free, 00122 vp8_decode, 00123 0, /* capabilities */ 00124 .long_name = NULL_IF_CONFIG_SMALL("libvpx VP8"), 00125 };