From 88f038ac97a875f25c2eceac6d2107a09314984c Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <michaelni@gmx.at>
Date: Thu, 17 Jul 2014 04:25:21 +0200
Subject: [PATCH] avformat/dv: implement fallback in dv_extract_pack()

Fixes Ticket2340
Fixes Ticket2341

Based-on mail from Dave Rice <dave@dericed.com>
Tested-by: Dave Rice <dave@dericed.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
---
 libavformat/dv.c | 43 +++++++++++++++++++++++--------------------
 1 file changed, 23 insertions(+), 20 deletions(-)

diff --git a/libavformat/dv.c b/libavformat/dv.c
index 4f7b062f8bb..1e15c082035 100644
--- a/libavformat/dv.c
+++ b/libavformat/dv.c
@@ -72,30 +72,33 @@ static inline uint16_t dv_audio_12to16(uint16_t sample)
     return result;
 }
 
-/*
- * This is the dumbest implementation of all -- it simply looks at
- * a fixed offset and if pack isn't there -- fails. We might want
- * to have a fallback mechanism for complete search of missing packs.
- */
 static const uint8_t *dv_extract_pack(uint8_t *frame, enum dv_pack_type t)
 {
     int offs;
+    int c;
 
-    switch (t) {
-    case dv_audio_source:
-        offs = (80 * 6 + 80 * 16 * 3 + 3);
-        break;
-    case dv_audio_control:
-        offs = (80 * 6 + 80 * 16 * 4 + 3);
-        break;
-    case dv_video_control:
-        offs = (80 * 5 + 48 + 5);
-        break;
-    case dv_timecode:
-        offs = (80*1 + 3 + 3);
-        break;
-    default:
-        return NULL;
+    for (c = 0; c < 10; c++) {
+        switch (t) {
+        case dv_audio_source:
+            if (c&1)    offs = (80 * 6 + 80 * 16 * 0 + 3 + c*12000);
+            else        offs = (80 * 6 + 80 * 16 * 3 + 3 + c*12000);
+            break;
+        case dv_audio_control:
+            if (c&1)    offs = (80 * 6 + 80 * 16 * 1 + 3 + c*12000);
+            else        offs = (80 * 6 + 80 * 16 * 4 + 3 + c*12000);
+            break;
+        case dv_video_control:
+            if (c&1)    offs = (80 * 3 + 8      + c*12000);
+            else        offs = (80 * 5 + 48 + 5 + c*12000);
+            break;
+        case dv_timecode:
+            offs = (80*1 + 3 + 3);
+            break;
+        default:
+            return NULL;
+        }
+        if (frame[offs] == t)
+            break;
     }
 
     return frame[offs] == t ? &frame[offs] : NULL;
-- 
GitLab