VP8 decoding via libvpx

Patch by James Zern for Google, Inc., jzern google com

backportd r23191,23303,23307-23308 by conrad, cehoyos and mstorsjo

Originally committed as revision 23374 to svn://svn.ffmpeg.org/ffmpeg/branches/0.6
This commit is contained in:
James Zern 2010-05-29 14:03:03 +00:00 committed by Reinhard Tartler
parent df62b0d9f5
commit 8261cce1f0
7 changed files with 137 additions and 3 deletions

View File

@ -1,7 +1,6 @@
Entries are sorted chronologically from oldest to youngest within each release, Entries are sorted chronologically from oldest to youngest within each release,
releases are sorted from youngest to oldest. releases are sorted from youngest to oldest.
version 0.6: version 0.6:
- PB-frame decoding for H.263 - PB-frame decoding for H.263
@ -79,6 +78,7 @@ version 0.6:
- faster H.264 decoding - faster H.264 decoding
- low overhead Ogg muxing - low overhead Ogg muxing
- WebM support in Matroska demuxer - WebM support in Matroska demuxer
- VP8 decoding via libvpx

5
configure vendored
View File

@ -183,6 +183,7 @@ External library support:
--enable-libtheora enable Theora encoding via libtheora [no] --enable-libtheora enable Theora encoding via libtheora [no]
--enable-libvorbis enable Vorbis encoding via libvorbis, --enable-libvorbis enable Vorbis encoding via libvorbis,
native implementation exists [no] native implementation exists [no]
--enable-libvpx enable VP8 support via libvpx [no]
--enable-libx264 enable H.264 encoding via x264 [no] --enable-libx264 enable H.264 encoding via x264 [no]
--enable-libxvid enable Xvid encoding via xvidcore, --enable-libxvid enable Xvid encoding via xvidcore,
native MPEG-4/Xvid encoder exists [no] native MPEG-4/Xvid encoder exists [no]
@ -927,6 +928,7 @@ CONFIG_LIST="
libspeex libspeex
libtheora libtheora
libvorbis libvorbis
libvpx
libx264 libx264
libxvid libxvid
lpc lpc
@ -1349,6 +1351,7 @@ libschroedinger_encoder_deps="libschroedinger"
libspeex_decoder_deps="libspeex" libspeex_decoder_deps="libspeex"
libtheora_encoder_deps="libtheora" libtheora_encoder_deps="libtheora"
libvorbis_encoder_deps="libvorbis" libvorbis_encoder_deps="libvorbis"
libvpx_decoder_deps="libvpx"
libx264_encoder_deps="libx264" libx264_encoder_deps="libx264"
libxvid_encoder_deps="libxvid" libxvid_encoder_deps="libxvid"
@ -2612,6 +2615,7 @@ enabled libschroedinger && add_cflags $(pkg-config --cflags schroedinger-1.0) &&
enabled libspeex && require libspeex speex/speex.h speex_decoder_init -lspeex enabled libspeex && require libspeex speex/speex.h speex_decoder_init -lspeex
enabled libtheora && require libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg enabled libtheora && require libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg
enabled libvorbis && require libvorbis vorbis/vorbisenc.h vorbis_info_init -lvorbisenc -lvorbis -logg enabled libvorbis && require libvorbis vorbis/vorbisenc.h vorbis_info_init -lvorbisenc -lvorbis -logg
enabled libvpx && require2 libvpx "vpx/vpx_decoder.h vpx/vp8dx.h" "vpx_codec_dec_init_ver" -lvpx
enabled libx264 && require libx264 x264.h x264_encoder_encode -lx264 -lm && enabled libx264 && require libx264 x264.h x264_encoder_encode -lx264 -lm &&
{ check_cpp_condition x264.h "X264_BUILD >= 83" || { check_cpp_condition x264.h "X264_BUILD >= 83" ||
die "ERROR: libx264 version must be >= 0.83."; } die "ERROR: libx264 version must be >= 0.83."; }
@ -2881,6 +2885,7 @@ echo "libschroedinger enabled ${libschroedinger-no}"
echo "libspeex enabled ${libspeex-no}" echo "libspeex enabled ${libspeex-no}"
echo "libtheora enabled ${libtheora-no}" echo "libtheora enabled ${libtheora-no}"
echo "libvorbis enabled ${libvorbis-no}" echo "libvorbis enabled ${libvorbis-no}"
echo "libvpx enabled ${libvpx-no}"
echo "libx264 enabled ${libx264-no}" echo "libx264 enabled ${libx264-no}"
echo "libxvid enabled ${libxvid-no}" echo "libxvid enabled ${libxvid-no}"
echo "zlib enabled ${zlib-no}" echo "zlib enabled ${zlib-no}"

