Mercurial > mplayer.hg
changeset 10094:5730f6098f98
theora video decoder, based on patch by David Kuehling <dvdkhlng@gmx.de>
author | arpi |
---|---|
date | Sun, 11 May 2003 18:26:48 +0000 |
parents | ad83de1c0038 |
children | 51da0282b302 |
files | libmpcodecs/vd_theora.c |
diffstat | 1 files changed, 157 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmpcodecs/vd_theora.c Sun May 11 18:26:48 2003 +0000 @@ -0,0 +1,157 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <assert.h> + +#include "config.h" +#include "mp_msg.h" +#include "help_mp.h" + +#ifdef HAVE_OGGTHEORA + +#include "vd_internal.h" + +static vd_info_t info = { + "Theora/VP3", + "theora", + "David Kuehling", + "www.theora.org", + "Theora project's VP3 codec" +}; + +LIBVD_EXTERN(theora) + +#include <theora/theora.h> + +// to set/get/query special features/parameters +static int control(sh_video_t *sh,int cmd,void* arg,...){ + return CONTROL_UNKNOWN; +} + +typedef struct theora_struct_st { + theora_state st; + theora_info inf; +} theora_struct_t; + +/* + * init driver + */ +static int init(sh_video_t *sh){ + theora_struct_t *context = NULL; + int failed = 1; + int errorCode = 0; + ogg_packet op; + + /* check whether video output format is supported */ + switch(sh->codec->outfmt[sh->outfmtidx]) + { + case IMGFMT_YV12: /* well, this should work... */ break; + default: + mp_msg (MSGT_DECVIDEO,MSGL_ERR,"Unsupported out_fmt: 0x%X\n", + sh->codec->outfmt[sh->outfmtidx]); + return 0; + } + + /* this is not a loop, just a context, from which we can break on error */ + do + { + context = (theora_struct_t *)calloc (sizeof (theora_struct_t), 1); + sh->context = context; + if (!context) + break; + + /* read initial header */ + op.bytes = ds_get_packet (sh->ds,&op.packet); + op.b_o_s = 1; + if((errorCode = theora_decode_header (&context->inf, &op))) { + mp_msg(MSGT_DECAUDIO,MSGL_ERR, + "Broken Theora header; erroroCode=%i!\n", errorCode); + break; + } + + errorCode = theora_decode_init (&context->st, &context->inf); + if (errorCode) + { + mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Theora decode init failed: %i \n", + errorCode); + break; + } + failed = 0; + } while (0); + + if (failed) + { + if (context) + { + free (context); + sh->context = NULL; + } + return 0; + } + + mp_msg(MSGT_DECVIDEO,MSGL_V,"INFO: Theora video init ok!\n"); + + return mpcodecs_config_vo (sh,sh->disp_w,sh->disp_h,IMGFMT_YV12); +} + +/* + * uninit driver + */ +static void uninit(sh_video_t *sh) +{ + theora_struct_t *context = (theora_struct_t *)sh->context; + + if (context) + { + theora_clear (&context->st); + free (context); + } +} + +/* + * decode frame + */ +static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags) +{ + theora_struct_t *context = (theora_struct_t *)sh->context; + int errorCode = 0; + ogg_packet op; + yuv_buffer yuv; + mp_image_t* mpi; + int i; + + bzero (&op, sizeof (op)); + op.bytes = len; + op.packet = data; + op.granulepos = -1; + + errorCode = theora_decode_packetin (&context->st, &op); + if (errorCode) + { + mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Theora decode packetin failed: %i \n", + errorCode); + return NULL; + } + + errorCode = theora_decode_YUVout (&context->st, &yuv); + if (errorCode) + { + mp_msg(MSGT_DEMUX,MSGL_ERR,"Theora decode YUVout failed: %i \n", + errorCode); + return 0; + } + + mpi = mpcodecs_get_image(sh, MP_IMGTYPE_EXPORT, 0, sh->disp_w, sh->disp_h); + if(!mpi) return NULL; + + mpi->planes[0]=yuv.y; + mpi->stride[0]=yuv.y_stride; + mpi->planes[1]=yuv.u; + mpi->stride[1]=yuv.uv_stride; + mpi->planes[2]=yuv.v; + mpi->stride[2]=yuv.uv_stride; + + return mpi; +} + +#endif