[xiph-commits] r14362 - in trunk/theora: include/theora lib lib/enc

tterribe at svn.xiph.org tterribe at svn.xiph.org
Fri Jan 4 12:20:57 PST 2008


Author: tterribe
Date: 2008-01-04 12:20:56 -0800 (Fri, 04 Jan 2008)
New Revision: 14362

Added:
   trunk/theora/include/theora/theoraenc.h
   trunk/theora/lib/enc/encapiwrapper.c
   trunk/theora/lib/enc/internal.c
Modified:
   trunk/theora/lib/Makefile.am
   trunk/theora/lib/enc/encoder_quant.c
   trunk/theora/lib/enc/encoder_toplevel.c
Log:
Add an API wrapper to the encoder to export the new theora-exp API.


Copied: trunk/theora/include/theora/theoraenc.h (from rev 14150, trunk/theora-exp/include/theora/theoraenc.h)
===================================================================
--- trunk/theora/include/theora/theoraenc.h	                        (rev 0)
+++ trunk/theora/include/theora/theoraenc.h	2008-01-04 20:20:56 UTC (rev 14362)
@@ -0,0 +1,347 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2003                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+  last mod: $Id: theora.h,v 1.8 2004/03/15 22:17:32 derf Exp $
+
+ ********************************************************************/
+
+/**\file
+ * The <tt>libtheoraenc</tt> C encoding API.*/
+
+#if !defined(_O_THEORA_THEORAENC_H_)
+# define _O_THEORA_THEORAENC_H_ (1)
+# include <ogg/ogg.h>
+# include "codec.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+
+/**The configuration information for the VBR encoding mode.
+ * This mode attempts to encode the video with a constant psychovisual
+ *  quality.
+ * It can be enabled by calling th_encode_ctl() with #TH_ENCCTL_SETUP_VBR.
+ * See the #th_info struct documentation for details on how the default
+ *  encoding mode is chosen.*/
+typedef struct th_vbr_cfg{
+  /**The target quality index.
+   * Valid values range from 0 to 63, inclusive, with higher values giving
+   *  higher quality.
+   * Note that, in this case, this corresponds to a <em>perceptual</em>
+   *  quality, and may not translate directly into a quantization setting.
+   * Limits on the admissible quantizers can be controlled below.*/
+  int qi;
+  /**The minimum quality to use for a keyframe.
+   * Valid values range from 0 to 63, inclusive, with higher values giving
+   *  higher quality.*/
+  int kf_qi_min;
+  /**The maximum quality to use for a keyframe.
+   * Valid values range from 0 to 63, inclusive, with higher values giving
+   *  higher quality.
+   * This must be at least as large as #kf_qi_max.*/
+  int kf_qi_max;
+  /**The minimum quality to use for a delta frame.
+   * Valid values range from 0 to 63, inclusive, with higher values giving
+   *  higher quality.*/
+  int df_qi_min;
+  /**The maximum quality to use for a delta frame.
+   * Valid values range from 0 to 63, inclusive, with higher values giving
+   *  higher quality.
+   * This must be at least as large as #df_qi_max.*/
+  int df_qi_max;
+}th_vbr_cfg;
+
+/**The configuration information for the constant QI encoding mode.
+ * This mode encodes the video with a constant quality index.
+ * This is the fastest encoding mode.
+ * It can be enabled by calling th_encode_ctl() with #TH_ENCCTL_SETUP_CQI.
+ * See the #th_info struct documentation for details on how the default
+ *  encoding mode is chosen.*/
+typedef struct th_cqi_cfg{
+  /**The target quality index.
+     Valid values range from 0 to 63, inclusive, with higher values giving
+      higher quality.*/
+  int qi;
+}th_cqi_cfg;
+
+/**\name th_encode_ctl() codes
+ * \anchor encctlcodes
+ * These are the available request codes for th_encode_ctl().
+ * By convention, these are even, to distinguish them from the
+ *  \ref decctlcodes "decoder control codes".
+ * Keep any experimental or vendor-specific values above \c 0x8000.*/
+/*@{*/
+/**Sets the Huffman tables to use.
+ * The tables are copied, not stored by reference, so they can be freed after
+ *  this call.
+ * <tt>NULL</tt> may be specified to revert to the default tables.
+ *
+ * \param[in] _buf <tt>#th_huff_code[#TH_NHUFFMAN_TABLES][#TH_NDCT_TOKENS]</tt>
+ * \retval TH_EFAULT \a _enc_ctx is <tt>NULL</tt>.
+ * \retval TH_EINVAL Encoding has already begun or one or more of the given
+ *                     tables is not full or prefix-free, \a _buf is
+ *                     <tt>NULL</tt> and \a _buf_sz is not zero, or \a _buf is
+ *                     non-<tt>NULL</tt> and \a _buf_sz is not
+ *                     <tt>sizeof(#th_huff_code)*#TH_NHUFFMAN_TABLES*#TH_NDCT_TOKENS</tt>.
+ * \retval TH_IMPL   Not supported by this implementation.*/
+#define TH_ENCCTL_SET_HUFFMAN_CODES (0)
+/**Sets the quantization parameters to use.
+ * The parameters are copied, not stored by reference, so they can be freed
+ *  after this call.
+ * <tt>NULL</tt> may be specified to revert to the default parameters.
+ * For the current encoder, <tt>scale[ci!=0][qi]</tt> must be no greater than
+ *  <tt>scale[ci!=0][qi-1]</tt> and <tt>base[qti][pli][qi][ci]</tt> must be no
+ *  greater than <tt>base[qti][pli][qi-1][ci]</tt>.
+ * These two conditions ensure that the actual quantizer for a given \a qti,
+ *  \a pli, and \a ci does not increase as \a qi increases.
+ *
+ * \param[in] _buf #th_quant_info
+ * \retval TH_EFAULT \a _enc_ctx is <tt>NULL</tt>.
+ * \retval TH_EINVAL Encoding has already begun, the quantization parameters
+ *                    do not meet one of the above stated conditions, \a _buf
+ *                    is <tt>NULL</tt> and \a _buf_sz is not zero, or \a _buf
+ *                    is non-<tt>NULL</tt> and \a _buf_sz is not
+ *                    <tt>sizeof(#th_quant_info)</tt>.
+ * \retval TH_IMPL   Not supported by this implementation.*/
+#define TH_ENCCTL_SET_QUANT_PARAMS (2)
+/**Sets the maximum distance between key frames.
+ * This can be changed during an encode, but will be bounded by
+ *  <tt>1<<th_info#keyframe_granule_shift</tt>.
+ * If it is set before encoding begins, th_info#keyframe_granule_shift will
+ *  be enlarged appropriately.
+ *
+ * \param[in]  _buf <tt>ogg_uint32_t</tt>: The maximum distance between key
+ *                   frames.
+ * \param[out] _buf <tt>ogg_uint32_t</tt>: The actual maximum distance set.
+ * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(ogg_uint32_t)</tt>.
+ * \retval TH_IMPL   Not supported by this implementation.*/
+#define TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE (4)
+/**Disables any encoder features that would prevent lossless transcoding back
+ *  to VP3.
+ * This primarily means disabling block-level QI values and not using 4MV mode
+ *  when any of the luma blocks in a macro block are not coded.
+ * It also includes using the VP3 quantization tables and Huffman codes; if you
+ *  set them explicitly after calling this function, the resulting stream will
+ *  not be VP3-compatible.
+ * If you enable VP3-compatibility when encoding 4:2:2 or 4:4:4 source
+ *  material, or when using a picture region smaller than the full frame (e.g.
+ *  a non-multiple-of-16 width or height), then non-VP3 bitstream features will
+ *  still be disabled, but the stream will still not be VP3-compatible, as VP3
+ *  was not capable of encoding such formats.
+ * If you call this after encoding has already begun, then the quantization
+ *  tables and codebooks cannot be changed, but the frame-level features will
+ *  be enabled or disabled as requested.
+ *
+ * \param[in]  _buf <tt>int</tt>: a non-zero value to enable VP3 compatibility,
+ *                   or 0 to disable it (the default).
+ * \param[out] _buf <tt>int</tt>: 1 if all bitstream features required for
+ *                   VP3-compatibility could be set, and 0 otherwise.
+ *                  The latter will be returned if the pixel format is not
+ *                   4:2:0, the picture region is smaller than the full frame,
+ *                   or if encoding has begun, preventing the quantization
+ *                   tables and codebooks from being set.
+ * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt>.
+ * \retval TH_IMPL   Not supported by this implementation.*/
+#define TH_ENCCTL_SET_VP3_COMPATIBLE (10)
+/**Gets the maximum speed level.
+ * Higher speed levels favor quicker encoding over better quality per bit.
+ * Depending on the encoding mode, and the internal algorithms used, quality
+ *  may actually improve, but in this case bitrate will also likely increase.
+ * In any case, overall rate/distortion performance will probably decrease.
+ * The maximum value, and the meaning of each value, may change depending on
+ *  the current encoding mode (VBR vs. CQI, etc.).
+ *
+ * \param[out] _buf int: The maximum encoding speed level.
+ * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt>.
+ * \retval TH_IMPL   Not supported by this implementation in the current
+ *                    encoding mode.*/
+#define TH_ENCCTL_GET_SPLEVEL_MAX (12)
+/**Sets the speed level.
+ * By default, the slowest speed (0) is used.
+ *
+ * \param[in] _buf int: The new encoding speed level.
+ *                      0 is slowest, larger values use less CPU.
+ * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt>, or the
+ *                    encoding speed level is out of bounds.
+ *                   The maximum encoding speed level may be
+ *                    implementation- and encoding mode-specific, and can be
+ *                    obtained via #TH_ENCCTL_GET_SPLEVEL_MAX.
+ * \retval TH_IMPL   Not supported by this implementation in the current
+ *                    encoding mode.*/
+#define TH_ENCCTL_SET_SPLEVEL (14)
+/**Puts the encoder in VBR mode.
+ * This can be done at any time during the encoding process, with different
+ *  configuration parameters, to encode different regions of the video segment
+ *  with different qualities.
+ * See the #th_info struct documentation for details on how the default
+ *  encoding mode is chosen.
+ *
+ * \param[in] _buf <tt>#th_vbr_cfg</tt>: the configuration parameters.
+ *                 This may be <tt>NULL</tt>, in which case the current VBR
+ *                  configuration is unchanged.
+ *                 The default is to use the QI setting passed in via the
+ *                  #th_info struct when the encoder was initialized, with a
+ *                  full range of admissible quantizers.
+ * \retval TH_EFAULT \a _enc_ctx is <tt>NULL</tt>.
+ * \retval TH_EINVAL The configuration parameters do not meet one of their
+ *                    stated requirements, \a _buf is <tt>NULL</tt> and
+ *                    \a _buf_sz is not zero, or \a _buf is non-<tt>NULL</tt>
+ *                    and \a _buf_sz is not <tt>sizeof(#th_vbr_cfg)</tt>.
+ * \retval TH_IMPL   Not supported by this implementation.*/
+#define TH_ENCCTL_SETUP_VBR (16)
+/**Puts the encoder in CQI mode.
+ * This can be done at any time during the encoding process, with different QI
+ *  values.
+ * See the #th_info struct documentation for details on how the default
+ *  encoding mode is chosen.
+ *
+ * \param[in] _buf <tt>#th_cqi_cfg</tt>: the configuration parameters.
+ *                 This may be <tt>NULL</tt>, in which case the current CQI
+ *                  configuration is unchanged.
+ *                 The default is to use the QI setting passed in via the
+ *                  #th_info struct when the encoder was initialized.
+ * \retval TH_EFAULT \a _enc_ctx is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(#th_cqi_cfg)</tt>.
+ * \retval TH_IMPL   Not supported by this implementation.*/
+#define TH_ENCCTL_SETUP_CQI (18)
+/*@}*/
+
+
+
+/**The quantization parameters used by VP3.*/
+extern const th_quant_info TH_VP31_QUANT_INFO;
+
+/**The Huffman tables used by VP3.*/
+extern const th_huff_code
+ TH_VP31_HUFF_CODES[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS];
+
+
+
+/**\name Encoder state
+   The following data structure is opaque, and its contents are not publicly
+    defined by this API.
+   Referring to its internals directly is unsupported, and may break without
+    warning.*/
+/*@{*/
+/**The encoder context.*/
+typedef struct th_enc_ctx    th_enc_ctx;
+/*@}*/
+
+
+
+/**\defgroup encfuncs Functions for Encoding*/
+/*@{*/
+/**\name Functions for encoding
+ * You must link to <tt>libtheoraenc</tt> and <tt>libtheoradec</tt>
+ *  if you use any of the functions in this section.
+ *
+ * The functions are listed in the order they are used in a typical encode.
+ * The basic steps are:
+ * - Fill in a #th_info structure with details on the format of the video you
+ *    wish to encode.
+ * - Allocate a #th_enc_ctx handle with th_encode_alloc().
+ * - Perform any additional encoder configuration required with
+ *    th_encode_ctl().
+ * - Repeatedly call th_encode_flushheader() to retrieve all the header
+ *    packets.
+ * - For each uncompressed frame:
+ *   - Submit the uncompressed frame via th_encode_ycbcr_in()
+ *   - Repeatedly call th_encode_packetout() to retrieve any video data packets
+ *      that are ready.
+ * - Call th_encode_free() to release all encoder memory.*/
+/*@{*/
+/**Allocates an encoder instance.
+ * \param _info A #th_info struct filled with the desired encoding parameters.
+ * \return The initialized #th_enc_ctx handle.
+ * \retval NULL If the encoding parameters were invalid.*/
+extern th_enc_ctx *th_encode_alloc(const th_info *_info);
+/**Encoder control function.
+ * This is used to provide advanced control the encoding process.
+ * \param _enc    A #th_enc_ctx handle.
+ * \param _req    The control code to process.
+ *                See \ref encctlcodes "the list of available control codes"
+ *                 for details.
+ * \param _buf    The parameters for this control code.
+ * \param _buf_sz The size of the parameter buffer.*/
+extern int th_encode_ctl(th_enc_ctx *_enc,int _req,void *_buf,size_t _buf_sz);
+/**Outputs the next header packet.
+ * This should be called repeatedly after encoder initialization until it
+ *  returns 0 in order to get all of the header packets, in order, before
+ *  encoding actual video data.
+ * \param _enc      A #th_enc_ctx handle.
+ * \param _comments The metadata to place in the comment header, when it is
+ *                   encoded.
+ * \param _op       An <tt>ogg_packet</tt> structure to fill.
+ *                  All of the elements of this structure will be set,
+ *                   including a pointer to the header data.
+ *                  The memory for the header data is owned by
+ *                   <tt>libtheoraenc</tt>, and may be invalidated when the
+ *                   next encoder function is called.
+ * \return A positive value indicates that a header packet was successfully
+ *          produced.
+ * \retval 0         No packet was produced, and no more header packets remain.
+ * \retval TH_EFAULT \a _enc, \a _comments, or \a _op was <tt>NULL</tt>.*/
+extern int th_encode_flushheader(th_enc_ctx *_enc,
+ th_comment *_comments,ogg_packet *_op);
+/**Submits an uncompressed frame to the encoder.
+ * \param _enc   A #th_enc_ctx handle.
+ * \param _ycbcr A buffer of Y'CbCr data to encode.
+ * \retval 0         Success.
+ * \retval TH_EFAULT \a _enc or \a _ycbcr is <tt>NULL</tt>.
+ * \retval TH_EINVAL The buffer size does not match the frame size the encoder
+ *                    was initialized with, or encoding has already
+ *                    completed.*/
+extern int th_encode_ycbcr_in(th_enc_ctx *_enc,th_ycbcr_buffer _ycbcr);
+/**Retrieves encoded video data packets.
+ * This should be called repeatedly after each frame is submitted to flush any
+ *  encoded packets, until it returns 0.
+ * The encoder will not buffer these packets as subsequent frames are
+ *  compressed, so a failure to do so will result in lost video data.
+ * \note Currently the encoder operates in a one-frame-in, one-packet-out
+ *        manner.
+ *       However, this may be changed in the future.
+ * \param _enc  A #th_enc_ctx handle.
+ * \param _last Set this flag to a non-zero value if no more uncompressed
+ *               frames will be submitted.
+ *              This ensures that a proper EOS flag is set on the last packet.
+ * \param _op   An <tt>ogg_packet</tt> structure to fill.
+ *              All of the elements of this structure will be set, including a
+ *               pointer to the video data.
+ *              The memory for the video data is owned by
+ *               <tt>libtheoraenc</tt>, and may be invalidated when the next
+ *               encoder function is called.
+ * \return A positive value indicates that a video data packet was successfully
+ *          produced.
+ * \retval 0         No packet was produced, and no more encoded video data
+ *                    remains.
+ * \retval TH_EFAULT \a _enc or \a _op was <tt>NULL</tt>.*/
+extern int th_encode_packetout(th_enc_ctx *_enc,int _last,ogg_packet *_op);
+/**Frees an allocated encoder instance.
+ * \param _enc A #th_enc_ctx handle.*/
+extern void th_encode_free(th_enc_ctx *_enc);
+/*@}*/
+/*@}*/
+
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif

