*
* 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 "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
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.
*
// 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;
}
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;
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
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
}
// Clean up the parser.
- av_read_frame_flush(s);
+ ff_read_frame_flush(s);
}
int64_t ff_gen_syncpoint_search(AVFormatContext *s,
// Find keyframes in all active streams with timestamp/position just before
// and just after requested timestamp/position.
- step = 1024;
- curpos = pos;
+ 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,
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) {
}
}
- url_fseek(s->pb, pos, SEEK_SET);
+ avio_seek(s->pb, pos, SEEK_SET);
av_free(sync);
return pos;
}
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;
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;
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;
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);
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);
}
-