mirror of
https://gitee.com/openharmony/third_party_ffmpeg
synced 2024-11-28 13:40:55 +00:00
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. Signed-off-by: Philip Langdale <philipl@overt.org> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
c2eae4bae7
commit
ea60a11e8e
@ -1262,7 +1262,7 @@ static int mov_write_nmhd_tag(AVIOContext *pb)
|
|||||||
|
|
||||||
static int mov_write_gmhd_tag(AVIOContext *pb)
|
static int mov_write_gmhd_tag(AVIOContext *pb)
|
||||||
{
|
{
|
||||||
avio_wb32(pb, 0x20); /* size */
|
avio_wb32(pb, 0x4C); /* size */
|
||||||
ffio_wfourcc(pb, "gmhd");
|
ffio_wfourcc(pb, "gmhd");
|
||||||
avio_wb32(pb, 0x18); /* gmin size */
|
avio_wb32(pb, 0x18); /* gmin size */
|
||||||
ffio_wfourcc(pb, "gmin");/* generic media info */
|
ffio_wfourcc(pb, "gmin");/* generic media info */
|
||||||
@ -1273,7 +1273,27 @@ static int mov_write_gmhd_tag(AVIOContext *pb)
|
|||||||
avio_wb16(pb, 0x8000); /* opColor (b?) */
|
avio_wb16(pb, 0x8000); /* opColor (b?) */
|
||||||
avio_wb16(pb, 0); /* balance */
|
avio_wb16(pb, 0); /* balance */
|
||||||
avio_wb16(pb, 0); /* reserved */
|
avio_wb16(pb, 0); /* reserved */
|
||||||
return 0x20;
|
|
||||||
|
/*
|
||||||
|
* This special text atom is required for
|
||||||
|
* Apple Quicktime chapters. The contents
|
||||||
|
* don't appear to be documented, so the
|
||||||
|
* bytes are copied verbatim.
|
||||||
|
*/
|
||||||
|
avio_wb32(pb, 0x2C); /* size */
|
||||||
|
ffio_wfourcc(pb, "text");
|
||||||
|
avio_wb16(pb, 0x01);
|
||||||
|
avio_wb32(pb, 0x00);
|
||||||
|
avio_wb32(pb, 0x00);
|
||||||
|
avio_wb32(pb, 0x00);
|
||||||
|
avio_wb32(pb, 0x01);
|
||||||
|
avio_wb32(pb, 0x00);
|
||||||
|
avio_wb32(pb, 0x00);
|
||||||
|
avio_wb32(pb, 0x00);
|
||||||
|
avio_wb32(pb, 0x00004000);
|
||||||
|
avio_wb16(pb, 0x0000);
|
||||||
|
|
||||||
|
return 0x4C;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mov_write_smhd_tag(AVIOContext *pb)
|
static int mov_write_smhd_tag(AVIOContext *pb)
|
||||||
@ -3052,6 +3072,8 @@ static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
// as samples, and a tref pointing from the other tracks to the chapter one.
|
// as samples, and a tref pointing from the other tracks to the chapter one.
|
||||||
static void mov_create_chapter_track(AVFormatContext *s, int tracknum)
|
static void mov_create_chapter_track(AVFormatContext *s, int tracknum)
|
||||||
{
|
{
|
||||||
|
AVIOContext *pb;
|
||||||
|
|
||||||
MOVMuxContext *mov = s->priv_data;
|
MOVMuxContext *mov = s->priv_data;
|
||||||
MOVTrack *track = &mov->tracks[tracknum];
|
MOVTrack *track = &mov->tracks[tracknum];
|
||||||
AVPacket pkt = { .stream_index = tracknum, .flags = AV_PKT_FLAG_KEY };
|
AVPacket pkt = { .stream_index = tracknum, .flags = AV_PKT_FLAG_KEY };
|
||||||
@ -3063,6 +3085,50 @@ static void mov_create_chapter_track(AVFormatContext *s, int tracknum)
|
|||||||
track->enc = avcodec_alloc_context3(NULL);
|
track->enc = avcodec_alloc_context3(NULL);
|
||||||
track->enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
|
track->enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
|
||||||
|
|
||||||
|
if (avio_open_dyn_buf(&pb) >= 0) {
|
||||||
|
int size;
|
||||||
|
uint8_t *buf;
|
||||||
|
|
||||||
|
/* Stub header (usually for Quicktime chapter track) */
|
||||||
|
// TextSampleEntry
|
||||||
|
avio_wb32(pb, 0x01); // displayFlags
|
||||||
|
avio_w8(pb, 0x00); // horizontal justification
|
||||||
|
avio_w8(pb, 0x00); // vertical justification
|
||||||
|
avio_w8(pb, 0x00); // bgColourRed
|
||||||
|
avio_w8(pb, 0x00); // bgColourGreen
|
||||||
|
avio_w8(pb, 0x00); // bgColourBlue
|
||||||
|
avio_w8(pb, 0x00); // bgColourAlpha
|
||||||
|
// BoxRecord
|
||||||
|
avio_wb16(pb, 0x00); // defTextBoxTop
|
||||||
|
avio_wb16(pb, 0x00); // defTextBoxLeft
|
||||||
|
avio_wb16(pb, 0x00); // defTextBoxBottom
|
||||||
|
avio_wb16(pb, 0x00); // defTextBoxRight
|
||||||
|
// StyleRecord
|
||||||
|
avio_wb16(pb, 0x00); // startChar
|
||||||
|
avio_wb16(pb, 0x00); // endChar
|
||||||
|
avio_wb16(pb, 0x01); // fontID
|
||||||
|
avio_w8(pb, 0x00); // fontStyleFlags
|
||||||
|
avio_w8(pb, 0x00); // fontSize
|
||||||
|
avio_w8(pb, 0x00); // fgColourRed
|
||||||
|
avio_w8(pb, 0x00); // fgColourGreen
|
||||||
|
avio_w8(pb, 0x00); // fgColourBlue
|
||||||
|
avio_w8(pb, 0x00); // fgColourAlpha
|
||||||
|
// FontTableBox
|
||||||
|
avio_wb32(pb, 0x0D); // box size
|
||||||
|
ffio_wfourcc(pb, "ftab"); // box atom name
|
||||||
|
avio_wb16(pb, 0x01); // entry count
|
||||||
|
// FontRecord
|
||||||
|
avio_wb16(pb, 0x01); // font ID
|
||||||
|
avio_w8(pb, 0x00); // font name length
|
||||||
|
|
||||||
|
if ((size = avio_close_dyn_buf(pb, &buf)) > 0) {
|
||||||
|
track->enc->extradata = buf;
|
||||||
|
track->enc->extradata_size = size;
|
||||||
|
} else {
|
||||||
|
av_free(&buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < s->nb_chapters; i++) {
|
for (i = 0; i < s->nb_chapters; i++) {
|
||||||
AVChapter *c = s->chapters[i];
|
AVChapter *c = s->chapters[i];
|
||||||
AVDictionaryEntry *t;
|
AVDictionaryEntry *t;
|
||||||
|
Loading…
Reference in New Issue
Block a user