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

📄 utils.c

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.10平台上编译为嵌入式图形界面操作系统。
💻 C
📖 第 1 页 / 共 4 页
字号:
    if (pktl) {        /* read packet from packet buffer, if there is data */        *pkt = pktl->pkt;        s->packet_buffer = pktl->next;        av_free(pktl);        return 0;    } else {        return s->iformat->read_packet(s, pkt);    }}/*******************************************************//* 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   compute the global bitrate if possible */static void av_update_stream_timings(AVFormatContext *ic){    int64_t start_time, 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) {            if (st->start_time < start_time)                start_time = st->start_time;            if (st->duration != AV_NOPTS_VALUE) {                end_time1 = st->start_time + st->duration;                if (end_time1 > end_time)                    end_time = end_time1;            }        }    }    if (start_time != MAXINT64) {        ic->start_time = start_time;        if (end_time != MAXINT64) {            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) {            st->start_time = ic->start_time;            st->duration = ic->duration;        }    }}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) {            duration = (int64_t)((8 * AV_TIME_BASE * (double)filesize) / (double)ic->bit_rate);            for(i = 0; i < ic->nb_streams; i++) {                st = ic->streams[i];                if (st->start_time == AV_NOPTS_VALUE ||                    st->duration == AV_NOPTS_VALUE) {                    st->start_time = 0;                    st->duration = duration;                }            }        }    }}static void flush_packet_queue(AVFormatContext *s){    AVPacketList *pktl;    for(;;) {        pktl = s->packet_buffer;        if (!pktl)             break;        s->packet_buffer = pktl->next;        av_free_packet(&pktl->pkt);        av_free(pktl);    }}#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 start_time, end_time, end_time1;    int64_t filesize, offset, duration;        /* 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 = (int64_t)((double)pkt->pts * ic->pts_num * (double)AV_TIME_BASE / ic->pts_den);        }        av_free_packet(pkt);    }    /* we compute the minimum start_time and use it as default */    start_time = MAXINT64;    for(i = 0; i < ic->nb_streams; i++) {        st = ic->streams[i];        if (st->start_time != AV_NOPTS_VALUE &&            st->start_time < start_time)            start_time = st->start_time;    }    if (start_time != MAXINT64)        ic->start_time = start_time;        /* 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;    /* flush packet queue */    flush_packet_queue(ic);    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 = (int64_t)((double)pkt->pts * ic->pts_num * (double)AV_TIME_BASE / ic->pts_den);            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);    }        /* estimate total duration */    end_time = MININT64;    for(i = 0;i < ic->nb_streams; i++) {        st = ic->streams[i];        if (st->duration != AV_NOPTS_VALUE) {            end_time1 = st->start_time + st->duration;            if (end_time1 > end_time)                end_time = end_time1;        }    }        /* update start_time (new stream may have been created, so we do       it at the end */    if (ic->start_time != AV_NOPTS_VALUE) {        for(i = 0; i < ic->nb_streams; i++) {            st = ic->streams[i];            if (st->start_time == AV_NOPTS_VALUE)                st->start_time = ic->start_time;        }    }    if (end_time != MININT64) {        /* put dummy values for duration if needed */        for(i = 0;i < ic->nb_streams; i++) {            st = ic->streams[i];            if (st->duration == AV_NOPTS_VALUE &&                 st->start_time != AV_NOPTS_VALUE)                st->duration = end_time - st->start_time;        }        ic->duration = end_time - ic->start_time;    }    url_fseek(&ic->pb, 0, SEEK_SET);}static void av_estimate_timings(AVFormatContext *ic){    URLContext *h;    int64_t file_size;    /* get the file size, if possible */    if (ic->iformat->flags & AVFMT_NOFILE) {        file_size = 0;    } else {        h = url_fileno(&ic->pb);        file_size = url_filesize(h);        if (file_size < 0)            file_size = 0;    }    ic->file_size = file_size;    if (ic->iformat == &mpegps_demux) {        /* 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}/* state for codec information */#define CSTATE_NOTFOUND    0#define CSTATE_DECODING    1#define CSTATE_FOUND       2static 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;        break;    default:        val = 1;        break;    }    return (val != 0);}/** * Read the beginning of a media file to get stream information. This * is useful for file formats with no headers such as MPEG. This * function also compute the real frame rate in case of mpeg2 repeat * frame mode. * * @param ic media file handle * @return >=0 if OK. AVERROR_xxx if error.   */int av_find_stream_info(AVFormatContext *ic){    int i, count, ret, got_picture, size, read_size;    AVCodec *codec;    AVStream *st;    AVPacket *pkt;    AVFrame picture;    AVPacketList *pktl=NULL, **ppktl;    short samples[AVCODEC_MAX_AUDIO_FRAME_SIZE / 2];    uint8_t *ptr;    int min_read_size, max_read_size;    /* typical mpeg ts rate is 40 Mbits. DVD rate is about 10       Mbits. We read at most 0.2 second of file to find all streams */    /* XXX: base it on stream bitrate when possible */    if (ic->iformat == &mpegts_demux) {        /* maximum number of bytes we accept to read to find all the streams           in a file */        min_read_size = 6000000;    } else {        min_read_size = 250000;    }    /* max read size is 2 seconds of video max */    max_read_size = min_read_size * 10;    /* set initial codec state */    for(i=0;i<ic->nb_streams;i++) {        st = ic->streams[i];        if (has_codec_parameters(&st->codec))            st->codec_info_state = CSTATE_FOUND;        else            st->codec_info_state = CSTATE_NOTFOUND;        st->codec_info_nb_repeat_frames = 0;        st->codec_info_nb_real_frames = 0;    }    count = 0;    read_size = 0;    ppktl = &ic->packet_buffer;    for(;;) {        /* check if one codec still needs to be handled */        for(i=0;i<ic->nb_streams;i++) {            st = ic->streams[i];            if (st->codec_info_state != CSTATE_FOUND)                break;        }        if (i == ic->nb_streams) {            /* NOTE: if the format has no header, then we need to read               some packets to get most of the streams, so we cannot               stop here */            if (!(ic->ctx_flags & AVFMTCTX_NOHEADER) ||                read_size >= min_read_size) {                /* if we found the info for all the codecs, we can stop */                ret = count;                break;            }        } else {            /* we did not get all the codec info, but we read too much data */            if (read_size >= max_read_size) {                ret = count;                break;            }        }        pktl = av_mallocz(sizeof(AVPacketList));        if (!pktl) {            ret = AVERROR_NOMEM;            break;        }        /* add the packet in the buffered packet list */        *ppktl = pktl;        ppktl = &pktl->next;        /* NOTE: a new stream can be added there if no header in file           (AVFMTCTX_NOHEADER) */        pkt = &pktl->pkt;        if (ic->iformat->read_packet(ic, pkt) < 0) {            /* EOF or error */            ret = -1; /* we could not have all the codec parameters before EOF */            if ((ic->ctx_flags & AVFMTCTX_NOHEADER) &&                i == ic->nb_streams)                ret = 0;            break;        }        read_size += pkt->size;        /* open new codecs */        for(i=0;i<ic->nb_streams;i++) {            st = ic->streams[i];            if (st->codec_info_state == CSTATE_NOTFOUND) {                /* set to found in case of error */                st->codec_info_state = CSTATE_FOUND;                 codec = avcodec_find_decoder(st->codec.codec_id);                if (codec) {                    if(codec->capabilities & CODEC_CAP_TRUNCATED)                        st->codec.flags |= CODEC_FLAG_TRUNCATED;                    ret = avcodec_open(&st->codec, codec);                    if (ret >= 0)                        st->codec_info_state = CSTATE_DECODING;                }            }        }        st = ic->streams[pkt->stream_index];

⌨️ 快捷键说明

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