[xiph-commits] r16350 - in trunk/ffmpeg2theora: . src

j at svn.xiph.org j at svn.xiph.org
Tue Jul 28 06:46:53 PDT 2009


Author: j
Date: 2009-07-28 06:46:53 -0700 (Tue, 28 Jul 2009)
New Revision: 16350

Modified:
   trunk/ffmpeg2theora/ChangeLog
   trunk/ffmpeg2theora/SConstruct
   trunk/ffmpeg2theora/ffmpeg2theora.1
   trunk/ffmpeg2theora/src/ffmpeg2theora.c
   trunk/ffmpeg2theora/src/ffmpeg2theora.h
   trunk/ffmpeg2theora/src/theorautils.c
   trunk/ffmpeg2theora/src/theorautils.h
Log:
use new libtheoraenc api
add --soft-target, --buf-delay



Modified: trunk/ffmpeg2theora/ChangeLog
===================================================================
--- trunk/ffmpeg2theora/ChangeLog	2009-07-28 09:11:16 UTC (rev 16349)
+++ trunk/ffmpeg2theora/ChangeLog	2009-07-28 13:46:53 UTC (rev 16350)
@@ -5,6 +5,8 @@
     - frontend mode outputs one json dict per line now
     - select video stream if input has more than one video(--videostream N)
     - update to ffmpeg trunk and new ffmepg api
+    - use new libtheora encoding api
+      add new encoding options --soft-target, --buf-delay
 
 0.24 2009-03-12
     - fix to make --max_size --no_upscaling work

Modified: trunk/ffmpeg2theora/SConstruct
===================================================================
--- trunk/ffmpeg2theora/SConstruct	2009-07-28 09:11:16 UTC (rev 16349)
+++ trunk/ffmpeg2theora/SConstruct	2009-07-28 13:46:53 UTC (rev 16350)
@@ -107,7 +107,7 @@
    print 'pkg-config >= %s not found.' % pkgconfig_version 
    Exit(1)
 
-XIPH_LIBS="ogg >= 1.1 vorbis vorbisenc theora >= 1.0beta1"
+XIPH_LIBS="ogg >= 1.1 vorbis vorbisenc theoradec theoraenc"
 
 if not conf.CheckPKG(XIPH_LIBS): 
   print 'some xiph libs are missing, ffmpeg2theora depends on %s' % XIPH_LIBS

Modified: trunk/ffmpeg2theora/ffmpeg2theora.1
===================================================================
--- trunk/ffmpeg2theora/ffmpeg2theora.1	2009-07-28 09:11:16 UTC (rev 16349)
+++ trunk/ffmpeg2theora/ffmpeg2theora.1	2009-07-28 13:46:53 UTC (rev 16350)
@@ -57,6 +57,14 @@
 .B \-V, \-\-videobitrate
 [1 to 16778] Set encoding bitrate for video (in kb/s).
 .TP
+.B\-\-soft\-target
+Use a large reservoir and treat the rate
+as a soft target; rate control is less
+strict but resulting quality is usually
+higher/smoother overall. Soft target also
+allows an optional \-v setting to specify
+a minimum allowed quality.
+.TP
 .B \-\-optimize
 Optimize output Theora video, using a full search for motion vectors
 instead of a hierarchical one. This can reduce video bitrate about 5%,
@@ -85,7 +93,21 @@
 sharper.
 .TP
 .B \-K, \-\-keyint
-[8 to 65536] Set keyframe interval (default: 64).
+[8 to 2147483647] Set keyframe interval (default: 64).
+.TP
+.B \-d, \-\-buf-delay
+Buffer delay (in frames). Longer delays
+allow smoother rate adaptation and provide
+better overall quality, but require more
+client side buffering and add latency. The
+default value is the keyframe interval for
+one-pass encoding (or somewhat larger if
+\-\-soft\-target is used) and infinite for
+two\-pass encoding. (only works in bitrate mode)
+.TP
+.B \-\-no-upscaling
+only scale video or resample audio if input is
+bigger than provided parameter
 .SS Video transfer options:
 .TP
 .B \-\-pp

