Message ID | 20160910020732.24359-2-rodger.combs@gmail.com |
---|---|
State | Superseded |
Headers | show |
On Fri, Sep 09, 2016 at 09:07:31PM -0500, Rodger Combs wrote: > 3 parts: > - Supports multiple chapter streams > - Exports regular text chapter streams as opaque data. This prevents consumers > from showing chapters as if they were regular subtitle streams. > - Exports video chapter streams as thumbnails, and provides the first one as > an attached_pic. > --- > libavformat/isom.h | 3 ++- > libavformat/mov.c | 52 +++++++++++++++++++++++++++++++++++++++++++++------- > 2 files changed, 47 insertions(+), 8 deletions(-) > > diff --git a/libavformat/isom.h b/libavformat/isom.h > index 2246fed..9038057 100644 > --- a/libavformat/isom.h > +++ b/libavformat/isom.h > @@ -210,7 +210,8 @@ typedef struct MOVContext { > unsigned trex_count; > int itunes_metadata; ///< metadata are itunes style > int handbrake_version; > - int chapter_track; > + int *chapter_tracks; > + unsigned int nb_chapter_tracks; > int use_absolute_path; > int ignore_editlist; > int ignore_chapters; > diff --git a/libavformat/mov.c b/libavformat/mov.c > index 6e80b93..22ca809 100644 > --- a/libavformat/mov.c > +++ b/libavformat/mov.c > @@ -3574,7 +3574,18 @@ static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) > > static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom) > { > - c->chapter_track = avio_rb32(pb); > + unsigned i, num; > + av_free(c->chapter_tracks); > + > + num = atom.size / 4; > + if (!(c->chapter_tracks = av_malloc(num * 4))) av_malloc_array() > + return AVERROR(ENOMEM); the error return leaves the size and array in an inconsistent tstate > + > + c->nb_chapter_tracks = num; > + > + for (i = 0; i < num; i++) > + c->chapter_tracks[i] = avio_rb32(pb); missing eof check reading 16gb without checking is not a good idea, it could waste alot of time this patch also appears to result in missing codec parameters(pix fmt) and ffmpeg failing to transcode it should i upload a file that causes this ? thx [...]
> On Sep 10, 2016, at 20:41, Michael Niedermayer <michael@niedermayer.cc> wrote: > > On Fri, Sep 09, 2016 at 09:07:31PM -0500, Rodger Combs wrote: >> 3 parts: >> - Supports multiple chapter streams >> - Exports regular text chapter streams as opaque data. This prevents consumers >> from showing chapters as if they were regular subtitle streams. >> - Exports video chapter streams as thumbnails, and provides the first one as >> an attached_pic. >> --- >> libavformat/isom.h | 3 ++- >> libavformat/mov.c | 52 +++++++++++++++++++++++++++++++++++++++++++++------- >> 2 files changed, 47 insertions(+), 8 deletions(-) >> >> diff --git a/libavformat/isom.h b/libavformat/isom.h >> index 2246fed..9038057 100644 >> --- a/libavformat/isom.h >> +++ b/libavformat/isom.h >> @@ -210,7 +210,8 @@ typedef struct MOVContext { >> unsigned trex_count; >> int itunes_metadata; ///< metadata are itunes style >> int handbrake_version; >> - int chapter_track; >> + int *chapter_tracks; >> + unsigned int nb_chapter_tracks; >> int use_absolute_path; >> int ignore_editlist; >> int ignore_chapters; >> diff --git a/libavformat/mov.c b/libavformat/mov.c >> index 6e80b93..22ca809 100644 >> --- a/libavformat/mov.c >> +++ b/libavformat/mov.c >> @@ -3574,7 +3574,18 @@ static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) >> >> static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom) >> { >> - c->chapter_track = avio_rb32(pb); >> + unsigned i, num; >> + av_free(c->chapter_tracks); >> + >> + num = atom.size / 4; >> + if (!(c->chapter_tracks = av_malloc(num * 4))) > > av_malloc_array() Done > >> + return AVERROR(ENOMEM); > > the error return leaves the size and array in an inconsistent tstate Fixed > > >> + >> + c->nb_chapter_tracks = num; >> + > >> + for (i = 0; i < num; i++) >> + c->chapter_tracks[i] = avio_rb32(pb); > > missing eof check > reading 16gb without checking is not a good idea, it could waste alot > of time Added > > this patch also appears to result in missing codec parameters(pix fmt) > and ffmpeg failing to transcode it > should i upload a file that causes this ? Would appreciate one, yeah > > thx > [...] > -- > Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB > > Republics decline into democracies and democracies degenerate into > despotisms. -- Aristotle > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
diff --git a/libavformat/isom.h b/libavformat/isom.h index 2246fed..9038057 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -210,7 +210,8 @@ typedef struct MOVContext { unsigned trex_count; int itunes_metadata; ///< metadata are itunes style int handbrake_version; - int chapter_track; + int *chapter_tracks; + unsigned int nb_chapter_tracks; int use_absolute_path; int ignore_editlist; int ignore_chapters; diff --git a/libavformat/mov.c b/libavformat/mov.c index 6e80b93..22ca809 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -3574,7 +3574,18 @@ static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom) { - c->chapter_track = avio_rb32(pb); + unsigned i, num; + av_free(c->chapter_tracks); + + num = atom.size / 4; + if (!(c->chapter_tracks = av_malloc(num * 4))) + return AVERROR(ENOMEM); + + c->nb_chapter_tracks = num; + + for (i = 0; i < num; i++) + c->chapter_tracks[i] = avio_rb32(pb); + return 0; } @@ -4637,25 +4648,50 @@ static int mov_probe(AVProbeData *p) static void mov_read_chapters(AVFormatContext *s) { MOVContext *mov = s->priv_data; - AVStream *st = NULL; + AVStream *st; MOVStreamContext *sc; int64_t cur_pos; - int i; + int i, j; + int chapter_track; + for (j = 0; j < mov->nb_chapter_tracks; j++) { + chapter_track = mov->chapter_tracks[j]; + st = NULL; for (i = 0; i < s->nb_streams; i++) - if (s->streams[i]->id == mov->chapter_track) { + if (s->streams[i]->id == chapter_track) { st = s->streams[i]; break; } if (!st) { av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n"); - return; + continue; } - st->discard = AVDISCARD_ALL; sc = st->priv_data; cur_pos = avio_tell(sc->pb); + if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { + st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS; + if (st->nb_index_entries) { + // Retrieve the first frame, if possible + AVPacket pkt; + AVIndexEntry *sample = &st->index_entries[0]; + if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) { + av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n"); + goto finish; + } + + if (av_get_packet(sc->pb, &pkt, sample->size) < 0) + goto finish; + + st->attached_pic = pkt; + st->attached_pic.stream_index = st->index; + st->attached_pic.flags |= AV_PKT_FLAG_KEY; + } + } else { + st->codec->codec_type = AVMEDIA_TYPE_DATA; + st->codec->codec_id = AV_CODEC_ID_BIN_DATA; + st->discard = AVDISCARD_ALL; for (i = 0; i < st->nb_index_entries; i++) { AVIndexEntry *sample = &st->index_entries[i]; int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration; @@ -4704,8 +4740,10 @@ static void mov_read_chapters(AVFormatContext *s) avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title); av_freep(&title); } + } finish: avio_seek(sc->pb, cur_pos, SEEK_SET); + } } static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, @@ -5028,7 +5066,7 @@ static int mov_read_header(AVFormatContext *s) av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb)); if (pb->seekable) { - if (mov->chapter_track > 0 && !mov->ignore_chapters) + if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters) mov_read_chapters(s); for (i = 0; i < s->nb_streams; i++) if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {