gimp-gap r810 - in trunk: . extern_libs libgapvidapi vid_enc_ffmpeg
- From: wolfgangh svn gnome org
- To: svn-commits-list gnome org
- Subject: gimp-gap r810 - in trunk: . extern_libs libgapvidapi vid_enc_ffmpeg
- Date: Sun, 8 Feb 2009 09:37:06 +0000 (UTC)
Author: wolfgangh
Date: Sun Feb 8 09:37:06 2009
New Revision: 810
URL: http://svn.gnome.org/viewvc/gimp-gap?rev=810&view=rev
Log:
updated external libs (ffmpeg and libmpeg3)
Modified:
trunk/ChangeLog
trunk/configure.in
trunk/extern_libs/Makefile.am
trunk/extern_libs/README_extern_libs
trunk/extern_libs/configure_options_ffmpeg.txt
trunk/extern_libs/ffmpeg.tar.gz
trunk/extern_libs/libmpeg3.tar.gz
trunk/libgapvidapi/gap_vid_api.h
trunk/libgapvidapi/gap_vid_api_ffmpeg.c
trunk/libgapvidapi/gap_vid_api_mpeg3.c
trunk/libgapvidapi/gap_vid_api_mpeg3toc.c
trunk/libgapvidapi/gap_vid_api_vidindex.c
trunk/vid_enc_ffmpeg/gap_enc_ffmpeg_gui.c
trunk/vid_enc_ffmpeg/gap_enc_ffmpeg_main.c
trunk/vid_enc_ffmpeg/gap_enc_ffmpeg_main.h
Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in (original)
+++ trunk/configure.in Sun Feb 8 09:37:06 2009
@@ -123,8 +123,25 @@
AM_CONDITIONAL(GAP_UNIX_FRONTENDS, test "x$enable_unix_frontends" != "xno")
+dnl check for bzip2 library (for ffmpeg matroskadec )
+dnl the check result does not matter unless libavformat is linked or built later on.
+FF_BZIP2=""
+ffbz2_warn=""
+AC_ARG_ENABLE(ff_libbz2,
+ [ --disable-ff-libbz2 configure libavformat without libbz2 disables matroskadec bz2 support])
+ if test "x$enable_ff_libbz2" != "xno"; then
+ AC_CHECK_LIB(bz2, BZ2_bzDecompressInit,
+ [AC_CHECK_HEADER(bzlib.h,
+ FF_BZIP2="-lbz2",
+ ffbz2_warn="$NEW_LINE ** bzip2 header file (bzlib.h) not found (limited support for ffmpeg matroskadec codec )")],
+ ffbz2_warn="bzip2 library (libbz2) not found (there will be limited support)")
+ fi
+
-dnl check for a52 library (required for ffmpeg dvd audio support)
+dnl ### checks for liba52 (once was required for ffmpeg dvd audio support)
+dnl ### recent ffmpeg no longer supports linking with liba52 (now wants libfaac libfaad libmp3lame)
+dnl ### will be reoved in future (when update to recent ffmpeg has proofed stable)
+dnl
dnl the check result does not matter unless libavformat is linked or built later on.
FF_LIBA52=""
a52_warn=""
@@ -138,7 +155,7 @@
a52_warn="a52 library (liba52) not found (there will be no DVD audio support)")
fi
dnl
-dnl libavformat can be configured to link liba52.a statical --enable-liba52
+dnl old libavformat could be configured to link liba52.a statical --enable-liba52
dnl or dynamical --enable-liba52bin (open liba52.so.0 at runtime )
dnl currently only the --enable-liba52bin option is handled automatically.
dnl
@@ -146,7 +163,63 @@
dnl the detection via AC_CHECK_LIB macro fails.
dnl
+dnl ## libmp3lame lame/lame.h lame_init -lmp3lame -lm
+
+dnl check for libmp3lame library (useful for ffmpeg audio MP3 support)
+dnl the check result does not matter unless libavformat is linked or built later on.
+FF_LIBMP3LAME=""
+mp3lame_warn=""
+AC_ARG_ENABLE(ff_libmp3lame,
+ [ --disable-ff-libmp3lame configure libavformat without libmp3lame])
+ if test "x$enable_ff_libmp3lame" != "xno"; then
+ AC_CHECK_LIB(mp3lame, lame_init,
+ [AC_CHECK_HEADER(lame/lame.h,
+ FF_LIBMP3LAME="-lmp3lame",
+ mp3lame_warn="$NEW_LINE ** mp3lame header file (lame/lame.h) not found (not critical)")],
+ mp3lame_warn="mp3lame library (libmp3lame) not found (not critical)")
+ fi
+dnl
+
+dnl check for faac library (useful for better ffmpeg audio support)
+dnl FAAC is an open source MPEG-4 and MPEG-2 AAC encoder, it is licensed under the LGPL
+dnl the check result does not matter unless libavformat is linked or built later on.
+FF_LIBFAAC=""
+faac_warn=""
+AC_ARG_ENABLE(ff_libfaac,
+ [ --disable-ff-libfaac configure libavformat without libfaac])
+ if test "x$enable_ff_libfaac" != "xno"; then
+ AC_CHECK_LIB(faac, faacEncGetVersion,
+ [AC_CHECK_HEADER(faac.h,
+ FF_LIBFAAC="-lfaac",
+ faac_warn="$NEW_LINE ** faac header file (faac.h) not found (not critical)")],
+ faac_warn="faac library (libfaac) not found (not critical)")
+ fi
+dnl
+
+dnl check for faad library (useful for better ffmpeg audio support)
+dnl FAAC is an open source MPEG-4 and MPEG-2 AAC encoder, it is licensed under the LGPL
+dnl the check result does not matter unless libavformat is linked or built later on.
+FF_LIBFAAD=""
+faad_warn=""
+AC_ARG_ENABLE(ff_libfaad,
+ [ --disable-ff-libfaad configure libavformat without libfaad])
+ if test "x$enable_ff_libfaad" != "xno"; then
+ AC_CHECK_LIB(faad, faacDecOpen,
+ [AC_CHECK_HEADER(faad.h,
+ FF_LIBFAAD="-lfaad",
+ faad_warn="$NEW_LINE ** faad header file (faad.h) not found (not critical)")],
+ faad_warn="faad library (libfaad) not found (not critical)")
+ fi
+dnl
+
+
+
+
+
+
dnl check for x264 library (additional for ffmpeg video codec support)
+dnl ### TODO check are no longer sufficient for recent ffmeg 2009.01.31.
+dnl ### check shall verify the condition "X264_BUILD >= 65
dnl the check result does not matter unless libavformat is linked or built later on.
FF_LIBX264=""
x264_warn=""
@@ -161,6 +234,10 @@
fi
+dnl ### TODO remove the next 2 lines when checks for recent libx264 are fixed.
+FF_LIBX264=""
+x264_warn=" WARNING checks for libx264 ar not up to date, ffmpeg is configured without libx264"
+
FF_LIBXVID=""
@@ -271,32 +348,59 @@
dnl options for ffmpeg ext libs configuration will be passed to ffmpeg/configure
dnl if some of those libs are installed (and not explicitly disabled)
- FFMPEG_EXTLIBS="$FF_LIBA52 $FF_LIBX264 $FF_LIBXVID"
+ FFMPEG_EXTLIBS="$FF_LIBA52 $FF_LIBX264 $FF_LIBXVID $FF_BZIP2 $FF_LIBMP3LAME $FF_LIBFAAC $FF_LIBFAAD"
GAP_VLIBS_FFMPEG=" $FFMPEG_LIBAVFORMAT_A $FFMPEG_LIBAVCODEC_A $FFMPEG_LIBAVUTIL_A $FFMPEG_EXTLIBS"
- GAP_VINCS_FFMPEG=" -I$FFMPEG_DIR/libavcodec -I$FFMPEG_DIR/libavformat -I$FFMPEG_DIR/libavutil "
+ GAP_VINCS_FFMPEG=" -I$FFMPEG_DIR -I$FFMPEG_DIR/libavcodec -I$FFMPEG_DIR/libavformat -I$FFMPEG_DIR/libavutil "
- vid_ffmpeg_warning="$x264_warn $a52_warn"
+ vid_ffmpeg_warning="
+ $x264_warn
+ $a52_warn
+ $ffbz2_warn
+ $mp3lame_warn
+ $faac_warn
+ $faad_warn
+ "
dnl read configure options for the external lib from a file
dnl the current simple implementation requires all options in one line
- FFMPEG_CONFIGURE_OPTIONS=`cat "$extern_libs_dir/configure_options_ffmpeg.txt" t | grep -v '^#'`
+ FFMPEG_CONFIGURE_OPTIONS=`cat "$extern_libs_dir/configure_options_ffmpeg.txt" | grep -v '^#'`
if test "x$CC" != "x"; then
FFMPEG_CONFIGURE_OPTIONS=" --cc=$CC $FFMPEG_CONFIGURE_OPTIONS"
fi
-
- if test "x$FF_LIBA52" != "x"; then
+
+ dnl configure ffmpeg bzip2 usage
+ if test "x$FF_BZIP2" != "x"; then
+ FFMPEG_CONFIGURE_OPTIONS="$FFMPEG_CONFIGURE_OPTIONS --enable-bzlib"
+ else
+ FFMPEG_CONFIGURE_OPTIONS="$FFMPEG_CONFIGURE_OPTIONS --disable-bzlib"
+ fi
+
+ dnl ### TODO recent ffmpeg no longer supports the option ---enable-liba52bin
+ dnl but now wants other audio libraries --enable-libmp3lame --enable-libfaac --enable-libfaad
+ dnl if test "x$FF_LIBA52" != "x"; then
dnl libavformat can be configured to link liba52.a statical --enable-liba52
dnl or dynamical --enable-liba52bin (open liba52.so.0 at runtime )
dnl 2007.05.17 test with dynamically linked liba52.so.0 did not work properly.
dnl (link ok, but audio extracting test delivered trashed wav file
- FFMPEG_CONFIGURE_OPTIONS="$FFMPEG_CONFIGURE_OPTIONS --enable-liba52bin"
- fi
+ dnl FFMPEG_CONFIGURE_OPTIONS="$FFMPEG_CONFIGURE_OPTIONS --enable-liba52bin"
+ dnl fi
- if test "x$FF_LIBX264" != "x"; then
- # FFMPEG_CONFIGURE_OPTIONS="$FFMPEG_CONFIGURE_OPTIONS --enable-x264"
- FFMPEG_CONFIGURE_OPTIONS="$FFMPEG_CONFIGURE_OPTIONS --enable-libx264"
+ dnl configure ffmpeg with optional audio libraries --enable-libmp3lame --enable-libfaac --enable-libfaad
+ if test "x$FF_LIBMP3LAME" != "x"; then
+ FFMPEG_CONFIGURE_OPTIONS="$FFMPEG_CONFIGURE_OPTIONS --enable-libmp3lame"
+ fi
+ if test "x$FF_LIBFAAC" != "x"; then
+ FFMPEG_CONFIGURE_OPTIONS="$FFMPEG_CONFIGURE_OPTIONS --enable-libfaac"
+ fi
+ if test "x$FF_LIBFAAD" != "x"; then
+ FFMPEG_CONFIGURE_OPTIONS="$FFMPEG_CONFIGURE_OPTIONS --enable-libfaad"
fi
+
+ dnl configure ffmpeg libx264 usage (for optional H.264 codec support via libx264)
+ dnl if test "x$FF_LIBX264" != "x"; then
+ dnl FFMPEG_CONFIGURE_OPTIONS="$FFMPEG_CONFIGURE_OPTIONS --enable-libfaac"
+ dnl fi
echo "================================="
@@ -323,7 +427,9 @@
if this tarball is not included in your gimp-gap distribution
you can get the ffmpeg tarball at:
- http://ffmpeg.sourceforge.net.
+ http://www.ffmpeg.org/
+ or http://ffmpeg.mplayerhq.hu/download.html
+ (old http://ffmpeg.sourceforge.net)
The configure option --disable-libavformat was activated due to this ERROR.
(This reduces the number of supported videoformats both for read and write
@@ -342,7 +448,10 @@
access. libavformat, libavcodec and libavutil are part of $FFMPEG_DIRNAME.
Warning: checks for libavformat, libavcodec and libavutil are not implemented yet.
-You can get ffmpeg at: http://ffmpeg.sourceforge.net.
+You can get ffmpeg at:
+ http://www.ffmpeg.org/
+ or http://ffmpeg.mplayerhq.hu/download.html
+ (old http://ffmpeg.sourceforge.net)
"
GAP_VLIBS_FFMPEG=" "
GAP_VINCS_FFMPEG=" "
@@ -393,7 +502,8 @@
libmpeg3 is limited to UNIX/LINUX operating systems.
This gimp-gap release includes the sourcecode of libmpeg3
(this is a duplicate of the original code libmpeg3-$REQ_LIBMPEG3_VERSION copied from:
- http://www.heroinewarrior.com/download.php3)
+ http:/prdownloads.sourceforge.net/heroines/libmpeg3-1.8-src.tar.bz2
+ old: http://www.heroinewarrior.com/download.php3)
"
@@ -495,22 +605,29 @@
if test "x$preinst_libmpeg3_specified" != "xyes"; then
- if test "x$enable_libmpeg3" != "no"; then
- dnl
- dnl First of all check if the compiler is able to handle the libmpeg3
- dnl code.
- dnl
-
- AC_MSG_CHECKING([if libmpeg3 code can be compiled])
- AC_COMPILE_IFELSE([
-int main(void) {
- unsigned char *data;
- *((unsigned short*)data)++ = 0x0;
- return 0;
-}],, enable_libmpeg3=no)
- AC_MSG_RESULT($enable_libmpeg3)
- fi
+dnl compile ability test is now disabled for libmpeg3
+dnl Note that this check once was introduced because old libmpeg3-1.5.4 did not compile
+dnl with recent gcc compiler versions.
+dnl libmpeg3-1.8 did compile fine on my openSuse 11.1 system
+dnl gcc (SUSE Linux) 4.3.2 [gcc-4_3-branch revision 141291]
+
+dnl if test "x$enable_libmpeg3" != "no"; then
+dnl dnl
+dnl dnl First of all check if the compiler is able to handle the libmpeg3
+dnl dnl code.
+dnl dnl
+dnl
+dnl AC_MSG_CHECKING([if libmpeg3 code can be compiled])
+dnl AC_COMPILE_IFELSE([
+dnl int main(void) {
+dnl unsigned char *data;
+dnl *((unsigned short*)data)++ = 0x0;
+dnl return 0;
+dnl }],, enable_libmpeg3=no)
+dnl AC_MSG_RESULT($enable_libmpeg3)
+dnl
+dnl fi
if test "x$enable_libmpeg3" != "xno"; then
@@ -602,7 +719,8 @@
if this tarball is not included in your gimp-gap distribution
you can get the source tarball libmpeg3-$REQ_LIBMPEG3_VERSION at:
- http://www.heroinewarrior.com/download.php3
+ http:/prdownloads.sourceforge.net/heroines/libmpeg3-1.8-src.tar.bz2
+ old: http://www.heroinewarrior.com/download.php3
The configure option --disable-libmpeg3 was activated due to this ERROR.
(This reduces the number of supported videoformats for read access.
Modified: trunk/extern_libs/Makefile.am
==============================================================================
--- trunk/extern_libs/Makefile.am (original)
+++ trunk/extern_libs/Makefile.am Sun Feb 8 09:37:06 2009
@@ -44,17 +44,17 @@
$(x_ffmpeg_libavformat):
echo "cd $(FFMPEG_DIR)"; \
cd $(FFMPEG_DIR);\
- make lib
+ make
$(x_ffmpeg_libavcodec):
echo "cd $(FFMPEG_DIR)"; \
cd $(FFMPEG_DIR);\
- make lib
+ make
$(x_ffmpeg_libavutil):
echo "cd $(FFMPEG_DIR)"; \
cd $(FFMPEG_DIR);\
- make lib
+ make
endif
Modified: trunk/extern_libs/README_extern_libs
==============================================================================
--- trunk/extern_libs/README_extern_libs (original)
+++ trunk/extern_libs/README_extern_libs Sun Feb 8 09:37:06 2009
@@ -3,18 +3,12 @@
CURRENT FFMPEG version is:
-- ffmpeg-export-snapshot-2007.10.31.tar.bz2
+- ffmpeg-export-snapshot.2009.01.31.tar.bz2
- Note: liba52 is no longer included in recent SVN snapshots
-
- ./configure --enable-shared --enable-static --disable-mmx --enable-gpl --enable-liba52
-
- results in ERROR: liba52 not found
- (older releases had liba52 subdirectory in libavcodec)
+CURRENT LIBMPEG3 version is:
-
-- libmpeg3-1.5.4
+- libmpeg3-1.8
The gimp-gap project does NOT maintain the sourcecode for those libs !
Bugs related to those libraries are never fixed here.
@@ -35,43 +29,27 @@
"FFMPEG" in the Master Videoencoder dialog).
You can get ffmpeg at:
- http://ffmpeg.sourceforge.net
-
-
-GIMP-GAP was developed and tested with several ffmpeg versions.
-The code still should compile and run with following versions:
-
- ==> BUG_001: read after seek fails on most MPEG1 videos
- (test with old gimp-gap and ffmpeg-CVS-2005.04.08
- shows the same problem !!)
-
-
- - ffmpeg-export-snapshot-2008.01.13.tar.bz2 NOT USABLE BREAKS video index compatibility
- - ffmpeg-export-snapshot-2007.12.20.tar.bz2 NOT USABLE BREAKS video index compatibility
- - ffmpeg-export-snapshot-2007.10.31.tar.bz2
-
- the option --enable-x264 was renamed to --enable-libx264
-
- - ffmpeg-export-snapshot-2007.05.15.tar.bz2
- - ffmpeg-export-snapshot-2007.04.20.tar.bz2 BUG_001
- - ffmpeg-export-snapshot-2007.04.04.tar.bz2 (Revision 8608) BUG_001
- - ffmpeg-export-snapshot-2007.03.06.tar.bz2 BUG_001
-
-
+ http://www.ffmpeg.org/
+ or http://ffmpeg.mplayerhq.hu/download.html
+ (old http://ffmpeg.sourceforge.net)
-It is recommanded to use the ffmpeg tarball that is included in
+It is highly recommanded to use the ffmpeg tarball that is included in
this GIMP-GAP distribution.
The ongoing ffmpeg development sometimes introduces incompatible changes
that would require changes and extension in the GIMP-GAP
- modules to enable compile together with GIMP-GAP and much testing
- to check if the new ffmpeg version will work.
+ modules to enable compile together with GIMP-GAP.
+ A succsessful build is no guarantee that GIMP-GAP
+ will work with a new ffmpeg version.
+ Typically it requires much testing and some knowledge
+ of bothe GIMP-GAP and ffmpeg internals to get new ffmpeg versions
+ working.
Therefore i decided to include an ffmpeg SVN snaphot
- that was tested with GIMP-GAP during April/May and November 2007
+ that was tested with GIMP-GAP during Jan/Feb 2009
- new ffmpeg SVN snapshots
+ newer ffmpeg SVN snapshots
may or may not compile, link and run with this GIMP-GAP release.
@@ -88,7 +66,32 @@
NOTE: Older ffmpeg versions that once worked with older GIMP-GAP
releases definitly will NOT compile / work with this GIMP-GAP release.
- GIMP-GAP has dropped support for the follwing old ffmpeg versions:
+GIMP-GAP has dropped support for the follwing old ffmpeg versions:
+
+ ==> BUG_003: Fails to detect DTS tmecode on some .VOB files
+ no native seek possible
+ (test with old gimp-gap and ffmpeg-export-snapshot-2008.01.13
+ shows the same problem !!)
+ ==> BUG_002: BREAKS video index compatibility based un url_ftell/url_fseek operations.
+ (test with old gimp-gap and ffmpeg-export-snapshot-2008.01.13
+ shows the same problem !!)
+ ==> BUG_001: read after seek fails on most MPEG1 videos
+ (test with old gimp-gap and ffmpeg-CVS-2005.04.08
+ shows the same problem !!)
+
+
+
+ ffmpeg-export-snapshot-2008.01.13.tar.bz2 BUG_002
+ ffmpeg-export-snapshot-2007.12.20.tar.bz2 BUG_002 breaks video index compatibility
+ ffmpeg-export-snapshot-2007.10.31.tar.bz2
+
+ the option --enable-x264 was renamed to --enable-libx264
+
+ ffmpeg-export-snapshot-2007.05.15.tar.bz2
+ ffmpeg-export-snapshot-2007.04.20.tar.bz2 BUG_001
+ ffmpeg-export-snapshot-2007.04.04.tar.bz2 (Revision 8608) BUG_001
+ ffmpeg-export-snapshot-2007.03.06.tar.bz2 BUG_001
+
ffmpeg-CVS-2005.04.08 (Support dropped)
ffmpeg-CVS-2005.03.02 (Support dropped)
ffmpeg-0.4.9pre1 (latest, but outdated official release is NOT SUPPORTED)
@@ -105,16 +108,19 @@
With libmpeg3 access to VCD and DVD is supported.
This includes read access to .vob and .ifo files.
-GIMP-GAP was developed and tested with libmpeg3-1.5.4
+GIMP-GAP was tested with libmpeg3-1.8
The sourcecode of this libmpeg3 version is included in the GIMP-GAP
distribution as tarball.
You can get libmpeg3 at:
- http://www.heroinewarrior.com/download.php3
+ http:/prdownloads.sourceforge.net/heroines/libmpeg3-1.8-src.tar.bz2
+ old: http://www.heroinewarrior.com/download.php3
-Note: the original has no installation support,
-it is recommanded to use the libmpeg3 tarball that is included in
-this GIMP-GAP distribution.
+Notes:
+- it is recommanded to use the libmpeg3 tarball that is included in
+ this GIMP-GAP distribution.
+- older GIMP-GAP versions had included libmpeg3-1.5.4,
+ this version is no longer supported.
Modified: trunk/extern_libs/configure_options_ffmpeg.txt
==============================================================================
--- trunk/extern_libs/configure_options_ffmpeg.txt (original)
+++ trunk/extern_libs/configure_options_ffmpeg.txt Sun Feb 8 09:37:06 2009
@@ -1,10 +1,15 @@
--enable-shared --enable-static --disable-mmx --enable-gpl
-# recent ffmpeg releases do no longer include liba52 (NO DVD audio support)
-# but supports dynamic linking if liba52 is installed.
+# recent ffmpeg releases does no longer support --enable-liba52
+# for audio /mp3 encoding ffmpeg recommands to link with the external libraries.
+#
# the gap main configure script checks if some of the external libs for ffmpeg
# are installed and adds further options automatically
-# --enable-liba52
-# --enable-libx264 (old name: --enable-x264)
-# --enable-libxvid (old name: --enable-xvid)
+#
+# --enable-libfaac
+# --enable-libfaad
+# --enable-libmp3lame
+# --enable-libx264 (old name: --enable-x264)
+# --enable-libxvid (old name: --enable-xvid)
+#
# options for the ffmpeg configure
Modified: trunk/extern_libs/ffmpeg.tar.gz
==============================================================================
Binary files. No diff available.
Modified: trunk/extern_libs/libmpeg3.tar.gz
==============================================================================
Binary files. No diff available.
Modified: trunk/libgapvidapi/gap_vid_api.h
==============================================================================
--- trunk/libgapvidapi/gap_vid_api.h (original)
+++ trunk/libgapvidapi/gap_vid_api.h Sun Feb 8 09:37:06 2009
@@ -161,7 +161,9 @@
typedef enum
{
- GVA_IDX_TT_GINT64
+ GVA_IDX_TT_WITHOUT_TIMECODE_GINT64 /* only used in old format */
+ ,GVA_IDX_TT_WITHOUT_TIMECODE_GDOUBLE /* only used in old format */
+ ,GVA_IDX_TT_GINT64
,GVA_IDX_TT_GDOUBLE
,GVA_IDX_TT_UNDEFINED
} t_GVA_IndexTabType;
@@ -172,6 +174,15 @@
gdouble offset_gdouble;
} t_GVA_UnionElem;
+typedef struct t_GVA_IndexElemWithoutTimecode /* old format */
+{
+ gint32 seek_nr;
+ guint16 frame_length;
+ guint16 checksum;
+
+ t_GVA_UnionElem uni;
+} t_GVA_IndexElemWithoutTimecode;
+
typedef struct t_GVA_IndexElem
{
gint32 seek_nr;
@@ -179,6 +190,7 @@
guint16 checksum;
t_GVA_UnionElem uni;
+ gint64 timecode_dts;
} t_GVA_IndexElem;
typedef struct t_GVA_Videoindex /* nick: vindex */
Modified: trunk/libgapvidapi/gap_vid_api_ffmpeg.c
==============================================================================
--- trunk/libgapvidapi/gap_vid_api_ffmpeg.c (original)
+++ trunk/libgapvidapi/gap_vid_api_ffmpeg.c Sun Feb 8 09:37:06 2009
@@ -39,9 +39,7 @@
/* some defines to enable theme specific debug printf's
* those defines are currently not configurable.
*/
-
#undef GAP_DEBUG_FF_NATIVE_SEEK
-/* #define GAP_DEBUG_FF_NATIVE_SEEK */
@@ -49,6 +47,17 @@
#define GIMPRC_PERSISTENT_ANALYSE "video-gva-libavformat-video-analyse-persistent"
#define ANALYSE_DEFAULT TRUE
+/* MAX_PREV_OFFSET defines how to record defered url_offest frames of previous frames for byte positions in video index
+ * in tests the byte based seek takes us to n frames after the wanted frame. Therefore video index creation
+ * tries to comensate this by recording the offsets of the nth pervious frame.
+ *
+ * tuning: values 1 upto 12 did not compensate enough.
+ * this resulted in more than 1 SYNC LOOP when positioning vio byte position and makes video index slower.
+ *
+ */
+#define MAX_PREV_OFFSET 14
+
+
/* -------------------------
* API READ extension FFMPEG
* -------------------------
@@ -58,6 +67,7 @@
/* samples buffer for ca. 500 Audioframes at 48000 Hz Samplerate and 30 fps
* if someone tries to get a bigger audio segment than this at once
* the call will fail !!
+ * (shall be defined >= AVCODEC_MAX_AUDIO_FRAME_SIZE (192000)
*/
#define GVA_SAMPLES_BUFFER_SIZE 2400000
@@ -114,12 +124,9 @@
gboolean capture_offset; /* TRUE: capture url_offsets to vindex while reading next frame */
gint32 max_frame_len;
gint32 frame_len;
- gint32 got_frame_length;
- gint64 prev_url_offset;
- gint64 prev_prev_url_offset;
- gint64 prev_key_url_offset;
+ guint16 got_frame_length16; /* 16 lower bits of the length */
+ gint64 prev_url_offset[MAX_PREV_OFFSET];
gint32 prev_key_seek_nr;
- gint32 prev_pkt_count;
gdouble guess_gop_size;
int vid_stream_index;
@@ -190,6 +197,7 @@
, gint64 url_offset
, guint16 frame_length
, guint16 checksum
+ , gint64 timecode_dts
);
static guint16 p_gva_checksum(AVPicture *picture_yuv, gint32 height);
static t_GVA_RetCode p_wrapper_ffmpeg_get_next_frame(t_GVA_Handle *gvahand);
@@ -222,6 +230,16 @@
static t_GVA_RetCode p_wrapper_ffmpeg_get_next_frame(t_GVA_Handle *gvahand);
static t_GVA_RetCode p_private_ffmpeg_get_next_frame(t_GVA_Handle *gvahand, gboolean do_copy_raw_chunk_data);
+/* -----------------------------
+ * p_wrapper_ffmpeg_check_sig
+ * -----------------------------
+ */
+static inline gboolean
+p_areTimecodesEqualWithTolerance(gint64 timecode1, gint64 timecode2)
+{
+#define TIMECODE_EQ_TOLERANCE 2
+ return (abs(timecode1 - timecode2) <= TIMECODE_EQ_TOLERANCE);
+}
/* -----------------------------
* p_wrapper_ffmpeg_check_sig
@@ -298,13 +316,16 @@
handle->dummy_read = FALSE;
handle->capture_offset = FALSE;
handle->guess_gop_size = 0;
- handle->prev_url_offset = 0;
- handle->prev_prev_url_offset = 0;
- handle->prev_key_url_offset = 0;
+ {
+ gint ii;
+ for(ii=0; ii < MAX_PREV_OFFSET; ii++)
+ {
+ handle->prev_url_offset[ii] = 0;
+ }
+ }
handle->prev_key_seek_nr = 1;
- handle->prev_pkt_count = 0;
handle->max_frame_len = 0;
- handle->got_frame_length = 0;
+ handle->got_frame_length16 = 0;
handle->vid_input_context = NULL; /* set later (if has video) */
handle->aud_input_context = NULL; /* set later (if has audio) */
handle->vid_codec_context = NULL; /* set later (if has video) */
@@ -410,7 +431,7 @@
handle->inbuf_len = 0; /* start with empty buffer */
- handle->frame_len = 0; /* start with empty buffer */
+ handle->frame_len = 0; /* start with 0 frame length */
handle->inbuf_ptr = NULL; /* start with empty buffer, after 1.st av_read_frame: pointer to pkt.data read pos */
/* yuv_buffer big enough for all supported PixelFormats
@@ -767,12 +788,90 @@
} /* end p_wrapper_ffmpeg_get_next_frame*/
+
+/* ----------------------------------
+ * p_url_ftell
+ * ----------------------------------
+ * GIMP-GAP private variant of url_ftell procedure
+ * (original implementation see see libacformat/aviobuf.c)
+ *
+ * restrictions:
+ * only the part for input strams is supported.
+ * (e.g. write_flag is ignored here)
+ * includes some chacks for inplausible results.
+ *
+ * the internal calculation looks like this:
+ * pos = s->pos - (s->write_flag ? 0 : (s->buf_end - s->buffer));
+ * return pos + (s->buf_ptr - s->buffer)
+ *
+ */
+inline static int64_t
+p_url_ftell(ByteIOContext *s)
+{
+ int64_t currentOffsetInStream;
+ int64_t bytesReadInBuffer;
+ int64_t bytesAlreadyHandledInBuffer;
+ int64_t bufferStartOffsetInStream;
+
+ if(s == NULL)
+ {
+ return (0);
+ }
+
+ /* ignore negative buffer size (in such cases the buffer is rather empty or not initialized properly) */
+ bytesReadInBuffer = MAX(0, (s->buf_end - s->buffer));
+
+ /* ignore negative buffer size (in such cases the buffer is rather empty or not initialized properly) */
+ bytesAlreadyHandledInBuffer = 0;
+ if((s->buf_ptr >= s->buffer) && (s->buf_ptr <= s->buf_end))
+ {
+ bytesAlreadyHandledInBuffer = MAX(0, (s->buf_ptr - s->buffer));
+ }
+ else
+ {
+ printf(" ** ERROR current buf_ptr:%d points outside of the buffer (start: %d end:%d)\n"
+ ,(int)s->buf_ptr
+ ,(int)s->buffer
+ ,(int)s->buf_end
+ );
+ }
+
+
+ /* ignore inplausible staart offsets */
+ bufferStartOffsetInStream = 0;
+ if(s->pos > bytesReadInBuffer)
+ {
+ bufferStartOffsetInStream = s->pos - bytesReadInBuffer;
+ }
+
+ currentOffsetInStream = bufferStartOffsetInStream + bytesAlreadyHandledInBuffer;
+
+ printf("P_URL_FTELL: url64:%lld pos: %lld, wr_flag:%d, buffer:%d buf_end:%d buf_ptr:%d\n"
+ " bufferStartOffsetInStream:%lld, bytesReadInBuffer:%lld bytesAlreadyHandledInBuffer:%lld\n\n"
+ ,currentOffsetInStream
+ ,s->pos
+ ,(int)s->write_flag
+ ,(int)s->buffer
+ ,(int)s->buf_end
+ ,(int)s->buf_ptr
+ ,bufferStartOffsetInStream
+ ,bytesReadInBuffer
+ ,bytesAlreadyHandledInBuffer
+ );
+
+ return (currentOffsetInStream);
+}
+
/* ----------------------------------
* p_private_ffmpeg_get_next_frame
* ----------------------------------
* read one frame from the video_track (stream)
* and decode the frame
* when EOF reached: update total_frames and close the stream)
+ * if recording of videoindex is enabled (in the handle)
+ * then record positions of keyframes in the videoindex.
+ * the flag do_copy_raw_chunk_data triggers copying the frame as raw data
+ * chunk (useful for lossless video cut purpose)
*/
static t_GVA_RetCode
p_private_ffmpeg_get_next_frame(t_GVA_Handle *gvahand, gboolean do_copy_raw_chunk_data)
@@ -780,16 +879,15 @@
t_GVA_ffmpeg *handle;
int l_got_picture;
int l_rc;
- gint64 l_url_offset;
+ gint64 l_curr_url_offset;
gint64 l_record_url_offset;
gint32 l_url_seek_nr;
gint32 l_len;
- gint32 l_frame_len;
gint32 l_pkt_size;
- gint32 l_pkt_count;
- gint32 l_prev_pkt_count;
+ guint16 l_frame_len; /* 16 lower bits of the length */
guint16 l_checksum;
gboolean l_potential_index_frame;
+ gboolean l_key_frame_detected;
handle = (t_GVA_ffmpeg *)gvahand->decoder_handle;
@@ -807,15 +905,11 @@
l_frame_len = 0;
l_pkt_size = 0;
- l_prev_pkt_count = handle->prev_pkt_count;
-
- /* capture the offest 2 frames ago */
- l_record_url_offset = handle->prev_key_url_offset;
- l_pkt_count = handle->prev_pkt_count;
-
- l_url_offset = -1;
+ l_record_url_offset = -1;
+ l_curr_url_offset = -1;
l_url_seek_nr = gvahand->current_seek_nr;
-
+ l_key_frame_detected = FALSE;
+
while(l_got_picture == 0)
{
int l_pktlen;
@@ -823,25 +917,14 @@
/* if inbuf is empty we must read the next packet */
if((handle->inbuf_len < 1) || (handle->inbuf_ptr == NULL))
{
- if((handle->vid_input_context->packet_buffer == NULL)
- && (l_url_offset < 0))
- {
- /* capture only if packet_buffer is empty
- * (the following av_read_frame call will read packages
- * from the packet_buffer if not empty, but reads from stream
- * on empty packet_buffer)
- */
- l_url_offset = url_ftell(&handle->vid_input_context->pb);
- if(l_url_offset != handle->prev_url_offset)
- {
- handle->prev_prev_url_offset = handle->prev_url_offset;
- handle->prev_url_offset = l_url_offset;
- handle->prev_pkt_count = l_pkt_count;
- l_pkt_count = 0;
- }
- }
-
-
+ /* query current position in the file url_ftell
+ * Note that url_ftell operates on the ByteIOContext handle->vid_input_context->pb
+ * and calculates correct file position by taking both the current (buffered) read position
+ * and buffer position into account.
+ */
+ //l_curr_url_offset = p_url_ftell(handle->vid_input_context->pb);
+ l_curr_url_offset = url_ftell(handle->vid_input_context->pb);
+
/* if (gap_debug) printf("p_wrapper_ffmpeg_get_next_frame: before av_read_frame\n"); */
/**
* Read a packet from a media file
@@ -857,7 +940,8 @@
{
printf("p_wrapper_ffmpeg_get_next_frame: EOF reached (or read ERROR)\n");
}
-
+ l_record_url_offset = -1;
+
if (gvahand->all_frames_counted != TRUE)
{
gvahand->total_frames = gvahand->current_frame_nr;
@@ -876,7 +960,6 @@
l_rc = 1;
break;
}
- l_pkt_count++;
/* if (gap_debug) printf("vid_stream:%d pkt.stream_index #%d, pkt.size: %d\n", handle->vid_stream_index, handle->vid_pkt.stream_index, handle->vid_pkt.size); */
@@ -887,6 +970,7 @@
/* discard packet */
/* if (gap_debug) printf("DISCARD Packet\n"); */
av_free_packet(&handle->vid_pkt);
+ l_record_url_offset = -1;
continue;
}
@@ -896,13 +980,17 @@
l_pkt_size = handle->vid_pkt.size;
handle->frame_len += l_pkt_size;
- /*if(gap_debug) printf("using Packet data:%d size:%d handle->frame_len:%d\n"
- * ,(int)handle->vid_pkt.data
- * ,(int)handle->vid_pkt.size
- * ,(int)handle->frame_len
- * );
- */
-
+
+ if(gap_debug)
+ { printf("using Packet data:%d size:%d handle->frame_len:%d dts:%lld pts:%lld AV_NOPTS_VALUE:%lld\n"
+ ,(int)handle->vid_pkt.data
+ ,(int)handle->vid_pkt.size
+ ,(int)handle->frame_len
+ , handle->vid_pkt.dts
+ , handle->vid_pkt.pts
+ , AV_NOPTS_VALUE
+ );
+ }
}
if (gap_debug)
@@ -989,10 +1077,25 @@
handle->inbuf_len -= l_len;
if(l_got_picture)
{
- l_frame_len = handle->frame_len + (l_len - l_pkt_size);
+ l_frame_len = (l_len & 0xffff);
handle->frame_len = (l_len - l_pkt_size);
+ l_record_url_offset = l_curr_url_offset;
+ l_key_frame_detected = ((handle->vid_pkt.flags & PKT_FLAG_KEY) != 0);
+
+ if(gap_debug)
+ {
+ /* log information that could be relevant for redesign of VINDEX creation */
+ printf("GOT PICTURE current_seek_nr:%06d pp_prev_offset:%lld url_offset:%lld keyflag:%d dts:%lld flen16:%d len:%d\n"
+ , (int)gvahand->current_seek_nr
+ , handle->prev_url_offset[MAX_PREV_OFFSET -1]
+ , l_record_url_offset
+ , (handle->vid_pkt.flags & PKT_FLAG_KEY)
+ , handle->vid_pkt.dts
+ ,(int)l_frame_len
+ ,(int)l_len
+ );
+ }
}
-
/* length of video packet was completely processed, we can free that packet now */
if(handle->inbuf_len < 1)
@@ -1009,18 +1112,17 @@
{
if(gvahand->current_seek_nr > 1)
{
- /* 1.st frame_len may contain headers (size may be too large)
- */
- handle->max_frame_len = MAX(handle->max_frame_len, l_frame_len);
+ /* 1.st frame_len may contain headers (size may be too large) */
+ handle->max_frame_len = MAX(handle->max_frame_len, l_len);
}
- handle->got_frame_length = l_frame_len;
+ handle->got_frame_length16 = l_frame_len;
if(gap_debug)
{
printf("GOT PIC: current_seek_nr:%06d l_frame_len:%d got_pic:%d key:%d\n"
, (int)gvahand->current_seek_nr
- , (int)l_frame_len
+ , (int)handle->got_frame_length16
, (int)l_got_picture
, (int)handle->big_picture_yuv.key_frame
);
@@ -1049,7 +1151,7 @@
l_potential_index_frame = FALSE;
- if(handle->big_picture_yuv.key_frame == 1)
+ if((handle->big_picture_yuv.key_frame == 1) || (l_key_frame_detected == TRUE))
{
l_potential_index_frame = TRUE;
handle->key_frame_detection_works = TRUE;
@@ -1125,19 +1227,36 @@
handle->guess_gop_size = MAX(GVA_LOW_GOP_LIMIT, ((handle->guess_gop_size + l_gopsize) / 2));
}
}
- if(l_url_seek_nr >= handle->prev_key_seek_nr + GVA_LOW_GOP_LIMIT)
+ if (l_url_seek_nr >= handle->prev_key_seek_nr + GVA_LOW_GOP_LIMIT)
{
- handle->prev_key_url_offset = handle->prev_prev_url_offset;
+ /* record the url_offset of 2 frames before. this is done because positioning to current
+ * frame via url_fseek will typically take us to frame number +2
+ */
p_vindex_add_url_offest(gvahand
, handle
, gvahand->vindex
, l_url_seek_nr
- , l_record_url_offset
- , (guint16)l_frame_len
+ , handle->prev_url_offset[MAX_PREV_OFFSET -1]
+ , handle->got_frame_length16
, l_checksum
+ , handle->vid_pkt.dts
);
handle->prev_key_seek_nr = l_url_seek_nr;
}
+
+ }
+
+ if(handle->capture_offset)
+ {
+ gint ii;
+
+ /* save history of the last captured url_offsets in the handle
+ */
+ for(ii = MAX_PREV_OFFSET -1; ii > 0; ii--)
+ {
+ handle->prev_url_offset[ii] = handle->prev_url_offset[ii -1];
+ }
+ handle->prev_url_offset[0] = l_record_url_offset;
}
gvahand->current_frame_nr = gvahand->current_seek_nr;
@@ -1597,6 +1716,7 @@
+
/* ------------------------------
* p_seek_private
* ------------------------------
@@ -1803,6 +1923,10 @@
if(l_idx > 0)
{
+ gint32 l_idx_target;
+
+ l_idx_target = l_idx;
+
l_readsteps = l_frame_pos - gvahand->current_seek_nr;
if((l_readsteps > vindex->stepsize)
|| (l_readsteps < 0))
@@ -1811,29 +1935,83 @@
gint32 l_nloops;
l_nloops = 1;
- while(l_idx >= 0)
+ while((l_idx >= 0) && (l_nloops < 12))
{
+ gboolean l_dts_timecode_usable;
+
+ l_dts_timecode_usable = FALSE;
+
+ if((vindex->ofs_tab[l_idx].timecode_dts != AV_NOPTS_VALUE)
+ && (l_nloops == 1)
+ && (vindex->ofs_tab[l_idx_target].timecode_dts != AV_NOPTS_VALUE)
+ && (vindex->ofs_tab[0].timecode_dts != AV_NOPTS_VALUE))
+ {
+ l_dts_timecode_usable = TRUE;
+ }
+
if(gap_debug)
{
- printf("SEEK: USING_INDEX: ofs_tab[%d]: ofs64: %d seek_nr:%d flen:%d chk:%d NLOOPS:%d\n"
+ printf("SEEK: USING_INDEX: ofs_tab[%d]: ofs64: %lld seek_nr:%d flen:%d chk:%d dts:%lld DTS_USABLE:%d NLOOPS:%d\n"
, (int)l_idx
- , (int)vindex->ofs_tab[l_idx].uni.offset_gint64
+ , vindex->ofs_tab[l_idx].uni.offset_gint64
, (int)vindex->ofs_tab[l_idx].seek_nr
, (int)vindex->ofs_tab[l_idx].frame_length
, (int)vindex->ofs_tab[l_idx].checksum
+ , vindex->ofs_tab[l_idx].timecode_dts
+ , l_dts_timecode_usable
, (int)l_nloops
);
}
-
- l_synctries = 4 + (vindex->stepsize * GVA_IDX_SYNC_STEPSIZE);
+
+ l_synctries = 4 + MAX_PREV_OFFSET +(vindex->stepsize * GVA_IDX_SYNC_STEPSIZE);
+
/* SYNC READ loop
* seek to offest found in the index table
* then read until we are at the KEYFRAME that matches
- * in length and checksum with the one from th index table
+ * in length and checksum with the one from the index table
+ *
+ * Note that Byte offest based seek is not frame exact. Seek may take us
+ * to positions after the wanted framenumber.
+ * (therefore we make more attempts l_nloops > 1 with previous index entries)
+ *
+ * Timecode based seek shall take us to the wanted frame already in the 1st attempt
+ * but will fail (probably in all attempts) when the video has corrupted timecodes.
+ * therefore switch seek strategy fo byte offset based seek in further attempts (l_nloops != 1)
+ *
+ * for some videofiles dts timecodes are available but not for all frames.
+ * for those videos seek via dts does NOT work.
+ * such videos are marked with AV_NOPTS_VALUE in entry at index 0
+ * (vindex->ofs_tab[0].timecode_dts == AV_NOPTS_VALUE)
+ *
*/
p_ffmpeg_vid_reopen_read(handle, gvahand);
- seek_pos = vindex->ofs_tab[l_idx].uni.offset_gint64;
- url_fseek(&handle->vid_input_context->pb, seek_pos, SEEK_SET);
+ if(l_dts_timecode_usable)
+ {
+ int ret_av_seek_frame;
+
+ l_synctries = 1;
+
+ if(gap_debug)
+ {
+ printf("USING DTS timecode based av_seek_frame\n");
+ }
+
+ /* timecode based seek */
+ ret_av_seek_frame = av_seek_frame(handle->vid_input_context, handle->vid_stream_index
+ , vindex->ofs_tab[l_idx].timecode_dts, AVSEEK_FLAG_BACKWARD);
+ }
+ else
+ {
+ int ret_av_seek_frame;
+ /* seek based on url_fseek (for support of old video indexes without timecode) */
+ seek_pos = vindex->ofs_tab[l_idx].uni.offset_gint64;
+ // url_fseek(handle->vid_input_context->pb, seek_pos, SEEK_SET);
+
+ /* byte position based seek AVSEEK_FLAG_BACKWARD AVSEEK_FLAG_ANY*/
+ ret_av_seek_frame = av_seek_frame(handle->vid_input_context, handle->vid_stream_index
+ ,seek_pos, AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_BYTE);
+
+ }
p_clear_inbuf_and_vid_packet(handle);
gvahand->current_seek_nr = vindex->ofs_tab[vindex->tabsize_used].uni.offset_gint64;
@@ -1842,24 +2020,48 @@
while((l_rc_rd == GVA_RET_OK)
&& (l_synctries > 0))
{
+ gboolean l_potentialCanditate;
+
+ l_potentialCanditate = FALSE;
l_rc_rd = p_wrapper_ffmpeg_get_next_frame(gvahand);
- /*
- * printf("SEEK_SYNC_LOOP: idx_frame_len:%d got_frame_length:%d Key:%d\n"
- * , (int)vindex->ofs_tab[l_idx].frame_length
- * , (int)handle->got_frame_length
- * , (int)handle->big_picture_yuv.key_frame
- * );
- */
+// printf("SEEK_SYNC_LOOP: idx_frame_len:%d got_frame_length16:%d Key:%d dts:%lld\n"
+// , (int)vindex->ofs_tab[l_idx_target].frame_length
+// , (int)handle->got_frame_length16
+// , (int)handle->big_picture_yuv.key_frame
+// , handle->vid_pkt.dts
+// );
- if(vindex->ofs_tab[l_idx].frame_length == handle->got_frame_length)
+ if(l_dts_timecode_usable == TRUE)
+ {
+ /* handling for index format with usable timecode
+ * for videos where DTS timecodes are consistent
+ * the 1st seek attempt shall take us already to the wanted position.
+ * (an additional length check would fail in this situation due to the buggy
+ * length information)
+ */
+ if(TRUE == p_areTimecodesEqualWithTolerance(vindex->ofs_tab[l_idx].timecode_dts, handle->vid_pkt.dts))
+ {
+ l_potentialCanditate = TRUE;
+ }
+ }
+ else
+ {
+ /* handling for old index formats without timecode */
+ if(vindex->ofs_tab[l_idx_target].frame_length == handle->got_frame_length16)
+ {
+ l_potentialCanditate = TRUE;
+ }
+ }
+
+ if (l_potentialCanditate == TRUE)
{
guint16 l_checksum;
l_checksum = p_gva_checksum(handle->picture_yuv, gvahand->height);
- if(l_checksum == vindex->ofs_tab[l_idx].checksum)
+ if(l_checksum == vindex->ofs_tab[l_idx_target].checksum)
{
- /* seems that we have found the wanted key frame */
+ /* we have found the wanted (key) frame */
break;
}
else
@@ -1870,16 +2072,18 @@
* continue searching for an exactly matching frame
*/
printf("SEEK_SYNC_LOOP: CHKSUM_MISSMATCH: CHECKSUM[%d]:%d l_checksum:%d\n"
- , (int)l_idx
- , (int)vindex->ofs_tab[l_idx].checksum
+ , (int)l_idx_target
+ , (int)vindex->ofs_tab[l_idx_target].checksum
, (int)l_checksum
);
}
}
-
}
+
l_synctries--;
- }
+ } /* end while */
+
+
if(l_synctries <= 0)
{
/* index sync search failed, try with previous index in the table */
@@ -1893,13 +2097,14 @@
}
else
{
+ /* index sync search had success */
- l_url_frame_pos = 1 + vindex->ofs_tab[l_idx].seek_nr;
+ l_url_frame_pos = 1 + vindex->ofs_tab[l_idx_target].seek_nr;
if(gap_debug)
{
- printf("SEEK: url_fseek seek_pos: %d l_idx:%d l_url_frame_pos:%d\n"
+ printf("SEEK: url_fseek seek_pos: %d l_idx_target:%d l_url_frame_pos:%d\n"
, (int)seek_pos
- , (int)l_idx
+ , (int)l_idx_target
, (int)l_url_frame_pos
);
}
@@ -1913,8 +2118,21 @@
break; /* OK, we are now at read position of the wanted keyframe */
}
- /* try another search with previous index table entry */
- l_idx -= GVA_IDX_SYNC_STEPSIZE;
+ if(l_dts_timecode_usable == TRUE)
+ {
+ /* if seek via dts timecode failed, switch to byte offset based seek
+ * but this must be restarted with the same index [l_idx]
+ * (we must not decrement l_idx because timecode based seek has only checked one frame.
+ * if the wanted frame is in the search range of current l_idx it will never be found
+ * if we advance at this point, which results in very slow sequential search afterwards)
+ */
+ l_dts_timecode_usable = FALSE;
+ }
+ else
+ {
+ /* try another search with previous index table entry */
+ l_idx -= GVA_IDX_SYNC_STEPSIZE;
+ }
l_nloops++;
}
@@ -2016,7 +2234,7 @@
* to allow clean sequential reads afterwards.
* futher results are stored in the decoder specific handle (part of gvahand)
* handle->video_libavformat_seek_gopsize
- * (is automaticall increased when necessary)
+ * (is automatically increased when necessary)
* handle->eof_timecode
* (is set when detected the 1st time)
* handle->handle->native_timecode_seek_failcount
@@ -2304,7 +2522,7 @@
if(gap_debug)
{
gint64 url_pos;
- url_pos = url_ftell(&handle->vid_input_context->pb);
+ url_pos = url_ftell(handle->vid_input_context->pb);
printf(" [%d.%02d] START nat-seek READ FRAME url_pos:%lld\n"
, l_tries
, l_ii
@@ -2320,7 +2538,7 @@
#ifdef GAP_DEBUG_FF_NATIVE_SEEK
{
gint64 url_pos;
- url_pos = url_ftell(&handle->vid_input_context->pb);
+ url_pos = url_ftell(handle->vid_input_context->pb);
printf(" [%d.%02d] END nat-seek READ FRAME url_pos:%lld curr_timecode:%lld rc:%d\n"
, l_tries
, l_ii
@@ -2347,14 +2565,14 @@
#ifdef GAP_DEBUG_FF_NATIVE_SEEK
printf("** ERROR AVFORMAT: (%d) errcount:%d timbased seek failed to read frame after native seek rc:%d\n"
- " * target_frame:%ld cur_timecode:%lld, l_fnr:%ld, total_frames:%ld, all_counted:%d\n"
- , l_ii
- , l_read_err_count
+ " * target_frame:%d cur_timecode:%lld, l_fnr:%d, total_frames:%d, all_counted:%d\n"
+ , (int)l_ii
+ , (int)l_read_err_count
, (int)l_rc_timeread
- , target_frame
+ , (int)target_frame
, l_curr_timecode
- , l_fnr
- , gvahand->total_frames
+ , (int)l_fnr
+ , (int)gvahand->total_frames
, (int)gvahand->all_frames_counted
);
#endif /* GAP_DEBUG_FF_NATIVE_SEEK */
@@ -3032,7 +3250,7 @@
{
AVCodec *codec;
- for(codec = first_avcodec; codec != NULL; codec = codec->next)
+ for(codec = av_codec_next(NULL); codec != NULL; codec = av_codec_next(codec))
{
printf("\n-------------------------\n");
printf("name: %s\n", codec->name);
@@ -3183,9 +3401,10 @@
rfps = ic->streams[ii]->r_frame_rate;
+ acc->strict_std_compliance = FF_COMPLIANCE_NORMAL;
acc->workaround_bugs = FF_BUG_AUTODETECT;
- acc->error_resilience = 2;
- acc->error_concealment = 3;
+ acc->error_recognition = FF_ER_COMPLIANT;
+ acc->error_concealment = FF_EC_DEBLOCK | FF_EC_GUESS_MVS;
acc->idct_algo= 0;
/*
* if(acc->codec->capabilities & CODEC_CAP_TRUNCATED)
@@ -3436,9 +3655,17 @@
{
av_free_packet(&handle->vid_pkt);
}
+ {
+ gint ii;
+ for(ii=0; ii < MAX_PREV_OFFSET; ii++)
+ {
+ handle->prev_url_offset[ii] = 0;
+ }
+ }
handle->vid_pkt.size = 0; /* REstart with empty packet */
handle->vid_pkt.data = NULL; /* REstart with empty packet */
handle->inbuf_len = 0; /* start with empty buffer */
+ handle->frame_len = 0; /* start with 0 frame length */
handle->inbuf_ptr = NULL; /* start with empty buffer, after 1.st av_read_frame: pointer to pkt.data read pos */
/* RE-open for the VIDEO part */
@@ -3776,13 +4003,14 @@
handle->abuf_len = handle->aud_pkt.size;
}
- /* if (gap_debug) printf("before avcodec_decode_audio: abuf_ptr:%d abuf_len:%d\n", (int)handle->abuf_ptr, (int)handle->abuf_len); */
+ /* if (gap_debug) printf("before avcodec_decode_audio2: abuf_ptr:%d abuf_len:%d\n", (int)handle->abuf_ptr, (int)handle->abuf_len); */
/* decode a frame. return -1 if error, otherwise return the number of
* bytes used. If no audio frame could be decompressed, data_size is
- * zero or lnegative.
+ * zero or negative.
*/
- l_len = avcodec_decode_audio(handle->aud_codec_context /* AVCodecContext * */
+ data_size = handle->samples_buffer_size;
+ l_len = avcodec_decode_audio2(handle->aud_codec_context /* AVCodecContext * */
,(int16_t *)handle->output_samples_ptr
,&data_size
,handle->abuf_ptr
@@ -3791,7 +4019,7 @@
if (gap_debug)
{
- printf("after avcodec_decode_audio: l_len:%d data_size:%d samples_read:%d\n"
+ printf("after avcodec_decode_audio2: l_len:%d data_size:%d samples_read:%d\n"
, (int)l_len
, (int)data_size
, (int)handle->samples_read
@@ -3800,7 +4028,13 @@
if(l_len < 0)
{
- printf("p_read_audio_packets: avcodec_decode_audio returned ERROR)\n");
+ printf("p_read_audio_packets: avcodec_decode_audio2 returned ERROR)\n"
+ "abuf_len:%d AVCODEC_MAX_AUDIO_FRAME_SIZE:%d samples_buffer_size:%d data_size:%d\n"
+ , (int)handle->abuf_len
+ , (int)AVCODEC_MAX_AUDIO_FRAME_SIZE
+ , (int)handle->samples_buffer_size
+ , (int)data_size
+ );
l_rc = 2;
break;
}
@@ -3890,6 +4124,7 @@
/* ----------------------------------
* p_vindex_add_url_offest
* ----------------------------------
+ * add one entry to the videoindex.
*/
static void
p_vindex_add_url_offest(t_GVA_Handle *gvahand
@@ -3899,6 +4134,7 @@
, gint64 url_offset
, guint16 frame_length
, guint16 checksum
+ , gint64 timecode_dts
)
{
static gint64 s_last_seek_nr;
@@ -3944,20 +4180,29 @@
vindex->ofs_tab[vindex->tabsize_used].seek_nr = seek_nr;
vindex->ofs_tab[vindex->tabsize_used].frame_length = frame_length;
vindex->ofs_tab[vindex->tabsize_used].checksum = checksum;
+ vindex->ofs_tab[vindex->tabsize_used].timecode_dts = timecode_dts;
if(gap_debug)
{
- printf("p_vindex_add_url_offest: ofs_tab[%d]: ofs64: %d seek_nr:%d flen:%d chk:%d\n"
+ printf("p_vindex_add_url_offest: ofs_tab[%d]: ofs64: %lld seek_nr:%d flen:%d chk:%d dts:%lld\n"
, (int)vindex->tabsize_used
- , (int)vindex->ofs_tab[vindex->tabsize_used].uni.offset_gint64
+ , vindex->ofs_tab[vindex->tabsize_used].uni.offset_gint64
, (int)vindex->ofs_tab[vindex->tabsize_used].seek_nr
, (int)vindex->ofs_tab[vindex->tabsize_used].frame_length
, (int)vindex->ofs_tab[vindex->tabsize_used].checksum
+ , vindex->ofs_tab[vindex->tabsize_used].timecode_dts
);
}
vindex->tabsize_used++;
}
-
+
+ if(timecode_dts == AV_NOPTS_VALUE)
+ {
+ /* at this point we detected that seek based on DTS timecode is not reliable for this video
+ * therefore store AV_NOPTS_VALUE at index [0] to disables timecode based seek in the video index.
+ */
+ vindex->ofs_tab[0].timecode_dts = AV_NOPTS_VALUE;
+ }
} /* end p_vindex_add_url_offest */
@@ -4688,7 +4933,9 @@
t_GVA_ffmpeg *copy_handle;
gdouble avg_fstepsize;
int64_t prev_timecode;
+ gint32 l_countValidTimecodes;
+ l_countValidTimecodes = 0;
master_handle->timecode_proberead_done = TRUE;
master_handle->timecode_step_abs_min = 99999999;
@@ -4727,6 +4974,10 @@
break;
}
+ if (copy_handle->vid_pkt.dts != AV_NOPTS_VALUE)
+ {
+ l_countValidTimecodes++;
+ }
master_handle->timecode_steps[l_readsteps] = copy_handle->vid_pkt.dts - prev_timecode;
master_handle->timecode_step_abs_min =
MIN(abs(master_handle->timecode_steps[l_readsteps])
@@ -4751,7 +5002,28 @@
/* close the extra handle (that was opened for counting only) */
p_wrapper_ffmpeg_close(copy_gvahand);
- p_analyze_stepsize_pattern(l_readsteps, master_gvahand);
+ if (l_countValidTimecodes > 0)
+ {
+ p_analyze_stepsize_pattern(l_readsteps, master_gvahand);
+ }
+ else
+ {
+ /* some older ffmpeg versions did always deliver valid dts timecodes,
+ * even if not present in the video.
+ * but unfortunately recent ffmpeg snapshots deliver AV_NOPTS_VALUE as dts
+ * for such videos. In this case native seek must be disabled.
+ */
+ master_handle->timecode_steps_sum = 0;
+ master_handle->count_timecode_steps = 1;
+ master_handle->video_libavformat_seek_gopsize = 0; /* DISABLE natvie seek */
+ master_handle->prefere_native_seek = FALSE;
+
+ printf("WARNING: p_probe_timecode_offset no valid timecode found in video:%s\n"
+ , master_gvahand->filename
+ );
+ printf(" native timecode based seek not possible\n");
+
+ }
}
Modified: trunk/libgapvidapi/gap_vid_api_mpeg3.c
==============================================================================
--- trunk/libgapvidapi/gap_vid_api_mpeg3.c (original)
+++ trunk/libgapvidapi/gap_vid_api_mpeg3.c Sun Feb 8 09:37:06 2009
@@ -80,6 +80,7 @@
mpeg3_t *tmp_handle;
gint l_rc;
char *l_filename;
+ int l_error_return;
/* here we are in the forked child process
* where we install our own signal handlers
@@ -92,15 +93,19 @@
signal(SIGFPE, p_mpeg3_sig_handler);
if(gap_debug) printf("GVA_MP3: CILD process before mpeg3_open\n");
- tmp_handle = mpeg3_open(l_filename);
+ tmp_handle = mpeg3_open(l_filename, &l_error_return);
if(gap_debug) printf("GVA_MP3: CILD process after mpeg3_open\n");
if(tmp_handle)
{
if(gap_debug) printf("GVA_MP3: CILD process before mpeg3_close\n");
mpeg3_close(tmp_handle); /* this call causes the crash (sometimes) */
if(gap_debug) printf("GVA_MP3: CILD process after mpeg3_close\n");
- l_rc = GVA_PROCESS_EXIT_OK; /* retcode for OK */
- }
+
+ if (l_error_return == 0)
+ {
+ l_rc = GVA_PROCESS_EXIT_OK; /* retcode for OK */
+ }
+ }
g_free(l_filename);
exit (l_rc);
}
@@ -295,19 +300,28 @@
*/
for(repeat_count = 0; repeat_count < 3; repeat_count++)
{
- handle->main_handle = mpeg3_open(filename);
+ int l_error_return;
+
+ handle->main_handle = mpeg3_open(filename, &l_error_return);
-//printf("GVA: oooooo OPEN handle->main_handle:%d\n", (int)handle->main_handle);
+ //if(gap_debug)
+ {
+ printf("GVA: libmpeg3 OPEN handle->main_handle:%d l_error_return:%d\n"
+ , (int)handle->main_handle
+ , (int)l_error_return
+ );
+ }
- if(handle->main_handle)
+ if((handle->main_handle) && (l_error_return == 0))
{
gvahand->decoder_handle = (void *)handle;
gvahand->frame_bpp = 3;
/* never use MMX, it sometimes delivers trashed frames
* and has no advantages on modern CPU's at all
+ * procedure mpeg3_set_mmx was removed since libmpeg3-1.8
*/
- mpeg3_set_mmx(handle->main_handle, FALSE);
+ /// mpeg3_set_mmx(handle->main_handle, FALSE);
if(mpeg3_has_video(handle->main_handle))
{
@@ -928,6 +942,7 @@
long l_size;
unsigned long code;
unsigned char *buffer;
+ int l_error_return;
if(frame_nr < 1)
{
@@ -956,8 +971,8 @@
if(handle->raw_handle == NULL)
{
- handle->raw_handle = mpeg3_open_copy(gvahand->filename, handle->main_handle);
- if(handle->raw_handle == NULL)
+ handle->raw_handle = mpeg3_open_copy(gvahand->filename, handle->main_handle, &l_error_return);
+ if((handle->raw_handle == NULL) || (l_error_return != 0))
{
return(GVA_RET_ERROR);
}
@@ -1119,6 +1134,7 @@
char *dummy_y;
char *dummy_u;
char *dummy_v;
+ int l_error_return;
l_rc = 0;
l_dirty_reads = 0;
@@ -1134,12 +1150,12 @@
/* printf(" ++ 1 ++ p_mpeg3_emulate_seek before mpeg3_open_copy %s\n", gvahand->filename); */
/* bakward seek: reopen needed */
- seek_handle = mpeg3_open_copy(gvahand->filename, handle);
+ seek_handle = mpeg3_open_copy(gvahand->filename, handle, &l_error_return);
/* printf(" ++ 2 ++ p_mpeg3_emulate_seek after mpeg3_open_copy %s\n", gvahand->filename); */
decoder_handle = (t_GVA_mpeg3*)gvahand->decoder_handle;
- if(seek_handle)
+ if((seek_handle) && (l_error_return == 0))
{
/* printf(" ++ 3 ++ p_mpeg3_emulate_seek before mpeg3_close\n"); */
mpeg3_close(decoder_handle->main_handle);
@@ -1299,6 +1315,7 @@
gdouble l_progress_step;
mpeg3_t* seek_handle;
t_GVA_mpeg3* decoder_handle;
+ int l_error_return;
l_rc = 0;
l_gopseek = MAX((seekto_frame - GVA_GOPSEEKSIZE), 1);
@@ -1315,8 +1332,8 @@
gvahand->percentage_done = 0.0001;
if(l_gopseek == 1)
{
- seek_handle = mpeg3_open_copy(gvahand->filename, handle);
- if(seek_handle)
+ seek_handle = mpeg3_open_copy(gvahand->filename, handle, &l_error_return);
+ if((seek_handle) && (l_error_return == 0))
{
decoder_handle = (t_GVA_mpeg3*)gvahand->decoder_handle;
mpeg3_close(decoder_handle->main_handle);
Modified: trunk/libgapvidapi/gap_vid_api_mpeg3toc.c
==============================================================================
--- trunk/libgapvidapi/gap_vid_api_mpeg3toc.c (original)
+++ trunk/libgapvidapi/gap_vid_api_mpeg3toc.c Sun Feb 8 09:37:06 2009
@@ -1,7 +1,7 @@
/* this file is a modified variante
- * of the meg3toc.c Code that came with libmpeg3-1.5.4
+ * of the meg3toc.c Code that came with libmpeg3-1.8
*
- * it is used to count total_frames and build the libmpeg3
+ * it is used to build the libmpeg3
* compatible "Table of content" files implicite
* when using the GIMP-GAP specific GVA video API.
* .TOC files are the libmpeg3 specific pendant to gvaindexes
@@ -27,662 +27,177 @@
#include <glib/gstdio.h>
-/* hof: mpeg3video_get_header is defined in libmpeg3/video/headers.c
- * but libmpeg3 does not provide this procedure difinition in its
- * header files.
- */
-extern int mpeg3video_get_header(mpeg3video_t *video, int dont_repeat);
-
extern int gap_debug;
-/*
- * Generate table of frame and sample offsets for editing.
- */
-
-
-#define INIT_VECTORS(data, size, allocation, tracks) \
-{ \
- int k; \
- data = calloc(1, sizeof(int64_t*) * tracks); \
- size = calloc(1, sizeof(int*) * tracks); \
- allocation = calloc(1, sizeof(int*) * tracks); \
- \
- for(k = 0; k < tracks; k++) \
- { \
- allocation[k] = 0x100; \
- data[k] = calloc(1, sizeof(int64_t) * allocation[k]); \
- } \
-}
-
-#if 1
-#define APPEND_VECTOR(data, size, allocation, track, value) \
-{ \
- uint64_t **track_data = &(data)[(track)]; \
- int *track_allocation = &(allocation)[(track)]; \
- int *track_size = &(size)[(track)]; \
- \
- if(!(*track_data) || (*track_allocation) <= (*track_size)) \
- { \
- int64_t *new_data = calloc(1, sizeof(int64_t) * (*track_allocation) * 2); \
- \
- if((*track_data)) \
- { \
- memcpy(new_data, (*track_data), sizeof(int64_t) * (*track_allocation)); \
- free((*track_data)); \
- } \
- (*track_allocation) *= 2; \
- (*track_data) = new_data; \
- } \
- \
- (*track_data)[(*track_size)++] = (value); \
-}
-#else
-#define APPEND_VECTOR(data, size, allocation, track, value) \
- ;
-#endif
-
-#define DELETE_VECTORS(data, size, allocation, tracks) \
-{ \
- int k; \
- for(k = 0; k < tracks; k++) if(data[k]) free(data[k]); \
- free(data); \
-}
-
-
-
-
-
-
-#define PUT_INT32(x) \
-{ \
- if(MPEG3_LITTLE_ENDIAN) \
- { \
- fputc(((unsigned char*)&x)[3], output); \
- fputc(((unsigned char*)&x)[2], output); \
- fputc(((unsigned char*)&x)[1], output); \
- fputc(((unsigned char*)&x)[0], output); \
- } \
- else \
- { \
- fputc(((unsigned char*)&x)[0], output); \
- fputc(((unsigned char*)&x)[1], output); \
- fputc(((unsigned char*)&x)[2], output); \
- fputc(((unsigned char*)&x)[3], output); \
- } \
-}
-
-
-
-#define PUT_INT64(x) \
-{ \
- if(MPEG3_LITTLE_ENDIAN) \
- { \
- fputc(((unsigned char*)&x)[7], output); \
- fputc(((unsigned char*)&x)[6], output); \
- fputc(((unsigned char*)&x)[5], output); \
- fputc(((unsigned char*)&x)[4], output); \
- fputc(((unsigned char*)&x)[3], output); \
- fputc(((unsigned char*)&x)[2], output); \
- fputc(((unsigned char*)&x)[1], output); \
- fputc(((unsigned char*)&x)[0], output); \
- } \
- else \
- { \
- fwrite(&x, 1, 8, output); \
- } \
-}
-
-
-
-
-
-// hof: changed main to GVA_create_libmpeg3_toc
-// int main(int argc, char *argv[])
-int
-GVA_create_libmpeg3_toc(int argc, char *argv[]
- , t_GVA_Handle *gvahand
- , int *ret_total_frames)
+/* -----------------------------
+ * p_get_total_frames_from_toc
+ * -----------------------------
+ */
+static gint32
+p_get_total_frames_from_toc(char *toc_filename, int vid_track)
{
- struct stat st;
- int i, j, l;
- char *src = 0, *dst = 0;
- int astream_override = -1;
+ mpeg3_t *toc_handle;
+ int l_error_return;
+ gint32 total_frames;
- gdouble progress_stepsize;
+ total_frames = 0;
+ toc_handle = mpeg3_open(toc_filename, &l_error_return);
- progress_stepsize = 1.0 / (gdouble)(MAX(gvahand->total_frames, 1000));
- gvahand->percentage_done = 0.05;
- if(gap_debug)
- {
- printf("GVA_create_libmpeg3_toc: gvahand->total_frames: %d stepsize:%.6f\n"
- , (int)gvahand->total_frames
- , (float)progress_stepsize
- );
- }
- *ret_total_frames = -1; // hof:
-
- if(argc < 3)
- {
- fprintf(stderr, "Create a table of contents for a DVD or mpeg stream.\n"
- " Usage: [-a audio streams] mpeg3toc <path> <output>\n"
- "\n"
- " -a override the number of audio streams to scan. Must be less than\n"
- "the total number of audio streams.\n"
- "\n"
- " The path should be absolute unless you plan\n"
- " to always run your movie editor from the same directory\n"
- " as the filename. For renderfarms the filesystem prefix\n"
- " should be / and the movie directory mounted under the same\n"
- " directory on each node.\n"
- "Example: mpeg3toc /cd2/video_ts/vts_01_0.ifo titanic.toc\n");
- exit(1);
- }
- for(i = 1; i < argc; i++)
+ if((toc_handle) && (l_error_return == 0))
{
- if(!strcmp(argv[i], "-a"))
- {
- if(i < argc - 1)
- {
- astream_override = atoi(argv[i + 1]);
- if(astream_override < 0)
- {
- fprintf(stderr, "Total audio streams may not be negative\n");
- exit(1);
- }
- else
- {
- fprintf(stderr,
- "Using first %d audio streams.\n",
- astream_override);
- }
- i++;
- }
- else
- {
- fprintf(stderr, "-a requires an argument.\n");
- exit(1);
- }
- }
- else
- if(!src)
- {
- src = argv[i];
- }
- else
- if(!dst)
+ if(mpeg3_has_video(toc_handle))
{
- dst = argv[i];
+ total_frames = mpeg3_video_frames(toc_handle, vid_track);
}
- else
- {
- fprintf(stderr, "Ignoring argument \"%s\"\n", argv[i]);
- }
- }
-
- if(!src)
- {
- fprintf(stderr, "source path not supplied.\n");
- exit(1);
- }
-
- if(!dst)
- {
- fprintf(stderr, "destination path not supplied.\n");
- exit(1);
- }
+ mpeg3_close(toc_handle);
+ } /* end for repeat_count */
- g_stat(src, &st);
-
- if(!st.st_size)
+ if(gap_debug)
{
- fprintf(stderr, "%s is 0 length. Skipping\n", src);
+ printf("GVA: p_get_total_frames_from_toc libmpeg3 OPEN %s handle->toc_handle:%d l_error_return:%d total_frames:%d\n"
+ , toc_filename
+ , (int)toc_handle
+ , (int)l_error_return
+ , (int)total_frames
+ );
}
- else
- {
- // int64_t size;
- int vtracks;
- int atracks;
- mpeg3_t *input;
- uint64_t **frame_offsets;
- uint64_t **keyframe_numbers;
- uint64_t **sample_offsets;
- int *total_frame_offsets;
- int *total_sample_offsets;
- int *total_keyframe_numbers;
- int *frame_offset_allocation;
- int *sample_offset_allocation;
- int *keyframe_numbers_allocation;
- int done = 0;
- double sample_rate = 1;
- double frame_rate = 1;
- FILE *output;
- int total_samples = 0;
- int total_frames = 0;
- int rewind = 1;
-
-//printf(__FUNCTION__ " 1\n");
- input = mpeg3_open(src);
-
-//printf(__FUNCTION__ " 2\n");
- vtracks = mpeg3_total_vstreams(input);
- atracks = mpeg3_total_astreams(input);
- if(astream_override >= 0) atracks = astream_override;
-
-
- if(atracks) sample_rate = mpeg3_sample_rate(input, 0);
- if(vtracks) frame_rate = mpeg3_frame_rate(input, 0);
-
-//printf(__FUNCTION__ " 3\n");
-// Handle titles
- INIT_VECTORS(frame_offsets, total_frame_offsets, frame_offset_allocation, vtracks);
- INIT_VECTORS(keyframe_numbers, total_keyframe_numbers, keyframe_numbers_allocation, vtracks);
- INIT_VECTORS(sample_offsets, total_sample_offsets, sample_offset_allocation, atracks);
-
-//printf(__FUNCTION__ " 4\n");
- while(!done)
- {
- int sample_count = MPEG3_AUDIO_CHUNKSIZE;
- int frame_count;
- int have_audio = 0;
- int have_video = 0;
- int64_t title_number = 0;
-
-
-
-
+ return (total_frames);
-// Audio section
-// Store current position and read sample_count from each atrack
- for(j = 0; j < atracks; j++)
- {
-//printf(__FUNCTION__ " 3 %d\n", total_sample_offsets[j]);
- if(rewind)
- {
- mpeg3_demuxer_t *demuxer = input->atrack[j]->demuxer;
- mpeg3demux_seek_byte(demuxer, 0);
- }
-
- if(!mpeg3_end_of_audio(input, j))
- {
-// Don't want to maintain separate vectors for offset and title.
- int64_t position = mpeg3demux_tell_byte(input->atrack[j]->demuxer);
- int64_t result;
-
- if(position < MPEG3_IO_SIZE) position = MPEG3_IO_SIZE;
-// result = (title_number << 56) | (position - MPEG3_IO_SIZE);
- result = position;
-
- have_audio = 1;
- APPEND_VECTOR(sample_offsets,
- total_sample_offsets,
- sample_offset_allocation,
- j,
- result);
-
- /* hof: handle GUI user cancel request */
- {
- gvahand->cancel_operation = (*gvahand->fptr_progress_callback)(gvahand->percentage_done, gvahand->progress_cb_user_data);
- if(gap_debug)
- {
- printf("MPEG3TOC: CANCEL(v):%d FPTR:%d\n"
- , (int)gvahand->cancel_operation
- , (int)gvahand->fptr_progress_callback
- );
- }
- if(gvahand->cancel_operation)
- {
- mpeg3_close(input);
- return 1;
- }
- }
-
-
-//printf(__FUNCTION__ " 6 %d\n", j);
-// Throw away samples
- mpeg3_read_audio(input,
- 0,
- 0,
- 0,
- sample_count, /* Number of samples to decode */
- j);
-
-//printf(__FUNCTION__ " 7 %d\n", total_sample_offsets[j]);
- }
-
- if(j == atracks - 1)
- {
- total_samples += sample_count;
- if(gap_debug)
- {
- printf("Audio: title=%lld total_samples=%d ", title_number, total_samples);
- }
- }
- }
+} /* end p_get_total_frames_from_toc */
-//printf(__FUNCTION__ " 8\n");
- if(have_audio)
- {
- frame_count =
- (int)((double)total_samples / sample_rate * frame_rate + 0.5) -
- total_frames;
- }
- else
- {
- frame_count = 1;
- }
-//printf(__FUNCTION__ " 9 %d\n", vtracks);
-
-
-
-
-
-
-
-
-// Video section
- for(j = 0; j < vtracks; j++)
- {
- mpeg3video_t *video = input->vtrack[j]->video;
- mpeg3_demuxer_t *demuxer = input->vtrack[j]->demuxer;
- if(rewind)
- {
- mpeg3demux_seek_byte(demuxer, 0);
- }
-
-
- for(l = 0; l < frame_count; l++)
- {
- if(!mpeg3_end_of_video(input, j))
- {
- int64_t position = mpeg3demux_tell_byte(demuxer);
- int64_t result;
- // uint32_t code = 0;
- int got_top = 0;
- int got_bottom = 0;
- int got_keyframe = 0;
- int fields = 0;
-
- if(position < MPEG3_IO_SIZE) position = MPEG3_IO_SIZE;
-// result = (title_number << 56) | (position - MPEG3_IO_SIZE);
- result = position;
- have_video = 1;
-
-
-//printf("%llx\n", position);
-// Store offset of every frame in table
- APPEND_VECTOR(frame_offsets,
- total_frame_offsets,
- frame_offset_allocation,
- j,
- result);
-
-
-
-// Search for next frame start.
- if(total_frame_offsets[j] == 1)
- {
-// Assume first frame is an I-frame and put its number in the keyframe number
-// table.
- APPEND_VECTOR(keyframe_numbers,
- total_keyframe_numbers,
- keyframe_numbers_allocation,
- j,
- 0);
-
-
-
-// Skip the first frame.
- mpeg3video_get_header(video, 0);
- video->current_repeat += 100;
- }
-
-
-
-
-// Get next frame
- do
- {
- mpeg3video_get_header(video, 0);
- video->current_repeat += 100;
-
- if(video->pict_struct == TOP_FIELD)
- {
- got_top = 1;
- }
- else
- if(video->pict_struct == BOTTOM_FIELD)
- {
- got_bottom = 1;
- }
- else
- if(video->pict_struct == FRAME_PICTURE)
- {
- got_top = got_bottom = 1;
- }
- fields++;
-
-// The way we do it, the I frames have the top field but both the I frame and
-// subsequent P frame make the keyframe.
- if(video->pict_type == I_TYPE)
- got_keyframe = 1;
- }while(!mpeg3_end_of_video(input, j) &&
- !got_bottom &&
- total_frame_offsets[j] > 1);
-
-
-
-
-// Store number of a keyframe in the keyframe number table
- if(got_keyframe)
- {
- APPEND_VECTOR(keyframe_numbers,
- total_keyframe_numbers,
- keyframe_numbers_allocation,
- j,
- total_frame_offsets[j] - 1);
-
- //hof:
- if(gvahand->fptr_progress_callback)
- {
- gvahand->percentage_done += progress_stepsize;
- if(gvahand->percentage_done > 1.0)
- {
- gvahand->percentage_done = 0.8;
- }
-
-//printf("V-BLOCK: percentage_done:%.4f\n"
-// , (float)gvahand->percentage_done
-// );
-
- gvahand->cancel_operation = (*gvahand->fptr_progress_callback)(gvahand->percentage_done, gvahand->progress_cb_user_data);
- if(gap_debug)
- {
- printf("MPEG3TOC: CANCEL(v):%d FPTR:%d\n"
- , (int)gvahand->cancel_operation
- , (int)gvahand->fptr_progress_callback
- );
- }
- if(gvahand->cancel_operation)
- {
- mpeg3_close(input);
- return 1;
- }
-
- }
- }
-
- if(j == vtracks - 1 && l == frame_count - 1)
- {
- total_frames += frame_count;
- *ret_total_frames = total_frames; // hof:
- if(gap_debug)
- {
- printf("Video: title=%lld total_frames=%d ", title_number, total_frames);
- }
- }
- }
- }
-
-
- }
-
- if(!have_audio && !have_video) done = 1;
-
- //printf("\r");
- fflush(stdout);
/*
- * if(total_frames > 10000)
- * {
- * printf("\n");
- * return 0;
- * }
+ * Generate table of frame and sample offsets for editing.
*/
+int
+GVA_create_libmpeg3_toc(int argc, char *argv[]
+ , t_GVA_Handle *gvahand
+ , int *ret_total_frames)
+{
+ int i, j, l;
+ char *src = 0, *dst = 0;
+ int verbose = 0;
+ gdouble progress_stepsize;
+
+ progress_stepsize = 1.0 / (gdouble)(MAX(gvahand->total_frames, 1000));
+ gvahand->percentage_done = 0.05;
+ if(gap_debug)
+ {
+ printf("GVA_create_libmpeg3_toc: gvahand->total_frames: %d stepsize:%.6f\n"
+ , (int)gvahand->total_frames
+ , (float)progress_stepsize
+ );
+ }
+ *ret_total_frames = -1; // hof:
+
+
+
+ if(argc < 3)
+ {
+ fprintf(stderr, "Table of contents generator version %d.%d.%d\n"
+ "Create a table of contents for a DVD or mpeg stream.\n"
+ "Usage: mpeg3toc <path> <output>\n"
+ "\n"
+ "-v Print tracking information\n"
+ "\n"
+ "The path should be absolute unless you plan\n"
+ "to always run your movie editor from the same directory\n"
+ "as the filename. For renderfarms the filesystem prefix\n"
+ "should be / and the movie directory mounted under the same\n"
+ "directory on each node.\n\n"
+ "Example: mpeg3toc -v /cdrom/video_ts/vts_01_0.ifo titanic.toc\n",
+ mpeg3_major(),
+ mpeg3_minor(),
+ mpeg3_release());
+ exit(1);
+ }
+
+ for(i = 1; i < argc; i++)
+ {
+ if(!strcmp(argv[i], "-v"))
+ {
+ verbose = 1;
+ }
+ else
+ if(argv[i][0] == '-')
+ {
+ fprintf(stderr, "Unrecognized command %s\n", argv[i]);
+ exit(1);
+ }
+ else
+ if(!src)
+ {
+ src = argv[i];
+ }
+ else
+ if(!dst)
+ {
+ dst = argv[i];
+ }
+ else
+ {
+ fprintf(stderr, "Ignoring argument \"%s\"\n", argv[i]);
+ }
+ }
+
+ if(!src)
+ {
+ fprintf(stderr, "source path not supplied.\n");
+ exit(1);
+ }
+
+ if(!dst)
+ {
+ fprintf(stderr, "destination path not supplied.\n");
+ exit(1);
+ }
+
+
+
+ int64_t total_bytes;
+ mpeg3_t *file = mpeg3_start_toc(src, dst, &total_bytes);
+ if(!file)
+ {
+ return 1;;
+ }
+
+ while(1)
+ {
+ int64_t bytes_processed = 0;
+ mpeg3_do_toc(file, &bytes_processed);
+
+ /* hof: handle GUI user cancel request */
+ {
+ gvahand->percentage_done = CLAMP((bytes_processed / MAX(1, total_bytes)), 0.0, 1.0);
+ gvahand->cancel_operation = (*gvahand->fptr_progress_callback)(gvahand->percentage_done, gvahand->progress_cb_user_data);
+ if(gap_debug)
+ {
+ printf("MPEG3TOC: CANCEL(v):%d FPTR:%d\n"
+ , (int)gvahand->cancel_operation
+ , (int)gvahand->fptr_progress_callback
+ );
+ }
+ if(gvahand->cancel_operation)
+ {
+ mpeg3_stop_toc(file);
+ return 1;
+ }
+ }
+
+
+ if(bytes_processed >= total_bytes) break;
+ }
-
- rewind = 0;
- }
-
- output = g_fopen(dst, "wb");
- if(output==NULL)
- {
- printf("** ERROR can not write toc-file: %s", dst);
- return -1;
- }
-
-
-
-// Write file type
- fputc('T', output);
- fputc('O', output);
- fputc('C', output);
- fputc(' ', output);
-
-// Write version
- fputc(MPEG3_TOC_VERSION, output);
-
- if(input->is_program_stream)
- {
- fputc(FILE_TYPE_PROGRAM, output);
- }
- else
- if(input->is_transport_stream)
- {
- fputc(FILE_TYPE_TRANSPORT, output);
- }
- else
- if(input->is_audio_stream)
- {
- fputc(FILE_TYPE_AUDIO, output);
- }
- else
- if(input->is_video_stream)
- {
- fputc(FILE_TYPE_VIDEO, output);
- }
-
-// Write stream ID's
-// Only program and transport streams have these
- for(i = 0; i < MPEG3_MAX_STREAMS; i++)
- {
- if(input->demuxer->astream_table[i])
- {
- fputc(STREAM_AUDIO, output);
- PUT_INT32(i);
- PUT_INT32(input->demuxer->astream_table[i]);
- }
-
- if(input->demuxer->vstream_table[i])
- {
- fputc(STREAM_VIDEO, output);
- PUT_INT32(i);
- PUT_INT32(input->demuxer->vstream_table[i]);
- }
- }
-
-
-// Write titles
- for(i = 0; i < input->demuxer->total_titles; i++)
- {
-// Path
- fputc(TITLE_PATH, output);
- fprintf(output, input->demuxer->titles[i]->fs->path);
- fputc(0, output);
-// Total bytes
- PUT_INT64(input->demuxer->titles[i]->total_bytes);
-// Byte offsets of cells
- PUT_INT32(input->demuxer->titles[i]->cell_table_size);
- for(j = 0; j < input->demuxer->titles[i]->cell_table_size; j++)
- {
- PUT_INT64(input->demuxer->titles[i]->cell_table[j].start_byte);
- PUT_INT64(input->demuxer->titles[i]->cell_table[j].end_byte);
- PUT_INT32(input->demuxer->titles[i]->cell_table[j].program);
- }
- }
-
-
-
-
-
-
-
-
- fputc(ATRACK_COUNT, output);
- PUT_INT32(atracks);
-
- fputc(VTRACK_COUNT, output);
- PUT_INT32(vtracks);
-
-// Audio streams
- for(j = 0; j < atracks; j++)
- {
- int channels = mpeg3_audio_channels(input, j);
- PUT_INT32(channels);
- PUT_INT32(total_sample_offsets[j]);
- for(i = 0; i < total_sample_offsets[j]; i++)
- {
- PUT_INT64(sample_offsets[j][i]);
-//printf("Audio: offset=%016llx\n", sample_offsets[j][i]);
- }
- }
-
-// Video streams
- for(j = 0; j < vtracks; j++)
- {
- PUT_INT32(total_frame_offsets[j]);
- for(i = 0; i < total_frame_offsets[j]; i++)
- {
- PUT_INT64(frame_offsets[j][i]);
-//printf("Video: offset=%016llx\n", frame_offsets[j][i]);
- }
-
- PUT_INT32(total_keyframe_numbers[j]);
- for(i = 0; i < total_keyframe_numbers[j]; i++)
- {
- PUT_INT64(keyframe_numbers[j][i]);
-//printf("Video: keyframe=%lld\n", keyframe_numbers[j][i]);
- }
- }
-
-
-
-
- DELETE_VECTORS(frame_offsets, total_frame_offsets, frame_offset_allocation, vtracks);
- DELETE_VECTORS(keyframe_numbers, total_keyframe_numbers, keyframe_numbers_allocation, vtracks);
- DELETE_VECTORS(sample_offsets, total_sample_offsets, sample_offset_allocation, atracks);
-
-
- mpeg3_close(input);
- fclose(output);
- }
-
+ mpeg3_stop_toc(file);
+ *ret_total_frames = p_get_total_frames_from_toc(dst, (int)gvahand->vid_track);
- return 0;
+ return 0;
}
+
Modified: trunk/libgapvidapi/gap_vid_api_vidindex.c
==============================================================================
--- trunk/libgapvidapi/gap_vid_api_vidindex.c (original)
+++ trunk/libgapvidapi/gap_vid_api_vidindex.c Sun Feb 8 09:37:06 2009
@@ -14,6 +14,7 @@
* 2004.03.06 hof created
*
*/
+
static char * p_build_videoindex_filename(const char *filename, gint32 track, const char *decoder_name);
static gboolean p_equal_mtime(time_t mtime_idx, time_t mtime_file);
@@ -251,8 +252,86 @@
/* ----------------------------------
+ * p_debug_print_videoindex
+ * ----------------------------------
+ */
+static void
+p_debug_print_videoindex(t_GVA_Videoindex *vindex)
+{
+ printf("\n");
+ printf("GVA_debug_print_videoindex: START\n");
+ if(vindex)
+ {
+ gint l_idx;
+
+ printf("GVA_VIDEOINDEX dump START");
+
+ printf("\n\videoindex_filename:%s\n", vindex->videoindex_filename);
+ printf(" MTIM: vindex->hdr.val_mtim:%s\n TYPE: vindex->hdr.val_type:%s\n"
+ , vindex->hdr.val_mtim
+ , vindex->hdr.val_type
+ );
+
+
+ printf("TYPE:");
+ switch(vindex->tabtype)
+ {
+ case GVA_IDX_TT_WITHOUT_TIMECODE_GDOUBLE:
+ printf("gdouble");
+ break;
+ case GVA_IDX_TT_WITHOUT_TIMECODE_GINT64:
+ printf("gint64");
+ break;
+ case GVA_IDX_TT_GDOUBLE:
+ printf("GDOUBLE");
+ break;
+ case GVA_IDX_TT_GINT64:
+ printf("GINT64");
+ break;
+ default:
+ printf("undefined");
+ break;
+ }
+ printf("\n");
+ printf("STEP:");
+ printf("%d\n", (int)vindex->stepsize);
+ printf("SIZE:");
+ printf("%d\n", (int)vindex->tabsize_used);
+ printf("TRAK:");
+ printf("%d\n", (int)vindex->track);
+ printf("FTOT:");
+ printf("%d\n", (int)vindex->total_frames);
+ printf("DECO:");
+ printf("%15s\n", vindex->hdr.val_deco);
+ printf("MTIM:");
+ printf("%ld\n", (long)vindex->mtime);
+ printf("FILE:%s\n\n", vindex->videofile_uri);
+
+ for(l_idx=0; l_idx < vindex->tabsize_used; l_idx++)
+ {
+ printf("VINDEX: ofs_tab[%d]: ofs64: %lld seek_nr:%d flen:%d chk:%d dts:%lld\n"
+ , (int)l_idx
+ , vindex->ofs_tab[l_idx].uni.offset_gint64
+ , (int)vindex->ofs_tab[l_idx].seek_nr
+ , (int)vindex->ofs_tab[l_idx].frame_length
+ , (int)vindex->ofs_tab[l_idx].checksum
+ , vindex->ofs_tab[l_idx].timecode_dts
+ );
+ }
+ }
+
+ printf("GVA_debug_print_videoindex: END\n\n");
+
+} /* end p_debug_print_videoindex */
+
+
+/* ----------------------------------
* GVA_load_videoindex
* ----------------------------------
+ * load videoindex from file
+ * note that the old fileformat without dts timecode is supported for backwards compatibility.
+ * the old format used lowercase type names "gint64" "gdouble"
+ * the new format uses uppercase "GINT64" "GDOUBLE"
*/
t_GVA_Videoindex *
GVA_load_videoindex(const char *filename, gint32 track, const char *decoder_name)
@@ -330,13 +409,21 @@
}
vindex->tabtype = GVA_IDX_TT_UNDEFINED;
- if(strcmp(vindex->hdr.val_type, "gdouble") == 0)
+ if(strcmp(vindex->hdr.val_type, "GINT64") == 0)
+ {
+ vindex->tabtype = GVA_IDX_TT_GINT64;
+ }
+ else if(strcmp(vindex->hdr.val_type, "GDOUBLE") == 0)
{
vindex->tabtype = GVA_IDX_TT_GDOUBLE;
}
- if(strcmp(vindex->hdr.val_type, "gint64") == 0)
+ else if(strcmp(vindex->hdr.val_type, "gint64") == 0)
{
- vindex->tabtype = GVA_IDX_TT_GINT64;
+ vindex->tabtype = GVA_IDX_TT_WITHOUT_TIMECODE_GINT64;
+ }
+ else if(strcmp(vindex->hdr.val_type, "gdouble") == 0)
+ {
+ vindex->tabtype = GVA_IDX_TT_WITHOUT_TIMECODE_GDOUBLE;
}
@@ -344,26 +431,56 @@
rd_size = -1;
switch(vindex->tabtype)
{
+ case GVA_IDX_TT_WITHOUT_TIMECODE_GINT64: /* old format */
+ case GVA_IDX_TT_WITHOUT_TIMECODE_GDOUBLE: /* old format */
+
+ delete_flag = TRUE;
+
+ //rd_size = sizeof(t_GVA_IndexElem) * vindex->tabsize_used;
+ //if(rd_size > 0)
+ //{
+ // vindex->ofs_tab = g_new(t_GVA_IndexElem, vindex->tabsize_used);
+ // if(vindex->ofs_tab)
+ // {
+ // int ii;
+ // t_GVA_IndexElemWithoutTimecode *oldIndexformatTab;
+ //
+ // oldIndexformatTab = g_new(t_GVA_IndexElemWithoutTimecode, vindex->tabsize_used);
+ // rd_len = fread(oldIndexformatTab, 1, rd_size, fp);
+ //
+ // /* migration loop to convert from old index format */
+ // for(ii=0; ii < vindex->tabsize_used; ii++)
+ // {
+ // vindex->ofs_tab[ii].timecode_dts = AV_NOPTS_VALUE;
+ // vindex->ofs_tab[ii].uni.offset_gint64 = oldIndexformatTab[ii].uni.offset_gint64;
+ // vindex->ofs_tab[ii].seek_nr = oldIndexformatTab[ii].seek_nr;
+ // vindex->ofs_tab[ii].frame_length = oldIndexformatTab[ii].frame_length;
+ // vindex->ofs_tab[ii].checksum = oldIndexformatTab[ii].checksum;
+ // }
+ // }
+ //}
+ break;
case GVA_IDX_TT_GINT64:
case GVA_IDX_TT_GDOUBLE:
- rd_size = sizeof(t_GVA_IndexElem) * vindex->tabsize_used;
- if(rd_size > 0)
- {
- vindex->ofs_tab = g_new(t_GVA_IndexElem, vindex->tabsize_used);
- if(vindex->ofs_tab)
- {
- rd_len = fread(vindex->ofs_tab, 1, rd_size, fp);
- }
- }
- break;
+ rd_size = sizeof(t_GVA_IndexElem) * vindex->tabsize_used;
+ if(rd_size > 0)
+ {
+ vindex->ofs_tab = g_new(t_GVA_IndexElem, vindex->tabsize_used);
+ if(vindex->ofs_tab)
+ {
+ rd_len = fread(vindex->ofs_tab, 1, rd_size, fp);
+ }
+ }
+ break;
default:
- break;
+ break;
}
if(rd_len == rd_size)
{
success = TRUE;
if(gap_debug)
{
+ p_debug_print_videoindex(vindex);
printf("GVA_load_videoindex SUCCESS\n");
}
}
@@ -418,6 +535,8 @@
/* ----------------------------------
* GVA_save_videoindex
* ----------------------------------
+ * save videoindex to fileformat
+ * (always save the new format with dts timecode)
*/
gboolean
GVA_save_videoindex(t_GVA_Videoindex *vindex, const char *filename, const char *decoder_name)
@@ -452,11 +571,13 @@
switch(vindex->tabtype)
{
case GVA_IDX_TT_GDOUBLE:
- g_snprintf(vindex->hdr.val_type, sizeof(vindex->hdr.val_type), "gdouble");
+ case GVA_IDX_TT_WITHOUT_TIMECODE_GDOUBLE:
+ g_snprintf(vindex->hdr.val_type, sizeof(vindex->hdr.val_type), "GDOUBLE");
break;
case GVA_IDX_TT_GINT64:
+ case GVA_IDX_TT_WITHOUT_TIMECODE_GINT64:
case GVA_IDX_TT_UNDEFINED:
- g_snprintf(vindex->hdr.val_type, sizeof(vindex->hdr.val_type), "gint64");
+ g_snprintf(vindex->hdr.val_type, sizeof(vindex->hdr.val_type), "GINT64");
break;
}
g_snprintf(vindex->hdr.key_step, sizeof(vindex->hdr.key_step), "STEP");
@@ -527,51 +648,6 @@
t_GVA_Videoindex *vindex;
vindex = gvahand->vindex;
- printf("\n");
- printf("GVA_debug_print_videoindex: START\n");
- if(vindex)
- {
- gint l_idx;
-
- printf("GVA_VIDEOINDEX dump START");
- printf("TYPE:");
- switch(vindex->tabtype)
- {
- case GVA_IDX_TT_GDOUBLE:
- printf("gdouble");
- break;
- case GVA_IDX_TT_GINT64:
- case GVA_IDX_TT_UNDEFINED:
- printf("gint64");
- break;
- }
- printf("\n");
- printf("STEP:");
- printf("%d\n", (int)vindex->stepsize);
- printf("SIZE:");
- printf("%d\n", (int)vindex->tabsize_used);
- printf("TRAK:");
- printf("%d\n", (int)vindex->track);
- printf("FTOT:");
- printf("%d\n", (int)vindex->total_frames);
- printf("DECO:");
- printf("%15s\n", vindex->hdr.val_deco);
- printf("MTIM:");
- printf("%ld\n", (long)vindex->mtime);
- printf("FILE:%s\n\n", vindex->videofile_uri);
-
- for(l_idx=0; l_idx < vindex->tabsize_used; l_idx++)
- {
- printf("VINDEX: ofs_tab[%d]: ofs64: %d seek_nr:%d flen:%d chk:%d\n"
- , (int)l_idx
- , (int)vindex->ofs_tab[l_idx].uni.offset_gint64
- , (int)vindex->ofs_tab[l_idx].seek_nr
- , (int)vindex->ofs_tab[l_idx].frame_length
- , (int)vindex->ofs_tab[l_idx].checksum
- );
- }
- }
-
- printf("GVA_debug_print_videoindex: END\n\n");
-
+ p_debug_print_videoindex(vindex);
+
} /* end GVA_debug_print_videoindex */
Modified: trunk/vid_enc_ffmpeg/gap_enc_ffmpeg_gui.c
==============================================================================
--- trunk/vid_enc_ffmpeg/gap_enc_ffmpeg_gui.c (original)
+++ trunk/vid_enc_ffmpeg/gap_enc_ffmpeg_gui.c Sun Feb 8 09:37:06 2009
@@ -279,7 +279,7 @@
l_idx = 0;
l_active_idx = 0;
- for(avcodec = first_avcodec; avcodec != NULL; avcodec = avcodec->next)
+ for(avcodec = av_codec_next(NULL); avcodec != NULL; avcodec = av_codec_next(avcodec))
{
char *menu_name;
char *object_data;
@@ -353,7 +353,7 @@
l_idx = 0;
l_active_idx = 0;
- for(avcodec = first_avcodec; avcodec != NULL; avcodec = avcodec->next)
+ for(avcodec = av_codec_next(NULL); avcodec != NULL; avcodec = av_codec_next(avcodec))
{
char *menu_name;
char *object_data;
@@ -1301,13 +1301,8 @@
/* the qscale spinbutton */
-#ifdef HAVE_OLD_FFMPEG_0408
- adj = gtk_adjustment_new (0, 0, 31, 1, 10, 0);
- spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1, 0);
-#else
adj = gtk_adjustment_new (0, 0, 255, 1, 10, 0);
spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1, 2);
-#endif
gpp->ff_qscale_spinbutton_adj = adj;
gpp->ff_qscale_spinbutton = spinbutton;
@@ -1582,12 +1577,16 @@
/* the motion estimation combo box */
- combo = gimp_int_combo_box_new (_("1 zero (fastest)"), GAP_GVE_FFMPEG_MOTION_ESTIMATION_01_ZERO,
- _("2 full (best)"), GAP_GVE_FFMPEG_MOTION_ESTIMATION_02_FULL,
- _("3 log"), GAP_GVE_FFMPEG_MOTION_ESTIMATION_03_LOG,
- _("4 phods"), GAP_GVE_FFMPEG_MOTION_ESTIMATION_04_PHODS,
- _("5 epzs (recommended)"), GAP_GVE_FFMPEG_MOTION_ESTIMATION_05_EPZS,
- _("6 x1"), GAP_GVE_FFMPEG_MOTION_ESTIMATION_06_X1,
+ combo = gimp_int_combo_box_new (_("1 zero (fastest)"), GAP_GVE_FFMPEG_MOTION_ESTIMATION_01_ZERO,
+ _("2 full (best)"), GAP_GVE_FFMPEG_MOTION_ESTIMATION_02_FULL,
+ _("3 log"), GAP_GVE_FFMPEG_MOTION_ESTIMATION_03_LOG,
+ _("4 phods"), GAP_GVE_FFMPEG_MOTION_ESTIMATION_04_PHODS,
+ _("5 epzs (recommended)"), GAP_GVE_FFMPEG_MOTION_ESTIMATION_05_EPZS,
+ _("6 x1"), GAP_GVE_FFMPEG_MOTION_ESTIMATION_06_X1,
+ _("7 hex (x264 specific)"), GAP_GVE_FFMPEG_MOTION_ESTIMATION_07_HEX,
+ _("8 umh (x264 specific)"), GAP_GVE_FFMPEG_MOTION_ESTIMATION_08_UMH,
+ _("9 iter (snow specific)"), GAP_GVE_FFMPEG_MOTION_ESTIMATION_09_ITER,
+ _("10 tesa (x264 specific)"), GAP_GVE_FFMPEG_MOTION_ESTIMATION_10_TESA,
NULL);
gpp->ff_motion_estimation_combo = combo;
gtk_widget_show (combo);
@@ -1626,9 +1625,7 @@
_("3 mmx"), GAP_GVE_FFMPEG_DCT_ALGO_03_MMX,
_("4 mlib"), GAP_GVE_FFMPEG_DCT_ALGO_04_MLIB,
_("5 altivec"), GAP_GVE_FFMPEG_DCT_ALGO_05_ALTIVEC,
-#ifdef HAVE_FULL_FFMPEG
_("6 faan"), GAP_GVE_FFMPEG_DCT_ALGO_06_FAAN,
-#endif
NULL);
gpp->ff_dct_algo_combo = combo;
gtk_widget_show (combo);
@@ -1661,20 +1658,30 @@
/* the IDCT algorithm combo */
- combo = gimp_int_combo_box_new (_("0 auto"), GAP_GVE_FFMPEG_IDCT_ALGO_00_AUTO,
- _("1 int"), GAP_GVE_FFMPEG_IDCT_ALGO_01_INT,
- _("2 simple"), GAP_GVE_FFMPEG_IDCT_ALGO_02_SIMPLE,
- _("3 simple mmx"), GAP_GVE_FFMPEG_IDCT_ALGO_03_SIMPLEMMX,
- _("4 libmpeg2mmx"), GAP_GVE_FFMPEG_IDCT_ALGO_04_LIBMPEG2MMX,
- _("5 ps2"), GAP_GVE_FFMPEG_IDCT_ALGO_05_PS2,
- _("6 mlib"), GAP_GVE_FFMPEG_IDCT_ALGO_06_MLIB,
- _("7 arm"), GAP_GVE_FFMPEG_IDCT_ALGO_07_ARM,
- _("8 altivec"), GAP_GVE_FFMPEG_IDCT_ALGO_08_ALTIVEC,
-#ifdef HAVE_FULL_FFMPEG
- _("9 sh4"), GAP_GVE_FFMPEG_IDCT_ALGO_09_SH4,
- _("10 simplearm"), GAP_GVE_FFMPEG_IDCT_ALGO_10_SIMPLEARM,
- _("11 h264"), GAP_GVE_FFMPEG_IDCT_ALGO_11_H264,
-#endif
+ combo = gimp_int_combo_box_new (_("0 auto"), GAP_GVE_FFMPEG_IDCT_ALGO_00_AUTO,
+ _("1 int"), GAP_GVE_FFMPEG_IDCT_ALGO_01_INT,
+ _("2 simple"), GAP_GVE_FFMPEG_IDCT_ALGO_02_SIMPLE,
+ _("3 simple mmx"), GAP_GVE_FFMPEG_IDCT_ALGO_03_SIMPLEMMX,
+ _("4 libmpeg2mmx"), GAP_GVE_FFMPEG_IDCT_ALGO_04_LIBMPEG2MMX,
+ _("5 ps2"), GAP_GVE_FFMPEG_IDCT_ALGO_05_PS2,
+ _("6 mlib"), GAP_GVE_FFMPEG_IDCT_ALGO_06_MLIB,
+ _("7 arm"), GAP_GVE_FFMPEG_IDCT_ALGO_07_ARM,
+ _("8 altivec"), GAP_GVE_FFMPEG_IDCT_ALGO_08_ALTIVEC,
+ _("9 sh4"), GAP_GVE_FFMPEG_IDCT_ALGO_09_SH4,
+ _("10 simplearm"), GAP_GVE_FFMPEG_IDCT_ALGO_10_SIMPLEARM,
+ _("11 h264"), GAP_GVE_FFMPEG_IDCT_ALGO_11_H264,
+ _("12 vp3"), GAP_GVE_FFMPEG_IDCT_ALGO_12_VP3,
+ _("13 ipp"), GAP_GVE_FFMPEG_IDCT_ALGO_13_IPP,
+ _("14 xvidmmx"), GAP_GVE_FFMPEG_IDCT_ALGO_14_XVIDMMX,
+ _("15 cavs"), GAP_GVE_FFMPEG_IDCT_ALGO_15_CAVS,
+ _("16 simplearmv5te"), GAP_GVE_FFMPEG_IDCT_ALGO_16_SIMPLEARMV5TE,
+ _("17 simplearmv6"), GAP_GVE_FFMPEG_IDCT_ALGO_17_SIMPLEARMV6,
+ _("18 simplevis"), GAP_GVE_FFMPEG_IDCT_ALGO_18_SIMPLEVIS,
+ _("19 wmv2"), GAP_GVE_FFMPEG_IDCT_ALGO_19_WMV2,
+ _("20 faan"), GAP_GVE_FFMPEG_IDCT_ALGO_20_FAAN,
+ _("21 ea"), GAP_GVE_FFMPEG_IDCT_ALGO_21_EA,
+ _("22 simpleneon"), GAP_GVE_FFMPEG_IDCT_ALGO_22_SIMPLENEON,
+ _("23 simplealpha"), GAP_GVE_FFMPEG_IDCT_ALGO_23_SIMPLEALPHA,
NULL);
gpp->ff_idct_algo_combo = combo;
@@ -1737,9 +1744,7 @@
/* the Coder Type label */
label = gtk_label_new (_("Coder Type:"));
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (label);
-#endif
gtk_table_attach (GTK_TABLE (table2), label, 0, 1, row, row+1,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -1751,9 +1756,7 @@
NULL);
gpp->ff_coder_combo = combo;
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (combo);
-#endif
gtk_table_attach (GTK_TABLE (table2), combo, 1, 2, row, row+1,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -1776,9 +1779,7 @@
/* the Predictor label */
label = gtk_label_new (_("Predictor:"));
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (label);
-#endif
gtk_table_attach (GTK_TABLE (table2), label, 0, 1, row, row+1,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -1791,9 +1792,7 @@
NULL);
gpp->ff_predictor_combo = combo;
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (combo);
-#endif
gtk_table_attach (GTK_TABLE (table2), combo, 1, 2, row, row+1,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -1816,9 +1815,7 @@
/* the Macroblock compare function label */
label = gtk_label_new (_("Macroblock cmp:"));
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (label);
-#endif
gtk_table_attach (GTK_TABLE (table2), label, 0, 1, row, row+1,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -1829,9 +1826,7 @@
combo = p_ff_cmp_func_combo_box_new ();
gpp->ff_mb_cmp_combo = combo;
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (combo);
-#endif
gtk_table_attach (GTK_TABLE (table2), combo, 1, 2, row, row+1,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -1854,9 +1849,7 @@
/* the ildct compare function label */
label = gtk_label_new (_("ildct cmp:"));
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (label);
-#endif
gtk_table_attach (GTK_TABLE (table2), label, 0, 1, row, row+1,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -1867,9 +1860,7 @@
combo = p_ff_cmp_func_combo_box_new ();
gpp->ff_ildct_cmp_combo = combo;
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (combo);
-#endif
gtk_table_attach (GTK_TABLE (table2), combo, 1, 2, row, row+1,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -1893,9 +1884,7 @@
/* the fullpel compare function label */
label = gtk_label_new (_("Fullpel cmp:"));
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (label);
-#endif
gtk_table_attach (GTK_TABLE (table2), label, 0, 1, row, row+1,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -1906,9 +1895,7 @@
combo = p_ff_cmp_func_combo_box_new ();
gpp->ff_cmp_combo = combo;
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (combo);
-#endif
gtk_table_attach (GTK_TABLE (table2), combo, 1, 2, row, row+1,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -1931,9 +1918,7 @@
/* the subpel compare function label */
label = gtk_label_new (_("Subpel cmp:"));
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (label);
-#endif
gtk_table_attach (GTK_TABLE (table2), label, 0, 1, row, row+1,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -1944,9 +1929,7 @@
combo = p_ff_cmp_func_combo_box_new ();
gpp->ff_sub_cmp_combo = combo;
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (combo);
-#endif
gtk_table_attach (GTK_TABLE (table2), combo, 1, 2, row, row+1,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -1969,9 +1952,7 @@
/* the pre motion estimation compare function label */
label = gtk_label_new (_("Pre motion estimation cmp:"));
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (label);
-#endif
gtk_table_attach (GTK_TABLE (table2), label, 0, 1, row, row+1,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -1982,9 +1963,7 @@
combo = p_ff_cmp_func_combo_box_new ();
gpp->ff_pre_cmp_combo = combo;
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (combo);
-#endif
gtk_table_attach (GTK_TABLE (table2), combo, 1, 2, row, row+1,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -2007,9 +1986,7 @@
/* the frame skip compare function label */
label = gtk_label_new (_("Frame skip cmp:"));
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (label);
-#endif
gtk_table_attach (GTK_TABLE (table2), label, 0, 1, row, row+1,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -2021,9 +1998,7 @@
combo = p_ff_cmp_func_combo_box_new ();
gpp->ff_frame_skip_cmp_combo = combo;
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (combo);
-#endif
gtk_table_attach (GTK_TABLE (table2), combo, 1, 2, row, row+1,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -2176,9 +2151,7 @@
/* the Closed GOP checkbutton */
checkbutton = gtk_check_button_new_with_label (_("Closed GOP"));
gpp->ff_closed_gop_checkbutton = checkbutton;
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (checkbutton);
-#endif
gtk_table_attach (GTK_TABLE (flags_table), checkbutton, 0, 1, flags_row, flags_row+1,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -2222,9 +2195,7 @@
/* the Strict GOP checkbutton */
checkbutton = gtk_check_button_new_with_label (_("Strict GOP"));
gpp->ff_strict_gop_checkbutton = checkbutton;
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (checkbutton);
-#endif
gtk_table_attach (GTK_TABLE (flags_table), checkbutton, 0, 1, flags_row, flags_row+1,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -2240,9 +2211,7 @@
/* the Use slice struct checkbutton */
checkbutton = gtk_check_button_new_with_label (_("Use slice struct"));
gpp->ff_use_ss_checkbutton = checkbutton;
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (checkbutton);
-#endif
gtk_table_attach (GTK_TABLE (flags_table), checkbutton, 1, 2, flags_row, flags_row+1,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -2256,9 +2225,7 @@
/* the Use Alt scantable checkbutton */
checkbutton = gtk_check_button_new_with_label (_("Use alt scantable"));
gpp->ff_use_alt_scan_checkbutton = checkbutton;
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (checkbutton);
-#endif
gtk_table_attach (GTK_TABLE (flags_table), checkbutton, 2, 3, flags_row, flags_row+1,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -2275,9 +2242,7 @@
/* the Use interlaced me checkbutton */
checkbutton = gtk_check_button_new_with_label (_("Use interlaced me"));
gpp->ff_do_interlace_me_checkbutton = checkbutton;
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (checkbutton);
-#endif
gtk_table_attach (GTK_TABLE (flags_table), checkbutton, 0, 1, flags_row, flags_row+1,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -2291,9 +2256,7 @@
/* the Use AIV checkbutton */
checkbutton = gtk_check_button_new_with_label (_("Use AIV"));
gpp->ff_use_aiv_checkbutton = checkbutton;
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (checkbutton);
-#endif
gtk_table_attach (GTK_TABLE (flags_table), checkbutton, 1, 2, flags_row, flags_row+1,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -2309,9 +2272,7 @@
/* the interlace dct checkbutton */
checkbutton = gtk_check_button_new_with_label (_("Interlace DCT"));
gpp->ff_do_interlace_dct_checkbutton = checkbutton;
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (checkbutton);
-#endif
gtk_table_attach (GTK_TABLE (flags_table), checkbutton, 0, 1, flags_row, flags_row+1,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -2325,9 +2286,7 @@
/* the Use OBMC checkbutton */
checkbutton = gtk_check_button_new_with_label (_("Overlapped block"));
gpp->ff_use_obmc_checkbutton = checkbutton;
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (checkbutton);
-#endif
gtk_table_attach (GTK_TABLE (flags_table), checkbutton, 1, 2, flags_row, flags_row+1,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -2344,9 +2303,7 @@
/* the quarter pel checkbutton */
checkbutton = gtk_check_button_new_with_label (_("quarter pel"));
gpp->ff_use_qpel_checkbutton = checkbutton;
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (checkbutton);
-#endif
gtk_table_attach (GTK_TABLE (flags_table), checkbutton, 0, 1, flags_row, flags_row+1,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -2359,9 +2316,7 @@
/* the Use Loop checkbutton */
checkbutton = gtk_check_button_new_with_label (_("Loop Filter"));
gpp->ff_use_loop_checkbutton = checkbutton;
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (checkbutton);
-#endif
gtk_table_attach (GTK_TABLE (flags_table), checkbutton, 1, 2, flags_row, flags_row+1,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -2377,9 +2332,7 @@
/* the Use qprd checkbutton */
checkbutton = gtk_check_button_new_with_label (_("Use qprd"));
gpp->ff_use_qprd_checkbutton = checkbutton;
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (checkbutton);
-#endif
gtk_table_attach (GTK_TABLE (flags_table), checkbutton, 0, 1, flags_row, flags_row+1,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -2394,9 +2347,7 @@
/* the Use cbprd checkbutton */
checkbutton = gtk_check_button_new_with_label (_("Use cbprd"));
gpp->ff_use_cbprd_checkbutton = checkbutton;
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (checkbutton);
-#endif
gtk_table_attach (GTK_TABLE (flags_table), checkbutton, 0, 1, flags_row, flags_row+1,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -2412,9 +2363,7 @@
/* the Use MV0 checkbutton */
checkbutton = gtk_check_button_new_with_label (_("Use MV0"));
gpp->ff_use_mv0_checkbutton = checkbutton;
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (checkbutton);
-#endif
gtk_table_attach (GTK_TABLE (flags_table), checkbutton, 0, 1, flags_row, flags_row+1,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -2429,9 +2378,7 @@
/* the Use Normalize checkbutton */
checkbutton = gtk_check_button_new_with_label (_("Normalize"));
gpp->ff_do_normalize_aqp_checkbutton = checkbutton;
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (checkbutton);
-#endif
gtk_table_attach (GTK_TABLE (flags_table), checkbutton, 0, 1, flags_row, flags_row+1,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -2448,9 +2395,7 @@
/* the SVCD scan offset checkbutton */
checkbutton = gtk_check_button_new_with_label (_("SVCD scan offset"));
gpp->ff_use_scan_offset_checkbutton = checkbutton;
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (checkbutton);
-#endif
gtk_table_attach (GTK_TABLE (flags_table), checkbutton, 0, 1, flags_row, flags_row+1,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -2467,9 +2412,7 @@
/* the Use trell checkbutton */
checkbutton = gtk_check_button_new_with_label (_("Use trell"));
gpp->ff_use_trell_checkbutton = checkbutton;
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (checkbutton);
-#endif
gtk_table_attach (GTK_TABLE (flags_table), checkbutton, 0, 1, flags_row, flags_row+1,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -3011,9 +2954,7 @@
/* the video bitrate label */
label = gtk_label_new (_("Mux Rate:"));
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (label);
-#endif
gtk_table_attach (GTK_TABLE (table), label, 0, 1, row, row+1,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -3025,9 +2966,7 @@
gpp->ff_mux_rate_adj = adj;
gpp->ff_mux_rate_spinbutton = spinbutton;
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (spinbutton);
-#endif
gtk_table_attach (GTK_TABLE (table), spinbutton, 1, 2, row, row+1,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -3043,9 +2982,7 @@
/* the video bitrate label */
label = gtk_label_new (_("Mux Packetsize:"));
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (label);
-#endif
gtk_table_attach (GTK_TABLE (table), label, 0, 1, row, row+1,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -3057,9 +2994,7 @@
gpp->ff_mux_packet_size_adj = adj;
gpp->ff_mux_packet_size_spinbutton = spinbutton;
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (spinbutton);
-#endif
gtk_table_attach (GTK_TABLE (table), spinbutton, 1, 2, row, row+1,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -3077,9 +3012,7 @@
/* the video bitrate label */
label = gtk_label_new (_("Mux Preload:"));
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (label);
-#endif
gtk_table_attach (GTK_TABLE (table), label, 0, 1, row, row+1,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -3091,9 +3024,7 @@
gpp->ff_mux_preload_adj = adj;
gpp->ff_mux_preload_spinbutton = spinbutton;
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (spinbutton);
-#endif
gtk_table_attach (GTK_TABLE (table), spinbutton, 1, 2, row, row+1,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -3110,9 +3041,7 @@
/* the video bitrate label */
label = gtk_label_new (_("Mux Max Delay:"));
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (label);
-#endif
gtk_table_attach (GTK_TABLE (table), label, 0, 1, row, row+1,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -3124,9 +3053,7 @@
gpp->ff_mux_max_delay_adj = adj;
gpp->ff_mux_max_delay_spinbutton = spinbutton;
-#ifdef HAVE_FULL_FFMPEG
gtk_widget_show (spinbutton);
-#endif
gtk_table_attach (GTK_TABLE (table), spinbutton, 1, 2, row, row+1,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -3432,12 +3359,7 @@
_("use DivX WINDOWS presets"), GAP_GVE_FFMPEG_PRESET_04_DIVX_MS,
_("use MPEG1 (VCD) presets"), GAP_GVE_FFMPEG_PRESET_05_MPEG1_VCD,
_("use MPEG1 high quality presets"), GAP_GVE_FFMPEG_PRESET_06_MPEG1_BEST,
-#ifdef HAVE_FULL_FFMPEG
- /* the SVCD preset does not work with old ffmpeg 0.4.8
- * (libavformat has no support for this fileformat)
- */
_("use MPEG2 (SVCD) presets"), GAP_GVE_FFMPEG_PRESET_07_MPEG2_SVCD,
-#endif
_("use MPEG2 (DVD) presets"), GAP_GVE_FFMPEG_PRESET_08_MPEG2_DVD,
_("use REAL video presets"), GAP_GVE_FFMPEG_PRESET_09_REAL,
NULL);
Modified: trunk/vid_enc_ffmpeg/gap_enc_ffmpeg_main.c
==============================================================================
--- trunk/vid_enc_ffmpeg/gap_enc_ffmpeg_main.c (original)
+++ trunk/vid_enc_ffmpeg/gap_enc_ffmpeg_main.c Sun Feb 8 09:37:06 2009
@@ -45,6 +45,7 @@
*/
/* revision history:
+ * version 2.1.0a; 2009.02.07 hof: update to ffmpeg snapshot 2009.01.31 (removed support for older ffmpeg versions)
* version 2.1.0a; 2005.07.16 hof: base support for encoding of multiple tracks
* video is still limited to 1 track
* multiple audio tracks are possible
@@ -55,7 +56,6 @@
* changed presets (are still a wild guess)
* version 2.1.0a; 2004.11.02 hof: added patch from pippin (allows compile with FFMPEG-0.4.0.9pre1)
* support for the incompatible older (stable) FFMPEG 0.4.8 version is available
- * via precompiler checks HAVE_OLD_FFMPEG_0408
* version 2.1.0a; 2004.06.10 hof: removed deinterlace option
* delace was not implemented in the encoder module
* and probably will never be implemented here for reasons a) and b)
@@ -92,6 +92,9 @@
#define DEFAULT_PASS_LOGFILENAME "ffmpeg2pass"
#define MAX_AUDIO_PACKET_SIZE 16384
+#ifndef DEFAULT_FRAME_RATE_BASE
+#define DEFAULT_FRAME_RATE_BASE 1001000
+#endif
/* define some Constant values
* (needed just in case we are compiling with older ffmpeg releases)
@@ -195,7 +198,6 @@
int frame_bottomBand;
int frame_leftBand;
int frame_rightBand;
- int frame_rate;
int video_bit_rate;
int video_bit_rate_tolerance;
float video_qscale;
@@ -225,7 +227,7 @@
int umv;
int use_4mv;
int workaround_bugs;
- int error_resilience;
+ int error_recognition;
int error_concealment;
int dct_algo;
int idct_algo;
@@ -255,7 +257,8 @@
char *pass_logfilename;
int audio_stream_copy;
int video_stream_copy;
- int64_t frame_duration_pts;
+ gdouble pts_stepsize_per_frame;
+ gint32 encode_frame_nr; /* number of frame to encode always starts at 1 and inc by one (base for monotone timecode calculation) */
} t_ffmpeg_handle;
@@ -280,6 +283,11 @@
, const GimpParam *param
, gint *nreturn_vals
, GimpParam **return_vals);
+
+
+static void p_debug_print_dump_AVCodecContext(AVCodecContext *codecContext);
+
+
static void p_gimp_get_data(const char *key, void *buffer, gint expected_size);
static void p_ffmpeg_init_default_params(GapGveFFMpegValues *epp);
@@ -301,6 +309,9 @@
static void p_close_audio_input_files(t_awk_array *awp);
static void p_open_audio_input_files(t_awk_array *awp, GapGveFFMpegGlobalParams *gpp);
+static gint64 p_calculate_current_timecode(t_ffmpeg_handle *ffh);
+static void p_set_timebase_from_framerate(AVRational *time_base, gdouble framerate);
+
static void p_ffmpeg_open_init(t_ffmpeg_handle *ffh, GapGveFFMpegGlobalParams *gpp);
static gboolean p_init_video_codec(t_ffmpeg_handle *ffh
, gint ii
@@ -730,6 +741,224 @@
} /* end run */
+/* ---------------------------------------
+ * p_debug_print_dump_AVCodecContext
+ * ---------------------------------------
+ * dump values of all (200 !!) parameters
+ * of the codec context to stdout
+ */
+static void
+p_debug_print_dump_AVCodecContext(AVCodecContext *codecContext)
+{
+ printf("AVCodecContext Settings START\n");
+
+ printf("(av_class (ptr AVClass*) %d)\n", (int) codecContext->av_class);
+ printf("(bit_rate %d)\n", (int) codecContext->bit_rate);
+ printf("(bit_rate_tolerance %d)\n", (int) codecContext->bit_rate_tolerance);
+ printf("(flags %d)\n", (int) codecContext->flags);
+ printf("(sub_id %d)\n", (int) codecContext->sub_id);
+ printf("(me_method %d)\n", (int) codecContext->me_method);
+ printf("(extradata (ptr uint8) %d)\n", (int) codecContext->extradata);
+ printf("(extradata_size %d)\n", (int) codecContext->extradata_size);
+ printf("(time_base.num %d)\n", (int) codecContext->time_base.num);
+ printf("(time_base.den %d)\n", (int) codecContext->time_base.den);
+ printf("(width %d)\n", (int) codecContext->width);
+ printf("(height %d)\n", (int) codecContext->height);
+ printf("(gop_size %d)\n", (int) codecContext->gop_size);
+ printf("(pix_fmt %d)\n", (int) codecContext->pix_fmt);
+ printf("(rate_emu %d)\n", (int) codecContext->rate_emu);
+ printf("(draw_horiz_band (fptr) %d)\n", (int) codecContext->draw_horiz_band);
+ printf("(sample_rate %d)\n", (int) codecContext->sample_rate);
+ printf("(channels %d)\n", (int) codecContext->channels);
+ printf("(sample_fmt %d)\n", (int) codecContext->sample_fmt);
+ printf("(frame_size (tabu) %d)\n", (int) codecContext->frame_size);
+ printf("(frame_number (tabu) %d)\n", (int) codecContext->frame_number);
+ printf("(real_pict_num (tabu) %d)\n", (int) codecContext->real_pict_num);
+ printf("(delay %d)\n", (int) codecContext->delay);
+ printf("(qcompress %f)\n", (float) codecContext->qcompress);
+ printf("(qblur %f)\n", (float) codecContext->qblur);
+ printf("(qmin %d)\n", (int) codecContext->qmin);
+ printf("(qmax %d)\n", (int) codecContext->qmax);
+ printf("(max_qdiff %d)\n", (int) codecContext->max_qdiff);
+ printf("(max_b_frames %d)\n", (int) codecContext->max_b_frames);
+ printf("(b_quant_factor %f)\n", (float) codecContext->b_quant_factor);
+ printf("(rc_strategy %d)\n", (int) codecContext->rc_strategy);
+ printf("(b_frame_strategy %d)\n", (int) codecContext->b_frame_strategy);
+ printf("(hurry_up %d)\n", (int) codecContext->hurry_up);
+ printf("(codec (AVCodec *) %d)\n", (int) codecContext->codec);
+ printf("(priv_data (void *) %d)\n", (int) codecContext->priv_data);
+ printf("(rtp_payload_size %d)\n", (int) codecContext->rtp_payload_size);
+ printf("(rtp_callback (fptr) %d)\n", (int) codecContext->rtp_callback);
+ printf("(mv_bits %d)\n", (int) codecContext->mv_bits);
+ printf("(header_bits %d)\n", (int) codecContext->header_bits);
+ printf("(i_tex_bits %d)\n", (int) codecContext->i_tex_bits);
+ printf("(p_tex_bits %d)\n", (int) codecContext->p_tex_bits);
+ printf("(i_count %d)\n", (int) codecContext->i_count);
+ printf("(p_count %d)\n", (int) codecContext->p_count);
+ printf("(skip_count %d)\n", (int) codecContext->skip_count);
+ printf("(misc_bits %d)\n", (int) codecContext->misc_bits);
+ printf("(frame_bits %d)\n", (int) codecContext->frame_bits);
+ printf("(opaque (void *) %d)\n", (int) codecContext->opaque);
+ printf("(codec_name %s)\n", (int) &codecContext->codec_name[0]);
+ printf("(codec_type %d)\n", (int) codecContext->codec_type);
+ printf("(codec_id %d)\n", (int) codecContext->codec_id);
+ printf("(codec_tag (fourcc) %d)\n", (int) codecContext->codec_tag);
+ printf("(workaround_bugs %d)\n", (int) codecContext->workaround_bugs);
+ printf("(luma_elim_threshold %d)\n", (int) codecContext->luma_elim_threshold);
+ printf("(chroma_elim_threshold %d)\n", (int) codecContext->chroma_elim_threshold);
+ printf("(strict_std_compliance %d)\n", (int) codecContext->strict_std_compliance);
+ printf("(b_quant_offset %f)\n", (float) codecContext->b_quant_offset);
+ printf("(error_recognition %d)\n", (int) codecContext->error_recognition);
+ printf("(get_buffer (fptr) %d)\n", (int) codecContext->get_buffer);
+ printf("(release_buffer (fptr) %d)\n", (int) codecContext->release_buffer);
+ printf("(has_b_frames %d)\n", (int) codecContext->has_b_frames);
+ printf("(block_align %d)\n", (int) codecContext->block_align);
+ printf("(parse_only %d)\n", (int) codecContext->parse_only);
+ printf("(mpeg_quant %d)\n", (int) codecContext->mpeg_quant);
+ printf("(stats_out (char*) %d)\n", (int) codecContext->stats_out);
+ printf("(stats_in (char*) %d)\n", (int) codecContext->stats_in);
+ printf("(rc_qsquish %f)\n", (float) codecContext->rc_qsquish);
+ printf("(rc_qmod_amp %f)\n", (float) codecContext->rc_qmod_amp);
+ printf("(rc_qmod_freq %d)\n", (int) codecContext->rc_qmod_freq);
+ printf("(rc_override (RcOverride*) %d)\n", (int) codecContext->rc_override);
+ printf("(rc_override_count %d)\n", (int) codecContext->rc_override_count);
+ printf("(rc_eq (char *) %d)\n", (int) codecContext->rc_eq);
+ printf("(rc_max_rate %d)\n", (int) codecContext->rc_max_rate);
+ printf("(rc_min_rate %d)\n", (int) codecContext->rc_min_rate);
+ printf("(rc_buffer_size %d)\n", (int) codecContext->rc_buffer_size);
+ printf("(rc_buffer_aggressivity %f)\n", (float) codecContext->rc_buffer_aggressivity);
+ printf("(i_quant_factor %f)\n", (float) codecContext->i_quant_factor);
+ printf("(i_quant_offset %f)\n", (float) codecContext->i_quant_offset);
+ printf("(rc_initial_cplx %f)\n", (float) codecContext->rc_initial_cplx);
+ printf("(dct_algo %d)\n", (int) codecContext->dct_algo);
+ printf("(lumi_masking %f)\n", (float) codecContext->lumi_masking);
+ printf("(temporal_cplx_masking %f)\n", (float) codecContext->temporal_cplx_masking);
+ printf("(spatial_cplx_masking %f)\n", (float) codecContext->spatial_cplx_masking);
+ printf("(p_masking %f)\n", (float) codecContext->p_masking);
+ printf("(dark_masking %f)\n", (float) codecContext->dark_masking);
+ printf("(idct_algo %d)\n", (int) codecContext->idct_algo);
+ printf("(slice_count %d)\n", (int) codecContext->slice_count);
+ printf("(slice_offset (int *) %d)\n", (int) codecContext->slice_offset);
+ printf("(error_concealment %d)\n", (int) codecContext->error_concealment);
+ printf("(dsp_mask %d)\n", (int) codecContext->dsp_mask);
+ printf("(bits_per_coded_sample %d)\n", (int) codecContext->bits_per_coded_sample);
+ printf("(prediction_method %d)\n", (int) codecContext->prediction_method);
+ printf("(sample_aspect_ratio.num %d)\n", (int) codecContext->sample_aspect_ratio.num);
+ printf("(sample_aspect_ratio.den %d)\n", (int) codecContext->sample_aspect_ratio.den);
+ printf("(coded_frame (AVFrame*) %d)\n", (int) codecContext->coded_frame);
+ printf("(debug %d)\n", (int) codecContext->debug);
+ printf("(debug_mv %d)\n", (int) codecContext->debug_mv);
+ printf("(error[0] %lld)\n", codecContext->error[0]);
+ printf("(error[1] %lld)\n", codecContext->error[1]);
+ printf("(error[2] %lld)\n", codecContext->error[2]);
+ printf("(error[3] %lld)\n", codecContext->error[3]);
+ printf("(mb_qmin %d)\n", (int) codecContext->mb_qmin);
+ printf("(mb_qmax %d)\n", (int) codecContext->mb_qmax);
+ printf("(me_cmp %d)\n", (int) codecContext->me_cmp);
+ printf("(me_sub_cmp %d)\n", (int) codecContext->me_sub_cmp);
+ printf("(mb_cmp %d)\n", (int) codecContext->mb_cmp);
+ printf("(ildct_cmp %d)\n", (int) codecContext->ildct_cmp);
+ printf("(dia_size %d)\n", (int) codecContext->dia_size);
+ printf("(last_predictor_count %d)\n", (int) codecContext->last_predictor_count);
+ printf("(pre_me %d)\n", (int) codecContext->pre_me);
+ printf("(me_pre_cmp %d)\n", (int) codecContext->me_pre_cmp);
+ printf("(pre_dia_size %d)\n", (int) codecContext->pre_dia_size);
+ printf("(me_subpel_quality %d)\n", (int) codecContext->me_subpel_quality);
+ printf("(get_format (fptr) %d)\n", (int) codecContext->get_format);
+ printf("(dtg_active_format %d)\n", (int) codecContext->dtg_active_format);
+ printf("(me_range %d)\n", (int) codecContext->me_range);
+ printf("(intra_quant_bias %d)\n", (int) codecContext->intra_quant_bias);
+ printf("(inter_quant_bias %d)\n", (int) codecContext->inter_quant_bias);
+ printf("(color_table_id %d)\n", (int) codecContext->color_table_id);
+ printf("(internal_buffer_count %d)\n", (int) codecContext->internal_buffer_count);
+ printf("(internal_buffer (void*) %d)\n", (int) codecContext->internal_buffer);
+ printf("(global_quality %d)\n", (int) codecContext->global_quality);
+ printf("(coder_type %d)\n", (int) codecContext->coder_type);
+ printf("(context_model %d)\n", (int) codecContext->context_model);
+ printf("(slice_flags %d)\n", (int) codecContext->slice_flags);
+ printf("(xvmc_acceleration %d)\n", (int) codecContext->xvmc_acceleration);
+ printf("(mb_decision %d)\n", (int) codecContext->mb_decision);
+ printf("(intra_matrix (uint16_t*) %d)\n", (int) codecContext->intra_matrix);
+ printf("(inter_matrix (uint16_t*) %d)\n", (int) codecContext->inter_matrix);
+ printf("(stream_codec_tag %d)\n", (int) codecContext->stream_codec_tag);
+ printf("(scenechange_threshold %d)\n", (int) codecContext->scenechange_threshold);
+ printf("(lmin %d)\n", (int) codecContext->lmin);
+ printf("(lmax %d)\n", (int) codecContext->lmax);
+ printf("(palctrl (AVPaletteControl*) %d)\n", (int) codecContext->palctrl);
+ printf("(noise_reduction %d)\n", (int) codecContext->noise_reduction);
+ printf("(reget_buffer (fptr) %d)\n", (int) codecContext->reget_buffer);
+ printf("(rc_initial_buffer_occupancy %d)\n", (int) codecContext->rc_initial_buffer_occupancy);
+ printf("(inter_threshold %d)\n", (int) codecContext->inter_threshold);
+ printf("(flags2 %d)\n", (int) codecContext->flags2);
+ printf("(error_rate %d)\n", (int) codecContext->error_rate);
+ printf("(antialias_algo %d)\n", (int) codecContext->antialias_algo);
+ printf("(quantizer_noise_shaping %d)\n", (int) codecContext->quantizer_noise_shaping);
+ printf("(thread_count %d)\n", (int) codecContext->thread_count);
+ printf("(execute (fptr) %d)\n", (int) codecContext->execute);
+ printf("(thread_opaque (void*) %d)\n", (int) codecContext->thread_opaque);
+ printf("(me_threshold %d)\n", (int) codecContext->me_threshold);
+ printf("(mb_threshold %d)\n", (int) codecContext->mb_threshold);
+ printf("(intra_dc_precision %d)\n", (int) codecContext->intra_dc_precision);
+ printf("(nsse_weight %d)\n", (int) codecContext->nsse_weight);
+ printf("(skip_top %d)\n", (int) codecContext->skip_top);
+ printf("(skip_bottom %d)\n", (int) codecContext->skip_bottom);
+ printf("(profile %d)\n", (int) codecContext->profile);
+ printf("(level %d)\n", (int) codecContext->level);
+ printf("(lowres %d)\n", (int) codecContext->lowres);
+ printf("(coded_width %d)\n", (int) codecContext->coded_width);
+ printf("(coded_height %d)\n", (int) codecContext->coded_height);
+ printf("(frame_skip_threshold %d)\n", (int) codecContext->frame_skip_threshold);
+ printf("(frame_skip_factor %d)\n", (int) codecContext->frame_skip_factor);
+ printf("(frame_skip_exp %d)\n", (int) codecContext->frame_skip_exp);
+ printf("(frame_skip_cmp %d)\n", (int) codecContext->frame_skip_cmp);
+ printf("(border_masking %f)\n", (float) codecContext->border_masking);
+ printf("(mb_lmin %d)\n", (int) codecContext->mb_lmin);
+ printf("(mb_lmax %d)\n", (int) codecContext->mb_lmax);
+ printf("(me_penalty_compensation %d)\n", (int) codecContext->me_penalty_compensation);
+ printf("(skip_loop_filter %d)\n", (int) codecContext->skip_loop_filter);
+ printf("(skip_idct %d)\n", (int) codecContext->skip_idct);
+ printf("(skip_frame %d)\n", (int) codecContext->skip_frame);
+ printf("(bidir_refine %d)\n", (int) codecContext->bidir_refine);
+ printf("(brd_scale %d)\n", (int) codecContext->brd_scale);
+ printf("(crf %f)\n", (float) codecContext->crf);
+ printf("(cqp %d)\n", (int) codecContext->cqp);
+ printf("(keyint_min %d)\n", (int) codecContext->keyint_min);
+ printf("(refs %d)\n", (int) codecContext->refs);
+ printf("(chromaoffset %d)\n", (int) codecContext->chromaoffset);
+ printf("(bframebias %d)\n", (int) codecContext->bframebias);
+ printf("(trellis %d)\n", (int) codecContext->trellis);
+ printf("(complexityblur %f)\n", (float) codecContext->complexityblur);
+ printf("(deblockalpha %d)\n", (int) codecContext->deblockalpha);
+ printf("(deblockbeta %d)\n", (int) codecContext->deblockbeta);
+ printf("(partitions %d)\n", (int) codecContext->partitions);
+ printf("(directpred %d)\n", (int) codecContext->directpred);
+ printf("(cutoff %d)\n", (int) codecContext->cutoff);
+ printf("(scenechange_factor %d)\n", (int) codecContext->scenechange_factor);
+ printf("(mv0_threshold %d)\n", (int) codecContext->mv0_threshold);
+ printf("(b_sensitivity %d)\n", (int) codecContext->b_sensitivity);
+ printf("(compression_level %d)\n", (int) codecContext->compression_level);
+ printf("(use_lpc %d)\n", (int) codecContext->use_lpc);
+ printf("(lpc_coeff_precision %d)\n", (int) codecContext->lpc_coeff_precision);
+ printf("(min_prediction_order %d)\n", (int) codecContext->min_prediction_order);
+ printf("(max_prediction_order %d)\n", (int) codecContext->max_prediction_order);
+ printf("(prediction_order_method %d)\n", (int) codecContext->prediction_order_method);
+ printf("(min_partition_order %d)\n", (int) codecContext->min_partition_order);
+ printf("(max_partition_order %d)\n", (int) codecContext->max_partition_order);
+ printf("(timecode_frame_start %lld)\n", codecContext->timecode_frame_start);
+ printf("(drc_scale %f)\n", (float) codecContext->drc_scale);
+ printf("(reordered_opaque %lld)\n", codecContext->reordered_opaque);
+ printf("(bits_per_raw_sample %d)\n", (int) codecContext->bits_per_raw_sample);
+ printf("(channel_layout %lld)\n", codecContext->channel_layout);
+ printf("(request_channel_layout %lld)\n", codecContext->request_channel_layout);
+ printf("(rc_max_available_vbv_use %f)\n", (float) codecContext->rc_max_available_vbv_use);
+ printf("(rc_min_vbv_overflow_use %f)\n", (float) codecContext->rc_min_vbv_overflow_use);
+
+ printf("AVCodecContext Settings END\n");
+
+} /* end p_debug_print_dump_AVCodecContext */
+
+
+
/* --------------------------------
* p_gimp_get_data
* --------------------------------
@@ -787,7 +1016,6 @@
static gint32 tab_gop_size[GAP_GVE_FFMPEG_PRESET_MAX_ELEMENTS] = { 12, 12, 96, 12, 18, 12, 18, 18, 18 };
static gint32 tab_intra[GAP_GVE_FFMPEG_PRESET_MAX_ELEMENTS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-//static float tab_qscale[GAP_GVE_FFMPEG_PRESET_MAX_ELEMENTS] = { 2, 1, 6, 2, 0, 1, 1, 1, 2 };
static float tab_qscale[GAP_GVE_FFMPEG_PRESET_MAX_ELEMENTS] = { 2, 1, 6, 2, 1, 1, 1, 1, 2 };
static gint32 tab_qmin[GAP_GVE_FFMPEG_PRESET_MAX_ELEMENTS] = { 2, 2, 8, 2, 2, 2, 2, 2, 2 };
@@ -1346,10 +1574,80 @@
} /* end p_open_audio_input_files */
+/* -----------------------------
+ * p_calculate_current_timecode
+ * -----------------------------
+ * returns the timecode for the current frame
+ */
+static gint64
+p_calculate_current_timecode(t_ffmpeg_handle *ffh)
+{
+ gdouble dblTimecode;
+ gint64 timecode64;
+
+ /*
+ * gdouble seconds;
+ * seconds = (ffh->encode_frame_nr / gpp->val.framerate);
+ */
+
+ dblTimecode = ffh->encode_frame_nr * ffh->pts_stepsize_per_frame;
+ timecode64 = dblTimecode;
+
+ return (timecode64);
+}
+
+
+/* -----------------------------
+ * p_set_timebase_from_framerate
+ * -----------------------------
+ * set the specified framerate (frames per second)
+ * in the ffmpeg typical AVRational struct.
+ *
+ * 25 frames per second shall be encoded ad num = 1, den = 25
+ * typedef struct AVRational{
+ * int num; numerator
+ * int den; denominator
+ * } AVRational;
+ */
+static void
+p_set_timebase_from_framerate(AVRational *time_base, gdouble framerate)
+{
+ gdouble truncatedFramerate;
+ time_base->num = 1;
+ time_base->den = framerate;
+ truncatedFramerate = time_base->den;
+ if((framerate - truncatedFramerate) != 0.0)
+ {
+ time_base->num = DEFAULT_FRAME_RATE_BASE;
+ time_base->den = framerate * DEFAULT_FRAME_RATE_BASE;
+ }
+ /* due to rounding errors, some typical framerates would be
+ * rejected by newer libavcodec encoders.
+ * therefore adjust those values to exact expected values of the codecs.
+ */
+ if ((framerate > 59.90) && (framerate < 59.99))
+ {
+ time_base->num = 1001;
+ time_base->den = 60000;
+
+ }
+ if ((framerate > 29.90) && (framerate < 29.99))
+ {
+ time_base->num = 1001;
+ time_base->den = 30000;
+
+ }
+ if ((framerate > 23.90) && (framerate < 23.99))
+ {
+ time_base->num = 1001;
+ time_base->den = 24000;
+
+ }
+} /* end p_set_timebase_from_framerate */
/* ------------------
@@ -1394,6 +1692,23 @@
ffh->ast[ii].audio_buffer = NULL;
ffh->ast[ii].audio_buffer_size = 0;
}
+
+ {
+ AVRational l_time_base;
+
+ p_set_timebase_from_framerate(&l_time_base, gpp->val.framerate);
+ ffh->pts_stepsize_per_frame = l_time_base.num;
+
+ //if(gap_debug)
+ {
+ printf("p_ffmpeg_open_init time_base: num:%d den:%d pts_stepsize_per_frame:%.4f\n"
+ ,(int)l_time_base.num
+ ,(int)l_time_base.den
+ ,(float)ffh->pts_stepsize_per_frame
+ );
+ }
+ }
+
/* initialize common things */
ffh->frame_width = (int)gpp->val.vid_width;
@@ -1402,8 +1717,7 @@
ffh->frame_bottomBand = 0;
ffh->frame_leftBand = 0;
ffh->frame_rightBand = 0;
- ffh->frame_duration_pts = (1.0 / gpp->val.framerate) * AV_TIME_BASE;
- ffh->frame_rate = gpp->val.framerate * DEFAULT_FRAME_RATE_BASE;
+ ffh->encode_frame_nr = 0;
ffh->video_bit_rate = epp->video_bitrate * 1000;
ffh->video_bit_rate_tolerance = epp->bitrate_tol * 1000;
ffh->video_qscale = epp->qscale;
@@ -1433,8 +1747,8 @@
ffh->umv = epp->umv;
ffh->use_4mv = epp->mv4;
ffh->workaround_bugs = FF_BUG_AUTODETECT;
- ffh->error_resilience = 2;
- ffh->error_concealment = 3;
+ ffh->error_recognition = FF_ER_COMPLIANT;
+ ffh->error_concealment = FF_EC_DEBLOCK;
ffh->dct_algo = epp->dct_algo;
ffh->idct_algo = epp->idct_algo;
ffh->strict = epp->strict;
@@ -1467,65 +1781,13 @@
} /* end p_ffmpeg_open_init */
-/* -----------------------------
- * p_set_timebase_from_framerate
- * -----------------------------
- * set the specified framerate (frames per second)
- * in the ffmpeg typical AVRational struct.
- *
- * 25 frames per second shall be encoded ad num = 25, den = 1
- * typedef struct AVRational{
- * int num; ///< numerator
- * int den; ///< denominator
- * } AVRational;
- */
-static void
-p_set_timebase_from_framerate(AVRational *time_base, gdouble framerate)
-{
- gdouble truncatedFramerate;
-
- time_base->num = 1;
- time_base->den = framerate;
-
- truncatedFramerate = time_base->den;
- if((framerate - truncatedFramerate) != 0.0)
- {
- time_base->num = DEFAULT_FRAME_RATE_BASE;
- time_base->den = framerate * DEFAULT_FRAME_RATE_BASE;
- }
-
-
-
- /* due to rounding errors, some typical framerates would be
- * rejected by newer libavcodec encoders.
- * therefore adjust those values to exact expected values of the codecs.
- */
- if ((framerate > 59.90) && (framerate < 59.99))
- {
- time_base->num = 1001;
- time_base->den = 60000;
-
- }
- if ((framerate > 29.90) && (framerate < 29.99))
- {
- time_base->num = 1001;
- time_base->den = 30000;
-
- }
- if ((framerate > 23.90) && (framerate < 23.99))
- {
- time_base->num = 1001;
- time_base->den = 24000;
-
- }
-
-} /* end p_set_timebase_from_framerate */
/* ------------------
* p_init_video_codec
* ------------------
- * init settings for the video codec
- * (just prepare for opening, but dont open yet)
+ * add stream for stream index ii (ii=0 for the 1st video stream)
+ * and init settings for the video codec to be used for encoding frames in the stream
+ * (just prepare the video codec for opening, but dont open yet)
*/
static gboolean
p_init_video_codec(t_ffmpeg_handle *ffh
@@ -1556,19 +1818,11 @@
/* set stream 0 (video stream) */
-#ifdef HAVE_OLD_FFMPEG_0408
- ffh->output_context->nb_streams += 1; /* number of streams */
- ffh->vst[ii].vid_stream = g_malloc0(sizeof(AVStream));
- avcodec_get_context_defaults(&ffh->vst[ii].vid_stream->codec);
- ffh->vst[ii].vid_stream->index = ii;
- ffh->vst[ii].vid_stream->id = ii; /* XXXx ? dont know how to init this ? = or ii ? */
- ffh->output_context->streams[ii] = ffh->vst[ii].vid_stream;
-#else
ffh->vst[ii].vid_stream = av_new_stream(ffh->output_context, ii /* vid_stream_index */ );
if(gap_debug)
{
- printf("p_ffmpeg_open ffh->vst[%d].vid_stream: %d ffh->output_context->streams[%d]: %d nb_streams:%d\n"
+ printf("p_init_video_codec ffh->vst[%d].vid_stream: %d ffh->output_context->streams[%d]: %d nb_streams:%d\n"
,(int)ii
,(int)ffh->vst[ii].vid_stream
,(int)ii
@@ -1576,18 +1830,21 @@
,(int)ffh->output_context->nb_streams
);
}
-#endif
- /* set Video codec context */
+ /* set Video codec context in the video stream array (vst) */
ffh->vst[ii].vid_codec_context = ffh->vst[ii].vid_stream->codec;
+
/* some formats need to know about the coded_frame
* and get the information from the AVCodecContext coded_frame Pointer
+ * 2009.01.31 Not sure if this is still required in recent ffmpeg versions,
+ * the coded_frame pointer seems to be dynamically allocated
+ * (in avcodec_open and avcodec_encode_video calls)
*/
- if(gap_debug) printf("(B) ffh->vst[ii].vid_codec_context:%d\n", (int)ffh->vst[ii].vid_codec_context);
ffh->vst[ii].vid_codec_context->coded_frame = ffh->vst[ii].big_picture_codec;
+
video_enc = ffh->vst[ii].vid_codec_context;
video_enc->codec_type = CODEC_TYPE_VIDEO;
@@ -1597,22 +1854,30 @@
video_enc->bit_rate_tolerance = epp->bitrate_tol * 1000;
p_set_timebase_from_framerate(&video_enc->time_base, gpp->val.framerate);
+
+ video_enc->width = gpp->val.vid_width;
+ video_enc->height = gpp->val.vid_height;
//if (gap_debug)
{
- printf("VCODEC: time_base.num :%d time_base.den:%d float:%f\n"
- " AV_TIME_BASE: %d DEFAULT_FRAME_RATE_BASE: %d\n"
+ printf("VCODEC: id:%d (%s) time_base.num :%d time_base.den:%d float:%f\n"
+ " DEFAULT_FRAME_RATE_BASE: %d\n"
+ , video_enc->codec_id
+ , epp->vcodec_name
, video_enc->time_base.num
, video_enc->time_base.den
, (float)gpp->val.framerate
- , (int)AV_TIME_BASE
, (int)DEFAULT_FRAME_RATE_BASE
);
+
+ /* dump all parameters (standard values reprsenting ffmpeg internal defaults) to stdout */
+ p_debug_print_dump_AVCodecContext(video_enc);
}
- video_enc->width = gpp->val.vid_width;
- video_enc->height = gpp->val.vid_height;
+
+ video_enc->pix_fmt = PIX_FMT_YUV420P; /* PIX_FMT_YUV444P; PIX_FMT_YUV420P; PIX_FMT_BGR24; PIX_FMT_RGB24; */
+
if(!strcmp(epp->format_name, "mp4")
|| !strcmp(epp->format_name, "mov")
@@ -1621,33 +1886,25 @@
video_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
-
-#ifdef HAVE_OLD_FFMPEG_0408
- if(epp->qscale)
- {
- video_enc->flags |= CODEC_FLAG_QSCALE;
- ffh->vst[ii].vid_stream->quality = epp->qscale; /* video_enc->quality = epp->qscale; */
- }
-
- video_enc->aspect_ratio = 0;
- if(epp->set_aspect_ratio)
+ /* mb_decision changed in ffmpeg-0.4.8
+ * 0: FF_MB_DECISION_SIMPLE
+ * 1: FF_MB_DECISION_BITS
+ * 2: FF_MB_DECISION_RD
+ */
+ video_enc->mb_decision = epp->mb_decision;
+ if (video_enc->codec_id == CODEC_ID_MPEG1VIDEO)
{
- if(epp->factor_aspect_ratio == 0.0)
- {
- video_enc->aspect_ratio = (gdouble)gpp->val.vid_width
- / (gdouble)(MAX(1,gpp->val.vid_height));
- }
- else
- {
- video_enc->aspect_ratio = epp->factor_aspect_ratio;
- }
+ /* Needed to avoid using macroblocks in which some coeffs overflow.
+ This does not happen with normal video, it just happens here as
+ the motion of the chroma plane does not match the luma plane. */
+ video_enc->mb_decision=2;
}
-#else
if(epp->qscale)
{
video_enc->flags |= CODEC_FLAG_QSCALE;
ffh->vst[ii].vid_stream->quality = FF_QP2LAMBDA * epp->qscale; /* video_enc->quality = epp->qscale; */
+ video_enc->global_quality = FF_QP2LAMBDA * epp->qscale; /* 2009.01.31 must init global_quality to avoid crash */
}
@@ -1682,12 +1939,21 @@
*/
l_dbl = l_aspect_factor * (gdouble)gpp->val.vid_height / (gdouble)MAX(1,gpp->val.vid_width);
+ //if(gap_debug)
+ {
+ printf("ASPECT ratio DEFAULT setting: NUM:%d DEN:%d\n"
+ ,(int)video_enc->sample_aspect_ratio.num
+ ,(int)video_enc->sample_aspect_ratio.den
+ );
+ }
video_enc->sample_aspect_ratio = av_d2q(l_dbl, 255);
+ ffh->vst[ii].vid_stream->sample_aspect_ratio = video_enc->sample_aspect_ratio; /* 2009.01.31 must init stream sample_aspect_ratio to avoid crash */
- if(gap_debug)
+ //if(gap_debug)
{
- printf("ASPECT ratio (w/h): %f av_d2q NUM:%d DEN:%d\n"
+ printf("ASPECT ratio (w/h): %f l_dbl:%f av_d2q NUM:%d DEN:%d\n"
,(float)l_aspect_factor
+ ,(float)l_dbl
,(int)video_enc->sample_aspect_ratio.num
,(int)video_enc->sample_aspect_ratio.den
);
@@ -1710,7 +1976,6 @@
video_enc->temporal_cplx_masking = epp->tcplx_mask;
video_enc->p_masking = epp->p_mask;
video_enc->quantizer_noise_shaping = epp->qns;
-#endif
if(!epp->intra) { video_enc->gop_size = epp->gop_size; }
else { video_enc->gop_size = 0; }
@@ -1730,20 +1995,12 @@
video_enc->flags |= CODEC_FLAG_BITEXACT;
}
- /* mb_decision changed in ffmpeg-0.4.8
- * 0: FF_MB_DECISION_SIMPLE
- * 1: FF_MB_DECISION_BITS
- * 2: FF_MB_DECISION_RD
- */
- video_enc->mb_decision = epp->mb_decision;
if(epp->umv)
{
video_enc->flags |= CODEC_FLAG_H263P_UMV;
}
-#ifdef HAVE_OLD_FFMPEG_0408
-#else
if (epp->use_ss)
{
video_enc->flags |= CODEC_FLAG_H263P_SLICE_STRUCT;
@@ -1769,7 +2026,7 @@
}
if (epp->use_trell)
{
- video_enc->flags |= CODEC_FLAG_TRELLIS_QUANT;
+ /// video_enc->flags |= CODEC_FLAG_TRELLIS_QUANT; /// this flag is no longer supported (TODO remove all occurances)
}
if (epp->use_mv0)
{
@@ -1787,7 +2044,6 @@
{
video_enc->flags |= CODEC_FLAG_CLOSED_GOP;
}
-#ifdef HAVE_FULL_FFMPEG
if (epp->strict_gop)
{
video_enc->flags2 |= CODEC_FLAG2_STRICT_GOP;
@@ -1796,7 +2052,6 @@
{
video_enc->flags2 |= CODEC_FLAG2_NO_OUTPUT;
}
-#endif
if (epp->use_qpel)
{
video_enc->flags |= CODEC_FLAG_QPEL;
@@ -1817,20 +2072,16 @@
{
video_enc->flags |= CODEC_FLAG_INTERLACED_ME;
}
-#endif
if(epp->aic)
{
- video_enc->flags |= CODEC_FLAG_H263P_AIC;
+ video_enc->flags |= CODEC_FLAG_AC_PRED; /// old flag no longer supported CODEC_FLAG_H263P_AIC
}
if (epp->mv4)
{
/* video_enc->flags |= CODEC_FLAG_HQ; */ /* CODEC_FLAG_HQ no longer supported in ffmpeg-0.4.8 */
-#ifdef HAVE_OLD_FFMPEG_0408
- video_enc->mb_decision = FF_MB_DECISION_BITS; /* FIXME remove */
-#endif
video_enc->flags |= CODEC_FLAG_4MV;
}
@@ -1870,7 +2121,7 @@
break;
}
}
-
+
video_enc->qmin = epp->qmin;
video_enc->qmax = epp->qmax;
video_enc->max_qdiff = epp->qdiff;
@@ -1895,8 +2146,6 @@
video_enc->mb_qmin = epp->mb_qmin;
video_enc->mb_qmax = epp->mb_qmax;
-#ifdef HAVE_OLD_FFMPEG_0408
-#else
video_enc->rc_initial_buffer_occupancy = video_enc->rc_buffer_size * 3/4;
video_enc->lmin = epp->video_lmin;
video_enc->lmax = epp->video_lmax;
@@ -1927,7 +2176,6 @@
video_enc->nsse_weight = epp->nsse_weight;
video_enc->me_subpel_quality = epp->subpel_quality;
-#ifdef HAVE_FULL_FFMPEG
video_enc->mb_lmin = epp->video_mb_lmin;
video_enc->mb_lmax = epp->video_mb_lmax;
video_enc->profile = epp->video_profile;
@@ -1936,20 +2184,15 @@
video_enc->frame_skip_factor = epp->frame_skip_factor;
video_enc->frame_skip_exp = epp->frame_skip_exp;
video_enc->frame_skip_cmp = epp->frame_skip_cmp;
-#endif
-
-#endif
if(epp->packet_size)
{
- video_enc->rtp_mode = 1;
video_enc->rtp_payload_size = epp->packet_size;
}
if (epp->psnr) { video_enc->flags |= CODEC_FLAG_PSNR; }
video_enc->me_method = epp->motion_estimation;
- video_enc->pix_fmt = PIX_FMT_YUV420P; /* PIX_FMT_YUV444P; PIX_FMT_YUV420P; PIX_FMT_BGR24; PIX_FMT_RGB24; */
if (epp->title[0] != '\0')
@@ -2052,6 +2295,7 @@
return (TRUE); /* OK */
+
} /* end p_init_video_codec */
@@ -2096,16 +2340,7 @@
ast_index = ffh->max_vst + ii;
/* set stream 1 (audio stream) */
-#ifdef HAVE_OLD_FFMPEG_0408
- ffh->output_context->nb_streams += 1; /* number of streams */
- ffh->ast[ii].aud_stream = g_malloc0(sizeof(AVStream));
- avcodec_get_context_defaults(&ffh->ast[ii].aud_stream->codec);
- ffh->ast[ii].aud_stream->index = ast_index;
- ffh->ast[ii].aud_stream->id = ast_index; /* XXXx ? dont know how to init this ? */
- ffh->output_context->streams[ast_index] = ffh->ast[ii].aud_stream;
-#else
ffh->ast[ii].aud_stream = av_new_stream(ffh->output_context, ast_index /* aud_stream_index */ );
-#endif
ffh->ast[ii].aud_codec_context = ffh->ast[ii].aud_stream->codec;
/* set codec context */
@@ -2134,13 +2369,9 @@
ffh->ast[ii].aud_codec = NULL;
}
-#ifdef HAVE_OLD_FFMPEG_0408
-#else
/* the following options were added after ffmpeg 0.4.8 */
audio_enc->thread_count = 1;
audio_enc->strict_std_compliance = epp->strict;
-#endif
-
}
}
@@ -2203,7 +2434,7 @@
return(NULL);
}
- if(gap_debug)
+ //if(gap_debug)
{
printf("AVOutputFormat ffh->file_oformat opened\n");
printf(" name: %s\n", ffh->file_oformat->name);
@@ -2220,13 +2451,9 @@
}
-#ifdef HAVE_OLD_FFMPEG_0408
- ffh->output_context = g_malloc0(sizeof(AVFormatContext));
-#else
ffh->output_context = av_alloc_format_context();
-#endif
ffh->output_context->oformat = ffh->file_oformat;
- strcpy(ffh->output_context->filename, &gpp->val.videoname[0]);
+ g_snprintf(ffh->output_context->filename, sizeof(ffh->output_context->filename), "%s", &gpp->val.videoname[0]);
ffh->output_context->nb_streams = 0; /* number of streams */
@@ -2261,6 +2488,8 @@
return(NULL);
}
+
+
/* open video codec(s) */
for (ii=0; ii < ffh->max_vst; ii++)
{
@@ -2380,12 +2609,11 @@
}
-#ifdef HAVE_FULL_FFMPEG
- ffh->output_context->packet_size = epp->mux_packet_size;
- ffh->output_context->mux_rate = epp->mux_rate;
- ffh->output_context->preload = (int)(epp->mux_preload*AV_TIME_BASE);
- ffh->output_context->max_delay = (int)(epp->mux_max_delay*AV_TIME_BASE);
-#endif
+
+ ffh->output_context->packet_size = epp->mux_packet_size;
+ ffh->output_context->mux_rate = epp->mux_rate;
+ ffh->output_context->preload = (int)(epp->mux_preload*AV_TIME_BASE);
+ ffh->output_context->max_delay = (int)(epp->mux_max_delay*AV_TIME_BASE);
if(gap_debug)
{
@@ -2400,6 +2628,8 @@
/* --------------------------
* p_ffmpeg_write_frame_chunk
* --------------------------
+ * write videoframe chunk 1:1 to the mediafile as packet.
+ * (typically used for lossless video cut to copy already encoded frames)
*/
static int
p_ffmpeg_write_frame_chunk(t_ffmpeg_handle *ffh, gint32 encoded_size, gint vid_track)
@@ -2494,16 +2724,26 @@
if(gap_debug)
{
- printf("CHUNK picture_number: enc_dummy_size:%d frame_type:%d pic_number: %d %d PTS:%d\n"
+ printf("CHUNK picture_number: enc_dummy_size:%d frame_type:%d pic_number: %d %d PTS:%lld\n"
, (int)encoded_dummy_size
, (int)chunk_frame_type
, (int)ffh->vst[ii].vid_codec_context->coded_frame->coded_picture_number
, (int)ffh->vst[ii].vid_codec_context->coded_frame->display_picture_number
- , (int)ffh->vst[ii].vid_codec_context->coded_frame->pts
+ , ffh->vst[ii].vid_codec_context->coded_frame->pts
);
}
- pkt.pts = ffh->vst[ii].vid_codec_context->coded_frame->pts;
+ ///// pkt.pts = ffh->vst[ii].vid_codec_context->coded_frame->pts; // OLD
+ {
+ AVCodecContext *c;
+
+ c = ffh->vst[ii].vid_codec_context;
+ if (c->coded_frame->pts != AV_NOPTS_VALUE)
+ {
+ pkt.pts= av_rescale_q(c->coded_frame->pts, c->time_base, ffh->vst[ii].vid_stream->time_base);
+ }
+ }
+
pkt.dts = AV_NOPTS_VALUE; /* let av_write_frame calculate the decompression timestamp */
pkt.stream_index = ffh->vst[ii].video_stream_index;
pkt.data = ffh->vst[ii].video_buffer;
@@ -2522,6 +2762,8 @@
/* --------------------
* p_ffmpeg_write_frame
* --------------------
+ * encode one videoframe using the selected codec and write
+ * the encoded frame to the mediafile as packet.
*/
static int
p_ffmpeg_write_frame(t_ffmpeg_handle *ffh, gboolean force_keyframe, gint vid_track)
@@ -2544,7 +2786,11 @@
codec = ffh->vst[ii].vid_codec_context->codec;
- printf("p_ffmpeg_write_frame: START codec: %d track:%d\n", (int)codec, (int)vid_track);
+ printf("p_ffmpeg_write_frame: START codec: %d track:%d frame_nr:%d\n"
+ , (int)codec
+ , (int)vid_track
+ , (int)ffh->encode_frame_nr
+ );
printf("\n-------------------------\n");
printf("name: %s\n", codec->name);
printf("type: %d\n", codec->type);
@@ -2567,7 +2813,10 @@
if(ffh->vst[ii].vid_codec_context->pix_fmt == PIX_FMT_YUV420P)
{
- if(gap_debug) printf("USE YUV420 (no pix_fmt convert needed)\n");
+ if(gap_debug)
+ {
+ printf("USE YUV420 (no pix_fmt convert needed)\n");
+ }
/* most of the codecs wants YUV420
* (we can use the picture in ffh->vst[ii].yuv420_buffer without pix_fmt conversion
@@ -2613,7 +2862,12 @@
* (same as AVPicture but with additional members at the end)
*/
- if(gap_debug) printf("before img_convert pix_fmt: %d (YUV420:%d)\n", (int)ffh->vst[ii].vid_codec_context->pix_fmt, (int)PIX_FMT_YUV420P);
+ if(gap_debug)
+ {
+ printf("before img_convert pix_fmt: %d (YUV420:%d)\n"
+ , (int)ffh->vst[ii].vid_codec_context->pix_fmt
+ , (int)PIX_FMT_YUV420P);
+ }
/* convert to pix_fmt needed by the codec */
img_convert(picture_codec, ffh->vst[ii].vid_codec_context->pix_fmt /* dst */
@@ -2645,9 +2899,15 @@
ffh->vst[ii].big_picture_codec->key_frame = 0;
}
+
if(ffh->output_context)
{
- if(gap_debug) printf("before avcodec_encode_video\n");
+ if(gap_debug)
+ {
+ printf("before avcodec_encode_video big_picture_codec:%d\n"
+ ,(int)ffh->vst[ii].big_picture_codec
+ );
+ }
encoded_size = avcodec_encode_video(ffh->vst[ii].vid_codec_context
,ffh->vst[ii].video_buffer, ffh->vst[ii].video_buffer_size
@@ -2657,26 +2917,60 @@
/* if zero size, it means the image was buffered */
if(encoded_size != 0)
{
- if(gap_debug)
- {
- printf("before av_write_frame encoded_size:%d\n", (int)encoded_size );
- }
{
AVPacket pkt;
+ AVCodecContext *c;
+
av_init_packet (&pkt);
+ c = ffh->vst[ii].vid_codec_context;
- if(gap_debug)
+
+ ///// pkt.pts = ffh->vst[ii].vid_codec_context->coded_frame->pts; // OLD
+
+ if (c->coded_frame->pts != AV_NOPTS_VALUE)
+ {
+ pkt.pts= av_rescale_q(c->coded_frame->pts, c->time_base, ffh->vst[ii].vid_stream->time_base);
+ }
+
+// if ((pkt.pts == 0) || (pkt.pts == AV_NOPTS_VALUE))
+// {
+// /* WORKAROND calculate pts timecode for the current frame
+// * because the codec did not deliver a valid timecode
+// */
+// pkt.pts = p_calculate_current_timecode(ffh);
+// }
+
+
+ if(c->coded_frame->key_frame)
{
- printf("before av_write_frame encoded_size:%d\n", (int)encoded_size );
+ pkt.flags |= PKT_FLAG_KEY;
}
-
- pkt.pts = ffh->vst[ii].vid_codec_context->coded_frame->pts;
+
pkt.stream_index = ffh->vst[ii].video_stream_index;
pkt.data = ffh->vst[ii].video_buffer;
pkt.size = encoded_size;
- if(ffh->vst[ii].vid_codec_context->coded_frame->key_frame)
+
+ if(gap_debug)
{
- pkt.flags |= PKT_FLAG_KEY;
+ AVStream *st;
+
+ st = ffh->output_context->streams[pkt.stream_index];
+
+ printf("before av_write_frame video encoded_size:%d\n"
+ " pkt.stream_index:%d pkt.pts:%lld dts:%lld coded_frame->pts:%lld c->time_base:%d den:%d\n"
+ " st->pts.num:%lld, st->pts.den:%lld st->pts.val:%lld\n"
+ , (int)encoded_size
+ , pkt.stream_index
+ , pkt.pts
+ , pkt.dts
+ , c->coded_frame->pts
+ , c->time_base.num
+ , c->time_base.den
+ ,st->pts.num
+ ,st->pts.den
+ ,st->pts.val
+ );
+
}
ret = av_write_frame(ffh->output_context, &pkt);
@@ -2735,17 +3029,47 @@
{
AVPacket pkt;
+ AVCodecContext *c;
+
av_init_packet (&pkt);
+ c = ffh->ast[ii].aud_codec_context;
+
- if(gap_debug) printf("before av_write_frame encoded_size:%d\n", (int)encoded_size );
+// pkt.pts = ffh->ast[ii].aud_codec_context->coded_frame->pts; // OLD
+
+ if (c->coded_frame->pts != AV_NOPTS_VALUE)
+ {
+ pkt.pts= av_rescale_q(c->coded_frame->pts, c->time_base, ffh->ast[ii].aud_stream->time_base);
+ }
- pkt.pts = ffh->ast[ii].aud_codec_context->coded_frame->pts;
+// if ((pkt.pts == 0) || (pkt.pts == AV_NOPTS_VALUE))
+// {
+// /* calculate pts timecode for the current frame
+// * because the codec did not deliver a valid timecode
+// */
+// pkt.pts = p_calculate_current_timecode(ffh);
+// }
+
+
pkt.stream_index = ffh->ast[ii].audio_stream_index;
pkt.data = ffh->ast[ii].audio_buffer;
pkt.size = encoded_size;
+
+ if(gap_debug)
+ {
+ printf("before av_write_frame audio encoded_size:%d pkt.pts:%lld dts:%lld\n"
+ , (int)encoded_size
+ , pkt.pts
+ , pkt.dts
+ );
+ }
+
ret = av_write_frame(ffh->output_context, &pkt);
- if(gap_debug) printf("after av_write_frame encoded_size:%d\n", (int)encoded_size );
+ if(gap_debug)
+ {
+ printf("after av_write_frame audio encoded_size:%d\n", (int)encoded_size );
+ }
}
}
return(ret);
@@ -2761,6 +3085,7 @@
* my private copy of (libavformat/aviobuf.c url_fclose)
* just skips the crashing step "av_free(s);" that frees up the ByteIOContext itself
* (free(): invalid pointer: 0x0859f3b0)
+ * The workaround is still required in ffmpeg snapshot from 2009.01.31
*/
int
my_url_fclose(ByteIOContext *s)
@@ -2787,7 +3112,7 @@
{
gint ii;
- //if(gap_debug)
+ if(gap_debug)
{
printf("free big_picture_codec\n");
}
@@ -2800,7 +3125,7 @@
ffh->vst[ii].big_picture_codec = NULL;
}
}
- //if(gap_debug)
+ if(gap_debug)
{
printf("Closing VIDEO stuff\n");
}
@@ -2809,7 +3134,7 @@
{
/* write the trailer if needed and close file */
av_write_trailer(ffh->output_context);
- //if(gap_debug)
+ if(gap_debug)
{
printf("after av_write_trailer\n");
}
@@ -2819,12 +3144,12 @@
{
if(ffh->vst[ii].vid_codec_context)
{
- //if(gap_debug)
+ if(gap_debug)
{
printf("[%d] before avcodec_close\n", ii);
}
avcodec_close(ffh->vst[ii].vid_codec_context);
- //if(gap_debug)
+ if(gap_debug)
{
printf("[%d] after avcodec_close\n", ii);
}
@@ -2841,52 +3166,52 @@
if(ffh->vst[ii].video_buffer)
{
- //if(gap_debug)
+ if(gap_debug)
{
printf("[%d] before g_free video_buffer\n", ii);
}
g_free(ffh->vst[ii].video_buffer);
ffh->vst[ii].video_buffer = NULL;
- //if(gap_debug)
+ if(gap_debug)
{
printf("[%d] after g_free video_buffer\n", ii);
}
}
if(ffh->vst[ii].video_dummy_buffer)
{
- //if(gap_debug)
+ if(gap_debug)
{
printf("[%d] before g_free video_dummy_buffer\n", ii);
}
g_free(ffh->vst[ii].video_dummy_buffer);
ffh->vst[ii].video_dummy_buffer = NULL;
- //if(gap_debug)
+ if(gap_debug)
{
printf("[%d] after g_free video_dummy_buffer\n", ii);
}
}
if(ffh->vst[ii].yuv420_buffer)
{
- //if(gap_debug)
+ if(gap_debug)
{
printf("[%d] before g_free yuv420_buffer\n", ii);
}
g_free(ffh->vst[ii].yuv420_buffer);
ffh->vst[ii].yuv420_buffer = NULL;
- //if(gap_debug)
+ if(gap_debug)
{
printf("[%d] after g_free yuv420_buffer\n", ii);
}
}
if(ffh->vst[ii].yuv420_dummy_buffer)
{
- //if(gap_debug)
+ if(gap_debug)
{
printf("[%d] before g_free yuv420_dummy_buffer\n", ii);
}
g_free(ffh->vst[ii].yuv420_dummy_buffer);
ffh->vst[ii].yuv420_dummy_buffer = NULL;
- //if(gap_debug)
+ if(gap_debug)
{
printf("[%d] after g_free yuv420_dummy_buffer\n", ii);
}
@@ -2894,7 +3219,7 @@
}
- //if(gap_debug)
+ if(gap_debug)
{
printf("Closing AUDIO stuff\n");
}
@@ -2919,12 +3244,13 @@
{
if (!(ffh->output_context->oformat->flags & AVFMT_NOFILE))
{
- //if(gap_debug)
+ if(gap_debug)
{
printf("before url_fclose\n");
}
my_url_fclose(&ffh->output_context->pb);
- //if(gap_debug)
+
+ if(gap_debug)
{
printf("after url_fclose\n");
}
@@ -3205,6 +3531,7 @@
l_max_master_frame_nr = abs(l_end - l_begin) + 1;
l_cur_frame_nr = l_begin;
+ ffh->encode_frame_nr = 1;
while(l_rc >= 0)
{
gboolean l_fetch_ok;
@@ -3239,7 +3566,7 @@
, l_check_flags
);
- //if(gap_debug)
+ if(gap_debug)
{
printf("\nFFenc: after gap_story_render_fetch_composite_image_or_chunk image_id:%d layer_id:%d\n"
, (int)l_tmp_image_id
@@ -3267,7 +3594,7 @@
l_cnt_encoded_frames++;
l_drawable = gimp_drawable_get (l_layer_id);
- //if (gap_debug)
+ if (gap_debug)
{
printf("DEBUG: %s encoding frame %d\n"
, epp->vcodec_name
@@ -3324,30 +3651,31 @@
break;
}
l_cur_frame_nr += l_step;
+ ffh->encode_frame_nr++;
} /* end loop foreach frame */
if(ffh != NULL)
{
- //if(gap_debug)
+ if(gap_debug)
{
printf("before: p_ffmpeg_close\n");
}
p_ffmpeg_close(ffh);
- //if(gap_debug)
+ if(gap_debug)
{
printf("after: p_ffmpeg_close\n");
}
g_free(ffh);
}
- //if(gap_debug)
+ if(gap_debug)
{
printf("before: p_close_audio_input_files\n");
}
p_close_audio_input_files(awp);
- //if(gap_debug)
+ if(gap_debug)
{
printf("after: p_close_audio_input_files\n");
}
Modified: trunk/vid_enc_ffmpeg/gap_enc_ffmpeg_main.h
==============================================================================
--- trunk/vid_enc_ffmpeg/gap_enc_ffmpeg_main.h (original)
+++ trunk/vid_enc_ffmpeg/gap_enc_ffmpeg_main.h Sun Feb 8 09:37:06 2009
@@ -39,19 +39,6 @@
#include "avcodec.h"
-#undef HAVE_FULL_FFMPEG
-
-#if FFMPEG_VERSION_INT == 0x000408
-#define HAVE_OLD_FFMPEG_0408
-#else
-#undef HAVE_OLD_FFMPEG_0408
-#if LIBAVCODEC_BUILD >= 4744
-#define HAVE_FULL_FFMPEG
-#endif
-#endif
-
-
-
#define GAP_HELP_ID_FFMPEG_PARAMS "plug-in-gap-encpar-ffmpeg"
#define GAP_PLUGIN_NAME_FFMPEG_PARAMS "plug-in-gap-encpar-ffmpeg"
#define GAP_PLUGIN_NAME_FFMPEG_ENCODE "plug-in-gap-enc-ffmpeg"
@@ -92,7 +79,15 @@
#define GAP_GVE_FFMPEG_MOTION_ESTIMATION_04_PHODS ME_PHODS
#define GAP_GVE_FFMPEG_MOTION_ESTIMATION_05_EPZS ME_EPZS
#define GAP_GVE_FFMPEG_MOTION_ESTIMATION_06_X1 ME_X1
-#define GAP_GVE_FFMPEG_MOTION_ESTIMATION_MAX_ELEMENTS 6
+/* motion estimation
+ * 7,8,10 are x264 specific
+ * 9 is snow specific
+ */
+#define GAP_GVE_FFMPEG_MOTION_ESTIMATION_07_HEX ME_HEX
+#define GAP_GVE_FFMPEG_MOTION_ESTIMATION_08_UMH ME_UMH
+#define GAP_GVE_FFMPEG_MOTION_ESTIMATION_09_ITER ME_ITER
+#define GAP_GVE_FFMPEG_MOTION_ESTIMATION_10_TESA ME_TESA
+#define GAP_GVE_FFMPEG_MOTION_ESTIMATION_MAX_ELEMENTS 10
@@ -106,19 +101,33 @@
#define GAP_GVE_FFMPEG_DCT_ALGO_MAX_ELEMENTS 7
-#define GAP_GVE_FFMPEG_IDCT_ALGO_00_AUTO 0
-#define GAP_GVE_FFMPEG_IDCT_ALGO_01_INT 1
-#define GAP_GVE_FFMPEG_IDCT_ALGO_02_SIMPLE 2
-#define GAP_GVE_FFMPEG_IDCT_ALGO_03_SIMPLEMMX 3
-#define GAP_GVE_FFMPEG_IDCT_ALGO_04_LIBMPEG2MMX 4
-#define GAP_GVE_FFMPEG_IDCT_ALGO_05_PS2 5
-#define GAP_GVE_FFMPEG_IDCT_ALGO_06_MLIB 6
-#define GAP_GVE_FFMPEG_IDCT_ALGO_07_ARM 7
-#define GAP_GVE_FFMPEG_IDCT_ALGO_08_ALTIVEC 8
-#define GAP_GVE_FFMPEG_IDCT_ALGO_09_SH4 9
-#define GAP_GVE_FFMPEG_IDCT_ALGO_10_SIMPLEARM 10
-#define GAP_GVE_FFMPEG_IDCT_ALGO_11_H264 11
-#define GAP_GVE_FFMPEG_IDCT_ALGO_MAX_ELEMENTS 12
+#define GAP_GVE_FFMPEG_IDCT_ALGO_00_AUTO FF_IDCT_AUTO
+#define GAP_GVE_FFMPEG_IDCT_ALGO_01_INT FF_IDCT_INT
+#define GAP_GVE_FFMPEG_IDCT_ALGO_02_SIMPLE FF_IDCT_SIMPLE
+#define GAP_GVE_FFMPEG_IDCT_ALGO_03_SIMPLEMMX FF_IDCT_SIMPLEMMX
+#define GAP_GVE_FFMPEG_IDCT_ALGO_04_LIBMPEG2MMX FF_IDCT_LIBMPEG2MMX
+#define GAP_GVE_FFMPEG_IDCT_ALGO_05_PS2 FF_IDCT_PS2
+#define GAP_GVE_FFMPEG_IDCT_ALGO_06_MLIB FF_IDCT_MLIB
+#define GAP_GVE_FFMPEG_IDCT_ALGO_07_ARM FF_IDCT_ARM
+#define GAP_GVE_FFMPEG_IDCT_ALGO_08_ALTIVEC FF_IDCT_ALTIVEC
+#define GAP_GVE_FFMPEG_IDCT_ALGO_09_SH4 FF_IDCT_SH4
+#define GAP_GVE_FFMPEG_IDCT_ALGO_10_SIMPLEARM FF_IDCT_SIMPLEARM
+#define GAP_GVE_FFMPEG_IDCT_ALGO_11_H264 FF_IDCT_H264
+#define GAP_GVE_FFMPEG_IDCT_ALGO_12_VP3 FF_IDCT_VP3
+#define GAP_GVE_FFMPEG_IDCT_ALGO_13_IPP FF_IDCT_IPP
+#define GAP_GVE_FFMPEG_IDCT_ALGO_14_XVIDMMX FF_IDCT_XVIDMMX
+#define GAP_GVE_FFMPEG_IDCT_ALGO_15_CAVS FF_IDCT_CAVS
+#define GAP_GVE_FFMPEG_IDCT_ALGO_16_SIMPLEARMV5TE FF_IDCT_SIMPLEARMV5TE
+#define GAP_GVE_FFMPEG_IDCT_ALGO_17_SIMPLEARMV6 FF_IDCT_SIMPLEARMV6
+#define GAP_GVE_FFMPEG_IDCT_ALGO_18_SIMPLEVIS FF_IDCT_SIMPLEVIS
+#define GAP_GVE_FFMPEG_IDCT_ALGO_19_WMV2 FF_IDCT_WMV2
+#define GAP_GVE_FFMPEG_IDCT_ALGO_20_FAAN FF_IDCT_FAAN
+#define GAP_GVE_FFMPEG_IDCT_ALGO_21_EA FF_IDCT_EA
+#define GAP_GVE_FFMPEG_IDCT_ALGO_22_SIMPLENEON FF_IDCT_SIMPLENEON
+#define GAP_GVE_FFMPEG_IDCT_ALGO_23_SIMPLEALPHA FF_IDCT_SIMPLEALPHA
+#define GAP_GVE_FFMPEG_IDCT_ALGO_MAX_ELEMENTS 24
+
+
#define GAP_GVE_FFMPEG_MB_DECISION_00_SIMPLE 0
#define GAP_GVE_FFMPEG_MB_DECISION_01_BITS 1
@@ -132,7 +141,6 @@
#define GAP_GVE_FFMPEG_ASPECT_MAX_ELEMENTS 4
-#ifdef HAVE_FULL_FFMPEG
#define GAP_GVE_FFMPEG_CMP_00_SAD FF_CMP_SAD
#define GAP_GVE_FFMPEG_CMP_01_SSE FF_CMP_SSE
#define GAP_GVE_FFMPEG_CMP_02_SATD FF_CMP_SATD
@@ -149,54 +157,19 @@
#define GAP_GVE_FFMPEG_CMP_13_DCTMAX FF_CMP_DCTMAX
#define GAP_GVE_FFMPEG_CMP_14_CHROMA FF_CMP_CHROMA
#define GAP_GVE_FFMPEG_CMP_MAX_ELEMENTS 15
-#else
-#define GAP_GVE_FFMPEG_CMP_00_SAD 0
-#define GAP_GVE_FFMPEG_CMP_01_SSE 1
-#define GAP_GVE_FFMPEG_CMP_02_SATD 2
-#define GAP_GVE_FFMPEG_CMP_03_DCT 3
-#define GAP_GVE_FFMPEG_CMP_04_PSNR 4
-#define GAP_GVE_FFMPEG_CMP_05_BIT 5
-#define GAP_GVE_FFMPEG_CMP_06_RD 6
-#define GAP_GVE_FFMPEG_CMP_07_ZERO 7
-#define GAP_GVE_FFMPEG_CMP_08_VSAD 8
-#define GAP_GVE_FFMPEG_CMP_09_VSSE 9
-#define GAP_GVE_FFMPEG_CMP_10_NSSE 10
-#define GAP_GVE_FFMPEG_CMP_11_W53 11
-#define GAP_GVE_FFMPEG_CMP_12_W97 12
-#define GAP_GVE_FFMPEG_CMP_13_DCTMAX 13
-#define GAP_GVE_FFMPEG_CMP_14_CHROMA 256
-#define GAP_GVE_FFMPEG_CMP_MAX_ELEMENTS 15
-#endif
-#ifdef HAVE_FULL_FFMPEG
#define GAP_GVE_FFMPEG_CODER_TYPE_00_VLC FF_CODER_TYPE_VLC
#define GAP_GVE_FFMPEG_CODER_TYPE_01_AC FF_CODER_TYPE_AC
#define GAP_GVE_FFMPEG_CODER_TYPE_MAX_ELEMENTS 2
-#else
-#define GAP_GVE_FFMPEG_CODER_TYPE_00_VLC 0
-#define GAP_GVE_FFMPEG_CODER_TYPE_01_AC 1
-#define GAP_GVE_FFMPEG_CODER_TYPE_MAX_ELEMENTS 2
-#endif
-#ifdef HAVE_FULL_FFMPEG
#define GAP_GVE_FFMPEG_PREDICTOR_00_LEFT FF_PRED_LEFT
#define GAP_GVE_FFMPEG_PREDICTOR_01_PLANE FF_PRED_PLANE
#define GAP_GVE_FFMPEG_PREDICTOR_02_MEDIAN FF_PRED_MEDIAN
#define GAP_GVE_FFMPEG_PREDICTOR_MAX_ELEMENTS 3
-#else
-#define GAP_GVE_FFMPEG_PREDICTOR_00_LEFT 0
-#define GAP_GVE_FFMPEG_PREDICTOR_01_PLANE 1
-#define GAP_GVE_FFMPEG_PREDICTOR_02_MEDIAN 2
-#define GAP_GVE_FFMPEG_PREDICTOR_MAX_ELEMENTS 3
-#endif
-#ifdef HAVE_FULL_FFMPEG
#define GAP_GVE_FF_QP2LAMBDA FF_QP2LAMBDA
-#else
-#define GAP_GVE_FF_QP2LAMBDA 118
-#endif
@@ -333,7 +306,7 @@
gint32 ntsc_height;
gint32 pal_width;
gint32 pal_height;
-
+
} GapGveFFMpegValues;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]