Mercurial > mplayer.hg
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 |