Modified: trunk/theora/lib/Makefile.am
===================================================================
--- trunk/theora/lib/Makefile.am	2008-01-04 20:12:47 UTC (rev 14361)
+++ trunk/theora/lib/Makefile.am	2008-01-04 20:20:56 UTC (rev 14362)
@@ -34,6 +34,7 @@
 	enc/encoder_idct.c \
 	enc/encoder_toplevel.c \
 	enc/encoder_quant.c \
+	enc/encapiwrapper.c \
 	enc/blockmap.c \
 	enc/dct.c \
 	enc/dct_decode.c \

Added: trunk/theora/lib/enc/encapiwrapper.c
===================================================================
--- trunk/theora/lib/enc/encapiwrapper.c	                        (rev 0)
+++ trunk/theora/lib/enc/encapiwrapper.c	2008-01-04 20:20:56 UTC (rev 14362)
@@ -0,0 +1,171 @@
+#include <string.h>
+#include "theora/theoraenc.h"
+#include "theora/theora.h"
+#include "codec_internal.h"
+
+/*Wrapper to translate the new API into the old API.
+  Eventually we need to convert the old functions to support the new API
+   natively and do the translation the other way.
+  theora-exp already the necessary code to do so.*/
+
+static void th_info2theora_info(theora_info *_ci,const th_info *_info){
+  _ci->version_major=_info->version_major;
+  _ci->version_minor=_info->version_minor;
+  _ci->version_subminor=_info->version_subminor;
+  _ci->width=_info->frame_width;
+  _ci->height=_info->frame_height;
+  _ci->frame_width=_info->pic_width;
+  _ci->frame_height=_info->pic_height;
+  _ci->offset_x=_info->pic_x;
+  _ci->offset_y=_info->pic_y;
+  _ci->fps_numerator=_info->fps_numerator;
+  _ci->fps_denominator=_info->fps_denominator;
+  _ci->aspect_numerator=_info->aspect_numerator;
+  _ci->aspect_denominator=_info->aspect_denominator;
+  switch(_info->colorspace){
+    case TH_CS_ITU_REC_470M:_ci->colorspace=OC_CS_ITU_REC_470M;break;
+    case TH_CS_ITU_REC_470BG:_ci->colorspace=OC_CS_ITU_REC_470BG;break;
+    default:_ci->colorspace=OC_CS_UNSPECIFIED;break;
+  }
+  switch(_info->pixel_fmt){
+    case TH_PF_420:_ci->pixelformat=OC_PF_420;break;
+    case TH_PF_422:_ci->pixelformat=OC_PF_422;break;
+    case TH_PF_444:_ci->pixelformat=OC_PF_444;break;
+    default:_ci->pixelformat=OC_PF_RSVD;
+  }
+  _ci->target_bitrate=_info->target_bitrate;
+  _ci->quality=_info->quality;
+  _ci->keyframe_frequency_force=1<<_info->keyframe_granule_shift;
+}
+
+th_enc_ctx *th_encode_alloc(const th_info *_info){
+  theora_info   ci;
+  theora_state *te;
+  th_info2theora_info(&ci,_info);
+  te=(theora_state *)_ogg_malloc(sizeof(*te));
+  if(theora_encode_init(te,&ci)<0){
+    _ogg_free(te);
+    te=NULL;
+  }
+  return (th_enc_ctx *)te;
+}
+
+int th_encode_ctl(th_enc_ctx *_enc,int _req,void *_buf,size_t _buf_sz){
+  return theora_control((theora_state *)_enc,_req,_buf,_buf_sz);
+}
+
+int th_encode_flushheader(th_enc_ctx *_enc,th_comment *_comments,
+ ogg_packet *_op){
+  theora_state *te;
+  CP_INSTANCE  *cpi;
+  if(_enc==NULL||_op==NULL)return OC_FAULT;
+  te=(theora_state *)_enc;
+  cpi=(CP_INSTANCE *)te->internal_encode;
+  switch(cpi->doneflag){
+    case -3:{
+      theora_encode_header(te,_op);
+      return -cpi->doneflag++;
+    }break;
+    case -2:{
+      if(_comments==NULL)return OC_FAULT;
+      theora_encode_comment((theora_comment *)_comments,_op);
+#ifndef LIBOGG2
+      /*The old API does not require a theora_state struct when writing the
+         comment header, so it can't use its internal buffer and relies on the
+         application to free it when using libogg 1.
+        The old documentation is wrong on this subject, and this breaks on
+         Windows when linking against multiple versions of libc (which is
+         almost always done when, e.g., using DLLs built with mingw32).
+        The new API _does_ require a th_enc_ctx, and states that libtheora owns
+         the memory.
+        Thus we move the contents of this packet into our internal
+         oggpack_buffer so it can be properly reclaimed.*/
+      oggpackB_reset(cpi->oggbuffer);
+      oggpackB_writecopy(cpi->oggbuffer,_op->packet,_op->bytes*8);
+      _ogg_free(_op->packet);
+      _op->packet=oggpackB_get_buffer(cpi->oggbuffer);
+#endif
+      return -cpi->doneflag++;
+    }break;
+    case -1:{
+      theora_encode_tables(te,_op);
+      return -cpi->doneflag++;
+    }break;
+    case 0:return 0;
+    default:return OC_EINVAL;
+  }
+}
+
+int th_encode_ycbcr_in(th_enc_ctx *_enc,th_ycbcr_buffer _ycbcr){
+  CP_INSTANCE   *cpi;
+  theora_state  *te;
+  yuv_buffer     yuv;
+  unsigned char *tmpbuf;
+  int            ret;
+  if(_enc==NULL||_ycbcr==NULL)return OC_FAULT;
+  te=(theora_state *)_enc;
+  /*theora_encode_YUVin() does not bother to check uv_width and uv_height, and
+     then uses them.
+    This is arguably okay (it will most likely lead to a crash if they're
+     wrong, which will make the developer who passed them fix the problem), but
+     our API promises to return an error code instead.*/
+  cpi=(CP_INSTANCE *)te->internal_encode;
+  if(_ycbcr[1].width!=_ycbcr[0].width>>!(cpi->pb.info.pixelformat&1)||
+   _ycbcr[1].height!=_ycbcr[0].height>>!(cpi->pb.info.pixelformat&2)||
+   _ycbcr[2].width!=_ycbcr[1].width||_ycbcr[2].height!=_ycbcr[1].height){
+    return OC_EINVAL;
+  }
+  yuv.y_width=_ycbcr[0].width;
+  yuv.y_height=_ycbcr[0].height;
+  yuv.y_stride=_ycbcr[0].ystride;
+  yuv.y=_ycbcr[0].data;
+  yuv.uv_width=_ycbcr[1].width;
+  yuv.uv_height=_ycbcr[1].height;
+  if(_ycbcr[1].ystride==_ycbcr[2].ystride){
+    yuv.uv_stride=_ycbcr[1].ystride;
+    yuv.u=_ycbcr[1].data;
+    yuv.v=_ycbcr[2].data;
+    tmpbuf=NULL;
+  }
+  else{
+    unsigned char *src;
+    unsigned char *dst;
+    int            i;
+    /*There's no way to signal different strides for the u and v components
+       when we pass them to theora_encode_YUVin().
+      Therefore we have to allocate a temporary buffer and copy them.*/
+    tmpbuf=(unsigned char *)_ogg_malloc(
+     (yuv.uv_width*yuv.uv_height<<1)*sizeof(*tmpbuf));
+    dst=tmpbuf;
+    yuv.u=dst;
+    src=_ycbcr[1].data;
+    for(i=0;i<yuv.uv_height;i++){
+      memcpy(dst,src,yuv.uv_width);
+      dst+=yuv.uv_width;
+      src+=_ycbcr[1].ystride;
+    }
+    yuv.v=dst;
+    src=_ycbcr[2].data;
+    for(i=0;i<yuv.uv_height;i++){
+      memcpy(dst,src,yuv.uv_width);
+      dst+=yuv.uv_width;
+      src+=_ycbcr[2].ystride;
+    }
+    yuv.uv_stride=yuv.uv_width;
+  }
+  ret=theora_encode_YUVin(te,&yuv);
+  _ogg_free(tmpbuf);
+  return ret;
+}
+
+int th_encode_packetout(th_enc_ctx *_enc,int _last,ogg_packet *_op){
+  if(_enc==NULL)return OC_FAULT;
+  return theora_encode_packetout((theora_state *)_enc,_last,_op);
+}
+
+void th_encode_free(th_enc_ctx *_enc){
+  if(_enc!=NULL){
+    theora_clear((theora_state *)_enc);
+    _ogg_free(_enc);
+  }
+}

