Browse code

flvdec: Allow parsing keyframes metadata without seeking in most cases

Stop the avio input at a point where amf_parse_object can
continue parsing the end of the object seamlessly, when all
data is available.

If unsupported data is encountered within the keyframes object,
try seeking to the start of the keyframes object - if the seek
back was successful, the caller can continue parsing the rest
of the AMF data.

Signed-off-by: Martin Storsjö <martin@martin.st>

Martin Storsjö authored on 2011/04/12 22:37:54
Showing 1 changed files
... ...
@@ -135,7 +135,7 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, AVStream
135 135
     char str_val[256];
136 136
     int64_t *times = NULL;
137 137
     int64_t *filepositions = NULL;
138
-    int ret = 0;
138
+    int ret = AVERROR(ENOSYS);
139 139
     int64_t initial_pos = avio_tell(ioc);
140 140
 
141 141
     while (avio_tell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) {
... ...
@@ -173,6 +173,12 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, AVStream
173 173
             num_val = av_int2dbl(avio_rb64(ioc));
174 174
             current_array[i] = num_val;
175 175
         }
176
+        if (times && filepositions) {
177
+            // All done, exiting at a position allowing amf_parse_object
178
+            // to finish parsing the object
179
+            ret = 0;
180
+            break;
181
+        }
176 182
     }
177 183
 
178 184
     if (timeslen == fileposlen)
... ...
@@ -184,7 +190,10 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, AVStream
184 184
 finish:
185 185
     av_freep(&times);
186 186
     av_freep(&filepositions);
187
-    avio_seek(ioc, initial_pos, SEEK_SET);
187
+    // If we got unexpected data, but successfully reset back to
188
+    // the start pos, the caller can continue parsing
189
+    if (ret < 0 && avio_seek(ioc, initial_pos, SEEK_SET) > 0)
190
+        return 0;
188 191
     return ret;
189 192
 }
190 193