History

movenc: Fix muxing of Apple Quicktime chapters. v3

There is basic support for muxing chapter information into the Apple Quicktime format already, but there are two errors which prevent correct detection on the player side. 1) A special apple 'text' atom needs to be included inside the gmhd atom. 2) The *different* 'text' atom inside the 'stsd' atom needs a proper header. With these changes, the chapters are now picked up by Apple players and reported correctly by tools like mediainfo and mp4chaps. v3 Update: The stub TextSampleEntry creation is moved to where the chapter track is created so it's now specific to this track.

Philip Langdale committed 14 years ago

Commit ea60a111 parent c2eae4b1 file · +68 −2Browse files

Unified · Split

libavformat/movenc.c+68−2
@@ -1262,7 +1262,7 @@ static int mov_write_nmhd_tag(AVIOContext *pb) · 1261 unmodified lines
12621262
12631263 static int mov_write_gmhd_tag(AVIOContext *pb)
12641264 {
1265− avio_wb32(pb, 0x20); /* size */
1265+ avio_wb32(pb, 0x4C); /* size */
12661266 ffio_wfourcc(pb, "gmhd");
12671267 avio_wb32(pb, 0x18); /* gmin size */
12681268 ffio_wfourcc(pb, "gmin");/* generic media info */
@@ -1273,7 +1273,27 @@ static int mov_write_gmhd_tag(AVIOContext *pb) · 4 unmodified lines
12731273 avio_wb16(pb, 0x8000); /* opColor (b?) */
12741274 avio_wb16(pb, 0); /* balance */
12751275 avio_wb16(pb, 0); /* reserved */
1276− return 0x20;
1276+
1277+ /*
1278+ * This special text atom is required for
1279+ * Apple Quicktime chapters. The contents
1280+ * don't appear to be documented, so the
1281+ * bytes are copied verbatim.
1282+ */
1283+ avio_wb32(pb, 0x2C); /* size */
1284+ ffio_wfourcc(pb, "text");
1285+ avio_wb16(pb, 0x01);
1286+ avio_wb32(pb, 0x00);
1287+ avio_wb32(pb, 0x00);
1288+ avio_wb32(pb, 0x00);
1289+ avio_wb32(pb, 0x01);
1290+ avio_wb32(pb, 0x00);
1291+ avio_wb32(pb, 0x00);
1292+ avio_wb32(pb, 0x00);
1293+ avio_wb32(pb, 0x00004000);
1294+ avio_wb16(pb, 0x0000);
1295+
1296+ return 0x4C;
12771297 }
12781298
12791299 static int mov_write_smhd_tag(AVIOContext *pb)
@@ -3052,6 +3072,8 @@ static int mov_write_packet(AVFormatContext *s, AVPacket *pkt) · 1772 unmodified lines
30523072 // as samples, and a tref pointing from the other tracks to the chapter one.
30533073 static void mov_create_chapter_track(AVFormatContext *s, int tracknum)
30543074 {
3075+ AVIOContext *pb;
3076+
30553077 MOVMuxContext *mov = s->priv_data;
30563078 MOVTrack *track = &mov->tracks[tracknum];
30573079 AVPacket pkt = { .stream_index = tracknum, .flags = AV_PKT_FLAG_KEY };
@@ -3063,6 +3085,50 @@ static void mov_create_chapter_track(AVFormatContext *s, int tracknum) · 5 unmodified lines
30633085 track->enc = avcodec_alloc_context3(NULL);
30643086 track->enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
30653087
3088+ if (avio_open_dyn_buf(&pb) >= 0) {
3089+ int size;
3090+ uint8_t *buf;
3091+
3092+ /* Stub header (usually for Quicktime chapter track) */
3093+ // TextSampleEntry
3094+ avio_wb32(pb, 0x01); // displayFlags
3095+ avio_w8(pb, 0x00); // horizontal justification
3096+ avio_w8(pb, 0x00); // vertical justification
3097+ avio_w8(pb, 0x00); // bgColourRed
3098+ avio_w8(pb, 0x00); // bgColourGreen
3099+ avio_w8(pb, 0x00); // bgColourBlue
3100+ avio_w8(pb, 0x00); // bgColourAlpha
3101+ // BoxRecord
3102+ avio_wb16(pb, 0x00); // defTextBoxTop
3103+ avio_wb16(pb, 0x00); // defTextBoxLeft
3104+ avio_wb16(pb, 0x00); // defTextBoxBottom
3105+ avio_wb16(pb, 0x00); // defTextBoxRight
3106+ // StyleRecord
3107+ avio_wb16(pb, 0x00); // startChar
3108+ avio_wb16(pb, 0x00); // endChar
3109+ avio_wb16(pb, 0x01); // fontID
3110+ avio_w8(pb, 0x00); // fontStyleFlags
3111+ avio_w8(pb, 0x00); // fontSize
3112+ avio_w8(pb, 0x00); // fgColourRed
3113+ avio_w8(pb, 0x00); // fgColourGreen
3114+ avio_w8(pb, 0x00); // fgColourBlue
3115+ avio_w8(pb, 0x00); // fgColourAlpha
3116+ // FontTableBox
3117+ avio_wb32(pb, 0x0D); // box size
3118+ ffio_wfourcc(pb, "ftab"); // box atom name
3119+ avio_wb16(pb, 0x01); // entry count
3120+ // FontRecord
3121+ avio_wb16(pb, 0x01); // font ID
3122+ avio_w8(pb, 0x00); // font name length
3123+
3124+ if ((size = avio_close_dyn_buf(pb, &buf)) > 0) {
3125+ track->enc->extradata = buf;
3126+ track->enc->extradata_size = size;
3127+ } else {
3128+ av_free(&buf);
3129+ }
3130+ }
3131+
30663132 for (i = 0; i < s->nb_chapters; i++) {
30673133 AVChapter *c = s->chapters[i];
30683134 AVDictionaryEntry *t;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t