[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