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 + -
显示快捷键?