View File

@ -437,6 +437,8 @@ following image formats are supported:
@tab fourcc: VP50 @tab fourcc: VP50
@item On2 VP6 @tab @tab X @item On2 VP6 @tab @tab X
@tab fourcc: VP60,VP61,VP62 @tab fourcc: VP60,VP61,VP62
at item VP8 @tab @tab X
@tab fourcc: VP80, decoding supported through external library libvpx
@item planar RGB @tab @tab X @item planar RGB @tab @tab X
@tab fourcc: 8BPS @tab fourcc: 8BPS
@item Q-team QPEG @tab @tab X @item Q-team QPEG @tab @tab X

View File

@ -525,6 +525,7 @@ OBJS-$(CONFIG_LIBSCHROEDINGER_ENCODER) += libschroedingerenc.o \
OBJS-$(CONFIG_LIBSPEEX_DECODER) += libspeexdec.o OBJS-$(CONFIG_LIBSPEEX_DECODER) += libspeexdec.o
OBJS-$(CONFIG_LIBTHEORA_ENCODER) += libtheoraenc.o OBJS-$(CONFIG_LIBTHEORA_ENCODER) += libtheoraenc.o
OBJS-$(CONFIG_LIBVORBIS_ENCODER) += libvorbis.o OBJS-$(CONFIG_LIBVORBIS_ENCODER) += libvorbis.o
OBJS-$(CONFIG_LIBVPX_DECODER) += libvpxdec.o
OBJS-$(CONFIG_LIBX264_ENCODER) += libx264.o OBJS-$(CONFIG_LIBX264_ENCODER) += libx264.o
OBJS-$(CONFIG_LIBXVID_ENCODER) += libxvidff.o libxvid_rc.o OBJS-$(CONFIG_LIBXVID_ENCODER) += libxvidff.o libxvid_rc.o

View File

@ -344,6 +344,7 @@ void avcodec_register_all(void)
REGISTER_DECODER (LIBSPEEX, libspeex); REGISTER_DECODER (LIBSPEEX, libspeex);
REGISTER_ENCODER (LIBTHEORA, libtheora); REGISTER_ENCODER (LIBTHEORA, libtheora);
REGISTER_ENCODER (LIBVORBIS, libvorbis); REGISTER_ENCODER (LIBVORBIS, libvorbis);
REGISTER_DECODER (LIBVPX, libvpx);
REGISTER_ENCODER (LIBX264, libx264); REGISTER_ENCODER (LIBX264, libx264);
REGISTER_ENCODER (LIBXVID, libxvid); REGISTER_ENCODER (LIBXVID, libxvid);

View File

