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

📄 utils.c

📁 ffmpeg移植到symbian的全部源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        }    }    /* 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;        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 &&            st->start_time != 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, old_offset, SEEK_SET);    for(i=0; i<ic->nb_streams; i++){        st= ic->streams[i];        st->cur_dts= st->first_dts;        st->last_IP_pts = AV_NOPTS_VALUE;    }}static void av_estimate_timings(AVFormatContext *ic, offset_t old_offset){    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 ((!strcmp(ic->iformat->name, "mpeg") ||         !strcmp(ic->iformat->name, "mpegts")) &&        file_size && !url_is_streamed(ic->pb)) {        /* get accurate estimate from the PTSes */        av_estimate_timings_from_pts(ic, old_offset);    } else if (av_has_duration(ic)) {        /* at least one component has timings - we use them for all           the components */        fill_all_stream_timings(ic);    } else {        /* less precise: use bitrate 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 && enc->channels;        if(!enc->frame_size &&           (enc->codec_id == CODEC_ID_VORBIS ||            enc->codec_id == CODEC_ID_AAC))            return 0;        break;    case CODEC_TYPE_VIDEO:        val = enc->width && enc->pix_fmt != PIX_FMT_NONE;        break;    default:        val = 1;        break;    }    return enc->codec_id != CODEC_ID_NONE && val != 0;}static int try_decode_frame(AVStream *st, const uint8_t *data, int size){    int16_t *samples;    AVCodec *codec;    int got_picture, data_size, 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, data, size);        break;    case CODEC_TYPE_AUDIO:        data_size = FFMAX(size, AVCODEC_MAX_AUDIO_FRAME_SIZE);        samples = av_malloc(data_size);        if (!samples)            goto fail;        ret = avcodec_decode_audio2(st->codec, samples,                                    &data_size, data, size);        av_free(samples);        break;    default:        break;    }  } fail:    return ret;}unsigned int codec_get_tag(const AVCodecTag *tags, int id){    while (tags->id != CODEC_ID_NONE) {        if (tags->id == id)            return tags->tag;        tags++;    }    return 0;}enum CodecID codec_get_id(const AVCodecTag *tags, unsigned int tag){    int i;    for(i=0; tags[i].id != CODEC_ID_NONE;i++) {        if(tag == tags[i].tag)            return tags[i].id;    }    for(i=0; tags[i].id != CODEC_ID_NONE; i++) {        if(   toupper((tag >> 0)&0xFF) == toupper((tags[i].tag >> 0)&0xFF)           && toupper((tag >> 8)&0xFF) == toupper((tags[i].tag >> 8)&0xFF)           && toupper((tag >>16)&0xFF) == toupper((tags[i].tag >>16)&0xFF)           && toupper((tag >>24)&0xFF) == toupper((tags[i].tag >>24)&0xFF))            return tags[i].id;    }    return CODEC_ID_NONE;}unsigned int av_codec_get_tag(const AVCodecTag *tags[4], enum CodecID id){    int i;    for(i=0; tags && tags[i]; i++){        int tag= codec_get_tag(tags[i], id);        if(tag) return tag;    }    return 0;}enum CodecID av_codec_get_id(const AVCodecTag *tags[4], unsigned int tag){    int i;    for(i=0; tags && tags[i]; i++){        enum CodecID id= codec_get_id(tags[i], tag);        if(id!=CODEC_ID_NONE) return id;    }    return CODEC_ID_NONE;}static void compute_chapters_end(AVFormatContext *s){    unsigned int i;    for (i=0; i+1<s->nb_chapters; i++)        if (s->chapters[i]->end == AV_NOPTS_VALUE) {            assert(s->chapters[i]->start <= s->chapters[i+1]->start);            assert(!av_cmp_q(s->chapters[i]->time_base, s->chapters[i+1]->time_base));            s->chapters[i]->end = s->chapters[i+1]->start;        }    if (s->nb_chapters && s->chapters[i]->end == AV_NOPTS_VALUE) {        assert(s->start_time != AV_NOPTS_VALUE);        assert(s->duration > 0);        s->chapters[i]->end = av_rescale_q(s->start_time + s->duration,                                           AV_TIME_BASE_Q,                                           s->chapters[i]->time_base);    }}/* absolute maximum size we read until we abort */#define MAX_READ_SIZE        5000000#define MAX_STD_TIMEBASES (60*12+5)static int get_std_framerate(int i){#ifndef __CW32__    if(i<60*12) return i*1001;    else        return ((int[]){24,30,60,12,15})[i-60*12]*1000*12;#else	const int t[] = {24,30,60,12,15};    if(i<60*12) return i*1001;    else        return t[i-60*12]*1000*12;#endif}/* * Is the time base unreliable. * This is a heuristic to balance between quick acceptance of the values in * the headers vs. some extra checks. * Old DivX and Xvid often have nonsense timebases like 1fps or 2fps. * MPEG-2 commonly misuses field repeat flags to store different framerates. * And there are "variable" fps files this needs to detect as well. */static int tb_unreliable(AVCodecContext *c){    if(   c->time_base.den >= 101L*c->time_base.num       || c->time_base.den <    5L*c->time_base.num/*       || c->codec_tag == ff_get_fourcc("DIVX")       || c->codec_tag == ff_get_fourcc("XVID")*/       || c->codec_id == CODEC_ID_MPEG2VIDEO)        return 1;    return 0;}int av_find_stream_info(AVFormatContext *ic){    int i, count, ret, read_size, j;    AVStream *st;    AVPacket pkt1, *pkt;    int64_t last_dts[MAX_STREAMS];    int duration_count[MAX_STREAMS]={0};    double (*duration_error)[MAX_STD_TIMEBASES];    offset_t old_offset = url_ftell(ic->pb);    int64_t codec_info_duration[MAX_STREAMS]={0};    int codec_info_nb_frames[MAX_STREAMS]={0};    duration_error = av_mallocz(MAX_STREAMS * sizeof(*duration_error));    if (!duration_error) return AVERROR(ENOMEM);    for(i=0;i<ic->nb_streams;i++) {        st = ic->streams[i];        if(st->codec->codec_type == CODEC_TYPE_VIDEO){/*            if(!st->time_base.num)                st->time_base= */            if(!st->codec->time_base.num)                st->codec->time_base= st->time_base;        }        //only for the split stuff        if (!st->parser) {            st->parser = av_parser_init(st->codec->codec_id);            if(st->need_parsing == AVSTREAM_PARSE_HEADERS && st->parser){                st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;            }        }    }    for(i=0;i<MAX_STREAMS;i++){        last_dts[i]= AV_NOPTS_VALUE;    }    count = 0;    read_size = 0;    for(;;) {        /* check if one codec still needs to be handled */        for(i=0;i<ic->nb_streams;i++) {            st = ic->streams[i];            if (!has_codec_parameters(st->codec))                break;            /* variable fps and no guess at the real fps */            if(   tb_unreliable(st->codec)               && duration_count[i]<20 && st->codec->codec_type == CODEC_TYPE_VIDEO)                break;            if(st->parser && st->parser->parser->split && !st->codec->extradata)                break;            if(st->first_dts == AV_NOPTS_VALUE)                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)) {                /* if we found the info for all the codecs, we can stop */                ret = count;                break;            }        }        /* we did not get all the codec info, but we read too much data */        if (read_size >= MAX_READ_SIZE) {            ret = count;            break;        }        /* NOTE: a new stream can be added there if no header in file           (AVFMTCTX_NOHEADER) */        ret = av_read_frame_internal(ic, &pkt1);        if (ret < 0) {            /* EOF or error */            ret = -1; /* we could not have all the codec parameters before EOF */            for(i=0;i<ic->nb_streams;i++) {                st = ic->streams[i];                if (!has_codec_parameters(st->codec)){                    char buf[256];                    avcodec_string(buf, sizeof(buf), st->codec, 0);                    av_log(ic, AV_LOG_INFO, "Could not find codec parameters (%s)\n", buf);                } else {                    ret = 0;                }            }            break;        }        pkt= add_to_pktbuf(&ic->packet_buffer, &pkt1);        if(av_dup_packet(pkt) < 0)            return AVERROR(ENOMEM);        read_size += pkt->size;        st = ic->streams[pkt->stream_index];        if(codec_info_nb_frames[st->index]>1)            codec_info_duration[st->index] += pkt->duration;        if (pkt->duration != 0)            codec_info_nb_frames[st->index]++;        {            int index= pkt->stream_index;            int64_t last= last_dts[index];            int64_t duration= pkt->dts - last;            if(pkt->dts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && duration>0){                double dur= duration * av_q2d(st->time_base);//                if(st->codec->codec_type == CODEC_TYPE_VIDEO)//                    av_log(NULL, AV_LOG_ERROR, "%f\n", dur);                if(duration_count[index] < 2)                    memset(duration_error[index], 0, sizeof(*duration_error));                for(i=1; i<MAX_STD_TIMEBASES; i++){                    int framerate= get_std_framerate(i);                    int ticks= lrintf(dur*framerate/(1001*12));                    double error= dur - ticks*1001*12/(double)framerate;                    duration_error[index][i] += error*error;                }                duration_count[index]++;            }            if(last == AV_NOPTS_VALUE || duration_count[index]<=1)                last_dts[pkt->stream_index]= pkt->dts;        }        if(st->parser && st->parser->parser->split && !st->codec->extradata){            int i= st->parser->parser->split(st->codec, pkt->data, pkt->size);            if(i){                st->codec->extradata_size= i;                st->codec->extradata= av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);                memcpy(st->codec->extradata, pkt->data, st->codec->extradata_size);                memset(st->codec->extradata + i, 0, FF_INPUT_BUFFER_PADDING_SIZE);            }        }        /* if still no information, we try to open the codec and to           decompress the frame. We try to avoid that in most case

⌨️ 快捷键说明

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