ve_lavc.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 1,050 行 · 第 1/3 页

C
1,050
字号
        mux_v->bih= realloc(mux_v->bih, sizeof(BITMAPINFOHEADER) + lavc_venc_context->extradata_size);        memcpy(mux_v->bih + 1, lavc_venc_context->extradata, lavc_venc_context->extradata_size);        mux_v->bih->biSize= sizeof(BITMAPINFOHEADER) + lavc_venc_context->extradata_size;    }        mux_v->decoder_delay = lavc_venc_context->max_b_frames ? 1 : 0;        return 1;}static int control(struct vf_instance_s* vf, int request, void* data){    switch(request){        case VFCTRL_FLUSH_FRAMES:            if(vf->priv->codec->capabilities & CODEC_CAP_DELAY)                while(encode_frame(vf, NULL, MP_NOPTS_VALUE) > 0);            return CONTROL_TRUE;        default:            return CONTROL_UNKNOWN;    }}static int query_format(struct vf_instance_s* vf, unsigned int fmt){    switch(fmt){    case IMGFMT_YV12:    case IMGFMT_IYUV:    case IMGFMT_I420:        if(lavc_param_format == IMGFMT_YV12)            return VFCAP_CSP_SUPPORTED | VFCAP_ACCEPT_STRIDE;        break;    case IMGFMT_411P:        if(lavc_param_format == IMGFMT_411P)            return VFCAP_CSP_SUPPORTED | VFCAP_ACCEPT_STRIDE;        break;    case IMGFMT_422P:        if(lavc_param_format == IMGFMT_422P)            return VFCAP_CSP_SUPPORTED | VFCAP_ACCEPT_STRIDE;        break;    case IMGFMT_444P:        if(lavc_param_format == IMGFMT_444P)            return VFCAP_CSP_SUPPORTED | VFCAP_ACCEPT_STRIDE;        break;    case IMGFMT_YVU9:        if(lavc_param_format == IMGFMT_YVU9)            return VFCAP_CSP_SUPPORTED | VFCAP_ACCEPT_STRIDE;        break;    case IMGFMT_BGR32:        if(lavc_param_format == IMGFMT_BGR32)            return VFCAP_CSP_SUPPORTED | VFCAP_ACCEPT_STRIDE;        break;    }    return 0;}static double psnr(double d){    if(d==0) return INFINITY;    return -10.0*log(d)/log(10);}static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){    AVFrame *pic= vf->priv->pic;    pic->data[0]=mpi->planes[0];    pic->data[1]=mpi->planes[1];    pic->data[2]=mpi->planes[2];    pic->linesize[0]=mpi->stride[0];    pic->linesize[1]=mpi->stride[1];    pic->linesize[2]=mpi->stride[2];    if(lavc_param_interlaced_dct){        if((mpi->fields & MP_IMGFIELD_ORDERED) && (mpi->fields & MP_IMGFIELD_INTERLACED))            pic->top_field_first= !!(mpi->fields & MP_IMGFIELD_TOP_FIRST);        else             pic->top_field_first= 1;            if(lavc_param_top!=-1)            pic->top_field_first= lavc_param_top;    }    return (encode_frame(vf, pic, pts) >= 0);}static int encode_frame(struct vf_instance_s* vf, AVFrame *pic, double pts){    const char pict_type_char[5]= {'?', 'I', 'P', 'B', 'S'};    int out_size;    double dts;    if(pts == MP_NOPTS_VALUE)        pts= lavc_venc_context->frame_number * av_q2d(lavc_venc_context->time_base);    if(pic){#if 0        pic->opaque= malloc(sizeof(pts));        memcpy(pic->opaque, &pts, sizeof(pts));#else        if(pts != MP_NOPTS_VALUE)            pic->pts= floor(pts / av_q2d(lavc_venc_context->time_base) + 0.5);        else            pic->pts= MP_NOPTS_VALUE;#endif    }	out_size = avcodec_encode_video(lavc_venc_context, mux_v->buffer, mux_v->buffer_size,	    pic);    if(pts != MP_NOPTS_VALUE)         dts= pts - lavc_venc_context->delay * av_q2d(lavc_venc_context->time_base);    else        dts= MP_NOPTS_VALUE;#if 0    pts= lavc_venc_context->coded_frame->opaque ?           *(double*)lavc_venc_context->coded_frame->opaque         : MP_NOPTS_VALUE;#else    if(lavc_venc_context->coded_frame->pts != MP_NOPTS_VALUE)        pts= lavc_venc_context->coded_frame->pts * av_q2d(lavc_venc_context->time_base);    else        pts= MP_NOPTS_VALUE;    assert(MP_NOPTS_VALUE == AV_NOPTS_VALUE);#endif//fprintf(stderr, "ve_lavc %f/%f\n", dts, pts);    if(out_size == 0 && lavc_param_skip_threshold==0 && lavc_param_skip_factor==0){        ++mux_v->encoder_delay;        return 0;    }               muxer_write_chunk(mux_v,out_size,lavc_venc_context->coded_frame->key_frame?0x10:0,                       dts, pts);    free(lavc_venc_context->coded_frame->opaque);    lavc_venc_context->coded_frame->opaque= NULL;            /* store psnr / pict size / type / qscale */    if(lavc_param_psnr){        static FILE *fvstats=NULL;        char filename[20];        double f= lavc_venc_context->width*lavc_venc_context->height*255.0*255.0;	double quality=0.0;	int8_t *q;        if(!fvstats) {            time_t today2;            struct tm *today;            today2 = time(NULL);            today = localtime(&today2);            sprintf(filename, "psnr_%02d%02d%02d.log", today->tm_hour,                today->tm_min, today->tm_sec);            fvstats = fopen(filename,"w");            if(!fvstats) {                perror("fopen");                lavc_param_psnr=0; // disable block                mp_msg(MSGT_MENCODER,MSGL_ERR,"Can't open %s for writing. Check its permissions.\n",filename);                return -1;                /*exit(1);*/            }        }		// average MB quantizer	q = lavc_venc_context->coded_frame->qscale_table;	if(q) {	    int x, y;	    int w = (lavc_venc_context->width+15) >> 4;	    int h = (lavc_venc_context->height+15) >> 4;	    for( y = 0; y < h; y++ ) {		for( x = 0; x < w; x++ )		    quality += (double)*(q+x);		q += lavc_venc_context->coded_frame->qstride;	    }	    quality /= w * h;	} else 	    quality = lavc_venc_context->coded_frame->quality / (float)FF_QP2LAMBDA;        fprintf(fvstats, "%6d, %2.2f, %6d, %2.2f, %2.2f, %2.2f, %2.2f %c\n",            lavc_venc_context->coded_frame->coded_picture_number,            quality,            out_size,            psnr(lavc_venc_context->coded_frame->error[0]/f),            psnr(lavc_venc_context->coded_frame->error[1]*4/f),            psnr(lavc_venc_context->coded_frame->error[2]*4/f),            psnr((lavc_venc_context->coded_frame->error[0]+lavc_venc_context->coded_frame->error[1]+lavc_venc_context->coded_frame->error[2])/(f*1.5)),            pict_type_char[lavc_venc_context->coded_frame->pict_type]            );    }    /* store stats if there are any */    if(lavc_venc_context->stats_out && stats_file)         fprintf(stats_file, "%s", lavc_venc_context->stats_out);    return out_size;}static void uninit(struct vf_instance_s* vf){    if(lavc_param_psnr){        double f= lavc_venc_context->width*lavc_venc_context->height*255.0*255.0;        f*= lavc_venc_context->coded_frame->coded_picture_number;                mp_msg(MSGT_MENCODER, MSGL_INFO, "PSNR: Y:%2.2f, Cb:%2.2f, Cr:%2.2f, All:%2.2f\n",            psnr(lavc_venc_context->error[0]/f),            psnr(lavc_venc_context->error[1]*4/f),            psnr(lavc_venc_context->error[2]*4/f),            psnr((lavc_venc_context->error[0]+lavc_venc_context->error[1]+lavc_venc_context->error[2])/(f*1.5))            );    }    av_freep(&lavc_venc_context->intra_matrix);    av_freep(&lavc_venc_context->inter_matrix);    avcodec_close(lavc_venc_context);    if(stats_file) fclose(stats_file);        /* free rc_override */    av_freep(&lavc_venc_context->rc_override);    av_freep(&vf->priv->context);}//===========================================================================//static int vf_open(vf_instance_t *vf, char* args){    vf->uninit=uninit;    vf->config=config;    vf->default_caps=VFCAP_CONSTANT;    vf->control=control;    vf->query_format=query_format;    vf->put_image=put_image;    vf->priv=malloc(sizeof(struct vf_priv_s));    memset(vf->priv,0,sizeof(struct vf_priv_s));    vf->priv->mux=(muxer_stream_t*)args;    /* XXX: hack: some of the MJPEG decoder DLL's needs exported huffman       table, so we define a zero-table, also lavc mjpeg encoder is putting       huffman tables into the stream, so no problem */    if (lavc_param_vcodec && !strcasecmp(lavc_param_vcodec, "mjpeg"))    {	mux_v->bih=malloc(sizeof(BITMAPINFOHEADER)+28);	memset(mux_v->bih, 0, sizeof(BITMAPINFOHEADER)+28);	mux_v->bih->biSize=sizeof(BITMAPINFOHEADER)+28;    }    else if (lavc_param_vcodec && (!strcasecmp(lavc_param_vcodec, "huffyuv")                                || !strcasecmp(lavc_param_vcodec, "ffvhuff")))    {    /* XXX: hack: huffyuv needs to store huffman tables (allthough we dunno the size yet ...) */	mux_v->bih=malloc(sizeof(BITMAPINFOHEADER)+1000);	memset(mux_v->bih, 0, sizeof(BITMAPINFOHEADER)+1000);	mux_v->bih->biSize=sizeof(BITMAPINFOHEADER)+1000;    }    else if (lavc_param_vcodec && !strcasecmp(lavc_param_vcodec, "asv1"))    {	mux_v->bih=malloc(sizeof(BITMAPINFOHEADER)+8);	memset(mux_v->bih, 0, sizeof(BITMAPINFOHEADER)+8);	mux_v->bih->biSize=sizeof(BITMAPINFOHEADER)+8;    }    else if (lavc_param_vcodec && !strcasecmp(lavc_param_vcodec, "asv2"))    {	mux_v->bih=malloc(sizeof(BITMAPINFOHEADER)+8);	memset(mux_v->bih, 0, sizeof(BITMAPINFOHEADER)+8);	mux_v->bih->biSize=sizeof(BITMAPINFOHEADER)+8;    }    else if (lavc_param_vcodec && !strcasecmp(lavc_param_vcodec, "wmv2"))    {	mux_v->bih=malloc(sizeof(BITMAPINFOHEADER)+4);	memset(mux_v->bih, 0, sizeof(BITMAPINFOHEADER)+4);	mux_v->bih->biSize=sizeof(BITMAPINFOHEADER)+4;    }    else    {	mux_v->bih=malloc(sizeof(BITMAPINFOHEADER));	memset(mux_v->bih, 0, sizeof(BITMAPINFOHEADER));	mux_v->bih->biSize=sizeof(BITMAPINFOHEADER);    }    mux_v->bih->biWidth=0;    mux_v->bih->biHeight=0;    mux_v->bih->biPlanes=1;    mux_v->bih->biBitCount=24;    if (!lavc_param_vcodec)    {	printf("No libavcodec codec specified! It's required!\n");	return 0;    }    if (!strcasecmp(lavc_param_vcodec, "mpeg1") || !strcasecmp(lavc_param_vcodec, "mpeg1video"))	mux_v->bih->biCompression = mmioFOURCC('m', 'p', 'g', '1');    else if (!strcasecmp(lavc_param_vcodec, "mpeg2") || !strcasecmp(lavc_param_vcodec, "mpeg2video"))	mux_v->bih->biCompression = mmioFOURCC('m', 'p', 'g', '2');    else if (!strcasecmp(lavc_param_vcodec, "h263") || !strcasecmp(lavc_param_vcodec, "h263p"))	mux_v->bih->biCompression = mmioFOURCC('h', '2', '6', '3');    else if (!strcasecmp(lavc_param_vcodec, "rv10"))	mux_v->bih->biCompression = mmioFOURCC('R', 'V', '1', '0');    else if (!strcasecmp(lavc_param_vcodec, "mjpeg"))	mux_v->bih->biCompression = mmioFOURCC('M', 'J', 'P', 'G');    else if (!strcasecmp(lavc_param_vcodec, "ljpeg"))	mux_v->bih->biCompression = mmioFOURCC('L', 'J', 'P', 'G');    else if (!strcasecmp(lavc_param_vcodec, "mpeg4"))	mux_v->bih->biCompression = mmioFOURCC('F', 'M', 'P', '4');    else if (!strcasecmp(lavc_param_vcodec, "msmpeg4"))	mux_v->bih->biCompression = mmioFOURCC('d', 'i', 'v', '3');    else if (!strcasecmp(lavc_param_vcodec, "msmpeg4v2"))	mux_v->bih->biCompression = mmioFOURCC('M', 'P', '4', '2');    else if (!strcasecmp(lavc_param_vcodec, "wmv1"))	mux_v->bih->biCompression = mmioFOURCC('W', 'M', 'V', '1');    else if (!strcasecmp(lavc_param_vcodec, "wmv2"))	mux_v->bih->biCompression = mmioFOURCC('W', 'M', 'V', '2');    else if (!strcasecmp(lavc_param_vcodec, "huffyuv"))	mux_v->bih->biCompression = mmioFOURCC('H', 'F', 'Y', 'U');    else if (!strcasecmp(lavc_param_vcodec, "ffvhuff"))	mux_v->bih->biCompression = mmioFOURCC('F', 'F', 'V', 'H');    else if (!strcasecmp(lavc_param_vcodec, "asv1"))	mux_v->bih->biCompression = mmioFOURCC('A', 'S', 'V', '1');    else if (!strcasecmp(lavc_param_vcodec, "asv2"))	mux_v->bih->biCompression = mmioFOURCC('A', 'S', 'V', '2');    else if (!strcasecmp(lavc_param_vcodec, "ffv1"))	mux_v->bih->biCompression = mmioFOURCC('F', 'F', 'V', '1');    else if (!strcasecmp(lavc_param_vcodec, "snow"))	mux_v->bih->biCompression = mmioFOURCC('S', 'N', 'O', 'W');    else if (!strcasecmp(lavc_param_vcodec, "flv"))	mux_v->bih->biCompression = mmioFOURCC('F', 'L', 'V', '1');    else if (!strcasecmp(lavc_param_vcodec, "dvvideo"))	mux_v->bih->biCompression = mmioFOURCC('d', 'v', 's', 'd');    else if (!strcasecmp(lavc_param_vcodec, "libx264"))	mux_v->bih->biCompression = mmioFOURCC('h', '2', '6', '4');    else	mux_v->bih->biCompression = mmioFOURCC(lavc_param_vcodec[0],		lavc_param_vcodec[1], lavc_param_vcodec[2], lavc_param_vcodec[3]); /* FIXME!!! */   if (!avcodec_inited){	avcodec_init();	avcodec_register_all();	avcodec_inited=1;    }    vf->priv->codec = (AVCodec *)avcodec_find_encoder_by_name(lavc_param_vcodec);    if (!vf->priv->codec) {	mp_msg(MSGT_MENCODER,MSGL_ERR,MSGTR_MissingLAVCcodec, lavc_param_vcodec);	return 0;    }    vf->priv->pic = avcodec_alloc_frame();    vf->priv->context = avcodec_alloc_context();    return 1;}vf_info_t ve_info_lavc = {    "libavcodec encoder",    "lavc",    "A'rpi, Alex, Michael",    "for internal use by mencoder",    vf_open};//===========================================================================//

⌨️ 快捷键说明

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