@ -30,8 +30,8 @@
#include "libavutil/avutil.h" #include "libavutil/avutil.h"
#define LIBAVCODEC_VERSION_MAJOR 52 #define LIBAVCODEC_VERSION_MAJOR 52
#define LIBAVCODEC_VERSION_MINOR 66 #define LIBAVCODEC_VERSION_MINOR 69
#define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_MICRO 1
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \ LIBAVCODEC_VERSION_MINOR, \
@ -210,6 +210,7 @@ enum CodecID {
CODEC_ID_IFF_BYTERUN1, CODEC_ID_IFF_BYTERUN1,
CODEC_ID_KGV1, CODEC_ID_KGV1,
CODEC_ID_YOP, CODEC_ID_YOP,
CODEC_ID_VP8,
/* various PCM "codecs" */ /* various PCM "codecs" */
CODEC_ID_PCM_S16LE= 0x10000, CODEC_ID_PCM_S16LE= 0x10000,

124
libavcodec/libvpxdec.c Normal file
View File

@ -0,0 +1,124 @@
/*
* Copyright (c) 2010, Google, Inc.
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* VP8 decoder support via libvpx
*/
#define VPX_CODEC_DISABLE_COMPAT 1
#include <vpx/vpx_decoder.h>
#include <vpx/vp8dx.h>
#include "avcodec.h"
typedef struct VP8DecoderContext {
struct vpx_codec_ctx decoder;
} VP8Context;
static av_cold int vp8_init(AVCodecContext *avctx)
{
VP8Context *ctx = avctx->priv_data;
const struct vpx_codec_iface *iface = &vpx_codec_vp8_dx_algo;
struct vpx_codec_dec_cfg deccfg = {
/* token partitions+1 would be a decent choice */
.threads = FFMIN(avctx->thread_count, 16)
};
av_log(avctx, AV_LOG_INFO, "%s\n", vpx_codec_version_str());
av_log(avctx, AV_LOG_VERBOSE, "%s\n", vpx_codec_build_config());
if (vpx_codec_dec_init(&ctx->decoder, iface, &deccfg, 0) != VPX_CODEC_OK) {
const char *error = vpx_codec_error(&ctx->decoder);
av_log(avctx, AV_LOG_ERROR, "Failed to initialize decoder: %s\n",
error);
return AVERROR(EINVAL);
}
avctx->pix_fmt = PIX_FMT_YUV420P;
return 0;
}
static int vp8_decode(AVCodecContext *avctx,
void *data, int *data_size, AVPacket *avpkt)
{
VP8Context *ctx = avctx->priv_data;
AVFrame *picture = data;
const void *iter = NULL;
struct vpx_image *img;
if (vpx_codec_decode(&ctx->decoder, avpkt->data, avpkt->size, NULL, 0) !=
VPX_CODEC_OK) {
const char *error = vpx_codec_error(&ctx->decoder);
const char *detail = vpx_codec_error_detail(&ctx->decoder);
av_log(avctx, AV_LOG_ERROR, "Failed to decode frame: %s\n", error);
if (detail)
av_log(avctx, AV_LOG_ERROR, " Additional information: %s\n",
detail);
return AVERROR_INVALIDDATA;
}
if ((img = vpx_codec_get_frame(&ctx->decoder, &iter))) {
if (img->fmt != VPX_IMG_FMT_I420) {
av_log(avctx, AV_LOG_ERROR, "Unsupported output colorspace (%d)\n",
img->fmt);
return AVERROR_INVALIDDATA;
}
if ((int) img->d_w != avctx->width || (int) img->d_h != avctx->height) {
av_log(avctx, AV_LOG_INFO, "dimension change! %dx%d -> %dx%d\n",
avctx->width, avctx->height, img->d_w, img->d_h);
if (avcodec_check_dimensions(avctx, img->d_w, img->d_h))
return AVERROR_INVALIDDATA;
avcodec_set_dimensions(avctx, img->d_w, img->d_h);
}
picture->data[0] = img->planes[0];
picture->data[1] = img->planes[1];
picture->data[2] = img->planes[2];
picture->data[3] = NULL;
picture->linesize[0] = img->stride[0];
picture->linesize[1] = img->stride[1];
picture->linesize[2] = img->stride[2];
picture->linesize[3] = 0;
*data_size = sizeof(AVPicture);
}
return avpkt->size;
}
static av_cold int vp8_free(AVCodecContext *avctx)
{
VP8Context *ctx = avctx->priv_data;
vpx_codec_destroy(&ctx->decoder);
return 0;
}
AVCodec libvpx_decoder = {
"libvpx",
AVMEDIA_TYPE_VIDEO,
CODEC_ID_VP8,
sizeof(VP8Context),
vp8_init,
NULL, /* encode */
vp8_free,
vp8_decode,
0, /* capabilities */
.long_name = NULL_IF_CONFIG_SMALL("libvpx VP8"),
};