1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/libtheora/lib/decapiwrapper.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,193 @@ 1.4 +/******************************************************************** 1.5 + * * 1.6 + * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * 1.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * 1.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * 1.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * 1.10 + * * 1.11 + * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * 1.12 + * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * 1.13 + * * 1.14 + ******************************************************************** 1.15 + 1.16 + function: 1.17 + last mod: $Id: decapiwrapper.c 13596 2007-08-23 20:05:38Z tterribe $ 1.18 + 1.19 + ********************************************************************/ 1.20 + 1.21 +#include <stdlib.h> 1.22 +#include <string.h> 1.23 +#include <limits.h> 1.24 +#include "apiwrapper.h" 1.25 +#include "decint.h" 1.26 +#include "theora/theoradec.h" 1.27 + 1.28 +static void th_dec_api_clear(th_api_wrapper *_api){ 1.29 + if(_api->setup)th_setup_free(_api->setup); 1.30 + if(_api->decode)th_decode_free(_api->decode); 1.31 + memset(_api,0,sizeof(*_api)); 1.32 +} 1.33 + 1.34 +static void theora_decode_clear(theora_state *_td){ 1.35 + if(_td->i!=NULL)theora_info_clear(_td->i); 1.36 + memset(_td,0,sizeof(*_td)); 1.37 +} 1.38 + 1.39 +static int theora_decode_control(theora_state *_td,int _req, 1.40 + void *_buf,size_t _buf_sz){ 1.41 + return th_decode_ctl(((th_api_wrapper *)_td->i->codec_setup)->decode, 1.42 + _req,_buf,_buf_sz); 1.43 +} 1.44 + 1.45 +static ogg_int64_t theora_decode_granule_frame(theora_state *_td, 1.46 + ogg_int64_t _gp){ 1.47 + return th_granule_frame(((th_api_wrapper *)_td->i->codec_setup)->decode,_gp); 1.48 +} 1.49 + 1.50 +static double theora_decode_granule_time(theora_state *_td,ogg_int64_t _gp){ 1.51 + return th_granule_time(((th_api_wrapper *)_td->i->codec_setup)->decode,_gp); 1.52 +} 1.53 + 1.54 +static const oc_state_dispatch_vtable OC_DEC_DISPATCH_VTBL={ 1.55 + (oc_state_clear_func)theora_decode_clear, 1.56 + (oc_state_control_func)theora_decode_control, 1.57 + (oc_state_granule_frame_func)theora_decode_granule_frame, 1.58 + (oc_state_granule_time_func)theora_decode_granule_time, 1.59 +}; 1.60 + 1.61 +static void th_info2theora_info(theora_info *_ci,const th_info *_info){ 1.62 + _ci->version_major=_info->version_major; 1.63 + _ci->version_minor=_info->version_minor; 1.64 + _ci->version_subminor=_info->version_subminor; 1.65 + _ci->width=_info->frame_width; 1.66 + _ci->height=_info->frame_height; 1.67 + _ci->frame_width=_info->pic_width; 1.68 + _ci->frame_height=_info->pic_height; 1.69 + _ci->offset_x=_info->pic_x; 1.70 + _ci->offset_y=_info->pic_y; 1.71 + _ci->fps_numerator=_info->fps_numerator; 1.72 + _ci->fps_denominator=_info->fps_denominator; 1.73 + _ci->aspect_numerator=_info->aspect_numerator; 1.74 + _ci->aspect_denominator=_info->aspect_denominator; 1.75 + switch(_info->colorspace){ 1.76 + case TH_CS_ITU_REC_470M:_ci->colorspace=OC_CS_ITU_REC_470M;break; 1.77 + case TH_CS_ITU_REC_470BG:_ci->colorspace=OC_CS_ITU_REC_470BG;break; 1.78 + default:_ci->colorspace=OC_CS_UNSPECIFIED;break; 1.79 + } 1.80 + switch(_info->pixel_fmt){ 1.81 + case TH_PF_420:_ci->pixelformat=OC_PF_420;break; 1.82 + case TH_PF_422:_ci->pixelformat=OC_PF_422;break; 1.83 + case TH_PF_444:_ci->pixelformat=OC_PF_444;break; 1.84 + default:_ci->pixelformat=OC_PF_RSVD; 1.85 + } 1.86 + _ci->target_bitrate=_info->target_bitrate; 1.87 + _ci->quality=_info->quality; 1.88 + _ci->keyframe_frequency_force=1<<_info->keyframe_granule_shift; 1.89 +} 1.90 + 1.91 +int theora_decode_init(theora_state *_td,theora_info *_ci){ 1.92 + th_api_info *apiinfo; 1.93 + th_api_wrapper *api; 1.94 + th_info info; 1.95 + api=(th_api_wrapper *)_ci->codec_setup; 1.96 + /*Allocate our own combined API wrapper/theora_info struct. 1.97 + We put them both in one malloc'd block so that when the API wrapper is 1.98 + freed, the info struct goes with it. 1.99 + This avoids having to figure out whether or not we need to free the info 1.100 + struct in either theora_info_clear() or theora_clear().*/ 1.101 + apiinfo=(th_api_info *)_ogg_calloc(1,sizeof(*apiinfo)); 1.102 + if(apiinfo==NULL)return OC_FAULT; 1.103 + /*Make our own copy of the info struct, since its lifetime should be 1.104 + independent of the one we were passed in.*/ 1.105 + *&apiinfo->info=*_ci; 1.106 + /*Convert the info struct now instead of saving the the one we decoded with 1.107 + theora_decode_header(), since the user might have modified values (i.e., 1.108 + color space, aspect ratio, etc. can be specified from a higher level). 1.109 + The user also might be doing something "clever" with the header packets if 1.110 + they are not using an Ogg encapsulation.*/ 1.111 + oc_theora_info2th_info(&info,_ci); 1.112 + /*Don't bother to copy the setup info; th_decode_alloc() makes its own copy 1.113 + of the stuff it needs.*/ 1.114 + apiinfo->api.decode=th_decode_alloc(&info,api->setup); 1.115 + if(apiinfo->api.decode==NULL){ 1.116 + _ogg_free(apiinfo); 1.117 + return OC_EINVAL; 1.118 + } 1.119 + apiinfo->api.clear=(oc_setup_clear_func)th_dec_api_clear; 1.120 + _td->internal_encode=NULL; 1.121 + /*Provide entry points for ABI compatibility with old decoder shared libs.*/ 1.122 + _td->internal_decode=(void *)&OC_DEC_DISPATCH_VTBL; 1.123 + _td->granulepos=0; 1.124 + _td->i=&apiinfo->info; 1.125 + _td->i->codec_setup=&apiinfo->api; 1.126 + return 0; 1.127 +} 1.128 + 1.129 +int theora_decode_header(theora_info *_ci,theora_comment *_cc,ogg_packet *_op){ 1.130 + th_api_wrapper *api; 1.131 + th_info info; 1.132 + int ret; 1.133 + api=(th_api_wrapper *)_ci->codec_setup; 1.134 + /*Allocate an API wrapper struct on demand, since it will not also include a 1.135 + theora_info struct like the ones that are used in a theora_state struct.*/ 1.136 + if(api==NULL){ 1.137 + _ci->codec_setup=_ogg_calloc(1,sizeof(*api)); 1.138 + if(_ci->codec_setup==NULL)return OC_FAULT; 1.139 + api=(th_api_wrapper *)_ci->codec_setup; 1.140 + api->clear=(oc_setup_clear_func)th_dec_api_clear; 1.141 + } 1.142 + /*Convert from the theora_info struct instead of saving our own th_info 1.143 + struct between calls. 1.144 + The user might be doing something "clever" with the header packets if they 1.145 + are not using an Ogg encapsulation, and we don't want to break this.*/ 1.146 + oc_theora_info2th_info(&info,_ci); 1.147 + /*We rely on the fact that theora_comment and th_comment structures are 1.148 + actually identical. 1.149 + Take care not to change this fact unless you change the code here as 1.150 + well!*/ 1.151 + ret=th_decode_headerin(&info,(th_comment *)_cc,&api->setup,_op); 1.152 + /*We also rely on the fact that the error return code values are the same, 1.153 + and that the implementations of these two functions return the same set of 1.154 + them. 1.155 + Note that theora_decode_header() really can return OC_NOTFORMAT, even 1.156 + though it is not currently documented to do so.*/ 1.157 + if(ret<0)return ret; 1.158 + th_info2theora_info(_ci,&info); 1.159 + return 0; 1.160 +} 1.161 + 1.162 +int theora_decode_packetin(theora_state *_td,ogg_packet *_op){ 1.163 + th_api_wrapper *api; 1.164 + ogg_int64_t gp; 1.165 + int ret; 1.166 + if(!_td||!_td->i||!_td->i->codec_setup)return OC_FAULT; 1.167 + api=(th_api_wrapper *)_td->i->codec_setup; 1.168 + ret=th_decode_packetin(api->decode,_op,&gp); 1.169 + if(ret<0)return OC_BADPACKET; 1.170 + _td->granulepos=gp; 1.171 + return 0; 1.172 +} 1.173 + 1.174 +int theora_decode_YUVout(theora_state *_td,yuv_buffer *_yuv){ 1.175 + th_api_wrapper *api; 1.176 + th_dec_ctx *decode; 1.177 + th_ycbcr_buffer buf; 1.178 + int ret; 1.179 + if(!_td||!_td->i||!_td->i->codec_setup)return OC_FAULT; 1.180 + api=(th_api_wrapper *)_td->i->codec_setup; 1.181 + decode=(th_dec_ctx *)api->decode; 1.182 + if(!decode)return OC_FAULT; 1.183 + ret=th_decode_ycbcr_out(decode,buf); 1.184 + if(ret>=0){ 1.185 + _yuv->y_width=buf[0].width; 1.186 + _yuv->y_height=buf[0].height; 1.187 + _yuv->y_stride=buf[0].stride; 1.188 + _yuv->uv_width=buf[1].width; 1.189 + _yuv->uv_height=buf[1].height; 1.190 + _yuv->uv_stride=buf[1].stride; 1.191 + _yuv->y=buf[0].data; 1.192 + _yuv->u=buf[1].data; 1.193 + _yuv->v=buf[2].data; 1.194 + } 1.195 + return ret; 1.196 +}