Commit 8299a7f8 authored by James Zern's avatar James Zern Committed by Carl Eugen Hoyos

VP8 decoding via libvpx.

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

Originally committed as revision 23303 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent ce2a9bc3
......@@ -7,6 +7,7 @@ version <next>:
- WebM support in Matroska demuxer
- low overhead Ogg muxing
- MMS-TCP support
- VP8 decoding via libvpx
......
......@@ -183,6 +183,7 @@ External library support:
--enable-libtheora enable Theora encoding via libtheora [no]
--enable-libvorbis enable Vorbis encoding via libvorbis,
native implementation exists [no]
--enable-libvpx enable VP8 support via libvpx [no]
--enable-libx264 enable H.264 encoding via x264 [no]
--enable-libxvid enable Xvid encoding via xvidcore,
native MPEG-4/Xvid encoder exists [no]
......@@ -927,6 +928,7 @@ CONFIG_LIST="
libspeex
libtheora
libvorbis
libvpx
libx264
libxvid
lpc
......@@ -1349,6 +1351,7 @@ libschroedinger_encoder_deps="libschroedinger"
libspeex_decoder_deps="libspeex"
libtheora_encoder_deps="libtheora"
libvorbis_encoder_deps="libvorbis"
libvpx_decoder_deps="libvpx"
libx264_encoder_deps="libx264"
libxvid_encoder_deps="libxvid"
......@@ -2617,6 +2620,7 @@ enabled libschroedinger && add_cflags $(pkg-config --cflags schroedinger-1.0) &&
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 libvorbis && require libvorbis vorbis/vorbisenc.h vorbis_info_init -lvorbisenc -lvorbis -logg
enabled libvpx && require2 libvpx "vpx_decoder.h vp8dx.h" "vpx_codec_dec_init_ver" -lvpx
enabled libx264 && require libx264 x264.h x264_encoder_encode -lx264 -lm &&
{ check_cpp_condition x264.h "X264_BUILD >= 90" ||
die "ERROR: libx264 version must be >= 0.90."; }
......@@ -2886,6 +2890,7 @@ echo "libschroedinger enabled ${libschroedinger-no}"
echo "libspeex enabled ${libspeex-no}"
echo "libtheora enabled ${libtheora-no}"
echo "libvorbis enabled ${libvorbis-no}"
echo "libvpx enabled ${libvpx-no}"
echo "libx264 enabled ${libx264-no}"
echo "libxvid enabled ${libxvid-no}"
echo "zlib enabled ${zlib-no}"
......
......@@ -437,6 +437,8 @@ following image formats are supported:
@tab fourcc: VP50
@item On2 VP6 @tab @tab X
@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
@tab fourcc: 8BPS
@item Q-team QPEG @tab @tab X
......
......@@ -536,6 +536,7 @@ OBJS-$(CONFIG_LIBSCHROEDINGER_ENCODER) += libschroedingerenc.o \
OBJS-$(CONFIG_LIBSPEEX_DECODER) += libspeexdec.o
OBJS-$(CONFIG_LIBTHEORA_ENCODER) += libtheoraenc.o
OBJS-$(CONFIG_LIBVORBIS_ENCODER) += libvorbis.o
OBJS-$(CONFIG_LIBVPX_DECODER) += libvpxdec.o
OBJS-$(CONFIG_LIBX264_ENCODER) += libx264.o
OBJS-$(CONFIG_LIBXVID_ENCODER) += libxvidff.o libxvid_rc.o
......
......@@ -349,6 +349,7 @@ void avcodec_register_all(void)
REGISTER_DECODER (LIBSPEEX, libspeex);
REGISTER_ENCODER (LIBTHEORA, libtheora);
REGISTER_ENCODER (LIBVORBIS, libvorbis);
REGISTER_DECODER (LIBVPX, libvpx);
REGISTER_ENCODER (LIBX264, libx264);
REGISTER_ENCODER (LIBXVID, libxvid);
......
......@@ -30,8 +30,8 @@
#include "libavutil/avutil.h"
#define LIBAVCODEC_VERSION_MAJOR 52
#define LIBAVCODEC_VERSION_MINOR 68
#define LIBAVCODEC_VERSION_MICRO 3
#define LIBAVCODEC_VERSION_MINOR 69
#define LIBAVCODEC_VERSION_MICRO 0
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \
......
/*
* 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_decoder.h>
#include <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"),
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment