summaryrefslogtreecommitdiffstats
path: root/libmpcodecs/vd_theora.c
diff options
context:
space:
mode:
authorarpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2>2003-05-11 18:26:48 +0000
committerarpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2>2003-05-11 18:26:48 +0000
commitffc479f7460c53cc0eaeb389935d78bb8b20eb3b (patch)
treea3ac1c58f9da4168c991b0a531da90b783091d93 /libmpcodecs/vd_theora.c
parentfd63a6fe684e3af0b975da26f7dda64ba3f3b628 (diff)
downloadmpv-ffc479f7460c53cc0eaeb389935d78bb8b20eb3b.tar.bz2
mpv-ffc479f7460c53cc0eaeb389935d78bb8b20eb3b.tar.xz
theora video decoder, based on patch by David Kuehling <dvdkhlng@gmx.de>
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@10095 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpcodecs/vd_theora.c')
-rw-r--r--libmpcodecs/vd_theora.c157
1 files changed, 157 insertions, 0 deletions
diff --git a/libmpcodecs/vd_theora.c b/libmpcodecs/vd_theora.c
new file mode 100644
index 0000000000..fad92349a7
--- /dev/null
+++ b/libmpcodecs/vd_theora.c
@@ -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