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
1262 1262
1263static int mov_write_gmhd_tag(AVIOContext *pb)1263static int mov_write_gmhd_tag(AVIOContext *pb)
1264{1264{
1265 avio_wb32(pb, 0x20); /* size */1265 avio_wb32(pb, 0x4C); /* size */
1266 ffio_wfourcc(pb, "gmhd");1266 ffio_wfourcc(pb, "gmhd");
1267 avio_wb32(pb, 0x18); /* gmin size */1267 avio_wb32(pb, 0x18); /* gmin size */
1268 ffio_wfourcc(pb, "gmin");/* generic media info */1268 ffio_wfourcc(pb, "gmin");/* generic media info */
@@ -1273,7 +1273,27 @@ static int mov_write_gmhd_tag(AVIOContext *pb) · 4 unmodified lines
1273 avio_wb16(pb, 0x8000); /* opColor (b?) */1273 avio_wb16(pb, 0x8000); /* opColor (b?) */
1274 avio_wb16(pb, 0); /* balance */1274 avio_wb16(pb, 0); /* balance */
1275 avio_wb16(pb, 0); /* reserved */1275 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;
1277}1297}
1278 1298
1279static int mov_write_smhd_tag(AVIOContext *pb)1299static int mov_write_smhd_tag(AVIOContext *pb)
@@ -3052,6 +3072,8 @@ static int mov_write_packet(AVFormatContext *s, AVPacket *pkt) · 1772 unmodified lines
3052// as samples, and a tref pointing from the other tracks to the chapter one.3072// as samples, and a tref pointing from the other tracks to the chapter one.
3053static void mov_create_chapter_track(AVFormatContext *s, int tracknum)3073static void mov_create_chapter_track(AVFormatContext *s, int tracknum)
3054{3074{
3075 AVIOContext *pb;
3076
3055 MOVMuxContext *mov = s->priv_data;3077 MOVMuxContext *mov = s->priv_data;
3056 MOVTrack *track = &mov->tracks[tracknum];3078 MOVTrack *track = &mov->tracks[tracknum];
3057 AVPacket pkt = { .stream_index = tracknum, .flags = AV_PKT_FLAG_KEY };3079 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
3063 track->enc = avcodec_alloc_context3(NULL);3085 track->enc = avcodec_alloc_context3(NULL);
3064 track->enc->codec_type = AVMEDIA_TYPE_SUBTITLE;3086 track->enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
3065 3087
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
3066 for (i = 0; i < s->nb_chapters; i++) {3132 for (i = 0; i < s->nb_chapters; i++) {
3067 AVChapter *c = s->chapters[i];3133 AVChapter *c = s->chapters[i];
3068 AVDictionaryEntry *t;3134 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