Modified: trunk/theora/lib/enc/encoder_quant.c
===================================================================
--- trunk/theora/lib/enc/encoder_quant.c	2008-01-04 20:12:47 UTC (rev 14361)
+++ trunk/theora/lib/enc/encoder_quant.c	2008-01-04 20:20:56 UTC (rev 14362)
@@ -27,13 +27,19 @@
 #endif
 
 #define OC_QUANT_MAX        (1024<<2)
-//unsigned OC_DC_QUANT_MIN[2]={4<<2,8<<2};
-//unsigned OC_AC_QUANT_MIN[2]={2<<2,4<<2};
+static const unsigned DC_QUANT_MIN[2]={4<<2,8<<2};
+static const unsigned AC_QUANT_MIN[2]={2<<2,4<<2};
 #define OC_MAXI(_a,_b)      ((_a)<(_b)?(_b):(_a))
 #define OC_MINI(_a,_b)      ((_a)>(_b)?(_b):(_a))
 #define OC_CLAMPI(_a,_b,_c) (OC_MAXI(_a,OC_MINI(_b,_c)))
 
+static int ilog(unsigned _v){
+  int ret;
+  for(ret=0;_v;ret++)_v>>=1;
+  return ret;
+}
 
+
 void WriteQTables(PB_INSTANCE *pbi,oggpack_buffer* _opb) {
   
   th_quant_info *_qinfo = &pbi->quant_info; 
@@ -57,17 +63,17 @@
      index 0, so search for it here.*/
   i=_qinfo->loop_filter_limits[0];
   for(qi=1;qi<64;qi++)i=OC_MAXI(i,_qinfo->loop_filter_limits[qi]);
-  nbits=oc_ilog(i);
+  nbits=ilog(i);
   oggpackB_write(_opb,nbits,3);
   for(qi=0;qi<64;qi++){
     oggpackB_write(_opb,_qinfo->loop_filter_limits[qi],nbits);
   }
   /* 580 bits for VP3.*/
-  nbits=OC_MAXI(oc_ilog(_qinfo->ac_scale[0]),1);
+  nbits=OC_MAXI(ilog(_qinfo->ac_scale[0]),1);
   oggpackB_write(_opb,nbits-1,4);
   for(qi=0;qi<64;qi++)oggpackB_write(_opb,_qinfo->ac_scale[qi],nbits);
   /* 516 bits for VP3.*/
-  nbits=OC_MAXI(oc_ilog(_qinfo->dc_scale[0]),1);
+  nbits=OC_MAXI(ilog(_qinfo->dc_scale[0]),1);
   oggpackB_write(_opb,nbits-1,4);
   for(qi=0;qi<64;qi++)oggpackB_write(_opb,_qinfo->dc_scale[qi],nbits);
   /*Consolidate any duplicate base matrices.*/
@@ -98,7 +104,7 @@
   /*Now store quant ranges and their associated indices into the base matrix
      list.
      46 bits for VP3 matrices.*/
-  nbits=oc_ilog(nbase_mats-1);
+  nbits=ilog(nbase_mats-1);
   for(i=0;i<6;i++){
     qti=i/3;
     pli=i%3;
@@ -128,7 +134,7 @@
     }
     oggpackB_write(_opb,indices[qti][pli][0],nbits);
     for(qi=qri=0;qi<63;qri++){
-      oggpackB_write(_opb,qranges->sizes[qri]-1,oc_ilog(62-qi));
+      oggpackB_write(_opb,qranges->sizes[qri]-1,ilog(62-qi));
       qi+=qranges->sizes[qri];
       oggpackB_write(_opb,indices[qti][pli][qri+1],nbits);
     }
@@ -170,13 +176,13 @@
 	  
 	  /*Scale DC the coefficient from the proper table.*/
 	  q=((ogg_uint32_t)qinfo->dc_scale[qi]*base[0]/100)<<2;
-	  q=OC_CLAMPI(OC_DC_QUANT_MIN[qti],q,OC_QUANT_MAX);
+	  q=OC_CLAMPI(DC_QUANT_MIN[qti],q,OC_QUANT_MAX);
 	  pbi->quant_tables[qti][pli][qi][0]=(ogg_uint16_t)q;
 	  
 	  /*Now scale AC coefficients from the proper table.*/
 	  for(ci=1;ci<64;ci++){
 	    q=((ogg_uint32_t)qinfo->ac_scale[qi]*base[ci]/100)<<2;
-	    q=OC_CLAMPI(OC_AC_QUANT_MIN[qti],q,OC_QUANT_MAX);
+	    q=OC_CLAMPI(AC_QUANT_MIN[qti],q,OC_QUANT_MAX);
 	    pbi->quant_tables[qti][pli][qi][ci]=(ogg_uint16_t)q;
 	  }
 	  

Modified: trunk/theora/lib/enc/encoder_toplevel.c
===================================================================
--- trunk/theora/lib/enc/encoder_toplevel.c	2008-01-04 20:12:47 UTC (rev 14361)
+++ trunk/theora/lib/enc/encoder_toplevel.c	2008-01-04 20:20:56 UTC (rev 14362)
@@ -1054,6 +1054,8 @@
   cpi->readyflag = 1;
   
   cpi->pb.HeadersWritten = 0;
+  /*We overload this flag to track header output.*/
+  cpi->doneflag=-3;
 
   return 0;
 }
