[xiph-commits] r14572 - in branches/theora-thusnelda: . examples include/theora lib lib/dec

xiphmont at svn.xiph.org xiphmont at svn.xiph.org
Mon Mar 10 21:54:41 PDT 2008


Author: xiphmont
Date: 2008-03-10 21:54:39 -0700 (Mon, 10 Mar 2008)
New Revision: 14572

Modified:
   branches/theora-thusnelda/configure.ac
   branches/theora-thusnelda/examples/player_example.c
   branches/theora-thusnelda/include/theora/theora.h
   branches/theora-thusnelda/include/theora/theoradec.h
   branches/theora-thusnelda/lib/Makefile.am
   branches/theora-thusnelda/lib/dec/decapiwrapper.c
   branches/theora-thusnelda/lib/dec/decint.h
   branches/theora-thusnelda/lib/dec/decode.c
   branches/theora-thusnelda/lib/internal.h
Log:
Begin addition of quick and dirty visualization output; just renders into the output frame whan appropriate decode ioctl is chosen.



Modified: branches/theora-thusnelda/configure.ac
===================================================================
--- branches/theora-thusnelda/configure.ac	2008-03-11 01:06:44 UTC (rev 14571)
+++ branches/theora-thusnelda/configure.ac	2008-03-11 04:54:39 UTC (rev 14572)
@@ -307,6 +307,25 @@
 AC_SUBST(PNG_CFLAGS)
 AC_SUBST(PNG_LIBS)
 
+dnl check for libcairo
+HAVE_CAIRO=no
+AC_ARG_ENABLE(telemetry,
+    [  --disable-telemetry           disable debugging output controls ],
+    [ ac_enable_telemetry=$enableval ], [ ac_enable_telemetry=no] )
+
+if test "x${ac_enable_telemetry}" = xyes; then
+   if test "x$HAVE_PKG_CONFIG" = "xyes"
+   then
+     PKG_CHECK_MODULES(CAIRO, cairo, HAVE_CAIRO=yes, HAVE_CAIRO=no)
+     AC_DEFINE([HAVE_CAIRO], [],  [libcairo is available for visual debugging output])  
+   fi
+   if test x$HAVE_CAIRO != xyes; then
+     AC_MSG_WARN([libcairo not found -- not compiling telemetry output support ])
+   fi
+   AC_SUBST(CAIRO_CFLAGS)
+   AC_SUBST(CAIRO_LIBS)
+fi
+
 dnl --------------------------------------------------
 dnl Overall build configuration options
 dnl --------------------------------------------------
@@ -426,6 +445,7 @@
     Encoding support: ........... ${ac_enable_encode}
     Floating point support: ..... ${ac_enable_float}
     Assembly optimization: ...... ${cpu_optimization}
+    Debugging telemetry: ........ ${ac_enable_telemetry}
     Build example code: ......... ${ac_enable_examples}
     API Documentation: .......... ${doc_build}
     Format Documentation: ....... ${spec_build}

Modified: branches/theora-thusnelda/examples/player_example.c
===================================================================
--- branches/theora-thusnelda/examples/player_example.c	2008-03-11 01:06:44 UTC (rev 14571)
+++ branches/theora-thusnelda/examples/player_example.c	2008-03-11 04:54:39 UTC (rev 14572)
@@ -590,6 +590,9 @@
     pp_level=pp_level_max;
     theora_control(&td,TH_DECCTL_SET_PPLEVEL,&pp_level,sizeof(pp_level));
     pp_inc=0;
