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

📄 ffmpeg.c

📁 F:图像处理资料264264书籍ffmpeg-0.4.9-pre1VideoStream.rar 一个视频解压缩源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
{    return q_pressed || (q_pressed = read_key() == 'q');}#elsestatic volatile int received_sigterm = 0;/* no interactive support */static void term_exit(void){}static void term_init(void){}static int read_key(void){    return 0;}#endifstatic int read_ffserver_streams(AVFormatContext *s, const char *filename){    int i, err;    AVFormatContext *ic;    err = av_open_input_file(&ic, filename, NULL, FFM_PACKET_SIZE, NULL);    if (err < 0)        return err;    /* copy stream format */    s->nb_streams = ic->nb_streams;    for(i=0;i<ic->nb_streams;i++) {        AVStream *st;        st = av_mallocz(sizeof(AVStream));        memcpy(st, ic->streams[i], sizeof(AVStream));        s->streams[i] = st;    }    av_close_input_file(ic);    return 0;}#define MAX_AUDIO_PACKET_SIZE (128 * 1024)static void do_audio_out(AVFormatContext *s,                          AVOutputStream *ost,                          AVInputStream *ist,                         unsigned char *buf, int size){    uint8_t *buftmp;    static uint8_t *audio_buf = NULL;    static uint8_t *audio_out = NULL;    const int audio_out_size= 4*MAX_AUDIO_PACKET_SIZE;    int size_out, frame_bytes, ret;    AVCodecContext *enc= &ost->st->codec;    /* SC: dynamic allocation of buffers */    if (!audio_buf)        audio_buf = av_malloc(2*MAX_AUDIO_PACKET_SIZE);    if (!audio_out)        audio_out = av_malloc(audio_out_size);    if (!audio_buf || !audio_out)        return;               /* Should signal an error ! */    if(audio_sync_method){        double delta = ost->sync_ipts * enc->sample_rate - ost->sync_opts                 - fifo_size(&ost->fifo, ost->fifo.rptr)/(ost->st->codec.channels * 2);        double idelta= delta*ist->st->codec.sample_rate / enc->sample_rate;        int byte_delta= ((int)idelta)*2*ist->st->codec.channels;        //FIXME resample delay        if(fabs(delta) > 50){            if(ist->is_start){                if(byte_delta < 0){                    byte_delta= FFMAX(byte_delta, -size);                    size += byte_delta;                    buf  -= byte_delta;                    if(verbose > 2)                        fprintf(stderr, "discarding %d audio samples\n", (int)-delta);                    if(!size)                        return;                    ist->is_start=0;                }else{                    static uint8_t *input_tmp= NULL;                    input_tmp= av_realloc(input_tmp, byte_delta + size);                    if(byte_delta + size <= MAX_AUDIO_PACKET_SIZE)                        ist->is_start=0;                    else                        byte_delta= MAX_AUDIO_PACKET_SIZE - size;                    memset(input_tmp, 0, byte_delta);                    memcpy(input_tmp + byte_delta, buf, size);                    buf= input_tmp;                    size += byte_delta;                    if(verbose > 2)                        fprintf(stderr, "adding %d audio samples of silence\n", (int)delta);                }            }else if(audio_sync_method>1){                int comp= clip(delta, -audio_sync_method, audio_sync_method);                assert(ost->audio_resample);                if(verbose > 2)                    fprintf(stderr, "compensating audio timestamp drift:%f compensation:%d in:%d\n", delta, comp, enc->sample_rate);                fprintf(stderr, "drift:%f len:%d opts:%lld ipts:%lld fifo:%d\n", delta, -1, ost->sync_opts, (int64_t)(ost->sync_ipts * enc->sample_rate), fifo_size(&ost->fifo, ost->fifo.rptr)/(ost->st->codec.channels * 2));                av_resample_compensate(*(struct AVResampleContext**)ost->resample, comp, enc->sample_rate);            }        }     }else        ost->sync_opts= lrintf(ost->sync_ipts * enc->sample_rate)                        - fifo_size(&ost->fifo, ost->fifo.rptr)/(ost->st->codec.channels * 2); //FIXME wrong    if (ost->audio_resample) {        buftmp = audio_buf;        size_out = audio_resample(ost->resample,                                   (short *)buftmp, (short *)buf,                                  size / (ist->st->codec.channels * 2));        size_out = size_out * enc->channels * 2;    } else {        buftmp = buf;        size_out = size;    }    /* now encode as many frames as possible */    if (enc->frame_size > 1) {        /* output resampled raw samples */        fifo_write(&ost->fifo, buftmp, size_out,                    &ost->fifo.wptr);        frame_bytes = enc->frame_size * 2 * enc->channels;                while (fifo_read(&ost->fifo, audio_buf, frame_bytes,                      &ost->fifo.rptr) == 0) {            AVPacket pkt;            av_init_packet(&pkt);            ret = avcodec_encode_audio(enc, audio_out, audio_out_size,                                        (short *)audio_buf);            audio_size += ret;            pkt.stream_index= ost->index;            pkt.data= audio_out;            pkt.size= ret;            if(enc->coded_frame)                pkt.pts= enc->coded_frame->pts;            pkt.flags |= PKT_FLAG_KEY;            av_interleaved_write_frame(s, &pkt);                        ost->sync_opts += enc->frame_size;        }    } else {        AVPacket pkt;        av_init_packet(&pkt);        ost->sync_opts += size_out / (2 * enc->channels);        /* output a pcm frame */        /* XXX: change encoding codec API to avoid this ? */        switch(enc->codec->id) {        case CODEC_ID_PCM_S16LE:        case CODEC_ID_PCM_S16BE:        case CODEC_ID_PCM_U16LE:        case CODEC_ID_PCM_U16BE:            break;        default:            size_out = size_out >> 1;            break;        }        ret = avcodec_encode_audio(enc, audio_out, size_out, 				   (short *)buftmp);        audio_size += ret;        pkt.stream_index= ost->index;        pkt.data= audio_out;        pkt.size= ret;        if(enc->coded_frame)            pkt.pts= enc->coded_frame->pts;        pkt.flags |= PKT_FLAG_KEY;        av_interleaved_write_frame(s, &pkt);    }}static void pre_process_video_frame(AVInputStream *ist, AVPicture *picture, void **bufp){    AVCodecContext *dec;    AVPicture *picture2;    AVPicture picture_tmp;    uint8_t *buf = 0;    dec = &ist->st->codec;    /* deinterlace : must be done before any resize */    if (do_deinterlace || using_vhook) {        int size;        /* create temporary picture */        size = avpicture_get_size(dec->pix_fmt, dec->width, dec->height);        buf = av_malloc(size);        if (!buf)            return;                picture2 = &picture_tmp;        avpicture_fill(picture2, buf, dec->pix_fmt, dec->width, dec->height);        if (do_deinterlace){            if(avpicture_deinterlace(picture2, picture,                                      dec->pix_fmt, dec->width, dec->height) < 0) {                /* if error, do not deinterlace */                av_free(buf);                buf = NULL;                picture2 = picture;            }        } else {            if (img_convert(picture2, dec->pix_fmt, picture,                             dec->pix_fmt, dec->width, dec->height) < 0) {                /* if error, do not copy */                av_free(buf);                buf = NULL;                picture2 = picture;            }        }    } else {        picture2 = picture;    }    frame_hook_process(picture2, dec->pix_fmt, dec->width, dec->height);    if (picture != picture2)        *picture = *picture2;    *bufp = buf;}/* we begin to correct av delay at this threshold */#define AV_DELAY_MAX 0.100/* Expects img to be yuv420 */static void fill_pad_region(AVPicture* img, int height, int width,        int padtop, int padbottom, int padleft, int padright, int *color) {      int i, y, shift;    uint8_t *optr;        for (i = 0; i < 3; i++) {        shift = (i == 0) ? 0 : 1;                if (padtop || padleft) {            memset(img->data[i], color[i], (((img->linesize[i] * padtop) +                             padleft) >> shift));        }        if (padleft || padright) {            optr = img->data[i] + (img->linesize[i] * (padtop >> shift)) +                (img->linesize[i] - (padright >> shift));            for (y = 0; y < ((height - (padtop + padbottom)) >> shift); y++) {                memset(optr, color[i], (padleft + padright) >> shift);                optr += img->linesize[i];            }        }              if (padbottom) {            optr = img->data[i] + (img->linesize[i] * ((height - padbottom) >> shift));            memset(optr, color[i], ((img->linesize[i] * padbottom) >> shift));        }    }}static uint8_t *bit_buffer= NULL;static void do_video_out(AVFormatContext *s,                          AVOutputStream *ost,                          AVInputStream *ist,                         AVFrame *in_picture,                         int *frame_size){    int nb_frames, i, ret;    AVFrame *final_picture, *formatted_picture;    AVFrame picture_format_temp, picture_crop_temp;    uint8_t *buf = NULL, *buf1 = NULL;    AVCodecContext *enc, *dec;    enum PixelFormat target_pixfmt;    #define VIDEO_BUFFER_SIZE (1024*1024)    avcodec_get_frame_defaults(&picture_format_temp);    avcodec_get_frame_defaults(&picture_crop_temp);    enc = &ost->st->codec;    dec = &ist->st->codec;    /* by default, we output a single frame */    nb_frames = 1;    *frame_size = 0;    if(video_sync_method){        double vdelta;        vdelta = ost->sync_ipts * enc->frame_rate / enc->frame_rate_base - ost->sync_opts;        //FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c        if (vdelta < -1.1)            nb_frames = 0;        else if (vdelta > 1.1)            nb_frames = 2;//fprintf(stderr, "vdelta:%f, ost->sync_opts:%lld, ost->sync_ipts:%f nb_frames:%d\n", vdelta, ost->sync_opts, ost->sync_ipts, nb_frames);        if (nb_frames == 0){            ++nb_frames_drop;            if (verbose>2)                fprintf(stderr, "*** drop!\n");        }else if (nb_frames == 2) {            ++nb_frames_dup;            if (verbose>2)                fprintf(stderr, "*** dup!\n");        }    }else        ost->sync_opts= lrintf(ost->sync_ipts * enc->frame_rate / enc->frame_rate_base);    if (nb_frames <= 0)         return;    /* convert pixel format if needed */    target_pixfmt = ost->video_resample || ost->video_pad        ? PIX_FMT_YUV420P : enc->pix_fmt;    if (dec->pix_fmt != target_pixfmt) {        int size;        /* create temporary picture */        size = avpicture_get_size(target_pixfmt, dec->width, dec->height);        buf = av_malloc(size);        if (!buf)            return;        formatted_picture = &picture_format_temp;        avpicture_fill((AVPicture*)formatted_picture, buf, target_pixfmt, dec->width, dec->height);                if (img_convert((AVPicture*)formatted_picture, target_pixfmt,                         (AVPicture *)in_picture, dec->pix_fmt,                         dec->width, dec->height) < 0) {            if (verbose >= 0)                fprintf(stderr, "pixel format conversion not handled\n");            goto the_end;        }    } else {        formatted_picture = in_picture;    }    /* XXX: resampling could be done before raw format conversion in       some cases to go faster */    /* XXX: only works for YUV420P */    if (ost->video_resample) {        final_picture = &ost->pict_tmp;        img_resample(ost->img_resample_ctx, (AVPicture*)final_picture, (AVPicture*)formatted_picture);               if (ost->padtop || ost->padbottom || ost->padleft || ost->padright) {            fill_pad_region((AVPicture*)final_picture, enc->height, enc->width,                    ost->padtop, ost->padbottom, ost->padleft, ost->padright,                    padcolor);        }        	if (enc->pix_fmt != PIX_FMT_YUV420P) {            int size;	    	    av_free(buf);

⌨️ 快捷键说明

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