[FFmpeg-cvslog] avformat/wavdec: add support for chapters

Paul B Mahol git at videolan.org
Tue Sep 1 15:21:33 EEST 2020


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Mon Aug 31 14:18:37 2020 +0200| [2a14d55a7c41ba8665cfd17b82d96e669ecd0e4c] | committer: Paul B Mahol

avformat/wavdec: add support for chapters

Support parsing 'cue ' and 'adtl' chunks.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=2a14d55a7c41ba8665cfd17b82d96e669ecd0e4c
---

 libavformat/wavdec.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/libavformat/wavdec.c b/libavformat/wavdec.c
index 4be0ed7b31..d6ab0dde35 100644
--- a/libavformat/wavdec.c
+++ b/libavformat/wavdec.c
@@ -500,6 +500,7 @@ static int wav_read_header(AVFormatContext *s)
             wav->smv_cur_pt = 0;
             goto break_loop;
         case MKTAG('L', 'I', 'S', 'T'):
+        case MKTAG('l', 'i', 's', 't'):
             if (size < 4) {
                 av_log(s, AV_LOG_ERROR, "too short LIST tag\n");
                 return AVERROR_INVALIDDATA;
@@ -507,6 +508,33 @@ static int wav_read_header(AVFormatContext *s)
             switch (avio_rl32(pb)) {
             case MKTAG('I', 'N', 'F', 'O'):
                 ff_read_riff_info(s, size - 4);
+                break;
+            case MKTAG('a', 'd', 't', 'l'):
+                if (s->nb_chapters > 0) {
+                    while (avio_tell(pb) < next_tag_ofs &&
+                           !avio_feof(pb)) {
+                        char cue_label[512];
+                        unsigned id, sub_size;
+
+                        if (avio_rl32(pb) != MKTAG('l', 'a', 'b', 'l'))
+                            break;
+
+                        sub_size = avio_rl32(pb);
+                        if (sub_size < 5)
+                            break;
+                        id       = avio_rl32(pb);
+                        avio_get_str(pb, sub_size - 4, cue_label, sizeof(cue_label));
+                        avio_skip(pb, avio_tell(pb) & 1);
+
+                        for (int i = 0; i < s->nb_chapters; i++) {
+                            if (s->chapters[i]->id == id) {
+                                av_dict_set(&s->chapters[i]->metadata, "title", cue_label, 0);
+                                break;
+                            }
+                        }
+                    }
+                }
+                break;
             }
             break;
         case MKTAG('I', 'D', '3', ' '):
@@ -521,6 +549,24 @@ static int wav_read_header(AVFormatContext *s)
             ff_id3v2_free_extra_meta(&id3v2_extra_meta);
             }
             break;
+        case MKTAG('c', 'u', 'e', ' '):
+            if (size >= 4 && got_fmt && st->codecpar->sample_rate > 0) {
+                AVRational tb = {1, st->codecpar->sample_rate};
+                unsigned nb_cues = avio_rl32(pb);
+
+                if (size >= nb_cues * 24LL + 4LL) {
+                    for (int i = 0; i < nb_cues; i++) {
+                        unsigned offset, id = avio_rl32(pb);
+
+                        avio_skip(pb, 16);
+                        offset = avio_rl32(pb);
+
+                        if (!avpriv_new_chapter(s, id, tb, offset, AV_NOPTS_VALUE, NULL))
+                            return AVERROR(ENOMEM);
+                    }
+                }
+            }
+            break;
         }
 
         /* seek to next tag unless we know that we'll run into EOF */



More information about the ffmpeg-cvslog mailing list