+
+    theora_control(&td,TH_DECCTL_SET_TELEMETRY_MBMODE,NULL,0);
+    theora_control(&td,TH_DECCTL_SET_TELEMETRY_MV,NULL,0);
   }else{
     /* tear down the partial theora setup */
     theora_info_clear(&ti);

Modified: branches/theora-thusnelda/include/theora/theora.h
===================================================================
--- branches/theora-thusnelda/include/theora/theora.h	2008-03-11 01:06:44 UTC (rev 14571)
+++ branches/theora-thusnelda/include/theora/theora.h	2008-03-11 04:54:39 UTC (rev 14572)
@@ -322,6 +322,8 @@
  */
 #define TH_DECCTL_SET_GRANPOS (5)
 
+#define TH_DECCTL_SET_TELEMETRY_MBMODE (9)
+#define TH_DECCTL_SET_TELEMETRY_MV (11)
 
 /**\anchor encctlcodes
  * These are the available request codes for theora_control()

Modified: branches/theora-thusnelda/include/theora/theoradec.h
===================================================================
--- branches/theora-thusnelda/include/theora/theoradec.h	2008-03-11 01:06:44 UTC (rev 14571)
+++ branches/theora-thusnelda/include/theora/theoradec.h	2008-03-11 04:54:39 UTC (rev 14572)
@@ -84,8 +84,11 @@
 #define TH_DECCTL_SET_STRIPE_CB (7)
 /*@}*/
 
+#define TH_DECCTL_SET_TELEMETRY_MBMODE (9)
+#define TH_DECCTL_SET_TELEMETRY_MV (11)
 
 
+
 /**A callback function for striped decode.
  * This is a function pointer to an application-provided function that will be
  *  called each time a section of the image is fully decoded in

Modified: branches/theora-thusnelda/lib/Makefile.am
===================================================================
--- branches/theora-thusnelda/lib/Makefile.am	2008-03-11 01:06:44 UTC (rev 14571)
+++ branches/theora-thusnelda/lib/Makefile.am	2008-03-11 04:54:39 UTC (rev 14572)
@@ -1,6 +1,6 @@
 INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/lib -I$(top_srcdir)/lib/dec -I$(top_srcdir)/lib/enc
-AM_CFLAGS = $(OGG_CFLAGS)
-LIBADD = $(OGG_LIBS)
+AM_CFLAGS = $(OGG_CFLAGS) $(CAIRO_CFLAGS)
+LIBADD = $(OGG_LIBS) 
 
 EXTRA_DIST = \
         enc/x86_32/dct_decode_mmx.c \
@@ -126,7 +126,7 @@
   Version_script-dec
 libtheoradec_la_LDFLAGS = \
   -version-info @THDEC_LIB_CURRENT@:@THDEC_LIB_REVISION@:@THDEC_LIB_AGE@ \
-  @THEORADEC_LDFLAGS@
+  @THEORADEC_LDFLAGS@ @CAIRO_LIBS@
 
 libtheoraenc_la_SOURCES = \
   cpu.c \
@@ -146,7 +146,7 @@
   Version_script-old
 libtheora_la_LDFLAGS = \
   -version-info @TH_LIB_CURRENT@:@TH_LIB_REVISION@:@TH_LIB_AGE@ \
-  @THEORA_LDFLAGS@
+  @THEORA_LDFLAGS@ @CAIRO_LIBS@
 
 debug:
 	$(MAKE) all CFLAGS="@DEBUG@" 

Modified: branches/theora-thusnelda/lib/dec/decapiwrapper.c
===================================================================
--- branches/theora-thusnelda/lib/dec/decapiwrapper.c	2008-03-11 01:06:44 UTC (rev 14571)
+++ branches/theora-thusnelda/lib/dec/decapiwrapper.c	2008-03-11 04:54:39 UTC (rev 14572)
@@ -5,7 +5,7 @@
  * 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                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2008                *
  * by the Xiph.Org Foundation http://www.xiph.org/                  *
  *                                                                  *
  ********************************************************************
@@ -19,8 +19,13 @@
 #include <string.h>
 #include <limits.h>
 #include "apiwrapper.h"
+#include "decint.h"
 #include "theora/theoradec.h"
 
+#ifdef HAVE_CAIRO
+#include <cairo.h>
+#endif
+
 static void th_dec_api_clear(th_api_wrapper *_api){
   if(_api->setup)th_setup_free(_api->setup);
   if(_api->decode)th_decode_free(_api->decode);
@@ -29,10 +34,6 @@
 
 static void theora_decode_clear(theora_state *_td){
   if(_td->i!=NULL)theora_info_clear(_td->i);
-#ifdef _TH_DEBUG_
-  fclose(debugout);
-  debugout=NULL;
-#endif
   memset(_td,0,sizeof(*_td));
 }
 
@@ -131,10 +132,6 @@
   th_info         info;
   int             ret;
 
-#ifdef _TH_DEBUG_
-  debugout = fopen("theoradec-debugout.txt","w");
-#endif
-
   api=(th_api_wrapper *)_ci->codec_setup;
   /*Allocate an API wrapper struct on demand, since it will not also include a
      theora_info struct like the ones that are used in a theora_state struct.*/
@@ -170,10 +167,6 @@
   api=(th_api_wrapper *)_td->i->codec_setup;
   ret=th_decode_packetin(api->decode,_op,&gp);
 
-#ifdef _TH_DEBUG_
-  dframe++;
-#endif 
-
   if(ret<0)return OC_BADPACKET;
   _td->granulepos=gp;
   return 0;
@@ -181,11 +174,116 @@
 
 int theora_decode_YUVout(theora_state *_td,yuv_buffer *_yuv){
   th_api_wrapper  *api;
+  th_dec_ctx      *decode;
   th_ycbcr_buffer  buf;
   int              ret;
 
   api=(th_api_wrapper *)_td->i->codec_setup;
-  ret=th_decode_ycbcr_out(api->decode,buf);
+  decode = (th_dec_ctx *)api->decode;
+  ret=th_decode_ycbcr_out(decode,buf);
+
+#ifdef HAVE_CAIRO
+  /* If telemetry ioctls are active, we need to draw to the output
+     buffer.  Stuff the plane into cairo. */
+  if(decode->telemetry){
+    /* 4:2:0 */
+    int w = buf[0].width;
+    int h = buf[0].height;
+    int x, y;
+    cairo_surface_t *cs=
+      cairo_image_surface_create(CAIRO_FORMAT_RGB24,w,h);
+
+    /* lazy data buffer init */
+    if(!decode->telemetry_frame_data)
+      decode->telemetry_frame_data = malloc(w*h*3*sizeof(*decode->telemetry_frame_data));
+
+    /* sadly, no YUV support in Cairo; convert into the RGB buffer */
+    unsigned char *data = cairo_image_surface_get_data(cs);
+    unsigned cstride = cairo_image_surface_get_stride(cs);
+    for(y=0;y<h;y+=2){
+      unsigned char *Ya = buf[0].data + y*buf[0].ystride;
+      unsigned char *Yb = buf[0].data + (y+1)*buf[0].ystride;
+      unsigned char *U  = buf[1].data + (y>>1)*buf[1].ystride;
+      unsigned char *V  = buf[2].data + (y>>1)*buf[2].ystride;
+      unsigned char *Ca = data + y*cstride; 
+      unsigned char *Cb = data + (y+1)*cstride; 
+      for(x=0;x<w*4;x+=8){
+	Ca[x+2] = OC_CLAMP255((Ya[0]*76309 + V[0]*104597 - 14609351)>>16);
+	Ca[x+1] = OC_CLAMP255((Ya[0]*76309 - U[0]*25674  - V[0]*53279 + 8885109)>>16); 
+	Ca[x+0] = OC_CLAMP255((Ya[0]*76309 + U[0]*132201 - 18142724)>>16);
+
+	Ca[x+6] = OC_CLAMP255((Ya[1]*76309 + V[0]*104597 - 14609351)>>16);
+	Ca[x+5] = OC_CLAMP255((Ya[1]*76309 - U[0]*25674  - V[0]*53279 + 8885109)>>16);
+	Ca[x+4] = OC_CLAMP255((Ya[1]*76309 + U[0]*132201 - 18142724)>>16);
+
+	Cb[x+2] = OC_CLAMP255((Yb[0]*76309 + V[0]*104597 - 14609351)>>16);
+	Cb[x+1] = OC_CLAMP255((Yb[0]*76309 - U[0]*25674  - V[0]*53279 + 8885109)>>16);
+	Cb[x+0] = OC_CLAMP255((Yb[0]*76309 + U[0]*132201 - 18142724)>>16);
+
+	Cb[x+6] = OC_CLAMP255((Yb[1]*76309 + V[0]*104597 - 14609351)>>16);
+	Cb[x+5] = OC_CLAMP255((Yb[1]*76309 - U[0]*25674  - V[0]*53279 + 8885109)>>16);
+	Cb[x+4] = OC_CLAMP255((Yb[1]*76309 + U[0]*132201 - 18142724)>>16);
+
+	Ya+=2;
+	Yb+=2;
+	U++;
+	V++;
+      }
+    }
+
+    {
+      cairo_t *c = cairo_create(cs);
+      cairo_set_source_rgba(c,1.,0,0,.5);
+      cairo_rectangle(c,100,100,100,100);
+      cairo_fill(c);
+      cairo_surface_flush(cs);
+      cairo_destroy(c);
+    }
+
+    /* out of the Cairo plane into the telemetry YUV buffer */
+    buf[0].data = decode->telemetry_frame_data;
+    buf[1].data = decode->telemetry_frame_data+h*buf[0].ystride;
+    buf[2].data = decode->telemetry_frame_data+h*buf[0].ystride+h/2*buf[1].ystride;
+
+    for(y=0;y<h;y+=2){
+      unsigned char *Ya = buf[0].data + y*buf[0].ystride;
+      unsigned char *Yb = buf[0].data + (y+1)*buf[0].ystride;
+      unsigned char *U  = buf[1].data + (y>>1)*buf[1].ystride;
+      unsigned char *V  = buf[2].data + (y>>1)*buf[2].ystride;
+      unsigned char *Ca = data + y*cstride; 
+      unsigned char *Cb = data + (y+1)*cstride; 
+      for(x=0;x<w*4;x+=8){
+
+	Ya[0] = ((Ca[2]*16829 + Ca[1]*33039 + Ca[0]*6416)>>16) + 16;
+	Ya[1] = ((Ca[6]*16829 + Ca[5]*33039 + Ca[4]*6416)>>16) + 16;
+	Yb[0] = ((Cb[2]*16829 + Cb[1]*33039 + Cb[0]*6416)>>16) + 16;
+	Yb[1] = ((Cb[6]*16829 + Cb[5]*33039 + Cb[4]*6416)>>16) + 16;
+
+	U[0] = ((-Ca[2]*9714 - Ca[1]*19070 + Ca[0]*28784 +
+		 -Ca[6]*9714 - Ca[5]*19070 + Ca[4]*28784 +
+		 -Cb[2]*9714 - Cb[1]*19070 + Cb[0]*28784 +
+		 -Cb[6]*9714 - Cb[5]*19070 + Cb[4]*28784)>>18) + 128;
+
+	V[0] = ((Ca[2]*28784 - Ca[1]*24103 - Ca[0]*4681 +
+		 Ca[6]*28784 - Ca[5]*24103 - Ca[4]*4681 +
+		 Cb[2]*28784 - Cb[1]*24103 - Cb[0]*4681 +
+		 Cb[6]*28784 - Cb[5]*24103 - Cb[4]*4681)>>18) + 128;
+
+	Ya+=2;
+	Yb+=2;
+	U++;
+	V++;
+	Ca+=8;
+	Cb+=8;
+      }
+    }
+
+
+    /* Finished.  Destroy the surface. */
+    cairo_surface_destroy(cs);
+  }
+#endif
+
   if(ret>=0){
     _yuv->y_width=buf[0].width;
     _yuv->y_height=buf[0].height;

Modified: branches/theora-thusnelda/lib/dec/decint.h
===================================================================
--- branches/theora-thusnelda/lib/dec/decint.h	2008-03-11 01:06:44 UTC (rev 14571)
+++ branches/theora-thusnelda/lib/dec/decint.h	2008-03-11 04:54:39 UTC (rev 14572)
@@ -86,9 +86,17 @@
   /*Whether or not the post-processsed frame buffer has space for chroma.*/
   int                      pp_frame_has_chroma;
   /*The buffer used for the post-processed frame.*/
-  th_ycbcr_buffer      pp_frame_buf;
+  th_ycbcr_buffer          pp_frame_buf;
   /*The striped decode callback function.*/
-  th_stripe_callback   stripe_cb;
+  th_stripe_callback       stripe_cb;
+
+#ifdef HAVE_CAIRO
+  /* output metrics for debugging */
+  int                      telemetry;
+  int                      telemetry_mbmode;
+  int                      telemetry_mv;
+  unsigned char           *telemetry_frame_data;
+#endif
 };
 
 /*Fix-ups for the libogg1 API, which returns -1 when there are insufficient

Modified: branches/theora-thusnelda/lib/dec/decode.c
===================================================================
--- branches/theora-thusnelda/lib/dec/decode.c	2008-03-11 01:06:44 UTC (rev 14571)
+++ branches/theora-thusnelda/lib/dec/decode.c	2008-03-11 04:54:39 UTC (rev 14572)
@@ -5,7 +5,7 @@
  * 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                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2008                *
  * by the Xiph.Org Foundation http://www.xiph.org/                  *
  *                                                                  *
  ********************************************************************
@@ -255,6 +255,7 @@
   _dec->dc_qis=NULL;
   _dec->variances=NULL;
   _dec->pp_frame_data=NULL;
+  _dec->telemetry_frame_data=NULL;
   _dec->stripe_cb.ctx=NULL;
   _dec->stripe_cb.stripe_decoded=NULL;
   return 0;
@@ -262,6 +263,8 @@
 
 static void oc_dec_clear(oc_dec_ctx *_dec){
   _ogg_free(_dec->pp_frame_data);
+  if(_dec->telemetry_frame_data)
+    _ogg_free(_dec->telemetry_frame_data);
   _ogg_free(_dec->variances);
   _ogg_free(_dec->dc_qis);
   oc_free_2d(_dec->extra_bits);
@@ -2077,44 +2080,56 @@
 int th_decode_ctl(th_dec_ctx *_dec,int _req,void *_buf,
  size_t _buf_sz){
   switch(_req){
-    case TH_DECCTL_GET_PPLEVEL_MAX:{
-      if(_dec==NULL||_buf==NULL)return TH_EFAULT;
-      if(_buf_sz!=sizeof(int))return TH_EINVAL;
-      (*(int *)_buf)=OC_PP_LEVEL_MAX;
-      return 0;
-    }break;
-    case TH_DECCTL_SET_PPLEVEL:{
-      int pp_level;
-      if(_dec==NULL||_buf==NULL)return TH_EFAULT;
-      if(_buf_sz!=sizeof(int))return TH_EINVAL;
-      pp_level=*(int *)_buf;
-      if(pp_level<0||pp_level>OC_PP_LEVEL_MAX)return TH_EINVAL;
-      _dec->pp_level=pp_level;
-      return 0;
-    }break;
-    case TH_DECCTL_SET_GRANPOS:{
-      ogg_int64_t granpos;
-      if(_dec==NULL||_buf==NULL)return TH_EFAULT;
-      if(_buf_sz!=sizeof(ogg_int64_t))return TH_EINVAL;
-      granpos=*(ogg_int64_t *)_buf;
-      if(granpos<0)return TH_EINVAL;
-      _dec->state.granpos=granpos;
-      _dec->state.keyframe_num=
-       granpos>>_dec->state.info.keyframe_granule_shift;
-      _dec->state.curframe_num=_dec->state.keyframe_num+
-       (granpos&(1<<_dec->state.info.keyframe_granule_shift)-1);
-      return 0;
-    }break;
-    case TH_DECCTL_SET_STRIPE_CB:{
-      th_stripe_callback *cb;
-      if(_dec==NULL||_buf==NULL)return TH_EFAULT;
-      if(_buf_sz!=sizeof(th_stripe_callback))return TH_EINVAL;
-      cb=(th_stripe_callback *)_buf;
-      _dec->stripe_cb.ctx=cb->ctx;
-      _dec->stripe_cb.stripe_decoded=cb->stripe_decoded;
-      return 0;
-    }break;
-    default:return TH_EIMPL;
+  case TH_DECCTL_GET_PPLEVEL_MAX:{
+    if(_dec==NULL||_buf==NULL)return TH_EFAULT;
+    if(_buf_sz!=sizeof(int))return TH_EINVAL;
+    (*(int *)_buf)=OC_PP_LEVEL_MAX;
+    return 0;
+  }break;
+  case TH_DECCTL_SET_PPLEVEL:{
+    int pp_level;
+    if(_dec==NULL||_buf==NULL)return TH_EFAULT;
+    if(_buf_sz!=sizeof(int))return TH_EINVAL;
+    pp_level=*(int *)_buf;
+    if(pp_level<0||pp_level>OC_PP_LEVEL_MAX)return TH_EINVAL;
+    _dec->pp_level=pp_level;
+    return 0;
+  }break;
+  case TH_DECCTL_SET_GRANPOS:{
+    ogg_int64_t granpos;
+    if(_dec==NULL||_buf==NULL)return TH_EFAULT;
+    if(_buf_sz!=sizeof(ogg_int64_t))return TH_EINVAL;
+    granpos=*(ogg_int64_t *)_buf;
+    if(granpos<0)return TH_EINVAL;
+    _dec->state.granpos=granpos;
+    _dec->state.keyframe_num=
+      granpos>>_dec->state.info.keyframe_granule_shift;
+    _dec->state.curframe_num=_dec->state.keyframe_num+
+      (granpos&(1<<_dec->state.info.keyframe_granule_shift)-1);
+    return 0;
+  }break;
+  case TH_DECCTL_SET_STRIPE_CB:{
+    th_stripe_callback *cb;
+    if(_dec==NULL||_buf==NULL)return TH_EFAULT;
+    if(_buf_sz!=sizeof(th_stripe_callback))return TH_EINVAL;
+    cb=(th_stripe_callback *)_buf;
+    _dec->stripe_cb.ctx=cb->ctx;
+    _dec->stripe_cb.stripe_decoded=cb->stripe_decoded;
+    return 0;
+  }break;
+#ifdef HAVE_CAIRO
+  case TH_DECCTL_SET_TELEMETRY_MBMODE:{
+    _dec->telemetry = 1;
+    _dec->telemetry_mbmode = 1;
+    return 0;
+  }break;
+  case TH_DECCTL_SET_TELEMETRY_MV:{
+    _dec->telemetry = 1;
+    _dec->telemetry_mv = 1;
+    return 0;
+  }break;
+#endif
+  default:return TH_EIMPL;
   }
 }
 

Modified: branches/theora-thusnelda/lib/internal.h
===================================================================
--- branches/theora-thusnelda/lib/internal.h	2008-03-11 01:06:44 UTC (rev 14571)
+++ branches/theora-thusnelda/lib/internal.h	2008-03-11 04:54:39 UTC (rev 14572)
@@ -43,7 +43,7 @@
 # endif
 
 /*This library's version.*/
-# define OC_VENDOR_STRING "Xiph.Org libTheora I 20071025 3 2 1"
+# define OC_VENDOR_STRING "Xiph.Org libThusnelda I 20080310"
 
 /*Theora bitstream version.*/
 # define TH_VERSION_MAJOR (3)



More information about the commits mailing list