12 #include "vd_internal.h"
14 static vd_info_t info
= {
19 "Theora project's VP3 codec"
24 #include <theora/theora.h>
26 #define THEORA_NUM_HEADER_PACKETS 3
28 // to set/get/query special features/parameters
29 static int control(sh_video_t
*sh
,int cmd
,void* arg
,...){
31 case VDCTRL_QUERY_FORMAT
:
32 if ((*((int*)arg
)) == IMGFMT_YV12
)
37 return CONTROL_UNKNOWN
;
40 typedef struct theora_struct_st
{
49 static int init(sh_video_t
*sh
){
50 theora_struct_t
*context
= NULL
;
56 /* check whether video output format is supported */
57 switch(sh
->codec
->outfmt
[sh
->outfmtidx
])
59 case IMGFMT_YV12
: /* well, this should work... */ break;
61 mp_msg (MSGT_DECVIDEO
,MSGL_ERR
,"Unsupported out_fmt: 0x%X\n",
62 sh
->codec
->outfmt
[sh
->outfmtidx
]);
66 /* this is not a loop, just a context, from which we can break on error */
69 context
= (theora_struct_t
*)calloc (sizeof (theora_struct_t
), 1);
70 sh
->context
= context
;
74 theora_info_init(&context
->inf
);
75 theora_comment_init(&context
->cc
);
77 /* Read all header packets, pass them to theora_decode_header. */
78 for (i
= 0; i
< THEORA_NUM_HEADER_PACKETS
; i
++)
80 op
.bytes
= ds_get_packet (sh
->ds
, &op
.packet
);
82 if ( (errorCode
= theora_decode_header (&context
->inf
, &context
->cc
, &op
)) )
84 mp_msg(MSGT_DECAUDIO
, MSGL_ERR
, "Broken Theora header; errorCode=%i!\n", errorCode
);
92 errorCode
= theora_decode_init (&context
->st
, &context
->inf
);
95 mp_msg(MSGT_DECVIDEO
,MSGL_ERR
,"Theora decode init failed: %i \n",
112 if(sh
->aspect
==0.0 && context
->inf
.aspect_denominator
!=0)
114 sh
->aspect
= (float)(context
->inf
.aspect_numerator
* context
->inf
.frame_width
)/
115 (context
->inf
.aspect_denominator
* context
->inf
.frame_height
);
118 mp_msg(MSGT_DECVIDEO
,MSGL_V
,"INFO: Theora video init ok!\n");
120 return mpcodecs_config_vo (sh
,context
->inf
.frame_width
,context
->inf
.frame_height
,IMGFMT_YV12
);
126 static void uninit(sh_video_t
*sh
)
128 theora_struct_t
*context
= (theora_struct_t
*)sh
->context
;
132 theora_clear (&context
->st
);
140 static mp_image_t
* decode(sh_video_t
*sh
,void* data
,int len
,int flags
)
142 theora_struct_t
*context
= (theora_struct_t
*)sh
->context
;
149 memset (&op
, 0, sizeof (op
));
154 errorCode
= theora_decode_packetin (&context
->st
, &op
);
157 mp_msg(MSGT_DECVIDEO
,MSGL_ERR
,"Theora decode packetin failed: %i \n",
162 errorCode
= theora_decode_YUVout (&context
->st
, &yuv
);
165 mp_msg(MSGT_DEMUX
,MSGL_ERR
,"Theora decode YUVout failed: %i \n",
170 mpi
= mpcodecs_get_image(sh
, MP_IMGTYPE_EXPORT
, 0, yuv
.y_width
, yuv
.y_height
);
171 if(!mpi
) return NULL
;
173 mpi
->planes
[0]=yuv
.y
;
174 mpi
->stride
[0]=yuv
.y_stride
;
175 mpi
->planes
[1]=yuv
.u
;
176 mpi
->stride
[1]=yuv
.uv_stride
;
177 mpi
->planes
[2]=yuv
.v
;
178 mpi
->stride
[2]=yuv
.uv_stride
;