⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 utils.c

📁 ffmpeg移植到symbian的全部源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    st= s->streams[stream_index];    if(st->index_entries){        AVIndexEntry *e;        index= av_index_search_timestamp(st, target_ts, flags | AVSEEK_FLAG_BACKWARD); //FIXME whole func must be checked for non-keyframe entries in index case, especially read_timestamp()        index= FFMAX(index, 0);        e= &st->index_entries[index];        if(e->timestamp <= target_ts || e->pos == e->min_distance){            pos_min= e->pos;            ts_min= e->timestamp;#ifdef DEBUG_SEEK        av_log(s, AV_LOG_DEBUG, "using cached pos_min=0x%"PRIx64" dts_min=%"PRId64"\n",               pos_min,ts_min);#endif        }else{            assert(index==0);        }        index= av_index_search_timestamp(st, target_ts, flags & ~AVSEEK_FLAG_BACKWARD);        assert(index < st->nb_index_entries);        if(index >= 0){            e= &st->index_entries[index];            assert(e->timestamp >= target_ts);            pos_max= e->pos;            ts_max= e->timestamp;            pos_limit= pos_max - e->min_distance;#ifdef DEBUG_SEEK        av_log(s, AV_LOG_DEBUG, "using cached pos_max=0x%"PRIx64" pos_limit=0x%"PRIx64" dts_max=%"PRId64"\n",               pos_max,pos_limit, ts_max);#endif        }    }    pos= av_gen_search(s, stream_index, target_ts, pos_min, pos_max, pos_limit, ts_min, ts_max, flags, &ts, avif->read_timestamp);    if(pos<0)        return -1;    /* do the seek */    url_fseek(s->pb, pos, SEEK_SET);    av_update_cur_dts(s, st, ts);    return 0;}int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, int64_t pos_min, int64_t pos_max, int64_t pos_limit, int64_t ts_min, int64_t ts_max, int flags, int64_t *ts_ret, int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t )){    int64_t pos, ts;    int64_t start_pos, filesize;    int no_change;#ifdef DEBUG_SEEK    av_log(s, AV_LOG_DEBUG, "gen_seek: %d %"PRId64"\n", stream_index, target_ts);#endif    if(ts_min == AV_NOPTS_VALUE){        pos_min = s->data_offset;        ts_min = read_timestamp(s, stream_index, &pos_min, INT64_MAX);        if (ts_min == AV_NOPTS_VALUE)            return -1;    }    if(ts_max == AV_NOPTS_VALUE){        int step= 1024;        filesize = url_fsize(s->pb);        pos_max = filesize - 1;        do{            pos_max -= step;            ts_max = read_timestamp(s, stream_index, &pos_max, pos_max + step);            step += step;        }while(ts_max == AV_NOPTS_VALUE && pos_max >= step);        if (ts_max == AV_NOPTS_VALUE)            return -1;        for(;;){            int64_t tmp_pos= pos_max + 1;            int64_t tmp_ts= read_timestamp(s, stream_index, &tmp_pos, INT64_MAX);            if(tmp_ts == AV_NOPTS_VALUE)                break;            ts_max= tmp_ts;            pos_max= tmp_pos;            if(tmp_pos >= filesize)                break;        }        pos_limit= pos_max;    }    if(ts_min > ts_max){        return -1;    }else if(ts_min == ts_max){        pos_limit= pos_min;    }    no_change=0;    while (pos_min < pos_limit) {#ifdef DEBUG_SEEK        av_log(s, AV_LOG_DEBUG, "pos_min=0x%"PRIx64" pos_max=0x%"PRIx64" dts_min=%"PRId64" dts_max=%"PRId64"\n",               pos_min, pos_max,               ts_min, ts_max);#endif        assert(pos_limit <= pos_max);        if(no_change==0){            int64_t approximate_keyframe_distance= pos_max - pos_limit;            // interpolate position (better than dichotomy)            pos = av_rescale(target_ts - ts_min, pos_max - pos_min, ts_max - ts_min)                + pos_min - approximate_keyframe_distance;        }else if(no_change==1){            // bisection, if interpolation failed to change min or max pos last time            pos = (pos_min + pos_limit)>>1;        }else{            /* linear search if bisection failed, can only happen if there               are very few or no keyframes between min/max */            pos=pos_min;        }        if(pos <= pos_min)            pos= pos_min + 1;        else if(pos > pos_limit)            pos= pos_limit;        start_pos= pos;        ts = read_timestamp(s, stream_index, &pos, INT64_MAX); //may pass pos_limit instead of -1        if(pos == pos_max)            no_change++;        else            no_change=0;#ifdef DEBUG_SEEKav_log(s, AV_LOG_DEBUG, "%"PRId64" %"PRId64" %"PRId64" / %"PRId64" %"PRId64" %"PRId64" target:%"PRId64" limit:%"PRId64" start:%"PRId64" noc:%d\n", pos_min, pos, pos_max, ts_min, ts, ts_max, target_ts, pos_limit, start_pos, no_change);#endif        if(ts == AV_NOPTS_VALUE){            av_log(s, AV_LOG_ERROR, "read_timestamp() failed in the middle\n");            return -1;        }        assert(ts != AV_NOPTS_VALUE);        if (target_ts <= ts) {            pos_limit = start_pos - 1;            pos_max = pos;            ts_max = ts;        }        if (target_ts >= ts) {            pos_min = pos;            ts_min = ts;        }    }    pos = (flags & AVSEEK_FLAG_BACKWARD) ? pos_min : pos_max;    ts  = (flags & AVSEEK_FLAG_BACKWARD) ?  ts_min :  ts_max;#ifdef DEBUG_SEEK    pos_min = pos;    ts_min = read_timestamp(s, stream_index, &pos_min, INT64_MAX);    pos_min++;    ts_max = read_timestamp(s, stream_index, &pos_min, INT64_MAX);    av_log(s, AV_LOG_DEBUG, "pos=0x%"PRIx64" %"PRId64"<=%"PRId64"<=%"PRId64"\n",           pos, ts_min, target_ts, ts_max);#endif    *ts_ret= ts;    return pos;}static int av_seek_frame_byte(AVFormatContext *s, int stream_index, int64_t pos, int flags){    int64_t pos_min, pos_max;#if 0    AVStream *st;    if (stream_index < 0)        return -1;    st= s->streams[stream_index];#endif    pos_min = s->data_offset;    pos_max = url_fsize(s->pb) - 1;    if     (pos < pos_min) pos= pos_min;    else if(pos > pos_max) pos= pos_max;    url_fseek(s->pb, pos, SEEK_SET);#if 0    av_update_cur_dts(s, st, ts);#endif    return 0;}static int av_seek_frame_generic(AVFormatContext *s,                                 int stream_index, int64_t timestamp, int flags){    int index;    AVStream *st;    AVIndexEntry *ie;    st = s->streams[stream_index];    index = av_index_search_timestamp(st, timestamp, flags);    if(index < 0 || index==st->nb_index_entries-1){        int i;        AVPacket pkt;        if(st->nb_index_entries){            assert(st->index_entries);            ie= &st->index_entries[st->nb_index_entries-1];            url_fseek(s->pb, ie->pos, SEEK_SET);            av_update_cur_dts(s, st, ie->timestamp);        }else            url_fseek(s->pb, 0, SEEK_SET);        for(i=0;; i++) {            int ret = av_read_frame(s, &pkt);            if(ret<0)                break;            av_free_packet(&pkt);            if(stream_index == pkt.stream_index){                if((pkt.flags & PKT_FLAG_KEY) && pkt.dts > timestamp)                    break;            }        }        index = av_index_search_timestamp(st, timestamp, flags);    }    if (index < 0)        return -1;    av_read_frame_flush(s);    if (s->iformat->read_seek){        if(s->iformat->read_seek(s, stream_index, timestamp, flags) >= 0)            return 0;    }    ie = &st->index_entries[index];    url_fseek(s->pb, ie->pos, SEEK_SET);    av_update_cur_dts(s, st, ie->timestamp);    return 0;}int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int flags){    int ret;    AVStream *st;    av_read_frame_flush(s);    if(flags & AVSEEK_FLAG_BYTE)        return av_seek_frame_byte(s, stream_index, timestamp, flags);    if(stream_index < 0){        stream_index= av_find_default_stream_index(s);        if(stream_index < 0)            return -1;        st= s->streams[stream_index];       /* timestamp for default must be expressed in AV_TIME_BASE units */        timestamp = av_rescale(timestamp, st->time_base.den, AV_TIME_BASE * (int64_t)st->time_base.num);    }    st= s->streams[stream_index];    /* first, we try the format specific seek */    if (s->iformat->read_seek)        ret = s->iformat->read_seek(s, stream_index, timestamp, flags);    else        ret = -1;    if (ret >= 0) {        return 0;    }    if(s->iformat->read_timestamp)        return av_seek_frame_binary(s, stream_index, timestamp, flags);    else        return av_seek_frame_generic(s, stream_index, timestamp, flags);}/*******************************************************//** * Returns TRUE if the stream has accurate duration in any stream. * * @return TRUE if the stream has accurate duration for at least one component. */static int av_has_duration(AVFormatContext *ic){    int i;    AVStream *st;    for(i = 0;i < ic->nb_streams; i++) {        st = ic->streams[i];        if (st->duration != AV_NOPTS_VALUE)            return 1;    }    return 0;}/** * Estimate the stream timings from the one of each components. * * Also computes the global bitrate if possible. */static void av_update_stream_timings(AVFormatContext *ic){    int64_t start_time, start_time1, end_time, end_time1;    int64_t duration, duration1;    int i;    AVStream *st;    start_time = INT64_MAX;    end_time = INT64_MIN;    duration = INT64_MIN;    for(i = 0;i < ic->nb_streams; i++) {        st = ic->streams[i];        if (st->start_time != AV_NOPTS_VALUE && st->time_base.den) {            start_time1= av_rescale_q(st->start_time, st->time_base, AV_TIME_BASE_Q);            if (start_time1 < start_time)                start_time = start_time1;            if (st->duration != AV_NOPTS_VALUE) {                end_time1 = start_time1                          + av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q);                if (end_time1 > end_time)                    end_time = end_time1;            }        }        if (st->duration != AV_NOPTS_VALUE) {            duration1 = av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q);            if (duration1 > duration)                duration = duration1;        }    }    if (start_time != INT64_MAX) {        ic->start_time = start_time;        if (end_time != INT64_MIN) {            if (end_time - start_time > duration)                duration = end_time - start_time;        }    }    if (duration != INT64_MIN) {        ic->duration = duration;        if (ic->file_size > 0) {            /* compute the bitrate */            ic->bit_rate = (double)ic->file_size * 8.0 * AV_TIME_BASE /                (double)ic->duration;        }    }}static void fill_all_stream_timings(AVFormatContext *ic){    int i;    AVStream *st;    av_update_stream_timings(ic);    for(i = 0;i < ic->nb_streams; i++) {        st = ic->streams[i];        if (st->start_time == AV_NOPTS_VALUE) {            if(ic->start_time != AV_NOPTS_VALUE)                st->start_time = av_rescale_q(ic->start_time, AV_TIME_BASE_Q, st->time_base);            if(ic->duration != AV_NOPTS_VALUE)                st->duration = av_rescale_q(ic->duration, AV_TIME_BASE_Q, st->time_base);        }    }}static void av_estimate_timings_from_bit_rate(AVFormatContext *ic){    int64_t filesize, duration;    int bit_rate, i;    AVStream *st;    /* if bit_rate is already set, we believe it */    if (ic->bit_rate == 0) {        bit_rate = 0;        for(i=0;i<ic->nb_streams;i++) {            st = ic->streams[i];            bit_rate += st->codec->bit_rate;        }        ic->bit_rate = bit_rate;    }    /* if duration is already set, we believe it */    if (ic->duration == AV_NOPTS_VALUE &&        ic->bit_rate != 0 &&        ic->file_size != 0)  {        filesize = ic->file_size;        if (filesize > 0) {            for(i = 0; i < ic->nb_streams; i++) {                st = ic->streams[i];                duration= av_rescale(8*filesize, st->time_base.den, ic->bit_rate*(int64_t)st->time_base.num);                if (st->duration == AV_NOPTS_VALUE)                    st->duration = duration;            }        }    }}#define DURATION_MAX_READ_SIZE 250000/* only usable for MPEG-PS streams */static void av_estimate_timings_from_pts(AVFormatContext *ic, offset_t old_offset){    AVPacket pkt1, *pkt = &pkt1;    AVStream *st;    int read_size, i, ret;    int64_t end_time;    int64_t filesize, offset, duration;    /* free previous packet */    if (ic->cur_st && ic->cur_st->parser)        av_free_packet(&ic->cur_pkt);    ic->cur_st = NULL;    /* flush packet queue */    flush_packet_queue(ic);    for(i=0;i<ic->nb_streams;i++) {        st = ic->streams[i];        if (st->parser) {            av_parser_close(st->parser);            st->parser= NULL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -