10 #include "vd_internal.h"
12 static const vd_info_t info
= {
17 "Theora project's VP3 codec"
22 #include <theora/theora.h>
24 #define THEORA_NUM_HEADER_PACKETS 3
26 // to set/get/query special features/parameters
27 static int control(sh_video_t
*sh
,int cmd
,void* arg
,...){
29 case VDCTRL_QUERY_FORMAT
:
30 if ((*((int*)arg
)) == IMGFMT_YV12
)
35 return CONTROL_UNKNOWN
;
38 typedef struct theora_struct_st
{
47 static int init(sh_video_t
*sh
){
48 theora_struct_t
*context
= NULL
;
54 /* check whether video output format is supported */
55 switch(sh
->codec
->outfmt
[sh
->outfmtidx
])
57 case IMGFMT_YV12
: /* well, this should work... */ break;
59 mp_msg (MSGT_DECVIDEO
,MSGL_ERR
,"Unsupported out_fmt: 0x%X\n",
60 sh
->codec
->outfmt
[sh
->outfmtidx
]);
64 /* this is not a loop, just a context, from which we can break on error */
67 context
= calloc (sizeof (theora_struct_t
), 1);
68 sh
->context
= context
;
72 theora_info_init(&context
->inf
);
73 theora_comment_init(&context
->cc
);
75 /* Read all header packets, pass them to theora_decode_header. */
76 for (i
= 0; i
< THEORA_NUM_HEADER_PACKETS
; i
++)
78 op
.bytes
= ds_get_packet (sh
->ds
, &op
.packet
);
80 if ( (errorCode
= theora_decode_header (&context
->inf
, &context
->cc
, &op
)) )
82 mp_msg(MSGT_DECAUDIO
, MSGL_ERR
, "Broken Theora header; errorCode=%i!\n", errorCode
);
90 errorCode
= theora_decode_init (&context
->st
, &context
->inf
);
93 mp_msg(MSGT_DECVIDEO
,MSGL_ERR
,"Theora decode init failed: %i \n",
110 if(sh
->aspect
==0.0 && context
->inf
.aspect_denominator
!=0)
112 sh
->aspect
= (float)(context
->inf
.aspect_numerator
* context
->inf
.frame_width
)/
113 (context
->inf
.aspect_denominator
* context
->inf
.frame_height
);
116 mp_msg(MSGT_DECVIDEO
,MSGL_V
,"INFO: Theora video init ok!\n");
118 return mpcodecs_config_vo (sh
,context
->inf
.frame_width
,context
->inf
.frame_height
,IMGFMT_YV12
);
124 static void uninit(sh_video_t
*sh
)
126 theora_struct_t
*context
= (theora_struct_t
*)sh
->context
;
130 theora_info_clear(&context
->inf
);
131 theora_comment_clear(&context
->cc
);
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
;
148 memset (&op
, 0, sizeof (op
));
153 errorCode
= theora_decode_packetin (&context
->st
, &op
);
156 mp_msg(MSGT_DECVIDEO
,MSGL_ERR
,"Theora decode packetin failed: %i \n",
161 errorCode
= theora_decode_YUVout (&context
->st
, &yuv
);
164 mp_msg(MSGT_DEMUX
,MSGL_ERR
,"Theora decode YUVout failed: %i \n",
169 mpi
= mpcodecs_get_image(sh
, MP_IMGTYPE_EXPORT
, 0, yuv
.y_width
, yuv
.y_height
);
170 if(!mpi
) return NULL
;
172 mpi
->planes
[0]=yuv
.y
;
173 mpi
->stride
[0]=yuv
.y_stride
;
174 mpi
->planes
[1]=yuv
.u
;
175 mpi
->stride
[1]=yuv
.uv_stride
;
176 mpi
->planes
[2]=yuv
.v
;
177 mpi
->stride
[2]=yuv
.uv_stride
;