[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