1 /* decmetadata.c - Extract and decode metadata from the source
3 This file is part of the HandBrake source code.
4 Homepage: <http://handbrake.fr/>.
5 It may be used under the terms of the GNU General Public License. */
7 #include <mp4v2/mp4v2.h>
11 void identify_art_type( hb_metadata_t *metadata )
13 typedef struct header_s {
15 char* name; // short string describing name of type
16 char* data; // header-bytes to match
19 // types which may be detected by first-bytes only
20 static header headers[] = {
21 { BMP, "bmp", "\x4d\x42" },
22 { GIF87A, "GIF (87a)", "GIF87a" },
23 { GIF89A, "GIF (89a)", "GIF89a" },
24 { JPG, "JPEG", "\xff\xd8\xff\xe0" },
25 { PNG, "PNG", "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a" },
26 { TIFFL, "TIFF (little-endian)", "II42" },
27 { TIFFB, "TIFF (big-endian)", "MM42" },
28 { UNKNOWN } // must be last
32 for( p = headers; p->type != UNKNOWN; p++ ) {
35 if( metadata->coverart_size < strlen(h->data) )
38 if( memcmp(h->data, metadata->coverart, strlen(h->data)) == 0 ) {
39 metadata->coverart_type = h->type;
45 static void decmp4metadata( hb_title_t *title )
47 MP4FileHandle input_file;
49 hb_deep_log( 2, "Got an MP4 input, read the metadata");
51 input_file = MP4Read( title->dvd, 0 );
53 if( input_file != MP4_INVALID_FILE_HANDLE )
56 uint8_t *cover_art = NULL;
61 * Store iTunes MetaData
63 if( MP4GetMetadataName( input_file, &value) && value )
65 hb_deep_log( 2, "Metadata Name in input file is '%s'", value);
66 strncpy( title->metadata->name, value, 255);
71 if( MP4GetMetadataArtist( input_file, &value) && value )
73 strncpy( title->metadata->artist, value, 255);
78 if( MP4GetMetadataComposer( input_file, &value) && value )
80 strncpy( title->metadata->composer, value, 255);
85 if( MP4GetMetadataComment( input_file, &value) && value )
87 strncpy( title->metadata->comment, value, 1024);
91 if( MP4GetMetadataReleaseDate( input_file, &value) && value )
93 strncpy( title->metadata->release_date, value, 255);
98 if( MP4GetMetadataAlbum( input_file, &value) && value )
100 strncpy( title->metadata->album, value, 255);
105 if( MP4GetMetadataGenre( input_file, &value) && value )
107 strncpy( title->metadata->genre, value, 255);
112 if( MP4GetMetadataCoverArt( input_file, &cover_art, &size, 0) &&
115 title->metadata->coverart = cover_art;
116 title->metadata->coverart_size = size;
117 identify_art_type( title->metadata );
118 hb_deep_log( 2, "Got some cover art of type %d, size %d",
119 title->metadata->coverart_type,
120 title->metadata->coverart_size);
124 * Handle the chapters.
126 MP4Chapter_t *chapter_list = NULL;
127 uint32_t chapter_count;
129 MP4GetChapters( input_file, &chapter_list, &chapter_count,
134 while( i <= chapter_count )
136 hb_chapter_t * chapter;
137 chapter = calloc( sizeof( hb_chapter_t ), 1 );
139 chapter->duration = chapter_list[i-1].duration * 90;
140 chapter->hours = chapter->duration / 90000 / 3600;
141 chapter->minutes = ( ( chapter->duration / 90000 ) % 3600 ) / 60;
142 chapter->seconds = ( chapter->duration / 90000 ) % 60;
143 strcpy( chapter->title, chapter_list[i-1].title );
144 hb_deep_log( 2, "Added chapter %i, name='%s', dur=%lld, (%02i:%02i:%02i)", chapter->index, chapter->title,
145 chapter->duration, chapter->hours,
146 chapter->minutes, chapter->seconds);
147 hb_list_add( title->list_chapter, chapter );
152 MP4Close( input_file );
159 * Look at the title and extract whatever metadata we can from that title.
161 void decmetadata( hb_title_t *title )
168 if( title->metadata )
170 free( title->metadata );
171 title->metadata = NULL;
174 title->metadata = calloc( sizeof(hb_metadata_t), 1);
176 if( !title->metadata )
182 * Hacky way of figuring out if this is an MP4, in which case read the data using libmp4v2
184 if( title->container_name && strcmp(title->container_name, "mov,mp4,m4a,3gp,3g2,mj2") == 0 )
186 decmp4metadata( title );
188 free( title->metadata );
189 title->metadata = NULL;