Modified: trunk/ffmpeg2theora/src/ffmpeg2theora.c
===================================================================
--- trunk/ffmpeg2theora/src/ffmpeg2theora.c	2009-07-28 09:11:16 UTC (rev 16349)
+++ trunk/ffmpeg2theora/src/ffmpeg2theora.c	2009-07-28 13:46:53 UTC (rev 16350)
@@ -35,7 +35,7 @@
 #include "libswscale/swscale.h"
 #include "libpostproc/postprocess.h"
 
-#include "theora/theora.h"
+#include "theora/theoraenc.h"
 #include "vorbis/codec.h"
 #include "vorbis/vorbisenc.h"
 
@@ -52,6 +52,7 @@
 enum {
     NULL_FLAG,
     DEINTERLACE_FLAG,
+    SOFTTARGET_FLAG,
     OPTIMIZE_FLAG,
     SYNC_FLAG,
     NOAUDIO_FLAG,
@@ -111,6 +112,12 @@
 static int padcolor[3] = { 16, 128, 128 };
 
 
+static int ilog(unsigned _v){
+  int ret;
+  for(ret=0;_v;ret++)_v>>=1;
+  return ret;
+}
+
 /**
  * Allocate and initialise an AVFrame.
  */
@@ -169,9 +176,8 @@
         this->videostream = -1;
         this->picture_width=0;      // set to 0 to not resize the output
         this->picture_height=0;      // set to 0 to not resize the output
-        this->video_quality=rint(5*6.3); // video quality 5
+        this->video_quality=-1; // defaults set later
         this->video_bitrate=0;
-        this->sharpness=0;
         this->keyint=64;
         this->force_input_fps.num = -1;
         this->force_input_fps.den = 1;
@@ -181,6 +187,8 @@
         this->frame_aspect=0;
         this->max_size=-1;
         this->deinterlace=0; // auto by default, if input is flaged as interlaced it will deinterlace.
+        this->soft_target=0;
+        this->buf_delay=-1;
         this->vhook=0;
         this->framerate_new.num = -1;
         this->framerate_new.den = 1;
@@ -283,27 +291,30 @@
     }
 }
 
