2 #include "theora/theoraenc.h"
3 #include "theora/theora.h"
4 #include "codec_internal.h"
6 /*Wrapper to translate the new API into the old API.
7 Eventually we need to convert the old functions to support the new API
8 natively and do the translation the other way.
9 theora-exp already the necessary code to do so.*/
11 static void th_info2theora_info(theora_info
*_ci
,const th_info
*_info
){
12 _ci
->version_major
=_info
->version_major
;
13 _ci
->version_minor
=_info
->version_minor
;
14 _ci
->version_subminor
=_info
->version_subminor
;
15 _ci
->width
=_info
->frame_width
;
16 _ci
->height
=_info
->frame_height
;
17 _ci
->frame_width
=_info
->pic_width
;
18 _ci
->frame_height
=_info
->pic_height
;
19 _ci
->offset_x
=_info
->pic_x
;
20 _ci
->offset_y
=_info
->pic_y
;
21 _ci
->fps_numerator
=_info
->fps_numerator
;
22 _ci
->fps_denominator
=_info
->fps_denominator
;
23 _ci
->aspect_numerator
=_info
->aspect_numerator
;
24 _ci
->aspect_denominator
=_info
->aspect_denominator
;
25 switch(_info
->colorspace
){
26 case TH_CS_ITU_REC_470M
:_ci
->colorspace
=OC_CS_ITU_REC_470M
;break;
27 case TH_CS_ITU_REC_470BG
:_ci
->colorspace
=OC_CS_ITU_REC_470BG
;break;
28 default:_ci
->colorspace
=OC_CS_UNSPECIFIED
;break;
30 switch(_info
->pixel_fmt
){
31 case TH_PF_420
:_ci
->pixelformat
=OC_PF_420
;break;
32 case TH_PF_422
:_ci
->pixelformat
=OC_PF_422
;break;
33 case TH_PF_444
:_ci
->pixelformat
=OC_PF_444
;break;
34 default:_ci
->pixelformat
=OC_PF_RSVD
;
36 _ci
->target_bitrate
=_info
->target_bitrate
;
37 _ci
->quality
=_info
->quality
;
38 _ci
->codec_setup
=NULL
;
39 /*Defaults from old encoder_example... eventually most of these should go
40 away when we make the encoder no longer use them.*/
42 _ci
->keyframe_auto_p
=1;
43 _ci
->keyframe_frequency
=1<<_info
->keyframe_granule_shift
;
44 _ci
->keyframe_frequency_force
=1<<_info
->keyframe_granule_shift
;
45 _ci
->keyframe_data_target_bitrate
=
46 _info
->target_bitrate
+(_info
->target_bitrate
>>1);
47 _ci
->keyframe_auto_threshold
=80;
48 _ci
->keyframe_mindistance
=8;
49 _ci
->noise_sensitivity
=1;
53 typedef struct th_enc_ctx
{
54 /*This is required at the start of the struct for the common functions to
57 /*The actual encoder.*/
62 th_enc_ctx
*th_encode_alloc(const th_info
*_info
){
65 th_info2theora_info(&ci
,_info
);
66 enc
=(th_enc_ctx
*)_ogg_malloc(sizeof(*enc
));
67 if(theora_encode_init(&enc
->state
,&ci
)<0){
71 else memcpy(&enc
->info
,_info
,sizeof(enc
->info
));
75 int th_encode_ctl(th_enc_ctx
*_enc
,int _req
,void *_buf
,size_t _buf_sz
){
76 return theora_control(&_enc
->state
,_req
,_buf
,_buf_sz
);
79 int th_encode_flushheader(th_enc_ctx
*_enc
,th_comment
*_comments
,
83 if(_enc
==NULL
||_op
==NULL
)return OC_FAULT
;
85 cpi
=(CP_INSTANCE
*)te
->internal_encode
;
86 switch(cpi
->doneflag
){
88 theora_encode_header(te
,_op
);
89 return -cpi
->doneflag
++;
92 if(_comments
==NULL
)return OC_FAULT
;
93 theora_encode_comment((theora_comment
*)_comments
,_op
);
94 /*The old API does not require a theora_state struct when writing the
95 comment header, so it can't use its internal buffer and relies on the
96 application to free it.
97 The old documentation is wrong on this subject, and this breaks on
98 Windows when linking against multiple versions of libc (which is
99 almost always done when, e.g., using DLLs built with mingw32).
100 The new API _does_ require a th_enc_ctx, and states that libtheora owns
102 Thus we move the contents of this packet into our internal
103 oggpack_buffer so it can be properly reclaimed.*/
104 oggpackB_reset(cpi
->oggbuffer
);
105 oggpackB_writecopy(cpi
->oggbuffer
,_op
->packet
,_op
->bytes
*8);
106 _ogg_free(_op
->packet
);
107 _op
->packet
=oggpackB_get_buffer(cpi
->oggbuffer
);
108 return -cpi
->doneflag
++;
111 theora_encode_tables(te
,_op
);
112 return -cpi
->doneflag
++;
115 default:return OC_EINVAL
;
119 int th_encode_ycbcr_in(th_enc_ctx
*_enc
,th_ycbcr_buffer _ycbcr
){
123 unsigned char *tmpbuf
;
125 if(_enc
==NULL
||_ycbcr
==NULL
)return OC_FAULT
;
127 /*theora_encode_YUVin() does not bother to check uv_width and uv_height, and
129 This is arguably okay (it will most likely lead to a crash if they're
130 wrong, which will make the developer who passed them fix the problem), but
131 our API promises to return an error code instead.*/
132 cpi
=(CP_INSTANCE
*)te
->internal_encode
;
133 if(_ycbcr
[1].width
!=_ycbcr
[0].width
>>!(cpi
->pb
.info
.pixelformat
&1)||
134 _ycbcr
[1].height
!=_ycbcr
[0].height
>>!(cpi
->pb
.info
.pixelformat
&2)||
135 _ycbcr
[2].width
!=_ycbcr
[1].width
||_ycbcr
[2].height
!=_ycbcr
[1].height
){
138 yuv
.y_width
=_ycbcr
[0].width
;
139 yuv
.y_height
=_ycbcr
[0].height
;
140 yuv
.y_stride
=_ycbcr
[0].stride
;
141 yuv
.y
=_ycbcr
[0].data
;
142 yuv
.uv_width
=_ycbcr
[1].width
;
143 yuv
.uv_height
=_ycbcr
[1].height
;
144 if(_ycbcr
[1].stride
==_ycbcr
[2].stride
){
145 yuv
.uv_stride
=_ycbcr
[1].stride
;
146 yuv
.u
=_ycbcr
[1].data
;
147 yuv
.v
=_ycbcr
[2].data
;
154 /*There's no way to signal different strides for the u and v components
155 when we pass them to theora_encode_YUVin().
156 Therefore we have to allocate a temporary buffer and copy them.*/
157 tmpbuf
=(unsigned char *)_ogg_malloc(
158 (yuv
.uv_width
*yuv
.uv_height
<<1)*sizeof(*tmpbuf
));
162 for(i
=0;i
<yuv
.uv_height
;i
++){
163 memcpy(dst
,src
,yuv
.uv_width
);
165 src
+=_ycbcr
[1].stride
;
169 for(i
=0;i
<yuv
.uv_height
;i
++){
170 memcpy(dst
,src
,yuv
.uv_width
);
172 src
+=_ycbcr
[2].stride
;
174 yuv
.uv_stride
=yuv
.uv_width
;
176 ret
=theora_encode_YUVin(te
,&yuv
);
181 int th_encode_packetout(th_enc_ctx
*_enc
,int _last
,ogg_packet
*_op
){
182 if(_enc
==NULL
)return OC_FAULT
;
183 return theora_encode_packetout(&_enc
->state
,_last
,_op
);
186 void th_encode_free(th_enc_ctx
*_enc
){
188 theora_clear(&_enc
->state
);