@@ -1066,7 +1068,7 @@
   CP_INSTANCE *cpi=(CP_INSTANCE *)(t->internal_encode);
 
   if(!cpi->readyflag)return OC_EINVAL;
-  if(cpi->doneflag)return OC_EINVAL;
+  if(cpi->doneflag>0)return OC_EINVAL;
 
   /* If frame size has changed, abort out for now */
   if (yuv->y_height != (int)cpi->pb.info.height ||
@@ -1151,7 +1153,7 @@
 
   if(!bytes)return(0);
   if(!cpi->packetflag)return(0);
-  if(cpi->doneflag)return(-1);
+  if(cpi->doneflag>0)return(-1);
 
 #ifndef LIBOGG2
   op->packet=oggpackB_get_buffer(cpi->oggbuffer);

Copied: trunk/theora/lib/enc/internal.c (from rev 14224, trunk/theora/lib/dec/internal.c)
===================================================================
--- trunk/theora/lib/enc/internal.c	                        (rev 0)
+++ trunk/theora/lib/enc/internal.c	2008-01-04 20:20:56 UTC (rev 14362)
@@ -0,0 +1,29 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+    last mod: $Id$
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+#include "../internal.h"
+#include "idct.h"
+
+
+int oc_ilog(unsigned _v){
+  int ret;
+  for(ret=0;_v;ret++)_v>>=1;
+  return ret;
+}



More information about the commits mailing list