[FFmpeg-devel] [PATCH 06/19] avformat: add AVFMT_RAW_ID3 for demuxers requiring unstripped ID3

Anssi Hannula anssi.hannula at iki.fi
Fri Jan 3 15:21:30 CET 2014


This is needed by hls_id3_audio since the ID3 tag contains private
timestamp data needed by read_header() and read_probe().

Signed-off-by: Anssi Hannula <anssi.hannula at iki.fi>
---

This is needed with the new separate subdemuxer approach, otherwise
the first ID3 tag would be stripped by generic code. Better suggestions
welcome.

 libavformat/avformat.h |  3 +++
 libavformat/utils.c    | 12 ++++++++----
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 6d719d7..3d46bf1 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -377,6 +377,9 @@ typedef struct AVProbeData {
                                         AVFormatContext.avoid_negative_ts
                                         */
 
+#define AVFMT_RAW_ID3      0x80000 /**< Format requires raw ID3 tags to not be
+                                        parsed/stripped before read_header */
+
 #define AVFMT_SEEK_TO_PTS   0x4000000 /**< Seeking is based on PTS */
 
 /**
diff --git a/libavformat/utils.c b/libavformat/utils.c
index b0cb427..97762d6 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -226,6 +226,7 @@ int av_filename_number_test(const char *filename)
 AVInputFormat *av_probe_input_format3(AVProbeData *pd, int is_opened, int *score_ret)
 {
     AVProbeData lpd = *pd;
+    AVProbeData lpd_with_id3;
     AVInputFormat *fmt1 = NULL, *fmt;
     int score, nodat = 0, score_max=0;
     const static uint8_t zerobuffer[AVPROBE_PADDING_SIZE];
@@ -233,6 +234,8 @@ AVInputFormat *av_probe_input_format3(AVProbeData *pd, int is_opened, int *score
     if (!lpd.buf)
         lpd.buf = zerobuffer;
 
+    lpd_with_id3 = lpd;
+
     if (lpd.buf_size > 10 && ff_id3v2_match(lpd.buf, ID3v2_DEFAULT_MAGIC)) {
         int id3len = ff_id3v2_tag_len(lpd.buf);
         if (lpd.buf_size > id3len + 16) {
@@ -244,13 +247,14 @@ AVInputFormat *av_probe_input_format3(AVProbeData *pd, int is_opened, int *score
 
     fmt = NULL;
     while ((fmt1 = av_iformat_next(fmt1))) {
+        int raw_id3 = fmt1->flags & AVFMT_RAW_ID3;
         if (!is_opened == !(fmt1->flags & AVFMT_NOFILE))
             continue;
         score = 0;
         if (fmt1->read_probe) {
-            score = fmt1->read_probe(&lpd);
+            score = fmt1->read_probe(raw_id3 ? &lpd_with_id3 : &lpd);
             if(fmt1->extensions && av_match_ext(lpd.filename, fmt1->extensions))
-                score = FFMAX(score, nodat ? AVPROBE_SCORE_EXTENSION / 2 - 1 : 1);
+                score = FFMAX(score, nodat && !raw_id3 ? AVPROBE_SCORE_EXTENSION / 2 - 1 : 1);
         } else if (fmt1->extensions) {
             if (av_match_ext(lpd.filename, fmt1->extensions)) {
                 score = AVPROBE_SCORE_EXTENSION;
@@ -262,7 +266,7 @@ AVInputFormat *av_probe_input_format3(AVProbeData *pd, int is_opened, int *score
         }else if (score == score_max)
             fmt = NULL;
     }
-    if(nodat)
+    if(nodat && fmt && !(fmt->flags & AVFMT_RAW_ID3))
         score_max = FFMIN(AVPROBE_SCORE_EXTENSION / 2 - 1, score_max);
     *score_ret= score_max;
 
@@ -544,7 +548,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma
     }
 
     /* e.g. AVFMT_NOFILE formats will not have a AVIOContext */
-    if (s->pb)
+    if (s->pb && !(s->iformat->flags & AVFMT_RAW_ID3))
         ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta);
 
     if (!(s->flags&AVFMT_FLAG_PRIV_OPT) && s->iformat->read_header)
-- 
1.8.1.5



More information about the ffmpeg-devel mailing list