summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkonablend <[email protected]>2009-04-21 02:36:46 +0000
committerkonablend <[email protected]>2009-04-21 02:36:46 +0000
commitf86f171f05ed4732264befad4d5f8fead750553e (patch)
treedc894bb8596ecaab493a43df0e8230bc0080a615
parent3dfb0337b4a31bb6416320ca4e095074568b82f6 (diff)
bump libmp4v2 r224 ->r286; chunk duration; tags; cover-art
The major changes to libmp4v2 include the new Tags API for iTunes metadata management and new API to set track chunk duration limits. Additionally, the patches for libmp4v2 are no longer required and libmp4v2 should build significantly faster as it now enabled precompiled headers on various platforms. Tags API effects common.h, decmetdata.c and muxmp4.c and replaces the operations in a near 1:1 mapping for functionality except all access happens in between alloc/fetch and store/free pattern. libhb no longer checks the bits of cover-art in order to determine image type. That functionality is now delegated to libmp4v2; and libhb identify_art_type() has been removed accordingly. Chunk duration support has been added which makes use of new API from libmp4v2: MP4SetTrackDurationPerChunk( MP4File, MP4TrackId ); And muxmp4 adds new internal function MP4TuneTrackDurationPerChunk() which is invoked after all video/audio track creation which tunes chunk duration to the equivalent of 4-frames in track timescale; as per van's suggestion. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@2347 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r--contrib/libmp4v2/P00-mingw-static.patch16
-rw-r--r--contrib/libmp4v2/P01-mingw-msvcrt-lower.patch31
-rw-r--r--contrib/libmp4v2/P02-mingw-configure.patch26
-rw-r--r--contrib/libmp4v2/module.defs8
-rw-r--r--libhb/common.h1
-rw-r--r--libhb/decmetadata.c131
-rw-r--r--libhb/muxmp4.c93
7 files changed, 122 insertions, 184 deletions
diff --git a/contrib/libmp4v2/P00-mingw-static.patch b/contrib/libmp4v2/P00-mingw-static.patch
deleted file mode 100644
index 268ff7689..000000000
--- a/contrib/libmp4v2/P00-mingw-static.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-Index: mp4v2/include/mp4v2/platform.h
-===================================================================
---- mp4v2/include/mp4v2/platform.h (revision 272)
-+++ mp4v2/include/mp4v2/platform.h (working copy)
-@@ -24,8 +24,10 @@
- #if defined( _WIN32 ) || defined( __MINGW32__ )
- # if defined( _WINDLL ) || defined( DLL_EXPORT )
- # define MP4V2_EXPORT __declspec(dllexport)
-+# elif defined( _DLL ) || defined( DLL_IMPORT )
-+# define MP4V2_EXPORT __declspec(dllimport)
- # else
--# define MP4V2_EXPORT __declspec(dllimport)
-+# define MP4V2_EXPORT
- # endif
- #else
- # define MP4V2_EXPORT __attribute__((visibility("default")))
diff --git a/contrib/libmp4v2/P01-mingw-msvcrt-lower.patch b/contrib/libmp4v2/P01-mingw-msvcrt-lower.patch
deleted file mode 100644
index 384542b06..000000000
--- a/contrib/libmp4v2/P01-mingw-msvcrt-lower.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-diff -Naur libmp4v2.orig/libplatform/io/File_win32.cpp libmp4v2/libplatform/io/File_win32.cpp
---- libmp4v2.orig/libplatform/io/File_win32.cpp 2008-11-16 02:50:26.000000000 -0500
-+++ libmp4v2/libplatform/io/File_win32.cpp 2009-03-13 02:00:09.000000000 -0400
-@@ -8,7 +8,8 @@
- bool
- StdioFile::getPosition( Size& pos_ )
- {
-- pos_ = _ftelli64( _handle );
-+ fflush( _handle ); // must flush because we're using _fileno routines
-+ pos_ = _telli64( _fileno( _handle ));
- return pos_ == -1;
- }
-
-@@ -17,6 +18,7 @@
- bool
- StdioFile::getSize( Size& size_ )
- {
-+ fflush( _handle ); // must flush because we're using _fileno routines
- LARGE_INTEGER n;
- if( !GetFileSizeEx( (HANDLE)_get_osfhandle( _fileno( _handle )), &n ))
- return true;
-@@ -29,7 +31,8 @@
- bool
- StdioFile::setPosition( Size pos_ )
- {
-- return _fseeki64( _handle, pos_, SEEK_SET ) != 0;
-+ fflush( _handle ); // must flush because we're using _fileno routines
-+ return _lseeki64( _fileno( _handle ), pos_, SEEK_SET ) == -1;
- }
-
- ///////////////////////////////////////////////////////////////////////////////
diff --git a/contrib/libmp4v2/P02-mingw-configure.patch b/contrib/libmp4v2/P02-mingw-configure.patch
deleted file mode 100644
index ba749201d..000000000
--- a/contrib/libmp4v2/P02-mingw-configure.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-diff -Naur libmp4v2.orig/configure.ac libmp4v2/configure.ac
---- libmp4v2.orig/configure.ac 2009-01-10 12:44:40.000000000 -0500
-+++ libmp4v2/configure.ac 2009-03-13 18:18:38.000000000 -0400
-@@ -103,11 +103,11 @@
- X_CXX_ARCH="$X_CXX_ARCH -mwin32"
- fi
- ;;
--*-*-mingw32)
-+*-*-mingw*)
- # do not support shared
- enable_shared=no
- X_PLATFORM=win32
-- X_MINGW_LIBS="$X_MINGW_LIBS -lmsvcr80"
-+ X_MINGW_LIBS="$X_MINGW_LIBS"
- X_CXX_W="$X_CXX_W -Wno-format"
- if test "$enable_mingw_threads" = "yes"; then
- X_CXX_ARCH="$X_CXX_ARCH -mthreads"
-@@ -197,7 +197,7 @@
- case ${host} in
- *-*-cygwin)
- ;;
-- *-*-mingw32)
-+ *-*-mingw*)
- ;;
- *)
- AC_LANG(C++)
diff --git a/contrib/libmp4v2/module.defs b/contrib/libmp4v2/module.defs
index ede60253e..434d93f75 100644
--- a/contrib/libmp4v2/module.defs
+++ b/contrib/libmp4v2/module.defs
@@ -1,7 +1,7 @@
$(eval $(call import.MODULE.defs,LIBMP4V2,libmp4v2))
$(eval $(call import.CONTRIB.defs,LIBMP4V2))
-LIBMP4V2.FETCH.url = http://download.m0k.org/handbrake/contrib/libmp4v2-2.0-r224-repack.tar.gz
+LIBMP4V2.FETCH.url = http://download.m0k.org/handbrake/contrib/libmp4v2-2.0-r286.tar.gz
LIBMP4V2.EXTRACT.tarbase = libmp4v2
## propagate more flags
@@ -10,8 +10,4 @@ LIBMP4V2.CONFIGURE.env.CXXFLAGS = CXXFLAGS="$(call fn.ARGS,LIBMP4V2.GCC,*archs *
## save some build-time by disabling utils
LIBMP4V2.CONFIGURE.extra += --disable-util
-
-ifeq ($(BUILD.system),mingw)
- ## mingw platform patches configure.ac and requires bootstrap
- LIBMP4V2.CONFIGURE.bootstrap = autoreconf -fiv;
-endif
+LIBMP4V2.CONFIGURE.extra += --enable-gch
diff --git a/libhb/common.h b/libhb/common.h
index b7c468672..5a6320a43 100644
--- a/libhb/common.h
+++ b/libhb/common.h
@@ -465,7 +465,6 @@ struct hb_metadata_s
char comment[1024];
char album[255];
char genre[255];
- enum arttype {UNKNOWN, BMP, GIF87A, GIF89A, JPG, PNG, TIFFL, TIFFB} coverart_type;
uint32_t coverart_size;
uint8_t *coverart;
};
diff --git a/libhb/decmetadata.c b/libhb/decmetadata.c
index 85c3cd28b..754eb7a25 100644
--- a/libhb/decmetadata.c
+++ b/libhb/decmetadata.c
@@ -8,117 +8,60 @@
#include "common.h"
-void identify_art_type( hb_metadata_t *metadata )
-{
- typedef struct header_s {
- enum arttype type;
- char* name; // short string describing name of type
- char* data; // header-bytes to match
- } header;
-
- // types which may be detected by first-bytes only
- static header headers[] = {
- { BMP, "bmp", "\x4d\x42" },
- { GIF87A, "GIF (87a)", "GIF87a" },
- { GIF89A, "GIF (89a)", "GIF89a" },
- { JPG, "JPEG", "\xff\xd8\xff\xe0" },
- { PNG, "PNG", "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a" },
- { TIFFL, "TIFF (little-endian)", "II42" },
- { TIFFB, "TIFF (big-endian)", "MM42" },
- { UNKNOWN } // must be last
- };
- header* p;
- header* found = NULL;
- for( p = headers; p->type != UNKNOWN; p++ ) {
- header *h = p;
-
- if( metadata->coverart_size < strlen(h->data) )
- continue;
-
- if( memcmp(h->data, metadata->coverart, strlen(h->data)) == 0 ) {
- metadata->coverart_type = h->type;
- break;
- }
- }
-}
-
static void decmp4metadata( hb_title_t *title )
{
MP4FileHandle input_file;
-
hb_deep_log( 2, "Got an MP4 input, read the metadata");
input_file = MP4Read( title->dvd, 0 );
if( input_file != MP4_INVALID_FILE_HANDLE )
{
- char *value = NULL;
- uint8_t *cover_art = NULL;
- uint32_t size;
- uint32_t count;
-
/*
* Store iTunes MetaData
*/
- if( MP4GetMetadataName( input_file, &value) && value )
- {
- hb_deep_log( 2, "Metadata Name in input file is '%s'", value);
- strncpy( title->metadata->name, value, 255);
- MP4Free(value);
- value = NULL;
- }
+ const MP4Tags* tags;
- if( MP4GetMetadataArtist( input_file, &value) && value )
- {
- strncpy( title->metadata->artist, value, 255);
- MP4Free(value);
- value = NULL;
- }
-
- if( MP4GetMetadataComposer( input_file, &value) && value )
- {
- strncpy( title->metadata->composer, value, 255);
- MP4Free(value);
- value = NULL;
- }
+ /* alloc,fetch tags */
+ tags = MP4TagsAlloc();
+ MP4TagsFetch( tags, input_file );
- if( MP4GetMetadataComment( input_file, &value) && value )
- {
- strncpy( title->metadata->comment, value, 1024);
- value = NULL;
- }
-
- if( MP4GetMetadataReleaseDate( input_file, &value) && value )
- {
- strncpy( title->metadata->release_date, value, 255);
- MP4Free(value);
- value = NULL;
+ if( tags->name ) {
+ hb_deep_log( 2, "Metadata Name in input file is '%s'", tags->name );
+ strncpy( title->metadata->name, tags->name, 255 );
}
-
- if( MP4GetMetadataAlbum( input_file, &value) && value )
- {
- strncpy( title->metadata->album, value, 255);
- MP4Free(value);
- value = NULL;
- }
-
- if( MP4GetMetadataGenre( input_file, &value) && value )
- {
- strncpy( title->metadata->genre, value, 255);
- MP4Free(value);
- value = NULL;
- }
-
- if( MP4GetMetadataCoverArt( input_file, &cover_art, &size, 0) &&
- cover_art )
- {
- title->metadata->coverart = cover_art;
- title->metadata->coverart_size = size;
- identify_art_type( title->metadata );
+
+ if( tags->artist )
+ strncpy( title->metadata->artist, tags->artist, 255 );
+
+ if( tags->composer )
+ strncpy( title->metadata->composer, tags->composer, 255 );
+
+ if( tags->comments )
+ strncpy( title->metadata->comment, tags->comments, 1024 );
+
+ if( tags->releaseDate )
+ strncpy( title->metadata->release_date, tags->releaseDate, 255 );
+
+ if( tags->album )
+ strncpy( title->metadata->album, tags->album, 255 );
+
+ if( tags->genre )
+ strncpy( title->metadata->genre, tags->genre, 255 );
+
+ if( tags->artworkCount > 0 ) {
+ const MP4TagArtwork* art = tags->artwork + 0; // first element
+ title->metadata->coverart = (uint8_t*)malloc( art->size );
+ title->metadata->coverart_size = art->size;
+ memcpy( title->metadata->coverart, art->data, art->size );
hb_deep_log( 2, "Got some cover art of type %d, size %d",
- title->metadata->coverart_type,
- title->metadata->coverart_size);
+ art->type,
+ title->metadata->coverart_size );
}
+
+ /* store,free tags */
+ MP4TagsStore( tags, input_file );
+ MP4TagsFree( tags );
/*
* Handle the chapters.
diff --git a/libhb/muxmp4.c b/libhb/muxmp4.c
index 3f9b2314f..9698fafcb 100644
--- a/libhb/muxmp4.c
+++ b/libhb/muxmp4.c
@@ -41,6 +41,31 @@ struct hb_mux_data_s
MP4TrackId track;
};
+/* Tune video track chunk duration.
+ * libmp4v2 default duration == dusamplerate == 1 second.
+ * Per van's suggestion we desire duration == 4 frames.
+ * Should be invoked immediately after track creation.
+ *
+ * return true on fail, false on success.
+ */
+static int MP4TuneTrackDurationPerChunk( hb_mux_object_t* m, MP4TrackId trackId )
+{
+ uint32_t tscale;
+ MP4Duration dur;
+
+ tscale = MP4GetTrackTimeScale( m->file, trackId );
+ dur = (MP4Duration)ceil( (double)tscale * (double)m->job->vrate_base / (double)m->job->vrate * 4.0 );
+
+ if( !MP4SetTrackDurationPerChunk( m->file, trackId, dur ))
+ {
+ hb_error( "muxmp4.c: MP4SetTrackDurationPerChunk failed!" );
+ *m->job->die = 1;
+ return 0;
+ }
+
+ hb_deep_log( 2, "muxmp4: track %u, chunk duration %llu", MP4FindTrackIndex( m->file, trackId ), dur );
+ return 1;
+}
/**********************************************************************
* MP4Init
@@ -115,7 +140,18 @@ static int MP4Init( hb_mux_object_t * m )
job->config.h264.sps[2], /* profile_compat */
job->config.h264.sps[3], /* AVCLevelIndication */
3 ); /* 4 bytes length before each NAL unit */
+ if ( mux_data->track == MP4_INVALID_TRACK_ID )
+ {
+ hb_error( "muxmp4.c: MP4AddH264VideoTrack failed!" );
+ *job->die = 1;
+ return 0;
+ }
+ /* Tune track chunk duration */
+ if( !MP4TuneTrackDurationPerChunk( m, mux_data->track ))
+ {
+ return 0;
+ }
MP4AddH264SequenceParameterSet( m->file, mux_data->track,
job->config.h264.sps, job->config.h264.sps_length );
@@ -143,6 +179,11 @@ static int MP4Init( hb_mux_object_t * m )
return 0;
}
+ /* Tune track chunk duration */
+ if( !MP4TuneTrackDurationPerChunk( m, mux_data->track ))
+ {
+ return 0;
+ }
/* VOL from FFmpeg or XviD */
if (!(MP4SetTrackESConfiguration( m->file, mux_data->track,
@@ -310,6 +351,9 @@ static int MP4Init( hb_mux_object_t * m )
lfeon,
bit_rate_code);
+ /* Tune track chunk duration */
+ MP4TuneTrackDurationPerChunk( m, mux_data->track );
+
if (audio->config.out.name == NULL) {
MP4SetTrackBytesProperty(
m->file, mux_data->track,
@@ -327,6 +371,10 @@ static int MP4Init( hb_mux_object_t * m )
mux_data->track = MP4AddAudioTrack(
m->file,
audio->config.out.samplerate, 1024, MP4_MPEG4_AUDIO_TYPE );
+
+ /* Tune track chunk duration */
+ MP4TuneTrackDurationPerChunk( m, mux_data->track );
+
if (audio->config.out.name == NULL) {
MP4SetTrackBytesProperty(
m->file, mux_data->track,
@@ -368,7 +416,7 @@ static int MP4Init( hb_mux_object_t * m )
them all at once. */
{
MP4SetTrackIntegerProperty(m->file, mux_data->track, "tkhd.flags", (TRACK_DISABLED | TRACK_IN_MOVIE));
- hb_deep_log( 2, "muxp4: disabled extra audio track %i", mux_data->track-1);
+ hb_deep_log( 2, "muxmp4: disabled extra audio track %u", MP4FindTrackIndex( m->file, mux_data->track ));
}
}
@@ -391,7 +439,15 @@ static int MP4Init( hb_mux_object_t * m )
char *tool_string;
tool_string = (char *)malloc(80);
snprintf( tool_string, 80, "HandBrake %s %i", HB_PROJECT_VERSION, HB_PROJECT_BUILD);
- MP4SetMetadataTool(m->file, tool_string);
+
+ /* allocate,fetch,populate,store,free tags structure */
+ const MP4Tags* tags;
+ tags = MP4TagsAlloc();
+ MP4TagsFetch( tags, m->file );
+ MP4TagsSetEncodingTool( tags, tool_string );
+ MP4TagsStore( tags, m->file );
+ MP4TagsFree( tags );
+
free(tool_string);
return 0;
@@ -549,20 +605,37 @@ static int MP4End( hb_mux_object_t * m )
if( title->metadata )
{
hb_metadata_t *md = title->metadata;
+ const MP4Tags* tags;
hb_deep_log( 2, "Writing Metadata to output file...");
- MP4SetMetadataName( m->file, md->name );
- MP4SetMetadataArtist( m->file, md->artist );
- MP4SetMetadataComposer( m->file, md->composer );
- MP4SetMetadataComment( m->file, md->comment );
- MP4SetMetadataReleaseDate( m->file, md->release_date );
- MP4SetMetadataAlbum( m->file, md->album );
- MP4SetMetadataGenre( m->file, md->genre );
+ /* allocate tags structure */
+ tags = MP4TagsAlloc();
+ /* fetch data from MP4 file (in case it already has some data) */
+ MP4TagsFetch( tags, m->file );
+
+ /* populate */
+ MP4TagsSetName( tags, md->name );
+ MP4TagsSetArtist( tags, md->artist );
+ MP4TagsSetComposer( tags, md->composer );
+ MP4TagsSetComments( tags, md->comment );
+ MP4TagsSetReleaseDate( tags, md->release_date );
+ MP4TagsSetAlbum( tags, md->album );
+ MP4TagsSetGenre( tags, md->genre );
+
if( md->coverart )
{
- MP4SetMetadataCoverArt( m->file, md->coverart, md->coverart_size);
+ MP4TagArtwork art;
+ art.data = md->coverart;
+ art.size = md->coverart_size;
+ art.type = MP4_ART_UNDEFINED; // delegate typing to libmp4v2
+ MP4TagsAddArtwork( tags, &art );
}
+
+ /* push data to MP4 file */
+ MP4TagsStore( tags, m->file );
+ /* free memory associated with structure */
+ MP4TagsFree( tags );
}
MP4Close( m->file );