Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(68)

Side by Side Diff: patched-ffmpeg-mt/libavformat/seek.c

Issue 789004: ffmpeg roll of source to mar 9 version... (Closed) Base URL: svn://chrome-svn/chrome/trunk/deps/third_party/ffmpeg/
Patch Set: '' Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * seek utility functions for use within format handlers 2 * seek utility functions for use within format handlers
3 * 3 *
4 * Copyright (c) 2009 Ivan Schreter 4 * Copyright (c) 2009 Ivan Schreter
5 * 5 *
6 * This file is part of FFmpeg. 6 * This file is part of FFmpeg.
7 * 7 *
8 * FFmpeg is free software; you can redistribute it and/or 8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public 9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version. 11 * version 2.1 of the License, or (at your option) any later version.
12 * 12 *
13 * FFmpeg is distributed in the hope that it will be useful, 13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details. 16 * Lesser General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU Lesser General Public 18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software 19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */ 21 */
22 22
23 #include "seek.h" 23 #include "seek.h"
24 #include "libavutil/mem.h" 24 #include "libavutil/mem.h"
25 #include "internal.h"
25 26
26 // NOTE: implementation should be moved here in another patch, to keep patches 27 // NOTE: implementation should be moved here in another patch, to keep patches
27 // separated. 28 // separated.
28 extern void av_read_frame_flush(AVFormatContext *s);
29 29
30 /** 30 /**
31 * helper structure describing keyframe search state of one stream 31 * helper structure describing keyframe search state of one stream
32 */ 32 */
33 typedef struct { 33 typedef struct {
34 int64_t pos_lo; ///< position of the frame with low timestamp in fi le or INT64_MAX if not found (yet) 34 int64_t pos_lo; ///< position of the frame with low timestamp in fi le or INT64_MAX if not found (yet)
35 int64_t ts_lo; ///< frame presentation timestamp or same as pos_lo for byte seeking 35 int64_t ts_lo; ///< frame presentation timestamp or same as pos_lo for byte seeking
36 36
37 int64_t pos_hi; ///< position of the frame with high timestamp in f ile or INT64_MAX if not found (yet) 37 int64_t pos_hi; ///< position of the frame with high timestamp in f ile or INT64_MAX if not found (yet)
38 int64_t ts_hi; ///< frame presentation timestamp or same as pos_hi for byte seeking 38 int64_t ts_hi; ///< frame presentation timestamp or same as pos_hi for byte seeking
39 39
40 int64_t last_pos; ///< last known position of a frame, for multi-fram e packets 40 int64_t last_pos; ///< last known position of a frame, for multi-fram e packets
41 41
42 int64_t term_ts; ///< termination timestamp (which TS we already rea d) 42 int64_t term_ts; ///< termination timestamp (which TS we already rea d)
43 AVRational term_ts_tb; ///< timebase for term_ts 43 AVRational term_ts_tb; ///< timebase for term_ts
44 int64_t first_ts; ///< first packet timestamp in this iteration (to f ill term_ts later) 44 int64_t first_ts; ///< first packet timestamp in this iteration (to f ill term_ts later)
45 AVRational first_ts_tb; ///< timebase for first_ts 45 AVRational first_ts_tb; ///< timebase for first_ts
46 46
47 int terminated; ///< termination flag for the current iteration 47 int terminated; ///< termination flag for the current iteration
48 } AVSyncPoint; 48 } AVSyncPoint;
49 49
50 /** 50 /**
51 * Compare two timestamps exactly, taking their respective time bases into accou nt.
52 *
53 * @param ts_a timestamp A
54 * @param tb_a time base for timestamp A
55 * @param ts_b timestamp B
56 * @param tb_b time base for timestamp A
57 * @return -1, 0 or 1 if timestamp A is less than, equal or greater than timesta mp B
58 */
59 static int compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb _b)
60 {
61 int64_t a, b, res;
62
63 if (ts_a == INT64_MIN)
64 return ts_a < ts_b ? -1 : 0;
65 if (ts_a == INT64_MAX)
66 return ts_a > ts_b ? 1 : 0;
67 if (ts_b == INT64_MIN)
68 return ts_a > ts_b ? 1 : 0;
69 if (ts_b == INT64_MAX)
70 return ts_a < ts_b ? -1 : 0;
71
72 a = ts_a * tb_a.num * tb_b.den;
73 b = ts_b * tb_b.num * tb_a.den;
74
75 res = a - b;
76 if (!res)
77 return 0;
78 else
79 return (res >> 63) | 1;
80 }
81
82 /**
83 * Compute a distance between timestamps. 51 * Compute a distance between timestamps.
84 * 52 *
85 * Distances are only comparable, if same time bases are used for computing 53 * Distances are only comparable, if same time bases are used for computing
86 * distances. 54 * distances.
87 * 55 *
88 * @param ts_hi high timestamp 56 * @param ts_hi high timestamp
89 * @param tb_hi high timestamp time base 57 * @param tb_hi high timestamp time base
90 * @param ts_lo low timestamp 58 * @param ts_lo low timestamp
91 * @param tb_lo low timestamp time base 59 * @param tb_lo low timestamp time base
92 * @return representation of distance between high and low timestamps 60 * @return representation of distance between high and low timestamps
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 if (sp->first_ts == AV_NOPTS_VALUE) { 177 if (sp->first_ts == AV_NOPTS_VALUE) {
210 // Note down termination timestamp for the next iteration - when 178 // Note down termination timestamp for the next iteration - when
211 // we encounter a packet with the same timestamp, we will ignore 179 // we encounter a packet with the same timestamp, we will ignore
212 // any further packets for this stream in next iteration (as the y 180 // any further packets for this stream in next iteration (as the y
213 // are already evaluated). 181 // are already evaluated).
214 sp->first_ts = ts; 182 sp->first_ts = ts;
215 sp->first_ts_tb = ts_tb; 183 sp->first_ts_tb = ts_tb;
216 } 184 }
217 185
218 if (sp->term_ts != AV_NOPTS_VALUE && 186 if (sp->term_ts != AV_NOPTS_VALUE &&
219 compare_ts(ts, ts_tb, sp->term_ts, sp->term_ts_tb) > 0) { 187 av_compare_ts(ts, ts_tb, sp->term_ts, sp->term_ts_tb) > 0) {
220 // past the end position from last iteration, ignore packet 188 // past the end position from last iteration, ignore packet
221 if (!sp->terminated) { 189 if (!sp->terminated) {
222 sp->terminated = 1; 190 sp->terminated = 1;
223 ++terminated_count; 191 ++terminated_count;
224 if (sp->pos_hi == INT64_MAX) { 192 if (sp->pos_hi == INT64_MAX) {
225 // no high frame exists for this stream 193 // no high frame exists for this stream
226 (*found_hi)++; 194 (*found_hi)++;
227 sp->ts_hi = INT64_MAX; 195 sp->ts_hi = INT64_MAX;
228 sp->pos_hi = INT64_MAX - 1; 196 sp->pos_hi = INT64_MAX - 1;
229 } 197 }
230 if (terminated_count == keyframes_to_find) 198 if (terminated_count == keyframes_to_find)
231 break; // all terminated, iteration done 199 break; // all terminated, iteration done
232 } 200 }
233 continue; 201 continue;
234 } 202 }
235 203
236 if (compare_ts(ts, ts_tb, timestamp, timebase) <= 0) { 204 if (av_compare_ts(ts, ts_tb, timestamp, timebase) <= 0) {
237 // keyframe found before target timestamp 205 // keyframe found before target timestamp
238 if (sp->pos_lo == INT64_MAX) { 206 if (sp->pos_lo == INT64_MAX) {
239 // found first keyframe lower than target timestamp 207 // found first keyframe lower than target timestamp
240 (*found_lo)++; 208 (*found_lo)++;
241 sp->ts_lo = ts; 209 sp->ts_lo = ts;
242 sp->pos_lo = pos; 210 sp->pos_lo = pos;
243 } else if (sp->ts_lo < ts) { 211 } else if (sp->ts_lo < ts) {
244 // found a better match (closer to target timestamp) 212 // found a better match (closer to target timestamp)
245 sp->ts_lo = ts; 213 sp->ts_lo = ts;
246 sp->pos_lo = pos; 214 sp->pos_lo = pos;
247 } 215 }
248 } 216 }
249 if (compare_ts(ts, ts_tb, timestamp, timebase) >= 0) { 217 if (av_compare_ts(ts, ts_tb, timestamp, timebase) >= 0) {
250 // keyframe found after target timestamp 218 // keyframe found after target timestamp
251 if (sp->pos_hi == INT64_MAX) { 219 if (sp->pos_hi == INT64_MAX) {
252 // found first keyframe higher than target timestamp 220 // found first keyframe higher than target timestamp
253 (*found_hi)++; 221 (*found_hi)++;
254 sp->ts_hi = ts; 222 sp->ts_hi = ts;
255 sp->pos_hi = pos; 223 sp->pos_hi = pos;
256 if (*found_hi >= keyframes_to_find && first_iter) { 224 if (*found_hi >= keyframes_to_find && first_iter) {
257 // We found high frame for all. They may get updated 225 // We found high frame for all. They may get updated
258 // to TS closer to target TS in later iterations (which 226 // to TS closer to target TS in later iterations (which
259 // will stop at start position of previous iteration). 227 // will stop at start position of previous iteration).
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 // closest to ts and between ts_min and ts_max. 352 // closest to ts and between ts_min and ts_max.
385 pos = INT64_MAX; 353 pos = INT64_MAX;
386 354
387 for (i = 0; i < s->nb_streams; ++i) { 355 for (i = 0; i < s->nb_streams; ++i) {
388 st = s->streams[i]; 356 st = s->streams[i];
389 if (st->discard < AVDISCARD_ALL) { 357 if (st->discard < AVDISCARD_ALL) {
390 sp = &sync[i]; 358 sp = &sync[i];
391 min_distance = INT64_MAX; 359 min_distance = INT64_MAX;
392 // Find timestamp closest to requested timestamp within min/max limi ts. 360 // Find timestamp closest to requested timestamp within min/max limi ts.
393 if (sp->pos_lo != INT64_MAX 361 if (sp->pos_lo != INT64_MAX
394 && compare_ts(ts_min, time_base, sp->ts_lo, st->time_base) <= 0 362 && av_compare_ts(ts_min, time_base, sp->ts_lo, st->time_base) <= 0
395 && compare_ts(sp->ts_lo, st->time_base, ts_max, time_base) <= 0) { 363 && av_compare_ts(sp->ts_lo, st->time_base, ts_max, time_base) <= 0) {
396 // low timestamp is in range 364 // low timestamp is in range
397 min_distance = ts_distance(ts, time_base, sp->ts_lo, st->time_ba se); 365 min_distance = ts_distance(ts, time_base, sp->ts_lo, st->time_ba se);
398 min_pos = sp->pos_lo; 366 min_pos = sp->pos_lo;
399 } 367 }
400 if (sp->pos_hi != INT64_MAX 368 if (sp->pos_hi != INT64_MAX
401 && compare_ts(ts_min, time_base, sp->ts_hi, st->time_base) <= 0 369 && av_compare_ts(ts_min, time_base, sp->ts_hi, st->time_base) <= 0
402 && compare_ts(sp->ts_hi, st->time_base, ts_max, time_base) <= 0) { 370 && av_compare_ts(sp->ts_hi, st->time_base, ts_max, time_base) <= 0) {
403 // high timestamp is in range, check distance 371 // high timestamp is in range, check distance
404 distance = ts_distance(sp->ts_hi, st->time_base, ts, time_base); 372 distance = ts_distance(sp->ts_hi, st->time_base, ts, time_base);
405 if (distance < min_distance) { 373 if (distance < min_distance) {
406 min_distance = distance; 374 min_distance = distance;
407 min_pos = sp->pos_hi; 375 min_pos = sp->pos_hi;
408 } 376 }
409 } 377 }
410 if (min_distance == INT64_MAX) { 378 if (min_distance == INT64_MAX) {
411 // no timestamp is in range, cannot seek 379 // no timestamp is in range, cannot seek
412 av_free(sync); 380 av_free(sync);
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 av_free_packet(&ss->cur_pkt); 509 av_free_packet(&ss->cur_pkt);
542 } 510 }
543 511
544 free_packet_list(state->packet_buffer); 512 free_packet_list(state->packet_buffer);
545 free_packet_list(state->raw_packet_buffer); 513 free_packet_list(state->raw_packet_buffer);
546 514
547 av_free(state->stream_states); 515 av_free(state->stream_states);
548 av_free(state); 516 av_free(state);
549 } 517 }
550 518
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698