[FFmpeg-devel] [PATCH] [PROPOSAL] Do not return immediately the result of a probe if we are still probing inside a possible ID3v2 tag.

Thierry Foucu tfoucu at gmail.com
Thu Apr 18 19:57:55 CEST 2013


Some mp3 files have a lot of ID3v2 Tag which could match  some other
probe and return invalid format. With this change, we are trying to
check if we probe pass the Id3v2 tag before returning.
---
 libavformat/utils.c | 37 ++++++++++++++++++++++++++++---------
 1 file changed, 28 insertions(+), 9 deletions(-)

diff --git a/libavformat/utils.c b/libavformat/utils.c
index e32f972..11aeffd 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -495,7 +495,7 @@ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt,
         }
         av_freep(&mime_type);
     }
-
+    AVInputFormat *best_fmt = NULL;
     for(probe_size= PROBE_BUF_MIN; probe_size<=max_probe_size && !*fmt;
         probe_size = FFMIN(probe_size<<1, FFMAX(max_probe_size, probe_size+1))) {
         int score = probe_size < max_probe_size ? AVPROBE_SCORE_RETRY : 0;
@@ -527,18 +527,37 @@ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt,
         memset(pd.buf + pd.buf_size, 0, AVPROBE_PADDING_SIZE);
 
         /* guess file format */
-        *fmt = av_probe_input_format2(&pd, 1, &score);
-        if(*fmt){
-            if(score <= AVPROBE_SCORE_RETRY){ //this can only be true in the last iteration
-                av_log(logctx, AV_LOG_WARNING, "Format %s detected only with low score of %d, misdetection possible!\n", (*fmt)->name, score);
-            }else
-                av_log(logctx, AV_LOG_DEBUG, "Format %s probed with size=%d and score=%d\n", (*fmt)->name, probe_size, score);
+        best_fmt = av_probe_input_format2(&pd, 1, &score);
+        if (best_fmt) {
+            AVProbeData lpd = pd;
+            // If the probing buffer starts with an ID3v2 tag, the format
+            // is valid only if we are probing well after the ID3v2 section.
+            if ((lpd.buf_size > 10) &&
+                ff_id3v2_match(lpd.buf, ID3v2_DEFAULT_MAGIC) &&
+                (lpd.buf_size > 2 * ff_id3v2_tag_len(lpd.buf))) {
+                *fmt = best_fmt;
+            }
+            if(*fmt){
+                if(score <= AVPROBE_SCORE_RETRY){ //this can only be true in the last iteration
+                    av_log(logctx, AV_LOG_WARNING, "Format %s detected only with low score of %d, misdetection possible!\n", (*fmt)->name, score);
+                }else
+                    av_log(logctx, AV_LOG_DEBUG, "Format %s probed with size=%d and score=%d\n", (*fmt)->name, probe_size, score);
+            } else {
+                // Still probing a potential ID3v2, but we do have a match.
+                av_log(logctx, AV_LOG_DEBUG, "Format %s probed with size=%d and score=%d (not final)\n", best_fmt->name, probe_size, score);
+            }
         }
     }
 
     if (!*fmt) {
-        av_free(buf);
-        return AVERROR_INVALIDDATA;
+        // We have reached max_probe_size. Use best_fmt if we have it.
+        if (best_fmt) {
+            av_log(logctx, AV_LOG_DEBUG, "Reached max_probe_size. Using best_fmt %s\n", best_fmt->name);
+            *fmt = best_fmt;
+        } else {
+          av_free(buf);
+          return AVERROR_INVALIDDATA;
+        }
     }
 
     /* rewind. reuse probe buffer to avoid seeking */
-- 
1.8.1.3



More information about the ffmpeg-devel mailing list