diff mbox

[FFmpeg-devel] lavf/mov.c: Fallback to finding non-keyframe in fix_index, if keyframe search fails.

Message ID 1478201996-18962-1-git-send-email-isasi@google.com
State Superseded
Headers show

Commit Message

Sasi Inguva Nov. 3, 2016, 7:39 p.m. UTC
Signed-off-by: Sasi Inguva <isasi@google.com>
---
 libavformat/mov.c  | 30 ++++++++++++++++++++----------
 tests/fate/mov.mak |  6 +++++-
 2 files changed, 25 insertions(+), 11 deletions(-)

Comments

Sasi Inguva Nov. 3, 2016, 10:35 p.m. UTC | #1
Sorry, forgot to add the fate test reference file. Sending it again.

On Thu, Nov 3, 2016 at 12:41 PM, Sasi Inguva <isasi@google.com> wrote:

> Attaching the fate sample.
>
> On Thu, Nov 3, 2016 at 12:39 PM, Sasi Inguva <isasi@google.com> wrote:
>
>> Signed-off-by: Sasi Inguva <isasi@google.com>
>> ---
>>  libavformat/mov.c  | 30 ++++++++++++++++++++----------
>>  tests/fate/mov.mak |  6 +++++-
>>  2 files changed, 25 insertions(+), 11 deletions(-)
>>
>> diff --git a/libavformat/mov.c b/libavformat/mov.c
>> index 4222088..f5b2035 100644
>> --- a/libavformat/mov.c
>> +++ b/libavformat/mov.c
>> @@ -2805,16 +2805,17 @@ static int get_edit_list_entry(MOVContext *mov,
>>  }
>>
>>  /**
>> - * Find the closest previous keyframe to the timestamp, in e_old index
>> - * entries.
>> + * Find the closest previous frame to the timestamp, in e_old index
>> + * entries. Searching for just any frame / just key frames can be
>> controlled by
>> + * last argument 'flag'.
>>   * Returns the index of the entry in st->index_entries if successful,
>>   * else returns -1.
>>   */
>> -static int64_t find_prev_closest_keyframe_index(AVStream *st,
>> -                                                AVIndexEntry *e_old,
>> -                                                int nb_old,
>> -                                                int64_t timestamp,
>> -                                                int flag)
>> +static int64_t find_prev_closest_index(AVStream *st,
>> +                                       AVIndexEntry *e_old,
>> +                                       int nb_old,
>> +                                       int64_t timestamp,
>> +                                       int flag)
>>  {
>>      AVIndexEntry *e_keep = st->index_entries;
>>      int nb_keep = st->nb_index_entries;
>> @@ -3031,10 +3032,19 @@ static void mov_fix_index(MOVContext *mov,
>> AVStream *st)
>>              search_timestamp = FFMAX(search_timestamp - msc->time_scale,
>> e_old[0].timestamp);
>>          }
>>
>> -        index = find_prev_closest_keyframe_index(st, e_old, nb_old,
>> search_timestamp, 0);
>> +        index = find_prev_closest_index(st, e_old, nb_old,
>> search_timestamp, 0);
>>          if (index == -1) {
>> -            av_log(mov->fc, AV_LOG_ERROR, "Missing key frame while
>> reordering index according to edit list\n");
>> -            continue;
>> +            av_log(mov->fc, AV_LOG_WARNING,
>> +                   "st: %d edit list: %"PRId64" Missing key frame while
>> searching for timestamp: %"PRId64"\n",
>> +                   st->index, edit_list_index, search_timestamp);
>> +            index = find_prev_closest_index(st, e_old, nb_old,
>> search_timestamp, AVSEEK_FLAG_ANY);
>> +
>> +            if (index == -1) {
>> +                av_log(mov->fc, AV_LOG_ERROR,
>> +                       "st: %d edit list %"PRId64" Cannot find an index
>> entry before timestamp: %"PRId64"\n",
>> +                       st->index, edit_list_index, search_timestamp);
>> +                continue;
>> +            }
>>          }
>>          current = e_old + index;
>>
>> diff --git a/tests/fate/mov.mak b/tests/fate/mov.mak
>> index 6b79832..b6ecbfc 100644
>> --- a/tests/fate/mov.mak
>> +++ b/tests/fate/mov.mak
>> @@ -5,7 +5,8 @@ FATE_MOV = fate-mov-3elist \
>>             fate-mov-elist-starts-ctts-2ndsample \
>>             fate-mov-1elist-ends-last-bframe \
>>             fate-mov-2elist-elist1-ends-bframe \
>> -           fate-mov-aac-2048-priming
>> +           fate-mov-aac-2048-priming \
>> +          fate-mp4-init-nonkeyframe
>>
>>  FATE_SAMPLES_AVCONV += $(FATE_MOV)
>>
>> @@ -30,3 +31,6 @@ fate-mov-2elist-elist1-ends-bframe: CMD = framemd5 -i
>> $(TARGET_SAMPLES)/mov/mov-
>>
>>  fate-mov-aac-2048-priming: ffprobe$(PROGSSUF)$(EXESUF)
>>  fate-mov-aac-2048-priming: CMD = run ffprobe$(PROGSSUF)$(EXESUF)
>> -show_packets -print_format compact $(TARGET_SAMPLES)/mov/aac-2048
>> -priming.mov
>> +
>> +fate-mp4-init-nonkeyframe: ffprobe$(PROGSSUF)$(EXESUF)
>> +fate-mp4-init-nonkeyframe: CMD = run ffprobe$(PROGSSUF)$(EXESUF)
>> -show_packets -print_format compact -select_streams v
>> $(TARGET_SAMPLES)/mov/mp4-init-nonkeyframe.mp4
>> --
>> 2.8.0.rc3.226.g39d4020
>>
>>
>
diff mbox

Patch

diff --git a/libavformat/mov.c b/libavformat/mov.c
index 4222088..f5b2035 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -2805,16 +2805,17 @@  static int get_edit_list_entry(MOVContext *mov,
 }
 
 /**
- * Find the closest previous keyframe to the timestamp, in e_old index
- * entries.
+ * Find the closest previous frame to the timestamp, in e_old index
+ * entries. Searching for just any frame / just key frames can be controlled by
+ * last argument 'flag'.
  * Returns the index of the entry in st->index_entries if successful,
  * else returns -1.
  */
-static int64_t find_prev_closest_keyframe_index(AVStream *st,
-                                                AVIndexEntry *e_old,
-                                                int nb_old,
-                                                int64_t timestamp,
-                                                int flag)
+static int64_t find_prev_closest_index(AVStream *st,
+                                       AVIndexEntry *e_old,
+                                       int nb_old,
+                                       int64_t timestamp,
+                                       int flag)
 {
     AVIndexEntry *e_keep = st->index_entries;
     int nb_keep = st->nb_index_entries;
@@ -3031,10 +3032,19 @@  static void mov_fix_index(MOVContext *mov, AVStream *st)
             search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
         }
 
-        index = find_prev_closest_keyframe_index(st, e_old, nb_old, search_timestamp, 0);
+        index = find_prev_closest_index(st, e_old, nb_old, search_timestamp, 0);
         if (index == -1) {
-            av_log(mov->fc, AV_LOG_ERROR, "Missing key frame while reordering index according to edit list\n");
-            continue;
+            av_log(mov->fc, AV_LOG_WARNING,
+                   "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
+                   st->index, edit_list_index, search_timestamp);
+            index = find_prev_closest_index(st, e_old, nb_old, search_timestamp, AVSEEK_FLAG_ANY);
+
+            if (index == -1) {
+                av_log(mov->fc, AV_LOG_ERROR,
+                       "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64"\n",
+                       st->index, edit_list_index, search_timestamp);
+                continue;
+            }
         }
         current = e_old + index;
 
diff --git a/tests/fate/mov.mak b/tests/fate/mov.mak
index 6b79832..b6ecbfc 100644
--- a/tests/fate/mov.mak
+++ b/tests/fate/mov.mak
@@ -5,7 +5,8 @@  FATE_MOV = fate-mov-3elist \
            fate-mov-elist-starts-ctts-2ndsample \
            fate-mov-1elist-ends-last-bframe \
            fate-mov-2elist-elist1-ends-bframe \
-           fate-mov-aac-2048-priming
+           fate-mov-aac-2048-priming \
+	   fate-mp4-init-nonkeyframe
 
 FATE_SAMPLES_AVCONV += $(FATE_MOV)
 
@@ -30,3 +31,6 @@  fate-mov-2elist-elist1-ends-bframe: CMD = framemd5 -i $(TARGET_SAMPLES)/mov/mov-
 
 fate-mov-aac-2048-priming: ffprobe$(PROGSSUF)$(EXESUF)
 fate-mov-aac-2048-priming: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_packets -print_format compact $(TARGET_SAMPLES)/mov/aac-2048-priming.mov
+
+fate-mp4-init-nonkeyframe: ffprobe$(PROGSSUF)$(EXESUF)
+fate-mp4-init-nonkeyframe: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_packets -print_format compact -select_streams v $(TARGET_SAMPLES)/mov/mp4-init-nonkeyframe.mp4