Initialize Tizen 2.3
[external/libtheora.git] / lib / decapiwrapper.c
1 /********************************************************************
2  *                                                                  *
3  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
4  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
5  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
7  *                                                                  *
8  * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009                *
9  * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
10  *                                                                  *
11  ********************************************************************
12
13   function:
14     last mod: $Id: decapiwrapper.c 13596 2007-08-23 20:05:38Z tterribe $
15
16  ********************************************************************/
17
18 #include <stdlib.h>
19 #include <string.h>
20 #include <limits.h>
21 #include "apiwrapper.h"
22 #include "decint.h"
23 #include "theora/theoradec.h"
24
25 static void th_dec_api_clear(th_api_wrapper *_api){
26   if(_api->setup)th_setup_free(_api->setup);
27   if(_api->decode)th_decode_free(_api->decode);
28   memset(_api,0,sizeof(*_api));
29 }
30
31 static void theora_decode_clear(theora_state *_td){
32   if(_td->i!=NULL)theora_info_clear(_td->i);
33   memset(_td,0,sizeof(*_td));
34 }
35
36 static int theora_decode_control(theora_state *_td,int _req,
37  void *_buf,size_t _buf_sz){
38   return th_decode_ctl(((th_api_wrapper *)_td->i->codec_setup)->decode,
39    _req,_buf,_buf_sz);
40 }
41
42 static ogg_int64_t theora_decode_granule_frame(theora_state *_td,
43  ogg_int64_t _gp){
44   return th_granule_frame(((th_api_wrapper *)_td->i->codec_setup)->decode,_gp);
45 }
46
47 static double theora_decode_granule_time(theora_state *_td,ogg_int64_t _gp){
48   return th_granule_time(((th_api_wrapper *)_td->i->codec_setup)->decode,_gp);
49 }
50
51 static const oc_state_dispatch_vtable OC_DEC_DISPATCH_VTBL={
52   (oc_state_clear_func)theora_decode_clear,
53   (oc_state_control_func)theora_decode_control,
54   (oc_state_granule_frame_func)theora_decode_granule_frame,
55   (oc_state_granule_time_func)theora_decode_granule_time,
56 };
57
58 static void th_info2theora_info(theora_info *_ci,const th_info *_info){
59   _ci->version_major=_info->version_major;
60   _ci->version_minor=_info->version_minor;
61   _ci->version_subminor=_info->version_subminor;
62   _ci->width=_info->frame_width;
63   _ci->height=_info->frame_height;
64   _ci->frame_width=_info->pic_width;
65   _ci->frame_height=_info->pic_height;
66   _ci->offset_x=_info->pic_x;
67   _ci->offset_y=_info->pic_y;
68   _ci->fps_numerator=_info->fps_numerator;
69   _ci->fps_denominator=_info->fps_denominator;
70   _ci->aspect_numerator=_info->aspect_numerator;
71   _ci->aspect_denominator=_info->aspect_denominator;
72   switch(_info->colorspace){
73     case TH_CS_ITU_REC_470M:_ci->colorspace=OC_CS_ITU_REC_470M;break;
74     case TH_CS_ITU_REC_470BG:_ci->colorspace=OC_CS_ITU_REC_470BG;break;
75     default:_ci->colorspace=OC_CS_UNSPECIFIED;break;
76   }
77   switch(_info->pixel_fmt){
78     case TH_PF_420:_ci->pixelformat=OC_PF_420;break;
79     case TH_PF_422:_ci->pixelformat=OC_PF_422;break;
80     case TH_PF_444:_ci->pixelformat=OC_PF_444;break;
81     default:_ci->pixelformat=OC_PF_RSVD;
82   }
83   _ci->target_bitrate=_info->target_bitrate;
84   _ci->quality=_info->quality;
85   _ci->keyframe_frequency_force=1<<_info->keyframe_granule_shift;
86 }
87
88 int theora_decode_init(theora_state *_td,theora_info *_ci){
89   th_api_info    *apiinfo;
90   th_api_wrapper *api;
91   th_info         info;
92   api=(th_api_wrapper *)_ci->codec_setup;
93   /*Allocate our own combined API wrapper/theora_info struct.
94     We put them both in one malloc'd block so that when the API wrapper is
95      freed, the info struct goes with it.
96     This avoids having to figure out whether or not we need to free the info
97      struct in either theora_info_clear() or theora_clear().*/
98   apiinfo=(th_api_info *)_ogg_calloc(1,sizeof(*apiinfo));
99   if(apiinfo==NULL)return OC_FAULT;
100   /*Make our own copy of the info struct, since its lifetime should be
101      independent of the one we were passed in.*/
102   *&apiinfo->info=*_ci;
103   /*Convert the info struct now instead of saving the the one we decoded with
104      theora_decode_header(), since the user might have modified values (i.e.,
105      color space, aspect ratio, etc. can be specified from a higher level).
106     The user also might be doing something "clever" with the header packets if
107      they are not using an Ogg encapsulation.*/
108   oc_theora_info2th_info(&info,_ci);
109   /*Don't bother to copy the setup info; th_decode_alloc() makes its own copy
110      of the stuff it needs.*/
111   apiinfo->api.decode=th_decode_alloc(&info,api->setup);
112   if(apiinfo->api.decode==NULL){
113     _ogg_free(apiinfo);
114     return OC_EINVAL;
115   }
116   apiinfo->api.clear=(oc_setup_clear_func)th_dec_api_clear;
117   _td->internal_encode=NULL;
118   /*Provide entry points for ABI compatibility with old decoder shared libs.*/
119   _td->internal_decode=(void *)&OC_DEC_DISPATCH_VTBL;
120   _td->granulepos=0;
121   _td->i=&apiinfo->info;
122   _td->i->codec_setup=&apiinfo->api;
123   return 0;
124 }
125
126 int theora_decode_header(theora_info *_ci,theora_comment *_cc,ogg_packet *_op){
127   th_api_wrapper *api;
128   th_info         info;
129   int             ret;
130   api=(th_api_wrapper *)_ci->codec_setup;
131   /*Allocate an API wrapper struct on demand, since it will not also include a
132      theora_info struct like the ones that are used in a theora_state struct.*/
133   if(api==NULL){
134     _ci->codec_setup=_ogg_calloc(1,sizeof(*api));
135     if(_ci->codec_setup==NULL)return OC_FAULT;
136     api=(th_api_wrapper *)_ci->codec_setup;
137     api->clear=(oc_setup_clear_func)th_dec_api_clear;
138   }
139   /*Convert from the theora_info struct instead of saving our own th_info
140      struct between calls.
141     The user might be doing something "clever" with the header packets if they
142      are not using an Ogg encapsulation, and we don't want to break this.*/
143   oc_theora_info2th_info(&info,_ci);
144   /*We rely on the fact that theora_comment and th_comment structures are
145      actually identical.
146     Take care not to change this fact unless you change the code here as
147      well!*/
148   ret=th_decode_headerin(&info,(th_comment *)_cc,&api->setup,_op);
149   /*We also rely on the fact that the error return code values are the same,
150     and that the implementations of these two functions return the same set of
151     them.
152    Note that theora_decode_header() really can return OC_NOTFORMAT, even
153     though it is not currently documented to do so.*/
154   if(ret<0)return ret;
155   th_info2theora_info(_ci,&info);
156   return 0;
157 }
158
159 int theora_decode_packetin(theora_state *_td,ogg_packet *_op){
160   th_api_wrapper *api;
161   ogg_int64_t     gp;
162   int             ret;
163   if(!_td||!_td->i||!_td->i->codec_setup)return OC_FAULT;
164   api=(th_api_wrapper *)_td->i->codec_setup;
165   ret=th_decode_packetin(api->decode,_op,&gp);
166   if(ret<0)return OC_BADPACKET;
167   _td->granulepos=gp;
168   return 0;
169 }
170
171 int theora_decode_YUVout(theora_state *_td,yuv_buffer *_yuv){
172   th_api_wrapper  *api;
173   th_dec_ctx      *decode;
174   th_ycbcr_buffer  buf;
175   int              ret;
176   if(!_td||!_td->i||!_td->i->codec_setup)return OC_FAULT;
177   api=(th_api_wrapper *)_td->i->codec_setup;
178   decode=(th_dec_ctx *)api->decode;
179   if(!decode)return OC_FAULT;
180   ret=th_decode_ycbcr_out(decode,buf);
181   if(ret>=0){
182     _yuv->y_width=buf[0].width;
183     _yuv->y_height=buf[0].height;
184     _yuv->y_stride=buf[0].stride;
185     _yuv->uv_width=buf[1].width;
186     _yuv->uv_height=buf[1].height;
187     _yuv->uv_stride=buf[1].stride;
188     _yuv->y=buf[0].data;
189     _yuv->u=buf[1].data;
190     _yuv->v=buf[2].data;
191   }
192   return ret;
193 }