[xiph-commits] r10035 - experimental/j/ffmpeg2theora-exp
j at svn.xiph.org
j at svn.xiph.org
Wed Sep 21 05:14:38 PDT 2005
Author: j
Date: 2005-09-21 05:14:15 -0700 (Wed, 21 Sep 2005)
New Revision: 10035
Modified:
experimental/j/ffmpeg2theora-exp/ChangeLog
experimental/j/ffmpeg2theora-exp/INSTALL
experimental/j/ffmpeg2theora-exp/Makefile.am
experimental/j/ffmpeg2theora-exp/README
experimental/j/ffmpeg2theora-exp/configure.ac
experimental/j/ffmpeg2theora-exp/ffmpeg2theora.1
experimental/j/ffmpeg2theora-exp/ffmpeg2theora.c
experimental/j/ffmpeg2theora-exp/get_ffmpeg_cvs.sh
experimental/j/ffmpeg2theora-exp/theorautils.c
experimental/j/ffmpeg2theora-exp/theorautils.h
Log:
* merge changes from trunk
- fix ogg muxing
- compile with current version of ffmpeg
Modified: experimental/j/ffmpeg2theora-exp/ChangeLog
===================================================================
--- experimental/j/ffmpeg2theora-exp/ChangeLog 2005-09-19 22:33:56 UTC (rev 10034)
+++ experimental/j/ffmpeg2theora-exp/ChangeLog 2005-09-21 12:14:15 UTC (rev 10035)
@@ -1,81 +1,93 @@
-0.13 2005-03-12
- - add new command line options, starttime, endtime, sharpness, keyint
- - fix compile issues with new version of faad
- - better support for stdout on win32,
- to allow ezstream streaming non-theora source types
- - deinterlace only input marked as interlaced by default
- - handle input files with frame sizes that are not a multiple of 16
- - document --channels to resample audio to i.e. 1 channel
+0.15 2005-08-31
+ - ti.dropframes_p = 0 so we do not loos half of the frames.
+ - also increase keyframe interval for better search support.
+ - this time the windows build als supports ac3 decoding again.
-0.12 2004-11-18
- - add more command line options, for bitrate modes, metadata
- - update kino plugin
+0.14 2005-08-15
+ - add support for v4l input devices
+ - update to latest version of ffmpeg-cvs(now uses pkg-config)
+ - --audiostream id, new option to select an audio stream if
+ input has more than one audio stream
+ - fixed ogg muxer
-0.11 2004-09-04
- - changed default, then called without parameters to -p preview mode
- - changed PREVIEW(PAL) settings to 384x288 to make pixel aspect ratio 1:1
- - performance improvement if compiled with theora-mmx
- [http://svn.xiph.org/branches/theora-mmx]
- - new option: --aspect to define frame aspect ratio: i.e. 4:3 or 16:9
+0.13 2005-03-12
+ - add new command line options, starttime, endtime, sharpness, keyint
+ - fix compile issues with new version of faad
+ - better support for stdout on win32,
+ to allow ezstream streaming non-theora source types
+ - deinterlace only input marked as interlaced by default
+ - handle input files with frame sizes that are not a multiple of 16
+ - document --channels to resample audio to i.e. 1 channel
-0.10.2 2004-07-17
- - add cropping support
- - remove support for ffmpeg<0.4.9-pre1
- - change configure.ac and Makefile.am to better build with
- mingw32
+0.12 2004-11-18
+ - add more command line options, for bitrate modes, metadata
+ - update kino plugin
-0.10.1 2004-07-15 21:03:15
- - fix problems with mpeg files using ffmpeg from cvs or versions
- newer than 0.4.8.
- - remove --with-ffmpegcvs and detect changes by LIBAVCODEC_BUILD
+0.11 2004-09-04
+ - changed default, then called without parameters to -p preview mode
+ - changed PREVIEW(PAL) settings to 384x288 to make pixel aspect ratio 1:1
+ - performance improvement if compiled with theora-mmx
+ [http://svn.xiph.org/branches/theora-mmx]
+ - new option: --aspect to define frame aspect ratio: i.e. 4:3 or 16:9
-0.10 2004-07-10 18:14:15
- - write eos at the end of the file.
- - fix memleak due to not enough calls of ogg_stream_pageout
+0.10.2 2004-07-17
+ - add cropping support
+ - remove support for ffmpeg<0.4.9-pre1
+ - change configure.ac and Makefile.am to better build with
+ mingw32
-0.9 2004-07-04 13:14:15
- - add presets
- - add more comandline options
+0.10.1 2004-07-15 21:03:15
+ - fix problems with mpeg files using ffmpeg from cvs or versions
+ newer than 0.4.8.
+ - remove --with-ffmpegcvs and detect changes by LIBAVCODEC_BUILD
-0.8 2004-06-19 18:47:14
- - use ffmpeg aspect ration if possible
- - normalize quality options to 0-10
- - fix skipping issues with a/v sync
+0.10 2004-07-10 18:14:15
+ - write eos at the end of the file.
+ - fix memleak due to not enough calls of ogg_stream_pageout
-0.7.1 2004-05-31 01:55:40
- - added --enable-ffmpegcvs to link against ffmpeg from cvs
- - try to find and link to shared avcodec/avformat
- if source not found
+0.9 2004-07-04 13:14:15
+ - add presets
+ - add more comandline options
-0.7 2004-05-30 18:40:40
- - add comandline options for audio/video quality
- - fix bug causing crashes with DV files, without resizing
- - use autotools
+0.8 2004-06-19 18:47:14
+ - use ffmpeg aspect ration if possible
+ - normalize quality options to 0-10
+ - fix skipping issues with a/v sync
-0.6 2004-05-06 13:47:30
- - added resize option
+0.7.1 2004-05-31 01:55:40
+ - added --enable-ffmpegcvs to link against ffmpeg from cvs
+ - try to find and link to shared avcodec/avformat
+ if source not found
+0.7 2004-05-30 18:40:40
+ - add comandline options for audio/video quality
+ - fix bug causing crashes with DV files, without resizing
+ - use autotools
+
+0.6 2004-05-06 13:47:30
+ - added resize option
+
0.5.1 2004-03-27 21:59:40
- - fix kino export
- - add -f fmt do define input format.
+ - fix kino export
+ - add -f fmt do define input format.
-0.5 2004-03-27 19:59:40
- - link against shared library on linux
- - kino export module and support to read from stdin
- [works only to some extend for now]
+0.5 2004-03-27 19:59:40
+ - link against shared library on linux
+ - kino export module and support to read from stdin
+ [works only to some extend for now]
0.4
- - fix wrong deinterlaceing
- - change memory allocation to work with mingw32
+ - fix wrong deinterlaceing
+ - change memory allocation to work with mingw32
0.3
- - make encoding of audio only files possible.
- can be used to transcode audio files[mp4,wav,ac3...] to ogg vorbis now
- time to call if ffmpeg2ogg?
- - some code cleanup
+ - make encoding of audio only files possible.
+ can be used to transcode audio files[mp4,wav,ac3...] to ogg vorbis now
+ time to call if ffmpeg2ogg?
+ - some code cleanup
0.2
- - added deinterlace support
-
+ - added deinterlace support
+
0.1
- - initial version
+ - initial version
Modified: experimental/j/ffmpeg2theora-exp/INSTALL
===================================================================
--- experimental/j/ffmpeg2theora-exp/INSTALL 2005-09-19 22:33:56 UTC (rev 10034)
+++ experimental/j/ffmpeg2theora-exp/INSTALL 2005-09-21 12:14:15 UTC (rev 10035)
@@ -2,31 +2,23 @@
---------------------------------
you need
- the latest version of libtheora ( http://www.theora.org/files )
-- ffmpeg 0.4.9-pre1 or cvs ( http://ffmpeg.sf.net ) / by running ./get_ffmpeg_cvs.sh
+- ffmpeg-cvs ( http://ffmpeg.sf.net ) / by running ./get_ffmpeg_cvs.sh
configure it with i.e.
- ./configure --enable-faad --enable-vorbis --disable-mp3lame --enable-pp --enable-a52 --enable-dts --enable-pthreads --disable-vhook --disable-v4l --disable-audio-oss --disable-dv1394 --disable-ffmpeg --disable-ffserver --disable-network --enable-gpl --enable-libogg --enable-vorbis --enable-theora
+ ./configure --disable-encoder --enable-faad --enable-pp --enable-a52 --enable-dts --enable-pthreads --disable-vhook --enable-gpl --enable-libogg --enable-vorbis --disable-theora
-now run:
-./configure [--with-ffmpegprefix=/path/to/ffmpeg_src]
-make
+if you did not install ffmpeg but want to staticly link it
+(recomended by ffmpeg developers) update PKG_CONFIG_PATH to
+point to your ffmpeg source:
+ export PKG_CONFIG_PATH=/path/to/ffmpeg_src:$PKG_CONFIG_PATH
-cross compiling with mingw32
-----------------------------------------------
+now you can build ffmpeg2theora:
+./configure
+make
- you need to crosscompiled libvorbis,libogg,libtheora
- you need ffmpeg, to build it with other crosscompiled libs in /usr/local/win32:
- ./configure --prefix=/usr/local/win32/build --enable-libogg --enable-vorbis --enable-theora --disable-mp3lame --enable-pp --enable-a52 --disable-pthreads --disable-vhook --disable-v4l --disable-audio-oss --disable-dv1394 --disable-ffmpeg --disable-ffserver --disable-network --enable-gpl --enable-mingw32 --cc=i586-mingw32msvc-gcc
- make
-
- to build ffmpeg2theora
- PREFIX=/usr/local/win32
- TARGET=i586-mingw32msvc
- PATH="$PREFIX/bin:$PREFIX/$TARGET/bin:$PATH"
- export PATH
- cache=cross-config.cache
- ./configure --cache-file="$cache" \
- --target=$TARGET --host=$TARGET --build=i386-linux --prefix=$PREFIX \
- --with-ffmpegprefix=/path/to/ffmpeg_src
-
+compinling on windows using mingw32:
+you have to compile libvorbis, libogg, libtheora
+configure ffmpeg like this:
+./configure --disable-encoder --enable-libogg --enable-vorbis --enable-theora \
+ --enable-pp --enable-a52 --enable-gpl
Modified: experimental/j/ffmpeg2theora-exp/Makefile.am
===================================================================
--- experimental/j/ffmpeg2theora-exp/Makefile.am 2005-09-19 22:33:56 UTC (rev 10034)
+++ experimental/j/ffmpeg2theora-exp/Makefile.am 2005-09-21 12:14:15 UTC (rev 10035)
@@ -2,14 +2,14 @@
SUBDIRS = kino_export
-EXTRA_DIST = Makefile.mingw32 theorautils.h get_ffmpeg_cvs.sh
+EXTRA_DIST = Makefile.mingw32 theorautils.h get_ffmpeg_cvs.sh ffmpeg2theora.1
EXTRA=-D_FILE_OFFSET_BITS=64 -I$(prefix)/include
bin_PROGRAMS = ffmpeg2theora
ffmpeg2theora_SOURCES = ffmpeg2theora.c theorautils.c
-ffmpeg2theora_LDFLAGS = -static -L$(prefix)/lib @FFMPEG_LIBS@ @XIPH_LIBS@
-ffmpeg2theora_CFLAGS = $(EXTRA) @XIPH_CFLAGS@ @FFMPEG_CFLAGS@
+ffmpeg2theora_LDFLAGS = -L$(prefix)/lib @XIPH_LIBS@ @FFMPEG_LIBS@
+ffmpeg2theora_CFLAGS = @XIPH_CFLAGS@ @FFMPEG_CFLAGS@
man_MANS = ffmpeg2theora.1
Modified: experimental/j/ffmpeg2theora-exp/README
===================================================================
--- experimental/j/ffmpeg2theora-exp/README 2005-09-19 22:33:56 UTC (rev 10034)
+++ experimental/j/ffmpeg2theora-exp/README 2005-09-21 12:14:15 UTC (rev 10035)
@@ -9,7 +9,7 @@
usage right now:
./ffmpeg2theora clip.avi
- will produce clip.avi.ogg
+ will produce clip.ogg
for more options run ffmpeg2theora -h
there is a export plugin for kino (http://kino.schirmacher.de/)
Modified: experimental/j/ffmpeg2theora-exp/configure.ac
===================================================================
--- experimental/j/ffmpeg2theora-exp/configure.ac 2005-09-19 22:33:56 UTC (rev 10034)
+++ experimental/j/ffmpeg2theora-exp/configure.ac 2005-09-21 12:14:15 UTC (rev 10035)
@@ -1,99 +1,41 @@
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.59)
-AC_INIT(ffmpeg2theora-exp,0.13-svn)
+AC_INIT(ffmpeg2theora-exp,0.14-svn)
AC_CONFIG_SRCDIR([Makefile.am])
AM_INIT_AUTOMAKE([dist-bzip2])
-AM_DISABLE_SHARED
-AM_ENABLE_STATIC
-
AC_PROG_CC
AM_PROG_LIBTOOL
-dnl ffmpeg integration here
-AC_ARG_WITH(ffmpegprefix,
- AS_HELP_STRING([--with-ffmpegprefix],
- [prefix to ffmpeg source, if libavcodec and libavformat are not in . (default=.)]),
- ffmpegprefix="$withval", ffmpegprefix="ffmpeg")
+AC_MSG_CHECKING(whether to link statically)
+AC_ARG_WITH(static-linking,
+[ --with-static-linking Link binaries statically],
+[ case "$withval" in
+ no)
+ AC_MSG_RESULT(no)
+ ;;
+ *)
+ AC_MSG_RESULT(yes)
+ LDFLAGS="-static $LDFLAGS"
+ ;;
+ esac],
+AC_MSG_RESULT(no)
+)
-dnl only check for libavcodec.a and libformat.a if not crosscompiling
-dnl
-dnl so LIBPREF and LIBSUF are configured by default,
+PKG_CHECK_MODULES(FFMPEG, libavformat libavcodec, HAVE_FFMPEG=yes, HAVE_FFMPEG=no)
+if test x$HAVE_FFMPEG = xno; then
+ export PKG_CONFIG_PATH=./ffmpeg:$PKG_CONFIG_PATH
+ PKG_CHECK_MODULES(FFMPEG, libavformat libavcodec, HAVE_FFMPEG=yes,
+ AC_MSG_ERROR([
-LIBPREF=lib
-LIBSUF=.a
-case "$host" in
- *mingw*)
- LIBPREF=
- LIBSUF=.lib
- ;;
-esac
-if test "$cross_compiling" = yes; then
- HAVE_FFMPEG=yes
- LIBPREF=
- LIBSUF=.lib
-else
- AC_CHECK_FILES([$ffmpegprefix/libavcodec/${LIBPREF}avcodec$LIBSUF $ffmpegprefix/libavformat/${LIBPREF}avformat$LIBSUF],[HAVE_FFMPEG=yes])
+could not find ffmpeg. please update PKG_CONFIG_PATH to point to ffmpegs source
+folder or run ./get_ffmpeg_cvs.sh (for more information see INSTALL)
+])
+)
fi
-
-dnl if not using ffmpegprefix try to look for shared files
-if test "x$HAVE_FFMPEG" != xyes; then
- AC_CHECK_PROG(HAVE_FFMPEG_CONFIG, ffmpeg-config, yes)
- if test "x$HAVE_FFMPEG_CONFIG" == xyes; then
- FFMPEG_CFLAGS=`ffmpeg-config --cflags`
- FFMPEG_LIBS=`ffmpeg-config --libs avformat`
- else
- if test "$ffmpegprefix" == ffmpeg; then
- AC_CHECK_HEADER(ffmpeg/avcodec.h,[HAVE_SHARED_AVCODEC=yes])
- AC_CHECK_HEADER(ffmpeg/avformat.h, [HAVE_SHARED_AVFORMAT=yes])
- AC_CHECK_FILE(/usr/local/include/ffmpeg, [HAVE_FFMPEG_LOCAL=yes])
- fi
- if test "x$HAVE_SHARED_AVCODEC$HAVE_SHARED_AVCODEC" != xyesyes; then
- AC_MSG_ERROR([
- you need libavcodec and libavformat from ffmpeg cvs
- to get it run get_ffmpeg_cvs.sh or point configure to
- your local copy with i.e.
- ./configure --with-ffmpegprefix=/usr/local/src/ffmpeg
- (see INSTALL for more information)
- ])
- else
- if test "x$HAVE_FFMPEG_LOCAL" != xyes; then
- FFMPEG_CFLAGS="-I/usr/include/ffmpeg"
- else
- FFMPEG_CFLAGS="-I/usr/local/include/ffmpeg"
- fi
- FFMPEG_EXTLIBS="-lm -lz"
- FFMPEG_LIBS="-L/usr/local/lib -L/usr/lib -lavformat -lavcodec $FFMPEG_EXTLIBS"
- fi
- fi
-else
- FFMPEG_CFLAGS="-I$ffmpegprefix/libavformat -I$ffmpegprefix/libavcodec"
- FFMPEG_EXTLIBS="-lm -lz"
- FFMPEG_LIBS="$ffmpegprefix/libavformat/${LIBPREF}avformat$LIBSUF $ffmpegprefix/libavcodec/${LIBPREF}avcodec$LIBSUF $FFMPEG_EXTLIBS"
-fi
-
-
-AC_CHECK_LIB(faad,faacDecClose, [
- AC_CHECK_HEADER(faad.h, [HAVE_FAAD=yes])
- ],,[-lm -lz])
-AC_CHECK_LIB(faad,NeAACDecInit, [
- AC_CHECK_HEADER(faad.h, [HAVE_FAAD=yes])
- ],,[-lm -lz])
-if test "x$HAVE_FAAD" = xyes; then
- FFMPEG_EXTLIBS="-lfaad"
- FFMPEG_LIBS="$FFMPEG_LIBS $FFMPEG_EXTLIBS"
-fi
AC_SUBST(FFMPEG_CFLAGS)
AC_SUBST(FFMPEG_LIBS)
-
-AC_CHECK_LIB(dts,dts_init, [
- AC_CHECK_HEADER(dts.h, [HAVE_DTS=yes])
- ],,[-lm -lz])
-if test "x$HAVE_DTS" = xyes; then
- FFMPEG_LIBS="$FFMPEG_LIBS -ldts"
-fi
-
PKG_CHECK_MODULES(XIPH,ogg >= 1.1 vorbis vorbisenc theoraenc)
AC_SUBST(XIPH_CFLAGS)
Modified: experimental/j/ffmpeg2theora-exp/ffmpeg2theora.1
===================================================================
--- experimental/j/ffmpeg2theora-exp/ffmpeg2theora.1 2005-09-19 22:33:56 UTC (rev 10034)
+++ experimental/j/ffmpeg2theora-exp/ffmpeg2theora.1 2005-09-21 12:14:15 UTC (rev 10035)
@@ -86,13 +86,17 @@
\*(lqffmpeg2theora -p info\*(rq for more information.
.SS Input options:
.TP
-.B \-d, \-\-deinterlace
+.B \-\-deinterlace
Force deinterlace. Otherwise only material marked as interlaced will be
deinterlaced.
.TP
.B \-f, \-\-format
Specify input format.
.TP
+.B \-\-v4l /dev/video0
+read data from v4l device /dev/video0,
+you have to specify an output file with -0
+.TP
.B \-\-inputfps
Override input fps.
.SS Metadata options:
Modified: experimental/j/ffmpeg2theora-exp/ffmpeg2theora.c
===================================================================
--- experimental/j/ffmpeg2theora-exp/ffmpeg2theora.c 2005-09-19 22:33:56 UTC (rev 10034)
+++ experimental/j/ffmpeg2theora-exp/ffmpeg2theora.c 2005-09-21 12:14:15 UTC (rev 10035)
@@ -1,7 +1,7 @@
/* -*- tab-width:4;c-file-style:"cc-mode"; -*- */
/*
- * ffmpeg2theora.c -- Convert ffmpeg supported a/v files to Ogg Theora
- * Copyright (C) 2003-2004 <j at v2v.cc>
+ * ffmpeg2theora.c -- Convert ffmpeg supported a/v files to Ogg Theora / Ogg Vorbis
+ * Copyright (C) 2003-2005 <j at v2v.cc>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,10 +29,82 @@
#ifdef WIN32
#include "fcntl.h"
+#define rindex strrchr
#endif
#include "theorautils.h"
+#define DEINTERLACE_FLAG 1
+#define SYNC_FLAG 3
+#define NOSOUND_FLAG 4
+#define V4L_FLAG 5
+#define CROPTOP_FLAG 6
+#define CROPBOTTOM_FLAG 7
+#define CROPRIGHT_FLAG 8
+#define CROPLEFT_FLAG 9
+#define ASPECT_FLAG 10
+#define INPUTFPS_FLAG 11
+#define AUDIOSTREAM_FLAG 12
+
+
+
+#define V2V_PRESET_PRO 1
+#define V2V_PRESET_PREVIEW 2
+
+
+typedef struct ff2theora{
+ AVFormatContext *context;
+ int video_index;
+ int audio_index;
+
+ int deinterlace;
+ int audiostream;
+ int sample_rate;
+ int channels;
+ int disable_audio;
+ float audio_quality;
+ int audio_bitrate;
+ int preset;
+
+ int picture_width;
+ int picture_height;
+ double fps;
+ ImgReSampleContext *img_resample_ctx; /* for image resampling/resizing */
+ ReSampleContext *audio_resample_ctx;
+ ogg_int32_t aspect_numerator;
+ ogg_int32_t aspect_denominator;
+ double frame_aspect;
+
+ int video_quality;
+ int video_bitrate;
+ int sharpness;
+ int keyint;
+
+ double force_input_fps;
+ int sync;
+
+ /* cropping */
+ int frame_topBand;
+ int frame_bottomBand;
+ int frame_leftBand;
+ int frame_rightBand;
+
+ int frame_width;
+ int frame_height;
+ int frame_x_offset;
+ int frame_y_offset;
+
+ /* In seconds */
+ int start_time;
+ int end_time;
+
+ double pts_offset; /* between given input pts and calculated output pts */
+ int64_t frame_count; /* total video frames output so far */
+ int64_t sample_count; /* total audio samples output so far */
+}
+*ff2theora;
+
+
static double rint(double x) {
if (x < 0.0)
return (double)(int)(x - 0.5);
@@ -40,7 +112,7 @@
return (double)(int)(x + 0.5);
}
-theoraframes_info info;
+oggmux_info info;
static int using_stdin = 0;
@@ -93,7 +165,7 @@
this->video_quality=31.5; // video quality 5
this->video_bitrate=0;
this->sharpness=2;
- this->keyint=1111;
+ this->keyint=64;
this->force_input_fps=0;
this->sync=0;
this->aspect_numerator=0;
@@ -164,7 +236,7 @@
this->fps = fps;
- if(info.preset == V2V_PRESET_PREVIEW){
+ if(this->preset == V2V_PRESET_PREVIEW){
// possible sizes 384/288,320/240
int pal_width=384;
int pal_height=288;
@@ -179,7 +251,7 @@
this->picture_height=ntsc_height;
}
}
- else if(info.preset == V2V_PRESET_PRO){
+ else if(this->preset == V2V_PRESET_PRO){
if(this->fps==25 && (venc->width!=720 || venc->height!=576) ){
this->picture_width=720;
this->picture_height=576;
@@ -360,13 +432,13 @@
/* config file? commandline options? v2v presets? */
theora_info_init (&info.ti);
-
- info.ti.frame_width = this->frame_width;
- info.ti.frame_height = this->frame_height;
- 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;
+
+ info.ti.frame_width = this->frame_width;
+ info.ti.frame_height = this->frame_height;
+ 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->force_input_fps) {
info.ti.fps_numerator = 1000000 * (this->fps); /* fps= numerator/denominator */
info.ti.fps_denominator = 1000000;
@@ -374,7 +446,6 @@
else {
info.ti.fps_numerator=vstream->r_frame_rate.num;
info.ti.fps_denominator = vstream->r_frame_rate.den;
- info.fps = (double) vstream->r_frame_rate.num / vstream->r_frame_rate.den;
}
/* this is pixel aspect ratio */
info.ti.aspect_numerator=this->aspect_numerator;
@@ -390,7 +461,7 @@
info.ti.target_bitrate = this->video_bitrate;
info.ti.quality = this->video_quality;
-/* info.ti.dropframes_p = 1;
+/* info.ti.dropframes_p = 0;
info.ti.quick_p = 1;
info.ti.keyframe_auto_p = 1;
info.ti.keyframe_frequency = this->keyint;
@@ -410,13 +481,11 @@
info.sample_rate = this->sample_rate;
info.vorbis_quality = this->audio_quality;
info.vorbis_bitrate = this->audio_bitrate;
- theoraframes_init (&info);
- /*seek to start time*/
-#if LIBAVFORMAT_BUILD <= 4616
- av_seek_frame( this->context, -1, (int64_t)AV_TIME_BASE*this->start_time);
-#else
- av_seek_frame( this->context, -1, (int64_t)AV_TIME_BASE*this->start_time, 1);
-#endif
+ oggmux_init (&info);
+ /*seek to start time*/
+ if(this->start_time) {
+ av_seek_frame( this->context, -1, (int64_t)AV_TIME_BASE*this->start_time, 1);
+ }
/*check for end time and caclulate number of frames to encode*/
no_frames = fps*(this->end_time - this->start_time);
if(this->end_time > 0 && no_frames <= 0){
@@ -431,8 +500,6 @@
do{
if(no_frames > 0){
if(this->frame_count > no_frames){
- if(info.debug)
- fprintf(stderr,"\nreached end specified with --endtime\n");
break;
}
}
@@ -451,7 +518,7 @@
int dups = 0;
if(len >0 &&
(len1 = avcodec_decode_video(vstream->codec,
- frame,&got_picture, ptr, len))>0) {
+ frame, &got_picture, ptr, len))>0) {
if(got_picture){
// this is disabled by default since it does not work
@@ -512,13 +579,29 @@
}
first=0;
//now output_resized
- do {
- if( theoraframes_add_video(this, &info,
- output_resized ,e_o_s) ){
- ret = -1;
- fprintf (stderr,"No theora frames available\n");
- break;
- }
+ /* pysical pages */
+ static theora_ycbcr_buffer ycbcr;
+ /* Theora is a one-frame-in,one-frame-out system; submit a frame
+ * for compression and pull out the packet */
+ ycbcr[0].width = this->frame_width;
+ ycbcr[0].height = this->frame_height;
+ ycbcr[0].ystride = output_resized->linesize[0];
+
+ ycbcr[1].width = this->frame_width / 2;
+ ycbcr[1].height = this->frame_height / 2;
+ ycbcr[1].ystride = output_resized->linesize[1];
+
+ ycbcr[2].width = this->frame_width / 2;
+ ycbcr[2].height = this->frame_height / 2;
+ ycbcr[2].ystride = output_resized->linesize[2];
+
+
+ ycbcr[0].data = output_resized->data[0];
+ ycbcr[1].data = output_resized->data[1];
+ ycbcr[2].data = output_resized->data[2];
+
+ do {
+ oggmux_add_video(&info, ycbcr ,e_o_s);
this->frame_count++;
} while(dups--);
if(e_o_s){
@@ -554,11 +637,8 @@
resampled=audio_buf;
}
}
- if (theoraframes_add_audio(&info, resampled,
- samples_out *(this->channels),samples_out,e_o_s)){
- ret = -1;
- fprintf (stderr,"No audio frames available\n");
- }
+ oggmux_add_audio(&info, resampled,
+ samples_out *(this->channels),samples_out,e_o_s);
this->sample_count += samples_out;
if(e_o_s && len <= 0){
break;
@@ -567,11 +647,15 @@
}
/* flush out the file */
- theoraframes_flush (&info, e_o_s);
+ oggmux_flush (&info, e_o_s);
av_free_packet (&pkt);
}
while (ret >= 0);
+/*
+ lets takes this out for now, this way glic stops complaining.
+*/
+/*
if(frame) av_free(frame);
if(frame_tmp) av_free(frame_tmp);
if(output) av_free(output);
@@ -584,13 +668,13 @@
av_free(resampled);
av_free(audio_buf);
}
-
+
if (this->img_resample_ctx)
img_resample_close(this->img_resample_ctx);
if (this->audio_resample_ctx)
audio_resample_close(this->audio_resample_ctx);
-
- theoraframes_close (&info);
+*/
+ oggmux_close (&info);
}
else{
fprintf (stderr, "No video or audio stream found\n");
@@ -688,7 +772,7 @@
"\t\t\t\t '"PACKAGE" -p info' for more informations\n"
"\nInput options:\n"
- "\t --deinterlace,-d \tforce deinterlace\n"
+ "\t --deinterlace \tforce deinterlace\n"
"\t\t\t\t otherwise only material marked as interlaced \n"
"\t\t\t\t will be deinterlaced\n"
"\t --format,-f\t\tspecify input format\n"
@@ -714,16 +798,18 @@
#ifndef _WIN32
"\t --nice\t\t\tset niceness to n\n"
#endif
- "\t --debug\t\toutput some more information during encoding\n"
"\t --help,-h\t\tthis message\n"
"\n Examples:\n"
- "\tffmpeg2theora videoclip.avi (will write output to videoclip.avi.ogg)\n\n"
+ "\tffmpeg2theora videoclip.avi (will write output to videoclip.ogg)\n\n"
"\tcat something.dv | ffmpeg2theora -f dv -o output.ogg -\n\n"
- "\tLive encoding from a DV camcorder (needs a fast machine)\n"
- "\tdvgrab - | ffmpeg2theora -f dv -x 352 -y 288 -o output.ogg -\n"
+ "\tLive streaming from V4L Device:\n"
+ "\t ffmpeg2theora --v4l /dev/video0 --inputfps 15 -x 160 -y 128 -o - \\ \n"
+ "\t\t | oggfwd iccast2server 8000 password /theora.ogg\n\n"
+ "\tLive encoding from a DV camcorder (needs a fast machine):\n"
+ "\t dvgrab - | ffmpeg2theora -f dv -x 352 -y 288 -o output.ogg -\n"
"\n\tLive encoding and streaming to icecast server:\n"
"\t dvgrab --format raw - | \\\n"
"\t ffmpeg2theora -f dv -x 160 -y 128 -o /dev/stdout - | \\\n"
@@ -737,20 +823,11 @@
int outputfile_set=0;
char outputfile_name[255];
char inputfile_name[255];
+ char *str_ptr;
- static int croptop_flag=0;
- static int cropbottom_flag=0;
- static int cropright_flag=0;
- static int cropleft_flag=0;
- static int nosound_flag=0;
- static int aspect_flag=0;
- static int inputfps_flag=0;
+ static int flag=-1;
static int metadata_flag=0;
- static int deinterlace_flag=0;
- static int audiostream_flag=0;
- static int sync_flag=0;
- static int v4l_flag=0;
-
+
AVInputFormat *input_fmt = NULL;
AVFormatParameters *formatParams = NULL;
@@ -767,23 +844,23 @@
{"audiobitrate",required_argument,NULL,'A'},
{"sharpness",required_argument,NULL,'S'},
{"keyint",required_argument,NULL,'K'},
- {"deinterlace",0,&deinterlace_flag,'d'},
+ {"deinterlace",0,&flag,DEINTERLACE_FLAG},
{"samplerate",required_argument,NULL,'H'},
{"channels",required_argument,NULL,'c'},
- {"nosound",0,&nosound_flag,1},
- {"v4l",required_argument,&v4l_flag,1},
- {"aspect",required_argument,&aspect_flag,1},
+ {"nosound",0,&flag,NOSOUND_FLAG},
+ {"v4l",required_argument,&flag,V4L_FLAG},
+ {"aspect",required_argument,&flag,ASPECT_FLAG},
{"v2v-preset",required_argument,NULL,'p'},
{"nice",required_argument,NULL,'N'},
- {"croptop",required_argument,&croptop_flag,1},
- {"cropbottom",required_argument,&cropbottom_flag,1},
- {"cropright",required_argument,&cropright_flag,1},
- {"cropleft",required_argument,&cropleft_flag,1},
- {"inputfps",required_argument,&inputfps_flag,1},
- {"audiostream",required_argument,&audiostream_flag,1},
+ {"croptop",required_argument,&flag,CROPTOP_FLAG},
+ {"cropbottom",required_argument,&flag,CROPBOTTOM_FLAG},
+ {"cropright",required_argument,&flag,CROPRIGHT_FLAG},
+ {"cropleft",required_argument,&flag,CROPLEFT_FLAG},
+ {"inputfps",required_argument,&flag,INPUTFPS_FLAG},
+ {"audiostream",required_argument,&flag,AUDIOSTREAM_FLAG},
{"starttime",required_argument,NULL,'s'},
{"endtime",required_argument,NULL,'e'},
- {"sync",0,&sync_flag,1},
+ {"sync",0,&flag,SYNC_FLAG},
{"artist",required_argument,&metadata_flag,10},
{"title",required_argument,&metadata_flag,11},
@@ -793,7 +870,6 @@
{"copyright",required_argument,&metadata_flag,15},
{"license",required_argument,&metadata_flag,16},
- {"debug",0,NULL,'D'},
{"help",0,NULL,'h'},
{NULL,0,NULL,0}
};
@@ -812,53 +888,58 @@
switch(c)
{
case 0:
- if (sync_flag){
- convert->sync=1;
- sync_flag=0;
+ if (flag) {
+ switch (flag)
+ {
+ case DEINTERLACE_FLAG:
+ convert->deinterlace=1;
+ flag=-1;
+ break;
+ case SYNC_FLAG:
+ convert->sync=1;
+ flag=-1;
+ break;
+ case NOSOUND_FLAG:
+ convert->disable_audio=1;
+ flag=-1;
+ break;
+ case V4L_FLAG:
+ formatParams = malloc(sizeof(AVFormatParameters));
+ formatParams->device = optarg;
+ flag=-1;
+ break;
+ /* crop */
+ case CROPTOP_FLAG:
+ convert->frame_topBand=crop_check(convert,"top",optarg);
+ flag=-1;
+ break;
+ case CROPBOTTOM_FLAG:
+ convert->frame_bottomBand=crop_check(convert,"bottom",optarg);
+ flag=-1;
+ break;
+ case CROPRIGHT_FLAG:
+ convert->frame_rightBand=crop_check(convert,"right",optarg);
+ flag=-1;
+ break;
+ case CROPLEFT_FLAG:
+ convert->frame_leftBand=crop_check(convert,"left",optarg);
+ flag=-1;
+ break;
+ case ASPECT_FLAG:
+ convert->frame_aspect=aspect_check(optarg);
+ flag=-1;
+ break;
+ case INPUTFPS_FLAG:
+ convert->force_input_fps=atof(optarg);
+ flag=-1;
+ break;
+ case AUDIOSTREAM_FLAG:
+ convert->audiostream=atoi(optarg);;
+ flag=-1;
+ break;
+ }
}
- if (nosound_flag){
- convert->disable_audio=1;
- nosound_flag=0;
- }
- if (v4l_flag) {
- formatParams = malloc(sizeof(AVFormatParameters));
- formatParams->device = optarg;
- v4l_flag = 0;
- }
- if (deinterlace_flag){
- convert->deinterlace=1;
- deinterlace_flag=0;
- }
- /* crop */
- if (croptop_flag){
- convert->frame_topBand=crop_check(convert,"top",optarg);
- croptop_flag=0;
- }
- if (cropbottom_flag){
- convert->frame_bottomBand=crop_check(convert,"bottom",optarg);
- cropbottom_flag=0;
- }
- if (cropright_flag){
- convert->frame_rightBand=crop_check(convert,"right",optarg);
- cropright_flag=0;
- }
- if (cropleft_flag){
- convert->frame_leftBand=crop_check(convert,"left",optarg);
- cropleft_flag=0;
- }
- if (aspect_flag){
- convert->frame_aspect=aspect_check(optarg);
- aspect_flag=0;
- }
- if (inputfps_flag){
- convert->force_input_fps=atof(optarg);
- inputfps_flag=0;
- }
- if (audiostream_flag){
- convert->audiostream=atoi(optarg);;
- audiostream_flag=0;
- }
/* metadata */
if (metadata_flag){
switch(metadata_flag) {
@@ -952,12 +1033,6 @@
exit(1);
}
break;
- case 'd':
- if(!strcmp(optarg,"off"))
- convert->deinterlace=0;
- else
- convert->deinterlace=1;
- break;
case 'H':
convert->sample_rate=atoi(optarg);
break;
@@ -973,7 +1048,7 @@
}
else if(!strcmp(optarg, "pro")){
//need a way to set resize here. and not later
- info.preset=V2V_PRESET_PRO;
+ convert->preset=V2V_PRESET_PRO;
convert->video_quality = rint(7*6.3);
convert->audio_quality=3*.099;
convert->channels=2;
@@ -982,7 +1057,7 @@
}
else if(!strcmp(optarg,"preview")){
//need a way to set resize here. and not later
- info.preset=V2V_PRESET_PREVIEW;
+ convert->preset=V2V_PRESET_PREVIEW;
convert->video_quality = rint(5*6.3);
convert->audio_quality=1*.099;
convert->channels=2;
@@ -1005,10 +1080,6 @@
#endif
}
break;
- case 'D':
- //enable debug informations
- info.debug=1;
- break;
case 'h':
print_usage ();
exit(1);
@@ -1017,7 +1088,7 @@
//use PREVIEW as default setting
if(argc==2){
//need a way to set resize here. and not later
- info.preset=V2V_PRESET_PREVIEW;
+ convert->preset=V2V_PRESET_PREVIEW;
convert->video_quality = rint(5*6.3);
convert->audio_quality=1*.099;
convert->channels=2;
@@ -1031,7 +1102,16 @@
sprintf(inputfile_name,"pipe:");
}
if(outputfile_set!=1){
- sprintf(outputfile_name,"%s.ogg",argv[optind]);
+ sprintf(outputfile_name, "%s", argv[optind]);
+ if(str_ptr = rindex(outputfile_name, '.')) {
+ sprintf(str_ptr, ".ogg");
+ if(!strcmp(inputfile_name, outputfile_name)){
+ sprintf(outputfile_name, "%s.ogg", inputfile_name);
+ }
+ }
+ else {
+ sprintf(outputfile_name, "%s.ogg", outputfile_name);
+ }
outputfile_set=1;
}
optind++;
Modified: experimental/j/ffmpeg2theora-exp/get_ffmpeg_cvs.sh
===================================================================
--- experimental/j/ffmpeg2theora-exp/get_ffmpeg_cvs.sh 2005-09-19 22:33:56 UTC (rev 10034)
+++ experimental/j/ffmpeg2theora-exp/get_ffmpeg_cvs.sh 2005-09-21 12:14:15 UTC (rev 10035)
@@ -1,2 +1,5 @@
#!/bin/sh
cvs -z3 -d:pserver:anonymous at cvs.mplayerhq.hu:/cvsroot/ffmpeg/ co ffmpeg
+cd ffmpeg
+./configure --enable-libogg --enable-theora --disable-mp3lame --enable-a52 --enable-pthreads --enable-vhook --enable-dv1394 --enable-gpl
+make
Modified: experimental/j/ffmpeg2theora-exp/theorautils.c
===================================================================
--- experimental/j/ffmpeg2theora-exp/theorautils.c 2005-09-19 22:33:56 UTC (rev 10034)
+++ experimental/j/ffmpeg2theora-exp/theorautils.c 2005-09-21 12:14:15 UTC (rev 10035)
@@ -1,7 +1,7 @@
/* -*- tab-width:4;c-file-style:"cc-mode"; -*- */
/*
- * theorautils.c - Ogg Theora abstraction layer
- * Copyright (C) 2003-2004 <j at v2v.cc>
+ * theorautils.c - Ogg Theora/Ogg Vorbis Abstraction and Muxing
+ * Copyright (C) 2003-2005 <j at v2v.cc>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,8 +18,6 @@
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
-#include "common.h"
-#include "avformat.h"
#include <stdio.h>
#include <stdlib.h>
@@ -28,7 +26,6 @@
#include "theorautils.h"
-
static double rint(double x)
{
if (x < 0.0)
@@ -37,19 +34,25 @@
return (double)(int)(x + 0.5);
}
-void init_info(theoraframes_info *info) {
+void init_info(oggmux_info *info) {
info->videotime = 0;
info->audiotime = 0;
- info->videoflag = 0;
- info->audioflag = 0;
- info->debug = 0;
-}
-
-void theoraframes_init (theoraframes_info *info){
- int ret = 0;
info->audio_bytesout = 0;
info->video_bytesout = 0;
+ info->videopage_valid = 0;
+ info->audiopage_valid = 0;
+ info->audiopage_buffer_length = 0;
+ info->videopage_buffer_length = 0;
+ info->audiopage = NULL;
+ info->videopage = NULL;
+}
+
+void oggmux_init (oggmux_info *info){
+ ogg_page og;
+ ogg_packet op;
+ int ret;
+
/* yayness. Set up Ogg output stream */
srand (time (NULL));
ogg_stream_init (&info->vo, rand ());
@@ -63,6 +66,7 @@
/* initialize Vorbis too, if we have audio. */
if(!info->video_only){
+ int ret;
vorbis_info_init (&info->vi);
/* Encoding using a VBR quality mode. */
if(info->vorbis_quality>-99)
@@ -90,31 +94,30 @@
/* first packet will get its own page automatically */
if(!info->audio_only){
- theora_comment_init(&info->tc);
- theora_comment_add_tag (&info->tc, "ENCODER",PACKAGE_STRING);
-
- if(theora_encode_flushheader(info->td,&info->tc,&info->op)<=0){
- fprintf(stderr,"Internal Theora library error.\n");
- exit(1);
- }
- ogg_stream_packetin(&info->to,&info->op);
- if(ogg_stream_pageout(&info->to,&info->og)!=1){
- fprintf(stderr,"Internal Ogg library error.\n");
- exit(1);
- }
- fwrite(info->og.header, 1, info->og.header_len, info->outfile);
- fwrite(info->og.body, 1, info->og.body_len, info->outfile);
-
- /* create the remaining theora headers */
- for(;;){
- ret = theora_encode_flushheader(info->td,&info->tc,&info->op);
- if(ret<0){
- fprintf(stderr,"Internal Theora library error.\n");
- exit(1);
+ theora_comment_init(&info->tc);
+ theora_comment_add_tag (&info->tc, "ENCODER",PACKAGE_STRING);
+ if(theora_encode_flushheader(info->td,&info->tc,&op)<=0){
+ fprintf(stderr,"Internal Theora library error.\n");
+ exit(1);
+ }
+ 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 */
+ for(;;){
+ ret = theora_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);
}
- else if(!ret)break;
- ogg_stream_packetin(&info->to,&info->op);
- }
}
if(!info->video_only){
ogg_packet header;
@@ -125,12 +128,12 @@
&header_comm, &header_code);
ogg_stream_packetin (&info->vo, &header); /* automatically placed in its own
* page */
- if (ogg_stream_pageout (&info->vo, &info->og) != 1){
+ if (ogg_stream_pageout (&info->vo, &og) != 1){
fprintf (stderr, "Internal Ogg library error.\n");
exit (1);
}
- fwrite (info->og.header, 1, info->og.header_len, info->outfile);
- fwrite (info->og.body, 1, info->og.body_len, info->outfile);
+ fwrite (og.header, 1, og.header_len, info->outfile);
+ fwrite (og.body, 1, og.body_len, info->outfile);
/* remaining vorbis header packets */
ogg_stream_packetin (&info->vo, &header_comm);
@@ -141,7 +144,7 @@
* the actual data in each stream will start
* on a new page, as per spec. */
while (1 && !info->audio_only){
- int result = ogg_stream_flush (&info->to, &info->og);
+ int result = ogg_stream_flush (&info->to, &og);
if (result < 0){
/* can't get here */
fprintf (stderr, "Internal Ogg library error.\n");
@@ -149,11 +152,11 @@
}
if (result == 0)
break;
- fwrite (info->og.header, 1, info->og.header_len, info->outfile);
- fwrite (info->og.body, 1, info->og.body_len, info->outfile);
+ fwrite (og.header, 1, og.header_len, info->outfile);
+ fwrite (og.body, 1, og.body_len, info->outfile);
}
while (1 && !info->video_only){
- int result = ogg_stream_flush (&info->vo, &info->og);
+ int result = ogg_stream_flush (&info->vo, &og);
if (result < 0){
/* can't get here */
fprintf (stderr, "Internal Ogg library error.\n");
@@ -161,51 +164,26 @@
}
if (result == 0)
break;
- fwrite (info->og.header, 1, info->og.header_len,info->outfile);
- fwrite (info->og.body, 1, info->og.body_len, info->outfile);
+ fwrite (og.header, 1, og.header_len,info->outfile);
+ fwrite (og.body, 1, og.body_len, info->outfile);
}
-
}
-
/**
* adds a video frame to the encoding sink
* if e_o_s is 1 the end of the logical bitstream will be marked.
* @param this ff2theora struct
- * @param info theoraframes_info
- * @param avframe AVFrame to encode
+ * @param info oggmux_info
+ * @param yuv_buffer
* @param e_o_s 1 indicates ond of stream
*/
-int theoraframes_add_video (ff2theora this, theoraframes_info *info, AVFrame * avframe, int e_o_s){
- /* pysical pages */
- static theora_ycbcr_buffer ycbcr;
- /* Theora is a one-frame-in,one-frame-out system; submit a frame
- * for compression and pull out the packet */
-
- ycbcr[0].width = this->frame_width;
- ycbcr[0].height = this->frame_height;
- ycbcr[0].ystride = avframe->linesize[0];
-
- ycbcr[1].width = this->frame_width / 2;
- ycbcr[1].height = this->frame_height / 2;
- ycbcr[1].ystride = avframe->linesize[1];
-
- ycbcr[2].width = this->frame_width / 2;
- ycbcr[2].height = this->frame_height / 2;
- ycbcr[2].ystride = avframe->linesize[1];
-
-
- ycbcr[0].data = avframe->data[0];
- ycbcr[1].data = avframe->data[1];
- ycbcr[2].data = avframe->data[2];
-
- theora_encode_ycbcr_in(info->td,ycbcr);
- while(theora_encode_packetout(info->td, e_o_s, &info->op)) {
- ogg_stream_packetin (&info->to, &info->op);
+void oggmux_add_video (oggmux_info *info, theora_ycbcr_buffer ycbcr, int e_o_s){
+ ogg_packet op;
+
+ theora_encode_ycbcr_in(info->td,ycbcr);
+ while(theora_encode_packetout(info->td, e_o_s, &op)) {
+ ogg_stream_packetin (&info->to, &op);
}
-
- info->videoflag=1;
- return 0;
}
/**
@@ -215,7 +193,9 @@
* @param samples samples in buffer
* @param e_o_s 1 indicates end of stream.
*/
-int theoraframes_add_audio (theoraframes_info *info, int16_t * buffer, int bytes, int samples, int e_o_s){
+void oggmux_add_audio (oggmux_info *info, int16_t * buffer, int bytes, int samples, int e_o_s){
+ ogg_packet op;
+
int i,j, count = 0;
float **vorbis_buffer;
if (bytes <= 0 && samples <= 0){
@@ -234,28 +214,18 @@
vorbis_analysis_wrote (&info->vd, samples);
}
while(vorbis_analysis_blockout (&info->vd, &info->vb) == 1){
-
/* analysis, assume we want to use bitrate management */
vorbis_analysis (&info->vb, NULL);
vorbis_bitrate_addblock (&info->vb);
/* weld packets into the bitstream */
- while (vorbis_bitrate_flushpacket (&info->vd, &info->op)){
- ogg_stream_packetin (&info->vo, &info->op);
+ while (vorbis_bitrate_flushpacket (&info->vd, &op)){
+ ogg_stream_packetin (&info->vo, &op);
}
-
}
- info->audioflag=1;
- /*
- if (ogg_stream_eos (&info->vo)){
- info->audioflag = 0;
- return 0;
- }
- */
- return 0;
}
-static void print_stats(theoraframes_info *info, double timebase){
+static void print_stats(oggmux_info *info, double timebase){
int hundredths = timebase * 100 - (long) timebase * 100;
int seconds = (long) timebase % 60;
int minutes = ((long) timebase / 60) % 60;
@@ -266,77 +236,115 @@
if(info->akbps<0)
info->akbps=0;
- if(info->debug==1 && !info->video_only && !info->audio_only){
- fprintf (stderr,"\r %d:%02d:%02d.%02d audio: %dkbps video: %dkbps diff: %.4f ",
- hours, minutes, seconds, hundredths,info->akbps, info->vkbps,info->audiotime-info->videotime);
- }
- else{
- fprintf (stderr,"\r %d:%02d:%02d.%02d audio: %dkbps video: %dkbps ",
+ fprintf (stderr,"\r %d:%02d:%02d.%02d audio: %dkbps video: %dkbps ",
hours, minutes, seconds, hundredths,info->akbps, info->vkbps);
- }
+}
+static int write_audio_page(oggmux_info *info)
+{
+ int ret;
+
+ ret = fwrite(info->audiopage, 1, info->audiopage_len, info->outfile);
+ if(ret < info->audiopage_len) {
+ fprintf(stderr,"error writing audio page\n");
+ }
+ else {
+ info->audio_bytesout += ret;
+ }
+ info->audiopage_valid = 0;
+
+ info->akbps = rint (info->audio_bytesout * 8. / info->audiotime * .001);
+ print_stats(info, info->audiotime);
}
+static int write_video_page(oggmux_info *info)
+{
+ int ret;
-void theoraframes_flush (theoraframes_info *info, int e_o_s){
- /* flush out the ogg pages to info->outfile */
-
- int flushloop=1;
+ ret = fwrite(info->videopage, 1, info->videopage_len, info->outfile);
+ if(ret < info->videopage_len) {
+ fprintf(stderr,"error writing video page\n");
+ }
+ else {
+ info->video_bytesout += ret;
+ }
+ info->videopage_valid = 0;
- while(flushloop){
- int video = -1;
- flushloop=0;
- while(!info->audio_only && (e_o_s ||
- ((info->videotime <= info->audiotime || info->video_only) && info->videoflag == 1))){
-
- info->videoflag = 0;
- while(ogg_stream_pageout (&info->to, &info->videopage) > 0){
- info->videotime =
- theora_granule_time (info->td,ogg_page_granulepos(&info->videopage));
+ info->vkbps = rint (info->video_bytesout * 8. / info->videotime * .001);
+ print_stats(info, info->videotime);
+}
- /* flush a video page */
- info->video_bytesout +=
- fwrite (info->videopage.header, 1,info->videopage.header_len, info->outfile);
- info->video_bytesout +=
- fwrite (info->videopage.body, 1,info->videopage.body_len, info->outfile);
-
- info->vkbps = rint (info->video_bytesout * 8. / info->videotime * .001);
+void oggmux_flush (oggmux_info *info, int e_o_s)
+{
+ int len;
+ ogg_page og;
- print_stats(info, info->videotime);
- video=1;
- info->videoflag = 1;
- flushloop=1;
- }
- if(e_o_s)
- break;
+ /* flush out the ogg pages to info->outfile */
+ while(1) {
+ /* Get pages for both streams, if not already present, and if available.*/
+ if(!info->audio_only && !info->videopage_valid) {
+ if(ogg_stream_pageout(&info->to, &og) > 0) {
+ len = og.header_len + og.body_len;
+ if(info->videopage_buffer_length < len) {
+ info->videopage = realloc(info->videopage, len);
+ info->videopage_buffer_length = len;
+ }
+ info->videopage_len = len;
+ memcpy(info->videopage, og.header, og.header_len);
+ memcpy(info->videopage+og.header_len , og.body, og.body_len);
+
+ info->videopage_valid = 1;
+ info->videotime = theora_granule_time (info->td,
+ ogg_page_granulepos(&og));
}
+ }
+ if(!info->video_only && !info->audiopage_valid) {
+ if(ogg_stream_pageout(&info->vo, &og) > 0) {
+ len = og.header_len + og.body_len;
+ if(info->audiopage_buffer_length < len) {
+ info->audiopage = realloc(info->audiopage, len);
+ info->audiopage_buffer_length = len;
+ }
+ info->audiopage_len = len;
+ memcpy(info->audiopage, og.header, og.header_len);
+ memcpy(info->audiopage+og.header_len , og.body, og.body_len);
- while (!info->video_only && (e_o_s ||
- ((info->audiotime < info->videotime || info->audio_only) && info->audioflag==1))){
-
- info->audioflag = 0;
- while(ogg_stream_pageout (&info->vo, &info->audiopage) > 0){
- /* flush an audio page */
- info->audiotime=
- vorbis_granule_time (&info->vd,ogg_page_granulepos(&info->audiopage));
- info->audio_bytesout +=
- fwrite (info->audiopage.header, 1,info->audiopage.header_len, info->outfile);
- info->audio_bytesout +=
- fwrite (info->audiopage.body, 1,info->audiopage.body_len, info->outfile);
+ info->audiopage_valid = 1;
+ info->audiotime= vorbis_granule_time (&info->vd,
+ ogg_page_granulepos(&og));
+ }
+ }
- info->akbps = rint (info->audio_bytesout * 8. / info->audiotime * .001);
- print_stats(info, info->audiotime);
- video=0;
- info->audioflag = 1;
- flushloop=1;
- }
- if(e_o_s)
- break;
- }
+ if(info->video_only && info->videopage_valid) {
+ write_video_page(info);
+ }
+ else if(info->audio_only && info->audiopage_valid) {
+ write_audio_page(info);
+ }
+ /* We're using both. We can output only:
+ * a) If we have valid pages for both
+ * b) At EOS, for the remaining stream.
+ */
+ else if(info->videopage_valid && info->audiopage_valid) {
+ /* Make sure they're in the right order. */
+ if(info->videotime <= info->audiotime)
+ write_video_page(info);
+ else
+ write_audio_page(info);
+ }
+ else if(e_o_s && info->videopage_valid) {
+ write_video_page(info);
+ }
+ else if(e_o_s && info->audiopage_valid) {
+ write_audio_page(info);
+ }
+ else {
+ break; /* Nothing more writable at the moment */
+ }
}
}
-void theoraframes_close (theoraframes_info *info){
+void oggmux_close (oggmux_info *info){
ogg_stream_clear (&info->vo);
vorbis_block_clear (&info->vb);
vorbis_dsp_clear (&info->vd);
@@ -348,4 +356,9 @@
if (info->outfile && info->outfile != stdout)
fclose (info->outfile);
+
+ if(info->videopage)
+ free(info->videopage);
+ if(info->audiopage)
+ free(info->audiopage);
}
Modified: experimental/j/ffmpeg2theora-exp/theorautils.h
===================================================================
--- experimental/j/ffmpeg2theora-exp/theorautils.h 2005-09-19 22:33:56 UTC (rev 10034)
+++ experimental/j/ffmpeg2theora-exp/theorautils.h 2005-09-21 12:14:15 UTC (rev 10035)
@@ -1,6 +1,7 @@
+/* -*- tab-width:4;c-file-style:"cc-mode"; -*- */
/*
- * theorautils.h -- ogg/theora Utils for ffmpeg2ogg
- * Copyright (C) 2003 <j at v2v.cc>
+ * theorautils.h -- Ogg Theora/Ogg Vorbis Abstraction and Muxing
+ * Copyright (C) 2003-2005 <j at v2v.cc>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,113 +23,63 @@
#include "theora/theoraenc.h"
#include "vorbis/codec.h"
#include "vorbis/vorbisenc.h"
+#include "ogg/ogg.h"
-#define V2V_PRESET_PRO 1
-#define V2V_PRESET_PREVIEW 2
-typedef struct ff2theora{
- AVFormatContext *context;
- int video_index;
- int audio_index;
-
- int deinterlace;
- int audiostream;
- int sample_rate;
- int channels;
- int disable_audio;
- float audio_quality;
- int audio_bitrate;
-
- int picture_width;
- int picture_height;
- double fps;
- ImgReSampleContext *img_resample_ctx; /* for image resampling/resizing */
- ReSampleContext *audio_resample_ctx;
- ogg_uint32_t aspect_numerator;
- ogg_uint32_t aspect_denominator;
- double frame_aspect;
-
- int video_quality;
- int video_bitrate;
- int sharpness;
- int keyint;
-
- double force_input_fps;
- int sync;
-
- /* cropping */
- int frame_topBand;
- int frame_bottomBand;
- int frame_leftBand;
- int frame_rightBand;
-
- int frame_width;
- int frame_height;
- int frame_x_offset;
- int frame_y_offset;
-
- /* In seconds */
- int start_time;
- int end_time;
-
- double pts_offset; /* between given input pts and calculated output pts */
- int64_t frame_count; /* total video frames output so far */
- int64_t sample_count; /* total audio samples output so far */
-}
-*ff2theora;
-
-
-
typedef struct
{
- int debug;
- int preset;
+ /* the file the mixed ogg stream is written to */
+ FILE *outfile;
+
int audio_only;
int video_only;
+
+ /* vorbis settings */
int sample_rate;
int channels;
double vorbis_quality;
int vorbis_bitrate;
- int scale;
- int wide;
- double fps;
- double start;
- double end;
- ogg_page videopage;
- ogg_page audiopage;
- int audioflag;
- int videoflag;
- double audiotime;
- double videotime;
- int vkbps;
- int akbps;
- ogg_int64_t audio_bytesout;
- ogg_int64_t video_bytesout;
- ogg_stream_state to; /* take physical pages, weld into a logical
- * stream of packets */
- ogg_stream_state vo; /* take physical pages, weld into a logical
- * stream of packets */
- ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */
- ogg_packet op; /* one raw packet of data for decode */
+ vorbis_info vi; /* struct that stores all the static vorbis bitstream settings */
+ vorbis_comment vc; /* struct that stores all the user comments */
+ /* theora settings */
theora_info ti;
theora_comment tc;
-
- theora_enc_ctx *td;
- vorbis_info vi; /* struct that stores all the static vorbis bitstream settings */
- vorbis_comment vc; /* struct that stores all the user comments */
-
+ /* state info */
+ theora_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 */
- FILE *outfile;
+
+ /* used for muxing */
+ ogg_stream_state to; /* take physical pages, weld into a logical
+ * stream of packets */
+ ogg_stream_state vo; /* take physical pages, weld into a logical
+ * stream of packets */
+
+ int audiopage_valid;
+ int videopage_valid;
+ unsigned char *audiopage;
+ unsigned char *videopage;
+ int videopage_len;
+ int audiopage_len;
+ int videopage_buffer_length;
+ int audiopage_buffer_length;
+
+ /* some stats */
+ double audiotime;
+ double videotime;
+ int vkbps;
+ int akbps;
+ ogg_int64_t audio_bytesout;
+ ogg_int64_t video_bytesout;
}
-theoraframes_info;
+oggmux_info;
-extern void init_info(theoraframes_info *info);
-extern void theoraframes_init (theoraframes_info *info);
-extern int theoraframes_add_video (ff2theora this, theoraframes_info *info, AVFrame *avframe, int e_o_s);
-extern int theoraframes_add_audio (theoraframes_info *info, int16_t * readbuffer, int bytesread, int samplesread,int e_o_s);
-extern void theoraframes_flush (theoraframes_info *info, int e_o_s);
-extern void theoraframes_close (theoraframes_info *info);
+extern void init_info(oggmux_info *info);
+extern void oggmux_init (oggmux_info *info);
+extern void oggmux_add_video (oggmux_info *info, theora_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_flush (oggmux_info *info, int e_o_s);
+extern void oggmux_close (oggmux_info *info);
More information about the commits
mailing list