X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=libavformat%2Fseek.c;h=9be8db97845bc7617316f0da9c0b1014e83905fa;hb=929ec39ec4497827f7530f2aaa31646ef35462ee;hp=93cb679f3c3843dfdada357f6bb9278c938699eb;hpb=dbe0ad85c1722b67fc681fcf084b8f7afdd15adf;p=ffmpeg diff --git a/libavformat/seek.c b/libavformat/seek.c index 93cb679f3c3..9be8db97845 100644 --- a/libavformat/seek.c +++ b/libavformat/seek.c @@ -3,29 +3,32 @@ * * Copyright (c) 2009 Ivan Schreter * - * This file is part of FFmpeg. + * This file is part of Libav. * - * FFmpeg is free software; you can redistribute it and/or + * Libav is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * FFmpeg is distributed in the hope that it will be useful, + * Libav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software + * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include + #include "seek.h" +#include "libavutil/mathematics.h" #include "libavutil/mem.h" +#include "internal.h" // NOTE: implementation should be moved here in another patch, to keep patches // separated. -extern void av_read_frame_flush(AVFormatContext *s); /** * helper structure describing keyframe search state of one stream @@ -47,38 +50,6 @@ typedef struct { int terminated; ///< termination flag for the current iteration } AVSyncPoint; -/** - * Compare two timestamps exactly, taking their respective time bases into account. - * - * @param ts_a timestamp A - * @param tb_a time base for timestamp A - * @param ts_b timestamp B - * @param tb_b time base for timestamp A - * @return -1, 0 or 1 if timestamp A is less than, equal or greater than timestamp B - */ -static int compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b) -{ - int64_t a, b, res; - - if (ts_a == INT64_MIN) - return ts_a < ts_b ? -1 : 0; - if (ts_a == INT64_MAX) - return ts_a > ts_b ? 1 : 0; - if (ts_b == INT64_MIN) - return ts_a > ts_b ? 1 : 0; - if (ts_b == INT64_MAX) - return ts_a < ts_b ? -1 : 0; - - a = ts_a * tb_a.num * tb_b.den; - b = ts_b * tb_b.num * tb_a.den; - - res = a - b; - if (!res) - return 0; - else - return (res >> 63) | 1; -} - /** * Compute a distance between timestamps. * @@ -194,7 +165,7 @@ static void search_hi_lo_keyframes(AVFormatContext *s, // Evaluate key frames with known TS (or any frames, if AVSEEK_FLAG_ANY set). if (pts != AV_NOPTS_VALUE && - ((flg & PKT_FLAG_KEY) || (flags & AVSEEK_FLAG_ANY))) { + ((flg & AV_PKT_FLAG_KEY) || (flags & AVSEEK_FLAG_ANY))) { if (flags & AVSEEK_FLAG_BYTE) { // for byte seeking, use position as timestamp ts = pos; @@ -216,7 +187,7 @@ static void search_hi_lo_keyframes(AVFormatContext *s, } if (sp->term_ts != AV_NOPTS_VALUE && - compare_ts(ts, ts_tb, sp->term_ts, sp->term_ts_tb) > 0) { + av_compare_ts(ts, ts_tb, sp->term_ts, sp->term_ts_tb) > 0) { // past the end position from last iteration, ignore packet if (!sp->terminated) { sp->terminated = 1; @@ -233,7 +204,7 @@ static void search_hi_lo_keyframes(AVFormatContext *s, continue; } - if (compare_ts(ts, ts_tb, timestamp, timebase) <= 0) { + if (av_compare_ts(ts, ts_tb, timestamp, timebase) <= 0) { // keyframe found before target timestamp if (sp->pos_lo == INT64_MAX) { // found first keyframe lower than target timestamp @@ -246,7 +217,7 @@ static void search_hi_lo_keyframes(AVFormatContext *s, sp->pos_lo = pos; } } - if (compare_ts(ts, ts_tb, timestamp, timebase) >= 0) { + if (av_compare_ts(ts, ts_tb, timestamp, timebase) >= 0) { // keyframe found after target timestamp if (sp->pos_hi == INT64_MAX) { // found first keyframe higher than target timestamp @@ -269,7 +240,7 @@ static void search_hi_lo_keyframes(AVFormatContext *s, } // Clean up the parser. - av_read_frame_flush(s); + ff_read_frame_flush(s); } int64_t ff_gen_syncpoint_search(AVFormatContext *s, @@ -345,7 +316,7 @@ int64_t ff_gen_syncpoint_search(AVFormatContext *s, step = s->pb->buffer_size; curpos = FFMAX(pos - step / 2, 0); for (;;) { - url_fseek(s->pb, curpos, SEEK_SET); + avio_seek(s->pb, curpos, SEEK_SET); search_hi_lo_keyframes(s, ts, time_base, flags, @@ -391,15 +362,15 @@ int64_t ff_gen_syncpoint_search(AVFormatContext *s, min_distance = INT64_MAX; // Find timestamp closest to requested timestamp within min/max limits. if (sp->pos_lo != INT64_MAX - && compare_ts(ts_min, time_base, sp->ts_lo, st->time_base) <= 0 - && compare_ts(sp->ts_lo, st->time_base, ts_max, time_base) <= 0) { + && av_compare_ts(ts_min, time_base, sp->ts_lo, st->time_base) <= 0 + && av_compare_ts(sp->ts_lo, st->time_base, ts_max, time_base) <= 0) { // low timestamp is in range min_distance = ts_distance(ts, time_base, sp->ts_lo, st->time_base); min_pos = sp->pos_lo; } if (sp->pos_hi != INT64_MAX - && compare_ts(ts_min, time_base, sp->ts_hi, st->time_base) <= 0 - && compare_ts(sp->ts_hi, st->time_base, ts_max, time_base) <= 0) { + && av_compare_ts(ts_min, time_base, sp->ts_hi, st->time_base) <= 0 + && av_compare_ts(sp->ts_hi, st->time_base, ts_max, time_base) <= 0) { // high timestamp is in range, check distance distance = ts_distance(sp->ts_hi, st->time_base, ts, time_base); if (distance < min_distance) { @@ -417,7 +388,7 @@ int64_t ff_gen_syncpoint_search(AVFormatContext *s, } } - url_fseek(s->pb, pos, SEEK_SET); + avio_seek(s->pb, pos, SEEK_SET); av_free(sync); return pos; } @@ -437,16 +408,16 @@ AVParserState *ff_store_parser_state(AVFormatContext *s) return NULL; } - state->fpos = url_ftell(s->pb); + state->fpos = avio_tell(s->pb); // copy context structures - state->cur_st = s->cur_st; state->packet_buffer = s->packet_buffer; + state->parse_queue = s->parse_queue; state->raw_packet_buffer = s->raw_packet_buffer; state->raw_packet_buffer_remaining_size = s->raw_packet_buffer_remaining_size; - s->cur_st = NULL; s->packet_buffer = NULL; + s->parse_queue = NULL; s->raw_packet_buffer = NULL; s->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE; @@ -459,20 +430,12 @@ AVParserState *ff_store_parser_state(AVFormatContext *s) ss->parser = st->parser; ss->last_IP_pts = st->last_IP_pts; ss->cur_dts = st->cur_dts; - ss->reference_dts = st->reference_dts; - ss->cur_ptr = st->cur_ptr; - ss->cur_len = st->cur_len; ss->probe_packets = st->probe_packets; - ss->cur_pkt = st->cur_pkt; st->parser = NULL; st->last_IP_pts = AV_NOPTS_VALUE; st->cur_dts = AV_NOPTS_VALUE; - st->reference_dts = AV_NOPTS_VALUE; - st->cur_ptr = NULL; - st->cur_len = 0; st->probe_packets = MAX_PROBE_PACKETS; - av_init_packet(&st->cur_pkt); } return state; @@ -483,16 +446,16 @@ void ff_restore_parser_state(AVFormatContext *s, AVParserState *state) int i; AVStream *st; AVParserStreamState *ss; - av_read_frame_flush(s); + ff_read_frame_flush(s); if (!state) return; - url_fseek(s->pb, state->fpos, SEEK_SET); + avio_seek(s->pb, state->fpos, SEEK_SET); // copy context structures - s->cur_st = state->cur_st; s->packet_buffer = state->packet_buffer; + s->parse_queue = state->parse_queue; s->raw_packet_buffer = state->raw_packet_buffer; s->raw_packet_buffer_remaining_size = state->raw_packet_buffer_remaining_size; @@ -504,11 +467,7 @@ void ff_restore_parser_state(AVFormatContext *s, AVParserState *state) st->parser = ss->parser; st->last_IP_pts = ss->last_IP_pts; st->cur_dts = ss->cur_dts; - st->reference_dts = ss->reference_dts; - st->cur_ptr = ss->cur_ptr; - st->cur_len = ss->cur_len; st->probe_packets = ss->probe_packets; - st->cur_pkt = ss->cur_pkt; } av_free(state->stream_states); @@ -538,13 +497,12 @@ void ff_free_parser_state(AVFormatContext *s, AVParserState *state) ss = &state->stream_states[i]; if (ss->parser) av_parser_close(ss->parser); - av_free_packet(&ss->cur_pkt); } free_packet_list(state->packet_buffer); + free_packet_list(state->parse_queue); free_packet_list(state->raw_packet_buffer); av_free(state->stream_states); av_free(state); } -