diff options
author | jstebbins <[email protected]> | 2014-08-06 17:34:08 +0000 |
---|---|---|
committer | jstebbins <[email protected]> | 2014-08-06 17:34:08 +0000 |
commit | 58d1681bcb286d99790887877e6dfa20f191dcf3 (patch) | |
tree | 77a0f4da10b2fcdb5b154ea819891218d47c85e3 | |
parent | fe74dd49d88433cf619aadbf0834bafc670356fd (diff) |
libhb: fix mp4 audio track titles
mp4 audio track titles were not being applied by libavformat
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@6270 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r-- | contrib/ffmpeg/A03-mp4-track-title.patch | 133 | ||||
-rw-r--r-- | libhb/muxavformat.c | 7 |
2 files changed, 140 insertions, 0 deletions
diff --git a/contrib/ffmpeg/A03-mp4-track-title.patch b/contrib/ffmpeg/A03-mp4-track-title.patch new file mode 100644 index 000000000..25ad12cb6 --- /dev/null +++ b/contrib/ffmpeg/A03-mp4-track-title.patch @@ -0,0 +1,133 @@ +diff --git a/libavformat/movenc.c b/libavformat/movenc.c +index 0c688f6..f89b630 100644 +--- a/libavformat/movenc.c ++++ b/libavformat/movenc.c +@@ -76,6 +76,17 @@ static const AVClass flavor ## _muxer_class = {\ + .version = LIBAVUTIL_VERSION_INT,\ + }; + ++static int utf8len(const uint8_t *b) ++{ ++ int len = 0; ++ int val; ++ while (*b) { ++ GET_UTF8(val, *b++, return -1;) ++ len++; ++ } ++ return len; ++} ++ + //FIXME support 64 bit variant with wide placeholders + static int64_t update_size(AVIOContext *pb, int64_t pos) + { +@@ -1325,6 +1336,15 @@ static int mov_write_hdlr_tag(AVIOContext *pb, MOVTrack *track) + "Unknown hldr_type for %s / 0x%04X, writing dummy values\n", + tag_buf, track->enc->codec_tag); + } ++ if (track->st) { ++ // hdlr.name is used by some players to identify the content title ++ // of the track. So if an alternate handler description is ++ // specified, use it. ++ AVDictionaryEntry *t; ++ t = av_dict_get(track->st->metadata, "handler", NULL, 0); ++ if (t && utf8len(t->value)) ++ descr = t->value; ++ } + } + + avio_wb32(pb, 0); /* size */ +@@ -1623,6 +1643,47 @@ static int mov_write_udta_sdp(AVIOContext *pb, MOVTrack *track) + return len + 24; + } + ++static int mov_write_track_metadata(AVIOContext *pb, AVStream *st, ++ const char *tag, const char *str) ++{ ++ int64_t pos = avio_tell(pb); ++ AVDictionaryEntry *t = av_dict_get(st->metadata, str, NULL, 0); ++ if (!t || !utf8len(t->value)) ++ return 0; ++ ++ avio_wb32(pb, 0); /* size */ ++ ffio_wfourcc(pb, tag); /* type */ ++ avio_write(pb, t->value, strlen(t->value)); /* UTF8 string value */ ++ return update_size(pb, pos); ++} ++ ++static int mov_write_track_udta_tag(AVIOContext *pb, MOVMuxContext *mov, ++ AVStream *st) ++{ ++ AVIOContext *pb_buf; ++ int ret, size; ++ uint8_t *buf; ++ ++ if (st == NULL) ++ return 0; ++ ++ ret = avio_open_dyn_buf(&pb_buf); ++ if (ret < 0) ++ return ret; ++ ++ if (mov->mode & MODE_MP4) ++ mov_write_track_metadata(pb_buf, st, "name", "title"); ++ ++ if ((size = avio_close_dyn_buf(pb_buf, &buf)) > 0) { ++ avio_wb32(pb, size + 8); ++ ffio_wfourcc(pb, "udta"); ++ avio_write(pb, buf, size); ++ } ++ av_free(buf); ++ ++ return 0; ++} ++ + static int mov_write_trak_tag(AVIOContext *pb, MOVMuxContext *mov, + MOVTrack *track, AVStream *st) + { +@@ -1647,6 +1708,7 @@ static int mov_write_trak_tag(AVIOContext *pb, MOVMuxContext *mov, + if (0.0 != sample_aspect_ratio && 1.0 != sample_aspect_ratio) + mov_write_tapt_tag(pb, track); + } ++ mov_write_track_udta_tag(pb, mov, st); + return update_size(pb, pos); + } + +@@ -1904,17 +1966,6 @@ static int mov_write_meta_tag(AVIOContext *pb, MOVMuxContext *mov, + return size; + } + +-static int utf8len(const uint8_t *b) +-{ +- int len = 0; +- int val; +- while (*b) { +- GET_UTF8(val, *b++, return -1;) +- len++; +- } +- return len; +-} +- + static int ascii_to_wc(AVIOContext *pb, const uint8_t *b) + { + int val; +@@ -3266,6 +3317,7 @@ static int mov_write_header(AVFormatContext *s) + MOVTrack *track= &mov->tracks[i]; + AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0); + ++ track->st = st; + track->enc = st->codec; + track->language = ff_mov_iso639_to_lang(lang?lang->value:"und", mov->mode!=MODE_MOV); + if (track->language < 0) +diff --git a/libavformat/movenc.h b/libavformat/movenc.h +index 226a28f..687299e 100644 +--- a/libavformat/movenc.h ++++ b/libavformat/movenc.h +@@ -133,6 +133,8 @@ typedef struct MOVTrack { + int packet_entry; + int slices; + } vc1_info; ++ ++ AVStream *st; + } MOVTrack; + + typedef struct MOVMuxContext { diff --git a/libhb/muxavformat.c b/libhb/muxavformat.c index a31aab321..d39cbdd8f 100644 --- a/libhb/muxavformat.c +++ b/libhb/muxavformat.c @@ -576,7 +576,14 @@ static int avformatInit( hb_mux_object_t * m ) { name = audio->config.out.name; } + // Set audio track title av_dict_set(&track->st->metadata, "title", name, 0); + if (job->mux == HB_MUX_AV_MP4) + { + // Some software (MPC, mediainfo) use hdlr description + // for track title + av_dict_set(&track->st->metadata, "handler", name, 0); + } } char * subidx_fmt = |