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

📄 utils.c

📁 mpeg4 video codec mpeg4 video codec
💻 C
📖 第 1 页 / 共 5 页
字号:
        ts = avif->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        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 = avif->read_timestamp(s, stream_index, &pos_min, INT64_MAX);    pos_min++;    ts_max = avif->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    /* do the seek */    url_fseek(&s->pb, pos, SEEK_SET);    av_update_cur_dts(s, st, ts);    return 0;}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;    if (!s->index_built) {        if (is_raw_stream(s)) {            av_build_index_raw(s);        } else {            return -1;        }        s->index_built = 1;    }    st = s->streams[stream_index];    index = av_index_search_timestamp(st, timestamp, flags);    if (index < 0)        return -1;    /* now we have found the index, we can seek */    ie = &st->index_entries[index];    av_read_frame_flush(s);    url_fseek(&s->pb, ie->pos, SEEK_SET);    av_update_cur_dts(s, st, ie->timestamp);    return 0;}/** * Seek to the key frame at timestamp. * 'timestamp' in 'stream_index'. * @param stream_index If stream_index is (-1), a default * stream is selected, and timestamp is automatically converted  * from AV_TIME_BASE units to the stream specific time_base. * @param timestamp timestamp in AVStream.time_base units *        or if there is no stream specified then in AV_TIME_BASE units * @param flags flags which select direction and seeking mode * @return >= 0 on success */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 timings in any stream. * * @return TRUE if the stream has accurate timings for at least one component. */static int av_has_timings(AVFormatContext *ic){    int i;    AVStream *st;    for(i = 0;i < ic->nb_streams; i++) {        st = ic->streams[i];        if (st->start_time != AV_NOPTS_VALUE &&            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;    int i;    AVStream *st;    start_time = MAXINT64;    end_time = MININT64;    for(i = 0;i < ic->nb_streams; i++) {        st = ic->streams[i];        if (st->start_time != AV_NOPTS_VALUE) {            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 (start_time != MAXINT64) {        ic->start_time = start_time;        if (end_time != MININT64) {            ic->duration = end_time - start_time;            if (ic->file_size > 0) {                /* compute the bit rate */                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->start_time == AV_NOPTS_VALUE ||                    st->duration == AV_NOPTS_VALUE) {                    st->start_time = 0;                    st->duration = duration;                }            }        }    }}#define DURATION_MAX_READ_SIZE 250000/* only usable for MPEG-PS streams */static void av_estimate_timings_from_pts(AVFormatContext *ic){    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;        }    }        /* we read the first packets to get the first PTS (not fully       accurate, but it is enough now) */    url_fseek(&ic->pb, 0, SEEK_SET);    read_size = 0;    for(;;) {        if (read_size >= DURATION_MAX_READ_SIZE)            break;        /* if all info is available, we can stop */        for(i = 0;i < ic->nb_streams; i++) {            st = ic->streams[i];            if (st->start_time == AV_NOPTS_VALUE)                break;        }        if (i == ic->nb_streams)            break;        ret = av_read_packet(ic, pkt);        if (ret != 0)            break;        read_size += pkt->size;        st = ic->streams[pkt->stream_index];        if (pkt->pts != AV_NOPTS_VALUE) {            if (st->start_time == AV_NOPTS_VALUE)                st->start_time = pkt->pts;        }        av_free_packet(pkt);    }    /* estimate the end time (duration) */    /* XXX: may need to support wrapping */    filesize = ic->file_size;    offset = filesize - DURATION_MAX_READ_SIZE;    if (offset < 0)        offset = 0;    url_fseek(&ic->pb, offset, SEEK_SET);    read_size = 0;    for(;;) {        if (read_size >= DURATION_MAX_READ_SIZE)            break;        /* if all info is available, we can stop */        for(i = 0;i < ic->nb_streams; i++) {            st = ic->streams[i];            if (st->duration == AV_NOPTS_VALUE)                break;        }        if (i == ic->nb_streams)            break;                ret = av_read_packet(ic, pkt);        if (ret != 0)            break;        read_size += pkt->size;        st = ic->streams[pkt->stream_index];        if (pkt->pts != AV_NOPTS_VALUE) {            end_time = pkt->pts;            duration = end_time - st->start_time;            if (duration > 0) {                if (st->duration == AV_NOPTS_VALUE ||                    st->duration < duration)                    st->duration = duration;            }        }        av_free_packet(pkt);    }        fill_all_stream_timings(ic);    url_fseek(&ic->pb, 0, SEEK_SET);}static void av_estimate_timings(AVFormatContext *ic){    int64_t file_size;    /* get the file size, if possible */    if (ic->iformat->flags & AVFMT_NOFILE) {        file_size = 0;    } else {        file_size = url_fsize(&ic->pb);        if (file_size < 0)            file_size = 0;    }    ic->file_size = file_size;    if ((ic->iformat == &mpegps_demux || ic->iformat == &mpegts_demux) && file_size && !ic->pb.is_streamed) {        /* get accurate estimate from the PTSes */        av_estimate_timings_from_pts(ic);    } else if (av_has_timings(ic)) {        /* at least one components has timings - we use them for all           the components */        fill_all_stream_timings(ic);    } else {        /* less precise: use bit rate info */        av_estimate_timings_from_bit_rate(ic);    }    av_update_stream_timings(ic);#if 0    {        int i;        AVStream *st;        for(i = 0;i < ic->nb_streams; i++) {            st = ic->streams[i];        printf("%d: start_time: %0.3f duration: %0.3f\n",                i, (double)st->start_time / AV_TIME_BASE,                (double)st->duration / AV_TIME_BASE);        }        printf("stream: start_time: %0.3f duration: %0.3f bitrate=%d kb/s\n",                (double)ic->start_time / AV_TIME_BASE,                (double)ic->duration / AV_TIME_BASE,               ic->bit_rate / 1000);    }#endif}static int has_codec_parameters(AVCodecContext *enc){    int val;    switch(enc->codec_type) {    case CODEC_TYPE_AUDIO:        val = enc->sample_rate;        break;    case CODEC_TYPE_VIDEO:        val = enc->width && enc->pix_fmt != PIX_FMT_NONE;        break;    default:        val = 1;        break;    }    return (val != 0);}static int try_decode_frame(AVStream *st, const uint8_t *data, int size){    int16_t *samples;    AVCodec *codec;    int got_picture, ret=0;    AVFrame picture;      if(!st->codec->codec){    codec = avcodec_find_decoder(st->codec->codec_id);    if (!codec)        return -1;    ret = avcodec_open(st->codec, codec);    if (ret < 0)        return ret;  }  if(!has_codec_parameters(st->codec)){    switch(st->codec->codec_type) {    case CODEC_TYPE_VIDEO:        ret = avcodec_decode_video(st->codec, &picture,                                    &got_picture, (uint8_t *)data, size);        break;    case CODEC_TYPE_AUDIO:        samples = av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);        if (!samples)            goto fail;        ret = avcodec_decode_audio(st->codec, samples,                                    &got_picture, (uint8_t *)data, size);        av_free(samples);        break;    default:        break;

⌨️ 快捷键说明

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