/*
 * seek utility functions for use within format handlers
 *
 * Copyright (c) 2009 Ivan Schreter
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg 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,
 * 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
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "seek.h"
#include "libavutil/mem.h"
#include "internal.h"

// NOTE: implementation should be moved here in another patch, to keep patches
// separated.

/**
 * helper structure describing keyframe search state of one stream
 */
typedef struct {
    int64_t     pos_lo;      ///< position of the frame with low timestamp in file or INT64_MAX if not found (yet)
    int64_t     ts_lo;       ///< frame presentation timestamp or same as pos_lo for byte seeking

    int64_t     pos_hi;      ///< position of the frame with high timestamp in file or INT64_MAX if not found (yet)
    int64_t     ts_hi;       ///< frame presentation timestamp or same as pos_hi for byte seeking

    int64_t     last_pos;    ///< last known position of a frame, for multi-frame packets

    int64_t     term_ts;     ///< termination timestamp (which TS we already read)
    AVRational  term_ts_tb;  ///< timebase for term_ts
    int64_t     first_ts;    ///< first packet timestamp in this iteration (to fill term_ts later)
    AVRational  first_ts_tb; ///< timebase for first_ts

    int         terminated;  ///< termination flag for the current iteration
} AVSyncPoint;

/**
 * Compute a distance between timestamps.
 *
 * Distances are only comparable, if same time bases are used for computing
 * distances.
 *
 * @param ts_hi high timestamp
 * @param tb_hi high timestamp time base
 * @param ts_lo low timestamp
 * @param tb_lo low timestamp time base
 * @return representation of distance between high and low timestamps
 */
static int64_t ts_distance(int64_t ts_hi,
                           AVRational tb_hi,
                           int64_t ts_lo,
                           AVRational tb_lo)
{
    int64_t hi, lo;

    hi = ts_hi * tb_hi.num * tb_lo.den;
    lo = ts_lo * tb_lo.num * tb_hi.den;

    return hi - lo;
}

/**
 * Partial search for keyframes in multiple streams.
 *
 * This routine searches in each stream for the next lower and the next higher
 * timestamp compared to the given target timestamp. The search starts at the current
 * file position and ends at the file position, where all streams have already been
 * examined (or when all higher key frames are found in the first iteration).
 *
 * This routine is called iteratively with an exponential backoff to find the lower
 * timestamp.
 *
 * @param s                 format context
 * @param timestamp         target timestamp (or position, if AVSEEK_FLAG_BYTE)
 * @param timebase          time base for timestamps
 * @param flags             seeking flags
 * @param sync              array with information per stream
 * @param keyframes_to_find count of keyframes to find in total
 * @param found_lo          ptr to the count of already found low timestamp keyframes
 * @param found_hi          ptr to the count of already found high timestamp keyframes
 * @param first_iter        flag for first iteration
 */