-static void prepare_yuv_buffer(ff2theora this, yuv_buffer *yuv, AVFrame *frame) {
+static void prepare_ycbcr_buffer(ff2theora this, th_ycbcr_buffer ycbcr, AVFrame *frame) {
     int i;
     /* pysical pages */
-    yuv->y_width = this->frame_width;
-    yuv->y_height = this->frame_height;
-    yuv->y_stride = frame->linesize[0];
+    ycbcr[0].width = this->frame_width;
+    ycbcr[0].height = this->frame_height;
+    ycbcr[0].stride = frame->linesize[0];
+    ycbcr[0].data = frame->data[0];
 
-    yuv->uv_width = this->frame_width / 2;
-    yuv->uv_height = this->frame_height / 2;
-    yuv->uv_stride = frame->linesize[1];
+    ycbcr[1].width = this->frame_width / 2;
+    ycbcr[1].height = this->frame_height / 2;
+    ycbcr[1].stride = frame->linesize[1];
+    ycbcr[1].data = frame->data[1];
 
-    yuv->y = frame->data[0];
-    yuv->u = frame->data[1];
-    yuv->v = frame->data[2];
+    ycbcr[2].width = this->frame_width / 2;
+    ycbcr[2].height = this->frame_height / 2;
+    ycbcr[2].stride = frame->linesize[1];
+    ycbcr[2].data = frame->data[2];
 
     if (this->y_lut_used) {
-        lut_apply(this->y_lut, yuv->y, yuv->y, yuv->y_width, yuv->y_height, yuv->y_stride);
+        lut_apply(this->y_lut, ycbcr[0].data, ycbcr[0].data, ycbcr[0].width, ycbcr[0].height, ycbcr[0].stride);
     }
     if (this->uv_lut_used) {
-        lut_apply(this->uv_lut, yuv->u, yuv->u, yuv->uv_width, yuv->uv_height, yuv->uv_stride);
-        lut_apply(this->uv_lut, yuv->v, yuv->v, yuv->uv_width, yuv->uv_height, yuv->uv_stride);
+        lut_apply(this->uv_lut, ycbcr[1].data, ycbcr[1].data, ycbcr[1].width, ycbcr[1].height, ycbcr[1].stride);
+        lut_apply(this->uv_lut, ycbcr[2].data, ycbcr[2].data, ycbcr[2].width, ycbcr[2].height, ycbcr[2].stride);
     }
 }
 
@@ -735,10 +746,11 @@
         this->frame_width = ((this->picture_width + 15) >>4)<<4;
         this->frame_height = ((this->picture_height + 15) >>4)<<4;
 
+        /*Force the offsets to be even so that chroma samples line up like we
+           expect.*/
+        this->frame_x_offset = this->frame_width-this->picture_width>>1&~1;
+        this->frame_y_offset = this->frame_height-this->picture_height>>1&~1;
 
-        this->frame_x_offset = 0;
-        this->frame_y_offset = 0;
-
         if (this->frame_width > 0 || this->frame_height > 0) {
             this->sws_colorspace_ctx = sws_getContext(
                             display_width, display_height, venc->pix_fmt,
@@ -944,14 +956,16 @@
             /* video settings here */
             /* config file? commandline options? v2v presets? */
 
-            theora_info_init(&info.ti);
+            th_info_init(&info.ti);
 
-            info.ti.width = this->frame_width;
-            info.ti.height = this->frame_height;
-            info.ti.frame_width = this->picture_width;
-            info.ti.frame_height = this->picture_height;
-            info.ti.offset_x = this->frame_x_offset;
-            info.ti.offset_y = this->frame_y_offset;
+            //encoded size
+            info.ti.frame_width = this->frame_width;
+            info.ti.frame_height = this->frame_height;
+            //displayed size
+            info.ti.pic_width = this->picture_width;
+            info.ti.pic_height = this->picture_height;
+            info.ti.pic_x = this->frame_x_offset;
+            info.ti.pic_y = this->frame_y_offset;
             if (this->framerate_new.num > 0) {
                 // new framerate is interger only right now,
                 // so denominator is always 1
@@ -965,17 +979,28 @@
             /* this is pixel aspect ratio */
             info.ti.aspect_numerator=this->aspect_numerator;
             info.ti.aspect_denominator=this->aspect_denominator;
+            /*
             // FIXME: is all input material with fps==25 OC_CS_ITU_REC_470BG?
             // guess not, commandline option to select colorspace would be the best.
             if ((this->fps-25)<1)
-                info.ti.colorspace = OC_CS_ITU_REC_470BG;
+                info.ti.colorspace = TH_CS_ITU_REC_470BG;
             else if (abs(this->fps-30)<1)
-                info.ti.colorspace = OC_CS_ITU_REC_470M;
+                info.ti.colorspace = TH_CS_ITU_REC_470M;
             else
-                info.ti.colorspace = OC_CS_UNSPECIFIED;
+            */
+            info.ti.colorspace = TH_CS_UNSPECIFIED;
 
-            info.ti.target_bitrate = this->video_bitrate;
+            /*Account for the Ogg page overhead.
+              This is 1 byte per 255 for lacing values, plus 26 bytes per 4096 bytes for
+               the page header, plus approximately 1/2 byte per packet (not accounted for
+               here).*/
+            info.ti.target_bitrate=(int)(64870*(ogg_int64_t)this->video_bitrate>>16);
+
             info.ti.quality = this->video_quality;
+            info.ti.keyframe_granule_shift = ilog(this->keyint-1);
+            info.ti.pixel_fmt = TH_PF_420;
+
+            /* no longer in new encoder api
             info.ti.dropframes_p = 0;
             info.ti.keyframe_auto_p = 1;
             info.ti.keyframe_frequency = this->keyint;
@@ -986,7 +1011,47 @@
             info.ti.noise_sensitivity = 1;
             // range 0-2, 0 sharp, 2 less sharp,less bandwidth
             info.ti.sharpness = this->sharpness;
+            */
+            info.td = th_encode_alloc(&info.ti);
 
+            if (info.speed_level >= 0) {
+                int max_speed_level;
+                th_encode_ctl(info.td, TH_ENCCTL_GET_SPLEVEL_MAX, &max_speed_level, sizeof(int));
+                if (info.speed_level > max_speed_level)
+                    info.speed_level = max_speed_level;
+                th_encode_ctl(info.td, TH_ENCCTL_SET_SPLEVEL, &info.speed_level, sizeof(int));
+            }
+            if(this->buf_delay >= 0){
+                ret = th_encode_ctl(info.td, TH_ENCCTL_SET_RATE_BUFFER,
+                                    &this->buf_delay, sizeof(this->buf_delay));
+                if(ret < 0){
+                    fprintf(stderr, "Warning: could not set desired buffer delay. %d\n", ret);
+                }
+            }
+            /* setting just the granule shift only allows power-of-two keyframe
+               spacing.  Set the actual requested spacing. */
+            ret = th_encode_ctl(info.td, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE,
+                                &this->keyint, sizeof(this->keyint-1));
+            if(ret<0){
+                fprintf(stderr,"Could not set keyframe interval to %d.\n",(int)this->keyint);
+            }
+            if(this->soft_target){
+              /* reverse the rate control flags to favor a 'long time' strategy */
+              int arg = TH_RATECTL_CAP_UNDERFLOW;
+              ret = th_encode_ctl(info.td, TH_ENCCTL_SET_RATE_FLAGS, &arg, sizeof(arg));
+              if(ret<0)
+                fprintf(stderr, "Could not set encoder flags for --soft-target\n");
+                /* Default buffer control is overridden on two-pass */
+                if(this->buf_delay<0){
+                if((this->keyint*7>>1)>5*this->framerate_new.num/this->framerate_new.den)
+                  arg = this->keyint*7>>1;
+                else
+                  arg = 30*this->framerate_new.num/this->framerate_new.den;
+                ret = th_encode_ctl(info.td, TH_ENCCTL_SET_RATE_BUFFER, &arg,sizeof(arg));
+                if(ret<0)
+                  fprintf(stderr, "Could not set rate control buffer for --soft-target\n");
+              }
+            }
         }
         /* audio settings here */
         info.channels = this->channels;
@@ -1101,7 +1166,7 @@
                 }
                 while(video_eos || avpkt.size > 0) {
                     int dups = 0;
-                    yuv_buffer yuv;
+                    static th_ycbcr_buffer ycbcr;
                     len1 = avcodec_decode_video2(vstream->codec, frame, &got_picture, &avpkt);
                     if (len1>=0) {
                         if (got_picture) {
@@ -1218,9 +1283,9 @@
 
                     if (!first) {
                         if (got_picture || video_eos) {
-                            prepare_yuv_buffer(this, &yuv, output_buffered);
+                            prepare_ycbcr_buffer(this, ycbcr, output_buffered);
                             do {
-                                oggmux_add_video(&info, &yuv, video_eos);
+                                oggmux_add_video(&info, ycbcr, video_eos);
                                 if(video_eos) {
                                     video_done = 1;
                                 }
@@ -1540,11 +1605,11 @@
         //  "v2v presets - more info at http://wiki.v2v.cc/presets"
         "v2v presets:\n"
         "  preview        Video: 320x240 if fps ~ 30, 384x288 otherwise\n"
-        "                        Quality 5 - Sharpness 2\n"
+        "                        Quality 5\n"
         "                 Audio: Max 2 channels - Quality 1\n"
         "\n"
         "  pro            Video: 720x480 if fps ~ 30, 720x576 otherwise\n"
-        "                        Quality 7 - Sharpness 0\n"
+        "                        Quality 7\n"
         "                 Audio: Max 2 channels - Quality 3\n"
         "\n"
         "  videobin       Video: 512x288 for 16:9 material, 448x336 for 4:3 material\n"
@@ -1552,7 +1617,7 @@
         "                 Audio: Max 2 channels - Quality 3\n"
         "\n"
         "  padma          Video: 640x360 for 16:9 material, 640x480 for 4:3 material\n"
-        "                        Quality 5 - Sharpness 0\n"
+        "                        Quality 5\n"
         "                 Audio: Max 2 channels - Quality 3\n"
         "\n"
         "  padma-stream   Video: 128x72 for 16:9 material, 128x96 for 4:3 material\n"
@@ -1580,8 +1645,15 @@
         "  -v, --videoquality     [0 to 10] encoding quality for video (default: 5)\n"
         "                                   use higher values for better quality\n"
         "  -V, --videobitrate     [1 to 16778] encoding bitrate for video (kb/s)\n"
+        "      --soft-target      Use a large reservoir and treat the rate\n"
+        "                         as a soft target; rate control is less\n"
+        "                         strict but resulting quality is usually\n"
+        "                         higher/smoother overall. Soft target also\n"
+        "                         allows an optional -v setting to specify\n"
+        "                         a minimum allowed quality.\n\n"
         "      --optimize         optimize video output filesize (slower) (same as speedlevel 0)\n"
         "      --speedlevel       [0 2] encoding is faster with higher values the cost is quality and bandwidth\n"
+
         "  -x, --width            scale to given width (in pixels)\n"
         "  -y, --height           scale to given height (in pixels)\n"
         "      --max_size         scale output frame to be withing box of \n"
@@ -1590,9 +1662,15 @@
         "  -F, --framerate        output framerate e.g 25:2 or 16\n"
         "      --croptop, --cropbottom, --cropleft, --cropright\n"
         "                         crop input by given pixels before resizing\n"
-        "  -S, --sharpness        [0 to 2] sharpness of images (default: 0).\n"
-        "                          Note: lower values make the video sharper.\n"
-        "  -K, --keyint           [1 to 65536] keyframe interval (default: 64)\n"
+        "  -K, --keyint           [1 to 2147483647] keyframe interval (default: 64)\n"
+        "  -d --buf-delay <n>     Buffer delay (in frames). Longer delays\n"
+        "                         allow smoother rate adaptation and provide\n"
+        "                         better overall quality, but require more\n"
+        "                         client side buffering and add latency. The\n"
+        "                         default value is the keyframe interval for\n"
+        "                         one-pass encoding (or somewhat larger if\n"
+        "                         --soft-target is used) and infinite for\n"
+        "                         two-pass encoding. (only works in bitrate mode)\n"
         "      --no-upscaling     only scale video or resample audio if input is\n"
         "                         bigger than provided parameters\n"
         "\n"
@@ -1708,7 +1786,7 @@
     AVFormatParameters params, *formatParams = NULL;
 
     int c,long_option_index;
-    const char *optstring = "P:o:k:f:F:x:y:v:V:a:A:S:K:d:H:c:G:Z:C:B:p:N:s:e:D:h::";
+    const char *optstring = "P:o:k:f:F:x:y:v:V:a:A:K:d:H:c:G:Z:C:B:p:N:s:e:D:h::";
     struct option options [] = {
         {"pid",required_argument,NULL, 'P'},
         {"output",required_argument,NULL,'o'},
@@ -1722,8 +1800,9 @@
         {"videobitrate",required_argument,NULL,'V'},
         {"audioquality",required_argument,NULL,'a'},
         {"audiobitrate",required_argument,NULL,'A'},
-        {"sharpness",required_argument,NULL,'S'},
+        {"soft-target",0,&flag,SOFTTARGET_FLAG},
         {"keyint",required_argument,NULL,'K'},
+        {"buf-delay",required_argument,NULL,'d'},
         {"deinterlace",0,&flag,DEINTERLACE_FLAG},
         {"pp",required_argument,&flag,PP_FLAG},
         {"samplerate",required_argument,NULL,'H'},
@@ -1804,6 +1883,10 @@
                             convert->deinterlace = 1;
                             flag = -1;
                             break;
+                        case SOFTTARGET_FLAG:
+                            convert->soft_target = 1;
+                            flag = -1;
+                            break;
                         case PP_FLAG:
                             if (!strcmp(optarg, "help")) {
                                 fprintf(stdout, "%s", pp_help);
@@ -2009,7 +2092,6 @@
                         fprintf(stderr, "Only values from 0 to 10 are valid for video quality.\n");
                         exit(1);
                 }
-                convert->video_bitrate=0;
                 break;
             case 'V':
                 convert->video_bitrate=rint(atof(optarg)*1000);
@@ -2017,7 +2099,6 @@
                     fprintf(stderr, "Only values from 1 to 16000 are valid for video bitrate (in kb/s).\n");
                     exit(1);
                 }
-                convert->video_quality=0;
                 break;
             case 'a':
                 convert->audio_quality=atof(optarg);
@@ -2047,20 +2128,16 @@
             case 'B':
                 convert->video_bright = atof(optarg);
                 break;
-            case 'S':
-                convert->sharpness = atoi(optarg);
-                if (convert->sharpness < 0 || convert->sharpness > 2) {
-                    fprintf(stderr, "Only values from 0 to 2 are valid for sharpness.\n");
-                    exit(1);
-                }
-                break;
             case 'K':
                 convert->keyint = atoi(optarg);
-                if (convert->keyint < 1 || convert->keyint > 65536) {
-                    fprintf(stderr, "Only values from 1 to 65536 are valid for keyframe interval.\n");
+                if (convert->keyint < 1 || convert->keyint > 2147483647) {
+                    fprintf(stderr, "Only values from 1 to 2147483647 are valid for keyframe interval.\n");
                     exit(1);
                 }
                 break;
+            case 'd':
+                convert->buf_delay = atoi(optarg);
+                break;
             case 'H':
                 convert->sample_rate=atoi(optarg);
                 break;
@@ -2085,7 +2162,6 @@
                     convert->preset=V2V_PRESET_PRO;
                     convert->video_quality = rint(7*6.3);
                     convert->audio_quality = 3.00;
-                    convert->sharpness = 0;
                     info.speed_level = 0;
                 }
                 else if (!strcmp(optarg,"preview")) {
@@ -2093,7 +2169,6 @@
                     convert->preset=V2V_PRESET_PREVIEW;
                     convert->video_quality = rint(5*6.3);
                     convert->audio_quality = 1.00;
-                    convert->sharpness = 2;
                     info.speed_level = 0;
                 }
                 else if (!strcmp(optarg,"videobin")) {
@@ -2101,14 +2176,12 @@
                     convert->video_bitrate=rint(600*1000);
                     convert->video_quality = 0;
                     convert->audio_quality = 3.00;
-                    convert->sharpness = 2;
                     info.speed_level = 0;
                 }
                 else if (!strcmp(optarg,"padma")) {
                     convert->preset=V2V_PRESET_PADMA;
                     convert->video_quality = rint(5*6.3);
                     convert->audio_quality = 3.00;
-                    convert->sharpness = 0;
                     info.speed_level = 0;
                 }
                 else if (!strcmp(optarg,"padma-stream")) {
@@ -2117,7 +2190,6 @@
                     convert->video_quality = 0;
                     convert->audio_quality = -1.00;
                     convert->sample_rate=44100;
-                    convert->sharpness = 2;
                     convert->keyint = 16;
                     info.speed_level = 0;
                 }
@@ -2184,6 +2256,24 @@
         exit(1);
     }
 
+    if (convert->soft_target) {
+        if (convert->video_bitrate <= 0) {
+          fprintf(stderr,"Soft rate target (--soft-tagret) requested without a bitrate (-V).\n");
+          exit(1);
+        }
+        if (convert->video_quality == -1)
+            convert->video_quality = 0;
+    } else {
+        if (convert->video_bitrate > 0)
+            convert->video_quality = 0;
+        if (convert->video_quality == -1)
+            convert->video_quality = rint(5*6.3); // default quality 5
+    }
+    if (convert->buf_delay>0 && convert->video_bitrate == 0) {
+        fprintf(stderr, "Buffer delay can only be used with target bitrate (-V).\n");
+        exit(1);
+    }
+
     if (*pidfile_name) {
         fpid = fopen(pidfile_name, "w");
         if (fpid != NULL) {

Modified: trunk/ffmpeg2theora/src/ffmpeg2theora.h
===================================================================
--- trunk/ffmpeg2theora/src/ffmpeg2theora.h	2009-07-28 09:11:16 UTC (rev 16349)
+++ trunk/ffmpeg2theora/src/ffmpeg2theora.h	2009-07-28 13:46:53 UTC (rev 16350)
@@ -32,6 +32,8 @@
     int audio_index;
 
     int deinterlace;
+    int soft_target;
+    int buf_delay;
     int vhook;
     int disable_video;
     int no_upscaling;
@@ -61,8 +63,7 @@
     int pix_fmt;
     int video_quality;
     int video_bitrate;
-    int sharpness;
-    int keyint;
+    ogg_uint32_t keyint;
     char pp_mode[255];
 
     AVRational force_input_fps;

Modified: trunk/ffmpeg2theora/src/theorautils.c
===================================================================
--- trunk/ffmpeg2theora/src/theorautils.c	2009-07-28 09:11:16 UTC (rev 16349)
+++ trunk/ffmpeg2theora/src/theorautils.c	2009-07-28 13:46:53 UTC (rev 16350)
@@ -25,7 +25,7 @@
 #include <string.h>
 #include <time.h>
 
-#include "theora/theora.h"
+#include "theora/theoraenc.h"
 #include "vorbis/codec.h"
 #include "vorbis/vorbisenc.h"
 #ifdef HAVE_OGGKATE
@@ -169,7 +169,7 @@
         write64le(op.packet+28, info->ti.fps_denominator); /* granulrate denominator */
         write64le(op.packet+36, 0); /* start granule */
         write32le(op.packet+44, 0); /* preroll, for theora its 0 */
-        *(op.packet+48) = theora_granule_shift (&info->ti); /* granule shift */
+        *(op.packet+48) = info->ti.keyframe_granule_shift; /* granule shift */
         memcpy(op.packet+FISBONE_SIZE, "Content-Type: video/theora\r\n", 28); /* message header field, Content-Type */
 
         op.b_o_s = 0;
@@ -244,6 +244,7 @@
 void oggmux_init (oggmux_info *info) {
     ogg_page og;
     ogg_packet op;
+    int ret;
 
     /* yayness.  Set up Ogg output stream */
     srand (time (NULL));
@@ -251,15 +252,6 @@
 
     if (!info->audio_only) {
         ogg_stream_init (&info->to, rand ());    /* oops, add one ot the above */
-        theora_encode_init (&info->td, &info->ti);
-
-        if (info->speed_level >= 0) {
-            int max_speed_level;
-            theora_control(&info->td, TH_ENCCTL_GET_SPLEVEL_MAX, &max_speed_level, sizeof(int));
-            if (info->speed_level > max_speed_level)
-                info->speed_level = max_speed_level;
-            theora_control(&info->td, TH_ENCCTL_SET_SPLEVEL, &info->speed_level, sizeof(int));
-        }
     }
     /* init theora done */
 
@@ -332,28 +324,37 @@
 
     /* first packet will get its own page automatically */
     if (!info->audio_only) {
+        /* write the bitstream header packets with proper page interleave */
+        th_comment_init(&info->tc);
+        th_comment_add_tag(&info->tc, "ENCODER",PACKAGE_STRING);
+        if (strcmp(info->oshash,"0") > 0) {
+            th_comment_add_tag(&info->tc, "SOURCE_OSHASH", info->oshash);
+        }
 
-        theora_encode_header (&info->td, &op);
-        ogg_stream_packetin (&info->to, &op);
-        if (ogg_stream_pageout (&info->to, &og) != 1) {
-            fprintf (stderr, "Internal Ogg library error.\n");
-            exit (1);
+        /* write the bitstream header packets with proper page interleave */
+        /* first packet will get its own page automatically */
+        if(th_encode_flushheader(info->td, &info->tc, &op) <= 0) {
+          fprintf(stderr, "Internal Theora library error.\n");
+          exit(1);
         }
-        fwrite (og.header, 1, og.header_len, info->outfile);
-        fwrite (og.body, 1, og.body_len, info->outfile);
+        ogg_stream_packetin(&info->to, &op);
+        if(ogg_stream_pageout(&info->to, &og) != 1) {
+            fprintf(stderr, "Internal Ogg library error.\n");
+            exit(1);
+        }
+        fwrite(og.header, 1, og.header_len, info->outfile);
+        fwrite(og.body, 1, og.body_len, info->outfile);
 
         /* create the remaining theora headers */
-        /* theora_comment_init (&info->tc); is called in main() prior to parsing options */
-        theora_comment_add_tag (&info->tc, "ENCODER",PACKAGE_STRING);
-        if (strcmp(info->oshash,"0") > 0) {
-            theora_comment_add_tag (&info->tc, "SOURCE_OSHASH", info->oshash);
+        for(;;){
+          ret=th_encode_flushheader(info->td, &info->tc, &op);
+          if(ret < 0) {
+            fprintf(stderr,"Internal Theora library error.\n");
+            exit(1);
+          }
+          else if(!ret) break;
+          ogg_stream_packetin(&info->to, &op);
         }
-        theora_encode_comment (&info->tc, &op);
-        ogg_stream_packetin (&info->to, &op);
-        _ogg_free (op.packet);
-
-        theora_encode_tables (&info->td, &op);
-        ogg_stream_packetin (&info->to, &op);
     }
     if (!info->video_only) {
         ogg_packet header;
@@ -421,10 +422,6 @@
         }
     }
 
-    if (!info->audio_only) {
-    theora_info_clear(&info->ti);
-    }
-
     /* Flush the rest of our headers. This ensures
      * the actual data in each stream will start
      * on a new page, as per spec. */
@@ -493,6 +490,9 @@
         fwrite (og.header, 1, og.header_len,info->outfile);
         fwrite (og.body, 1, og.body_len, info->outfile);
     }
+    if (!info->audio_only) {
+        th_info_clear(&info->ti);
+    }
 }
 
 /**
@@ -503,10 +503,11 @@
  * @param yuv_buffer
  * @param e_o_s 1 indicates ond of stream
  */
-void oggmux_add_video (oggmux_info *info, yuv_buffer *yuv, int e_o_s) {
+void oggmux_add_video (oggmux_info *info, th_ycbcr_buffer ycbcr, int e_o_s) {
     ogg_packet op;
-    theora_encode_YUVin (&info->td, yuv);
-    while (theora_encode_packetout (&info->td, e_o_s, &op) > 0) {
+    int r;
+    th_encode_ycbcr_in(info->td, ycbcr);
+    while (th_encode_packetout (info->td, e_o_s, &op) > 0) {
         ogg_stream_packetin (&info->to, &op);
         info->v_pkg++;
     }
@@ -801,7 +802,7 @@
 
                 info->videopage_valid = 1;
                 if (ogg_page_granulepos(&og)>0) {
-                    info->videotime = theora_granule_time (&info->td, ogg_page_granulepos(&og));
+                    info->videotime = th_granule_time(info->td, ogg_page_granulepos(&og));
                 }
             }
         }
@@ -921,8 +922,7 @@
     vorbis_info_clear (&info->vi);
 
     ogg_stream_clear (&info->to);
-    theora_comment_clear (&info->tc);
-    theora_clear (&info->td);
+    th_comment_clear (&info->tc);
 
 #ifdef HAVE_KATE
     for (n=0; n<info->n_kate_streams; ++n) {

Modified: trunk/ffmpeg2theora/src/theorautils.h
===================================================================
--- trunk/ffmpeg2theora/src/theorautils.h	2009-07-28 09:11:16 UTC (rev 16349)
+++ trunk/ffmpeg2theora/src/theorautils.h	2009-07-28 13:46:53 UTC (rev 16350)
@@ -21,7 +21,7 @@
 #define _F2T_THEORAUTILS_H_
 
 #include <stdint.h>
-#include "theora/theora.h"
+#include "theora/theoraenc.h"
 #include "vorbis/codec.h"
 #include "vorbis/vorbisenc.h"
 #ifdef HAVE_KATE
@@ -75,12 +75,12 @@
     vorbis_comment vc;    /* struct that stores all the user comments */
 
     /* theora settings */
-    theora_info ti;
-    theora_comment tc;
+    th_info ti;
+    th_comment tc;
     int speed_level;
 
     /* state info */
-    theora_state td;
+    th_enc_ctx *td;
     vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
     vorbis_block vb;     /* local working space for packet->PCM decode */
 
@@ -133,7 +133,7 @@
 void init_info(oggmux_info *info);
 extern void oggmux_setup_kate_streams(oggmux_info *info, int n_kate_streams);
 extern void oggmux_init (oggmux_info *info);
-extern void oggmux_add_video (oggmux_info *info, yuv_buffer *yuv, int e_o_s);
+extern void oggmux_add_video (oggmux_info *info, th_ycbcr_buffer ycbcr, int e_o_s);
 extern void oggmux_add_audio (oggmux_info *info, int16_t * readbuffer, int bytesread, int samplesread,int e_o_s);
 extern void oggmux_add_kate_text (oggmux_info *info, int idx, double t0, double t1, const char *text, size_t len);
 extern void oggmux_add_kate_end_packet (oggmux_info *info, int idx, double t);



More information about the commits mailing list