media/libtheora/lib/decapiwrapper.c

changeset 0
6474c204b198
     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 +}

mercurial