static void search_hi_lo_keyframes(AVFormatContext *s,
                                   int64_t timestamp,
                                   AVRational timebase,
                                   int flags,
                                   AVSyncPoint *sync,
                                   int keyframes_to_find,
                                   int *found_lo,
                                   int *found_hi,
                                   int first_iter)
{
    AVPacket pkt;
    AVSyncPoint *sp;
    AVStream *st;
    int idx;
    int flg;
    int terminated_count = 0;
    int64_t pos;
    int64_t pts, dts;   // PTS/DTS from stream
    int64_t ts;         // PTS in stream-local time base or position for byte seeking
    AVRational ts_tb;   // Time base of the stream or 1:1 for byte seeking

    for (;;) {
        if (av_read_frame(s, &pkt) < 0) {
            // EOF or error, make sure high flags are set
            for (idx = 0; idx < s->nb_streams; ++idx) {
                if (s->streams[idx]->discard < AVDISCARD_ALL) {
                    sp = &sync[idx];
                    if (sp->pos_hi == INT64_MAX) {
                        // no high frame exists for this stream
                        (*found_hi)++;
                        sp->ts_hi  = INT64_MAX;
                        sp->pos_hi = INT64_MAX - 1;
                    }
                }
            }
            break;
        }

        idx = pkt.stream_index;
        st = s->streams[idx];
        if (st->discard >= AVDISCARD_ALL)
            // this stream is not active, skip packet
            continue;

        sp = &sync[idx];

        flg = pkt.flags;
        pos = pkt.pos;
        pts = pkt.pts;
        dts = pkt.dts;
        if (pts == AV_NOPTS_VALUE)
            // some formats don't provide PTS, only DTS
            pts = dts;

        av_free_packet(&pkt);

        // Multi-frame packets only return position for the very first frame.
        // Other frames are read with position == -1. Therefore, we note down
        // last known position of a frame and use it if a frame without
        // position arrives. In this way, it's possible to seek to proper
        // position. Additionally, for parsers not providing position at all,
        // an approximation will be used (starting position of this iteration).
        if (pos < 0)
            pos = sp->last_pos;
        else
            sp->last_pos = pos;

        // Evaluate key frames with known TS (or any frames, if AVSEEK_FLAG_ANY set).
        if (pts != AV_NOPTS_VALUE &&
            ((flg & AV_PKT_FLAG_KEY) || (flags & AVSEEK_FLAG_ANY))) {
            if (flags & AVSEEK_FLAG_BYTE) {
                // for byte seeking, use position as timestamp
                ts        = pos;
                ts_tb.num = 1;
                ts_tb.den = 1;
            } else {
                // otherwise, get stream time_base
                ts    = pts;
                ts_tb = st->time_base;
            }

            if (sp->first_ts == AV_NOPTS_VALUE) {
                // Note down termination timestamp for the next iteration - when
                // we encounter a packet with the same timestamp, we will ignore
                // any further packets for this stream in next iteration (as they
                // are already evaluated).
                sp->first_ts    = ts;
                sp->first_ts_tb = ts_tb;
            }

            if (sp->term_ts != AV_NOPTS_VALUE &&
                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;
                    ++terminated_count;
                    if (sp->pos_hi == INT64_MAX) {
                        // no high frame exists for this stream
                        (*found_hi)++;
                        sp->ts_hi  = INT64_MAX;
                        sp->pos_hi = INT64_MAX - 1;
                    }
                    if (terminated_count == keyframes_to_find)
                        break;  // all terminated, iteration done
                }
                continue;
            }

            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
                    (*found_lo)++;
                    sp->ts_lo  = ts;
                    sp->pos_lo = pos;
                } else if (sp->ts_lo < ts) {
                    // found a better match (closer to target timestamp)
                    sp->ts_lo  = ts;
                    sp->pos_lo = pos;
                }
            }
            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
                    (*found_hi)++;
                    sp->ts_hi  = ts;
                    sp->pos_hi = pos;
                    if (*found_hi >= keyframes_to_find && first_iter) {
                        // We found high frame for all. They may get updated
                        // to TS closer to target TS in later iterations (which
                        // will stop at start position of previous iteration).
                        break;
                    }
                } else if (sp->ts_hi > ts) {
                    // found a better match (actually, shouldn't happen)
                    sp->ts_hi  = ts;
                    sp->pos_hi = pos;
                }
            }
        }
    }

    // Clean up the parser.
    ff_read_frame_flush(s);
}

int64_t ff_gen_syncpoint_search(AVFormatContext *s,
                                int stream_index,
                                int64_t pos,
                                int64_t ts_min,
                                int64_t ts,
                                int64_t ts_max,
                                int flags)
{
    AVSyncPoint *sync, *sp;
    AVStream *st;
    int i;
    int keyframes_to_find = 0;
    int64_t curpos;
    int64_t step;
    int found_lo = 0, found_hi = 0;
    int64_t min_distance, distance;
    int64_t min_pos = 0;
    int first_iter = 1;
    AVRational time_base;

    if (flags & AVSEEK_FLAG_BYTE) {
        // for byte seeking, we have exact 1:1 "timestamps" - positions
        time_base.num = 1;
        time_base.den = 1;
    } else {
        if (stream_index >= 0) {
            // we have a reference stream, which time base we use
            st = s->streams[stream_index];
            time_base = st->time_base;
        } else {
            // no reference stream, use AV_TIME_BASE as reference time base
            time_base.num = 1;
            time_base.den = AV_TIME_BASE;
        }
    }

    // Initialize syncpoint structures for each stream.
    sync = av_malloc(s->nb_streams * sizeof(AVSyncPoint));
    if (!sync)
        // cannot allocate helper structure
        return -1;

    for (i = 0; i < s->nb_streams; ++i) {
        st = s->streams[i];
        sp = &sync[i];

        sp->pos_lo     = INT64_MAX;
        sp->ts_lo      = INT64_MAX;
        sp->pos_hi     = INT64_MAX;
        sp->ts_hi      = INT64_MAX;
        sp->terminated = 0;
        sp->first_ts   = AV_NOPTS_VALUE;
        sp->term_ts    = ts_max;
        sp->term_ts_tb = time_base;
        sp->last_pos   = pos;

        st->cur_dts    = AV_NOPTS_VALUE;

        if (st->discard < AVDISCARD_ALL)
            ++keyframes_to_find;
    }

    if (!keyframes_to_find) {
        // no stream active, error
        av_free(sync);
        return -1;
    }

    // Find keyframes in all active streams with timestamp/position just before
    // and just after requested timestamp/position.
    step = s->pb->buffer_size;
    curpos = FFMAX(pos - step / 2, 0);
    for (;;) {
        avio_seek(s->pb, curpos, SEEK_SET);
        search_hi_lo_keyframes(s,
                               ts, time_base,
                               flags,
                               sync,
                               keyframes_to_find,
                               &found_lo, &found_hi,
                               first_iter);
        if (found_lo == keyframes_to_find && found_hi == keyframes_to_find)
            break;  // have all keyframes we wanted
        if (!curpos)
            break;  // cannot go back anymore

        curpos = pos - step;
        if (curpos < 0)
            curpos = 0;
        step *= 2;

        // switch termination positions
        for (i = 0; i < s->nb_streams; ++i) {
            st = s->streams[i];
            st->cur_dts = AV_NOPTS_VALUE;

            sp = &sync[i];
            if (sp->first_ts != AV_NOPTS_VALUE) {
                sp->term_ts    = sp->first_ts;
                sp->term_ts_tb = sp->first_ts_tb;
                sp->first_ts   = AV_NOPTS_VALUE;
            }
            sp->terminated = 0;
            sp->last_pos = curpos;
        }
        first_iter = 0;
    }

    // Find actual position to start decoding so that decoder synchronizes
    // closest to ts and between ts_min and ts_max.
    pos = INT64_MAX;

    for (i = 0; i < s->nb_streams; ++i) {
        st = s->streams[i];
        if (st->discard < AVDISCARD_ALL) {
            sp = &sync[i];
            min_distance = INT64_MAX;
            // Find timestamp closest to requested timestamp within min/max limits.
            if (sp->pos_lo != INT64_MAX
                && 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
                && 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) {
                    min_distance = distance;
                    min_pos = sp->pos_hi;
                }
            }
            if (min_distance == INT64_MAX) {
                // no timestamp is in range, cannot seek
                av_free(sync);
                return -1;
            }
            if (min_pos < pos)
                pos = min_pos;
        }
    }

    avio_seek(s->pb, pos, SEEK_SET);
    av_free(sync);
    return pos;
}

AVParserState *ff_store_parser_state(AVFormatContext *s)
{
    int i;
    AVStream *st;
    AVParserStreamState *ss;
    AVParserState *state = av_malloc(sizeof(AVParserState));
    if (!state)
        return NULL;

    state->stream_states = av_malloc(sizeof(AVParserStreamState) * s->nb_streams);
    if (!state->stream_states) {
        av_free(state);
        return NULL;
    }

    state->fpos = avio_tell(s->pb);

    // copy context structures
    state->cur_st                           = s->cur_st;
    state->packet_buffer                    = s->packet_buffer;
    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->raw_packet_buffer                    = NULL;
    s->raw_packet_buffer_remaining_size     = RAW_PACKET_BUFFER_SIZE;

    // copy stream structures
    state->nb_streams = s->nb_streams;
    for (i = 0; i < s->nb_streams; i++) {
        st = s->streams[i];
        ss = &state->stream_states[i];

        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;
}

void ff_restore_parser_state(AVFormatContext *s, AVParserState *state)
{
    int i;
    AVStream *st;
    AVParserStreamState *ss;
    ff_read_frame_flush(s);

    if (!state)
        return;

    avio_seek(s->pb, state->fpos, SEEK_SET);

    // copy context structures
    s->cur_st                           = state->cur_st;
    s->packet_buffer                    = state->packet_buffer;
    s->raw_packet_buffer                = state->raw_packet_buffer;
    s->raw_packet_buffer_remaining_size = state->raw_packet_buffer_remaining_size;

    // copy stream structures
    for (i = 0; i < state->nb_streams; i++) {
        st = s->streams[i];
        ss = &state->stream_states[i];

        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);
    av_free(state);
}

static void free_packet_list(AVPacketList *pktl)
{
    AVPacketList *cur;
    while (pktl) {
        cur = pktl;
        pktl = cur->next;
        av_free_packet(&cur->pkt);
        av_free(cur);
    }
}

void ff_free_parser_state(AVFormatContext *s, AVParserState *state)
{
    int i;
    AVParserStreamState *ss;

    if (!state)
        return;

    for (i = 0; i < state->nb_streams; i++) {
        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->raw_packet_buffer);

    av_free(state->stream_states);
    av_free(state);
}

