2 * This file is part of MPlayer.
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include "vd_internal.h"
30 static const vd_info_t info
= {
35 "Theora project's VP3 codec"
40 #include <theora/theora.h>
42 #define THEORA_NUM_HEADER_PACKETS 3
44 typedef struct theora_struct_st
{
50 /** Convert Theora pixelformat to the corresponding IMGFMT_ */
51 static uint32_t theora_pixelformat2imgfmt(theora_pixelformat fmt
){
53 case OC_PF_420
: return IMGFMT_YV12
;
54 case OC_PF_422
: return IMGFMT_422P
;
55 case OC_PF_444
: return IMGFMT_444P
;
60 // to set/get/query special features/parameters
61 static int control(sh_video_t
*sh
,int cmd
,void* arg
,...){
62 theora_struct_t
*context
= sh
->context
;
64 case VDCTRL_QUERY_FORMAT
:
65 if (*(int*)arg
== theora_pixelformat2imgfmt(context
->inf
.pixelformat
))
70 return CONTROL_UNKNOWN
;
76 static int init(sh_video_t
*sh
){
77 theora_struct_t
*context
= NULL
;
82 context
= calloc (sizeof (theora_struct_t
), 1);
83 sh
->context
= context
;
87 theora_info_init(&context
->inf
);
88 theora_comment_init(&context
->cc
);
90 /* Read all header packets, pass them to theora_decode_header. */
91 for (i
= 0; i
< THEORA_NUM_HEADER_PACKETS
; i
++)
93 op
.bytes
= ds_get_packet (sh
->ds
, &op
.packet
);
95 if ( (errorCode
= theora_decode_header (&context
->inf
, &context
->cc
, &op
)) )
97 mp_msg(MSGT_DECAUDIO
, MSGL_ERR
, "Broken Theora header; errorCode=%i!\n", errorCode
);
103 errorCode
= theora_decode_init (&context
->st
, &context
->inf
);
106 mp_msg(MSGT_DECVIDEO
,MSGL_ERR
,"Theora decode init failed: %i \n", errorCode
);
110 if(sh
->aspect
==0.0 && context
->inf
.aspect_denominator
!=0)
112 sh
->aspect
= ((double)context
->inf
.aspect_numerator
* context
->inf
.frame_width
)/
113 ((double)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
,theora_pixelformat2imgfmt(context
->inf
.pixelformat
));
129 static void uninit(sh_video_t
*sh
)
131 theora_struct_t
*context
= sh
->context
;
135 theora_info_clear(&context
->inf
);
136 theora_comment_clear(&context
->cc
);
137 theora_clear (&context
->st
);
145 static mp_image_t
* decode(sh_video_t
*sh
,void* data
,int len
,int flags
)
147 theora_struct_t
*context
= sh
->context
;
153 memset (&op
, 0, sizeof (op
));
158 errorCode
= theora_decode_packetin (&context
->st
, &op
);
161 mp_msg(MSGT_DECVIDEO
,MSGL_ERR
,"Theora decode packetin failed: %i \n",
166 errorCode
= theora_decode_YUVout (&context
->st
, &yuv
);
169 mp_msg(MSGT_DEMUX
,MSGL_ERR
,"Theora decode YUVout failed: %i \n",
174 mpi
= mpcodecs_get_image(sh
, MP_IMGTYPE_EXPORT
, 0, yuv
.y_width
, yuv
.y_height
);
175 if(!mpi
) return NULL
;
177 mpi
->planes
[0]=yuv
.y
;
178 mpi
->stride
[0]=yuv
.y_stride
;
179 mpi
->planes
[1]=yuv
.u
;
180 mpi
->stride
[1]=yuv
.uv_stride
;
181 mpi
->planes
[2]=yuv
.v
;
182 mpi
->stride
[2]=yuv
.uv_stride
;