[xiph-commits] r11667 - trunk/theora-exp/lib
msmith at svn.xiph.org
msmith at svn.xiph.org
Thu Jun 29 07:50:52 PDT 2006
Author: msmith
Date: 2006-06-29 07:50:46 -0700 (Thu, 29 Jun 2006)
New Revision: 11667
Added:
trunk/theora-exp/lib/apiwrapper.c
Modified:
trunk/theora-exp/lib/Makefile.am
Log:
Add a decode-side API wrapper for the old libtheora API.
Allows libtheora-using apps to link to theoradec and get the (better, faster)
theora-exp decoder. Very minimally tested; a few things still need cleanup.
Modified: trunk/theora-exp/lib/Makefile.am
===================================================================
--- trunk/theora-exp/lib/Makefile.am 2006-06-29 11:46:12 UTC (rev 11666)
+++ trunk/theora-exp/lib/Makefile.am 2006-06-29 14:50:46 UTC (rev 11667)
@@ -45,6 +45,7 @@
x86/x86int.h
libtheoradec_la_SOURCES = \
+ apiwrapper.c \
decinfo.c \
decode.c \
dequant.c \
Added: trunk/theora-exp/lib/apiwrapper.c
===================================================================
--- trunk/theora-exp/lib/apiwrapper.c 2006-06-29 11:46:12 UTC (rev 11666)
+++ trunk/theora-exp/lib/apiwrapper.c 2006-06-29 14:50:46 UTC (rev 11667)
@@ -0,0 +1,233 @@
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <ogg/ogg.h>
+
+/* libtheora header */
+#include <theora/theora.h>
+
+/* theora-exp header */
+#include "theora/theoradec.h"
+
+/* TODO: Use appropriate allocation functions? */
+
+typedef struct {
+ th_info info;
+
+ th_setup_info *setup;
+
+ th_dec_ctx *decode;
+
+} th_api_wrapper;
+
+const char *theora_version_string(void) {
+ return th_version_string();
+}
+
+ogg_uint32_t theora_version_number(void) {
+ return th_version_number();
+}
+
+void theora_info_init(theora_info *c)
+{
+ th_api_wrapper *api = calloc(1, sizeof(th_api_wrapper));
+
+ memset(c, 0, sizeof(theora_info));
+
+ c->codec_setup = api;
+
+ th_info_init(&api->info);
+}
+
+void theora_info_clear (theora_info *c)
+{
+ th_api_wrapper *api = (th_api_wrapper *)c->codec_setup;
+
+ if (api->setup)
+ th_setup_free(api->setup);
+
+ if (api->decode)
+ th_decode_free(api->decode);
+
+ th_info_clear(&api->info);
+
+ free (c->codec_setup);
+
+ memset(c, 0, sizeof(theora_info));
+}
+
+/* TODO: see if this is ok - which bits are we allowed to clear here? */
+void theora_clear(theora_state *t)
+{
+ th_api_wrapper *api = (th_api_wrapper *)t->i->codec_setup;
+
+ api->decode = NULL; /* Should we clear this here? Right now we do it in
+ info_clear. TODO */
+
+}
+
+int theora_decode_init (theora_state *th, theora_info *c)
+{
+ th_api_wrapper *api = (th_api_wrapper *)c->codec_setup;
+
+ th->internal_encode = NULL;
+ th->internal_decode = NULL; /* We don't need this */
+ th->i = c;
+ th->granulepos = 0;
+
+ api->decode = th_decode_alloc(&api->info, api->setup);
+}
+
+int theora_decode_header(theora_info *ci, theora_comment *cc, ogg_packet *op)
+{
+ th_api_wrapper *api = (th_api_wrapper *)ci->codec_setup;
+ th_info *info = &api->info;
+ int ret;
+
+ /* Rely on the fact that theora_comment and th_comment structures are
+ * actually identical. Take care not to break this invariant unless you
+ * change the code here as well! */
+
+ ret = th_decode_headerin(info, (th_comment *)cc, &api->setup, op);
+
+ if (ret < 0)
+ return ret; // TODO: map_ret_val(ret);
+
+ 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;
+ }
+
+ ci->target_bitrate = info->target_bitrate;
+ ci->quality = info->quality;
+
+ 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->keyframe_frequency_force = 1 << info->keyframe_granule_shift;
+
+ ci->version_major = info->version_major;
+ ci->version_minor = info->version_minor;
+ ci->version_subminor = info->version_subminor;
+
+ return 0;
+}
+
+int theora_decode_packetin(theora_state *th, ogg_packet *op)
+{
+ th_api_wrapper *api = (th_api_wrapper *)th->i->codec_setup;
+ int ret;
+ ogg_int64_t gp;
+
+ ret = th_decode_packetin(api->decode, op, &gp);
+
+ if (ret)
+ return OC_BADPACKET;
+
+ th->granulepos = gp;
+
+ return 0;
+}
+
+int theora_decode_YUVout(theora_state *th, yuv_buffer *yuv)
+{
+ th_api_wrapper *api = (th_api_wrapper *)th->i->codec_setup;
+ int ret;
+ th_ycbcr_buffer buf;
+
+ ret = th_decode_ycbcr_out(api->decode, buf);
+
+ if (!ret) {
+ /* Convert... */
+ yuv->y_width = buf[0].width;
+ yuv->y_height = buf[0].height;
+ yuv->y_stride = buf[0].ystride;
+
+ yuv->uv_width = buf[1].width;
+ yuv->uv_height = buf[1].height;
+ yuv->uv_stride = buf[1].ystride;
+
+ yuv->y = buf[0].data;
+ yuv->u = buf[1].data;
+ yuv->v = buf[2].data;
+ }
+
+ return ret;
+}
+
+int theora_packet_isheader(ogg_packet *op)
+{
+ return th_packet_isheader(op);
+}
+
+int theora_packet_iskeyframe(ogg_packet *op)
+{
+ return th_packet_iskeyframe(op);
+}
+
+int theora_granule_shift (theora_info *ti)
+{
+ return ((th_api_wrapper *)ti->codec_setup)->info.keyframe_granule_shift;
+}
+
+ogg_int64_t theora_granule_frame (theora_state *th, ogg_int64_t granulepos)
+{
+ return th_granule_frame (((th_api_wrapper *)th->i->codec_setup)->decode,
+ granulepos);
+}
+
+double theora_granule_time(theora_state *th, ogg_int64_t granulepos)
+{
+ return th_granule_time (((th_api_wrapper *)th->i->codec_setup)->decode,
+ granulepos);
+}
+
+void theora_comment_init(theora_comment *tc)
+{
+ th_comment_init((th_comment *)tc);
+}
+
+char *theora_comment_query(theora_comment *tc, char *tag, int count)
+{
+ return th_comment_query((th_comment *)tc, tag, count);
+}
+
+int theora_comment_query_count(theora_comment *tc, char *tag)
+{
+ return th_comment_query_count((th_comment *)tc, tag);
+}
+
+void theora_comment_clear(theora_comment *tc)
+{
+ th_comment_clear((th_comment *)tc);
+}
+
More information about the commits
mailing list