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

📄 ffmpeg.c

📁 ffmpeg源码分析
💻 C
📖 第 1 页 / 共 5 页
字号:
                    enc->coded_frame->quality/(float)FF_QP2LAMBDA);        }        if (!vid && enc->codec_type == CODEC_TYPE_VIDEO) {            frame_number = ost->frame_number;            snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "frame=%5d q=%3.1f ",                    frame_number, enc->coded_frame ? enc->coded_frame->quality/(float)FF_QP2LAMBDA : -1);            if(is_last_report)                snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "L");            if(qp_hist && enc->coded_frame){                int j;                int qp= lrintf(enc->coded_frame->quality/(float)FF_QP2LAMBDA);                if(qp>=0 && qp<sizeof(qp_histogram)/sizeof(int))                    qp_histogram[qp]++;                for(j=0; j<32; j++)                    snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%X", (int)lrintf(log(qp_histogram[j]+1)/log(2)));            }            if (enc->flags&CODEC_FLAG_PSNR){                int j;                double error, error_sum=0;                double scale, scale_sum=0;                char type[3]= {'Y','U','V'};                snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "PSNR=");                for(j=0; j<3; j++){                    if(is_last_report){                        error= enc->error[j];                        scale= enc->width*enc->height*255.0*255.0*frame_number;                    }else{                        error= enc->coded_frame->error[j];                        scale= enc->width*enc->height*255.0*255.0;                    }                    if(j) scale/=4;                    error_sum += error;                    scale_sum += scale;                    snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%c:%2.2f ", type[j], psnr(error/scale));                }                snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "*:%2.2f ", psnr(error_sum/scale_sum));            }            vid = 1;        }        /* compute min output value */        pts = (double)ost->st->pts.val * ost->st->time_base.num / ost->st->time_base.den;        if ((pts < ti1) && (pts > 0))            ti1 = pts;    }    if (ti1 < 0.01)        ti1 = 0.01;    if (verbose || is_last_report) {        bitrate = (double)(total_size * 8) / ti1 / 1000.0;        snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),            "size=%8.0fkB time=%0.1f bitrate=%6.1fkbits/s",            (double)total_size / 1024, ti1, bitrate);        if (verbose > 1)          snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " dup=%d drop=%d",                  nb_frames_dup, nb_frames_drop);        if (verbose >= 0)            fprintf(stderr, "%s    \r", buf);        fflush(stderr);    }    if (is_last_report && verbose >= 0){        int64_t raw= audio_size + video_size + extra_size;        fprintf(stderr, "\n");        fprintf(stderr, "video:%1.0fkB audio:%1.0fkB global headers:%1.0fkB muxing overhead %f%%\n",                video_size/1024.0,                audio_size/1024.0,                extra_size/1024.0,                100.0*(total_size - raw)/raw        );    }}/* pkt = NULL means EOF (needed to flush decoder buffers) */static int output_packet(AVInputStream *ist, int ist_index,                         AVOutputStream **ost_table, int nb_ostreams,                         const AVPacket *pkt){    AVFormatContext *os;    AVOutputStream *ost;    uint8_t *ptr;    int len, ret, i;    uint8_t *data_buf;    int data_size, got_picture;    AVFrame picture;    void *buffer_to_free;    static unsigned int samples_size= 0;    static short *samples= NULL;    AVSubtitle subtitle, *subtitle_to_free;    int got_subtitle;    if(!pkt){        ist->pts= ist->next_pts; // needed for last packet if vsync=0    } else if (pkt->dts != AV_NOPTS_VALUE) { //FIXME seems redundant, as libavformat does this too        ist->next_pts = ist->pts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q);    } else {//        assert(ist->pts == ist->next_pts);    }    if (pkt == NULL) {        /* EOF handling */        ptr = NULL;        len = 0;        goto handle_eof;    }    len = pkt->size;    ptr = pkt->data;    while (len > 0) {    handle_eof:        /* decode the packet if needed */        data_buf = NULL; /* fail safe */        data_size = 0;        subtitle_to_free = NULL;        if (ist->decoding_needed) {            switch(ist->st->codec->codec_type) {            case CODEC_TYPE_AUDIO:{                if(pkt)                    samples= av_fast_realloc(samples, &samples_size, FFMAX(pkt->size, AVCODEC_MAX_AUDIO_FRAME_SIZE));                    /* XXX: could avoid copy if PCM 16 bits with same                       endianness as CPU */                ret = avcodec_decode_audio(ist->st->codec, samples, &data_size,                                           ptr, len);                if (ret < 0)                    goto fail_decode;                ptr += ret;                len -= ret;                /* Some bug in mpeg audio decoder gives */                /* data_size < 0, it seems they are overflows */                if (data_size <= 0) {                    /* no audio frame */                    continue;                }                data_buf = (uint8_t *)samples;                ist->next_pts += ((int64_t)AV_TIME_BASE/2 * data_size) /                    (ist->st->codec->sample_rate * ist->st->codec->channels);                break;}            case CODEC_TYPE_VIDEO:                    data_size = (ist->st->codec->width * ist->st->codec->height * 3) / 2;                    /* XXX: allocate picture correctly */                    avcodec_get_frame_defaults(&picture);                    ret = avcodec_decode_video(ist->st->codec,                                               &picture, &got_picture, ptr, len);                    ist->st->quality= picture.quality;                    if (ret < 0)                        goto fail_decode;                    if (!got_picture) {                        /* no picture yet */                        goto discard_packet;                    }                    if (ist->st->codec->time_base.num != 0) {                        ist->next_pts += ((int64_t)AV_TIME_BASE *                                          ist->st->codec->time_base.num) /                            ist->st->codec->time_base.den;                    }                    len = 0;                    break;            case CODEC_TYPE_SUBTITLE:                ret = avcodec_decode_subtitle(ist->st->codec,                                              &subtitle, &got_subtitle, ptr, len);                if (ret < 0)                    goto fail_decode;                if (!got_subtitle) {                    goto discard_packet;                }                subtitle_to_free = &subtitle;                len = 0;                break;            default:                goto fail_decode;            }        } else {                switch(ist->st->codec->codec_type) {                case CODEC_TYPE_AUDIO:                    ist->next_pts += ((int64_t)AV_TIME_BASE * ist->st->codec->frame_size) /                        (ist->st->codec->sample_rate * ist->st->codec->channels);                    break;                case CODEC_TYPE_VIDEO:                    if (ist->st->codec->time_base.num != 0) {                        ist->next_pts += ((int64_t)AV_TIME_BASE *                                          ist->st->codec->time_base.num) /                            ist->st->codec->time_base.den;                    }                    break;                }                data_buf = ptr;                data_size = len;                ret = len;                len = 0;            }            buffer_to_free = NULL;            if (ist->st->codec->codec_type == CODEC_TYPE_VIDEO) {                pre_process_video_frame(ist, (AVPicture *)&picture,                                        &buffer_to_free);            }            // preprocess audio (volume)            if (ist->st->codec->codec_type == CODEC_TYPE_AUDIO) {                if (audio_volume != 256) {                    short *volp;                    volp = samples;                    for(i=0;i<(data_size / sizeof(short));i++) {                        int v = ((*volp) * audio_volume + 128) >> 8;                        if (v < -32768) v = -32768;                        if (v >  32767) v = 32767;                        *volp++ = v;                    }                }            }            /* frame rate emulation */            if (ist->st->codec->rate_emu) {                int64_t pts = av_rescale((int64_t) ist->frame * ist->st->codec->time_base.num, 1000000, ist->st->codec->time_base.den);                int64_t now = av_gettime() - ist->start;                if (pts > now)                    usleep(pts - now);                ist->frame++;            }#if 0            /* mpeg PTS deordering : if it is a P or I frame, the PTS               is the one of the next displayed one */            /* XXX: add mpeg4 too ? */            if (ist->st->codec->codec_id == CODEC_ID_MPEG1VIDEO) {                if (ist->st->codec->pict_type != B_TYPE) {                    int64_t tmp;                    tmp = ist->last_ip_pts;                    ist->last_ip_pts  = ist->frac_pts.val;                    ist->frac_pts.val = tmp;                }            }#endif            /* if output time reached then transcode raw format,               encode packets and output them */            if (start_time == 0 || ist->pts >= start_time)                for(i=0;i<nb_ostreams;i++) {                    int frame_size;                    ost = ost_table[i];                    if (ost->source_index == ist_index) {                        os = output_files[ost->file_index];#if 0                        printf("%d: got pts=%0.3f %0.3f\n", i,                               (double)pkt->pts / AV_TIME_BASE,                               ((double)ist->pts / AV_TIME_BASE) -                               ((double)ost->st->pts.val * ost->st->time_base.num / ost->st->time_base.den));#endif                        /* set the input output pts pairs */                        //ost->sync_ipts = (double)(ist->pts + input_files_ts_offset[ist->file_index] - start_time)/ AV_TIME_BASE;                        if (ost->encoding_needed) {                            switch(ost->st->codec->codec_type) {                            case CODEC_TYPE_AUDIO:                                do_audio_out(os, ost, ist, data_buf, data_size);                                break;                            case CODEC_TYPE_VIDEO:                                    do_video_out(os, ost, ist, &picture, &frame_size);                                    video_size += frame_size;                                    if (do_vstats && frame_size)                                        do_video_stats(os, ost, frame_size);                                break;                            case CODEC_TYPE_SUBTITLE:                                do_subtitle_out(os, ost, ist, &subtitle,                                                pkt->pts);                                break;                            default:                                av_abort();                            }                        } else {                            AVFrame avframe; //FIXME/XXX remove this                            AVPacket opkt;                            av_init_packet(&opkt);                            /* no reencoding needed : output the packet directly */                            /* force the input stream PTS */                            avcodec_get_frame_defaults(&avframe);                            ost->st->codec->coded_frame= &avframe;                            avframe.key_frame = pkt->flags & PKT_FLAG_KEY;                            if(ost->st->codec->codec_type == CODEC_TYPE_AUDIO)                                audio_size += data_size;                            else if (ost->st->codec->codec_type == CODEC_TYPE_VIDEO) {                                video_size += data_size;                                ost->sync_opts++;                            }                            opkt.stream_index= ost->index;                            if(pkt->pts != AV_NOPTS_VALUE)                                opkt.pts= av_rescale_q(av_rescale_q(pkt->pts, ist->st->time_base, AV_TIME_BASE_Q) + input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q,  ost->st->time_base);                            else                                opkt.pts= AV_NOPTS_VALUE;                            {                                int64_t dts;                                if (pkt->dts == AV_NOPTS_VALUE)                                    dts = ist->next_pts;                                else                                    dts= av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q);                                opkt.dts= av_rescale_q(dts + input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q,  ost->st->time_base);                            }                            opkt.flags= pkt->flags;                            if(av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, data_buf, data_size, pkt->flags & PKT_FLAG_KEY))                                opkt.destruct= av_destruct_packet;                            av_interleaved_write_frame(os, &opkt);                            ost->st->codec->frame_number++;                            ost->frame_number++;                            av_free_packet(&opkt);                        }                    }                }            av_free(buffer_to_free);            /* XXX: allocate the subtitles in the codec ? */            if (subtitle_to_free) {                if (subtitle_to_free->rects != NULL) {                    for (i = 0; i < subtitle_to_free->num_rects; i++) {                        av_free(subtitle_to_free->rects[i].bitmap);                        av_free(subtitle_to_free->rects[i].rgba_palette);                    }                    av_freep(&subtitle_to_free->rects);                }                subtitle_to_free->num_rects = 0;                subtitle_to_free = NULL;            }        } discard_packet:    if (pkt == NULL) {        /* EOF handling */        for(i=0;i<nb_ostreams;i++) {            ost = ost_table[i];            if (ost->source_index == ist_index) {                AVCodecContext *enc= ost->st->codec;                os = output_files[ost->file_index];                if(ost->st->codec->codec_type == CODEC_TYPE_AUDIO && enc->frame_size <=1)                    continue;                if(ost->st->codec->codec_type == CODEC_TYPE_VIDEO && (os->oformat->flags & AVFMT_RAWPICTURE))                    continue;                if (ost->encoding_needed) {                    for(;;) {                        AVPacket pkt;                        av_init_packet(&pkt);                        pkt.stream_index= ost->index;                        switch(ost->st->codec->codec_type) {                        case CODEC_TYPE_AUDIO:                            ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, NULL);                            audio_size += ret;                            pkt.flags |= PKT_FLAG_KEY;

⌨️ 快捷键说明

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