comparison libmpcodecs/vd_theora.c @ 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
children 95dc2037fb27
comparison
equal deleted inserted replaced
10093:ad83de1c0038 10094:5730f6098f98
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdarg.h>
4 #include <assert.h>
5
6 #include "config.h"
7 #include "mp_msg.h"
8 #include "help_mp.h"
9
10 #ifdef HAVE_OGGTHEORA
11
12 #include "vd_internal.h"
13
14 static vd_info_t info = {
15 "Theora/VP3",
16 "theora",
17 "David Kuehling",
18 "www.theora.org",
19 "Theora project's VP3 codec"
20 };
21
22 LIBVD_EXTERN(theora)
23
24 #include <theora/theora.h>
25
26 // to set/get/query special features/parameters
27 static int control(sh_video_t *sh,int cmd,void* arg,...){
28 return CONTROL_UNKNOWN;
29 }
30
31 typedef struct theora_struct_st {
32 theora_state st;
33 theora_info inf;
34 } theora_struct_t;
35
36 /*
37 * init driver
38 */
39 static int init(sh_video_t *sh){
40 theora_struct_t *context = NULL;
41 int failed = 1;
42 int errorCode = 0;
43 ogg_packet op;
44
45 /* check whether video output format is supported */
46 switch(sh->codec->outfmt[sh->outfmtidx])
47 {
48 case IMGFMT_YV12: /* well, this should work... */ break;
49 default:
50 mp_msg (MSGT_DECVIDEO,MSGL_ERR,"Unsupported out_fmt: 0x%X\n",
51 sh->codec->outfmt[sh->outfmtidx]);
52 return 0;
53 }
54
55 /* this is not a loop, just a context, from which we can break on error */
56 do
57 {
58 context = (theora_struct_t *)calloc (sizeof (theora_struct_t), 1);
59 sh->context = context;
60 if (!context)
61 break;
62
63 /* read initial header */
64 op.bytes = ds_get_packet (sh->ds,&op.packet);
65 op.b_o_s = 1;
66 if((errorCode = theora_decode_header (&context->inf, &op))) {
67 mp_msg(MSGT_DECAUDIO,MSGL_ERR,
68 "Broken Theora header; erroroCode=%i!\n", errorCode);
69 break;
70 }
71
72 errorCode = theora_decode_init (&context->st, &context->inf);
73 if (errorCode)
74 {
75 mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Theora decode init failed: %i \n",
76 errorCode);
77 break;
78 }
79 failed = 0;
80 } while (0);
81
82 if (failed)
83 {
84 if (context)
85 {
86 free (context);
87 sh->context = NULL;
88 }
89 return 0;
90 }
91
92 mp_msg(MSGT_DECVIDEO,MSGL_V,"INFO: Theora video init ok!\n");
93
94 return mpcodecs_config_vo (sh,sh->disp_w,sh->disp_h,IMGFMT_YV12);
95 }
96
97 /*
98 * uninit driver
99 */
100 static void uninit(sh_video_t *sh)
101 {
102 theora_struct_t *context = (theora_struct_t *)sh->context;
103
104 if (context)
105 {
106 theora_clear (&context->st);
107 free (context);
108 }
109 }
110
111 /*
112 * decode frame
113 */
114 static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags)
115 {
116 theora_struct_t *context = (theora_struct_t *)sh->context;
117 int errorCode = 0;
118 ogg_packet op;
119 yuv_buffer yuv;
120 mp_image_t* mpi;
121 int i;
122
123 bzero (&op, sizeof (op));
124 op.bytes = len;
125 op.packet = data;
126 op.granulepos = -1;
127
128 errorCode = theora_decode_packetin (&context->st, &op);
129 if (errorCode)
130 {
131 mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Theora decode packetin failed: %i \n",
132 errorCode);
133 return NULL;
134 }
135
136 errorCode = theora_decode_YUVout (&context->st, &yuv);
137 if (errorCode)
138 {
139 mp_msg(MSGT_DEMUX,MSGL_ERR,"Theora decode YUVout failed: %i \n",
140 errorCode);
141 return 0;
142 }
143
144 mpi = mpcodecs_get_image(sh, MP_IMGTYPE_EXPORT, 0, sh->disp_w, sh->disp_h);
145 if(!mpi) return NULL;
146
147 mpi->planes[0]=yuv.y;
148 mpi->stride[0]=yuv.y_stride;
149 mpi->planes[1]=yuv.u;
150 mpi->stride[1]=yuv.uv_stride;
151 mpi->planes[2]=yuv.v;
152 mpi->stride[2]=yuv.uv_stride;
153
154 return mpi;
155 }
156
157 #endif