summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2014-08-06 17:34:08 +0000
committerjstebbins <[email protected]>2014-08-06 17:34:08 +0000
commit58d1681bcb286d99790887877e6dfa20f191dcf3 (patch)
tree77a0f4da10b2fcdb5b154ea819891218d47c85e3
parentfe74dd49d88433cf619aadbf0834bafc670356fd (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.patch133
-rw-r--r--libhb/muxavformat.c7
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 =