📄 libmpcodecs.txt
字号:
}Functions in vf_instance_s:NOTE: All these are optional, their function pointer is either NULL or pointsto a default implementation. If you implement them, don't forget to setvf->FUNCNAME in your open() ! int (*query_format)(struct vf_instance_s* vf, unsigned int fmt);The query_format() function is called one or more times before the config(),to find out the capabilities and/or support status of a given colorspace (fmt).For the return values, see vfcap.h!Normally, a filter should return at least VFCAP_CSP_SUPPORTED for all supportedcolorspaces it accepts as input, and 0 for the unsupported ones.If your filter does linear conversion, it should query the next filter,and merge in its capability flags. Note: You should always ensure that thenext filter will accept at least one of your possible output colorspaces!Sample:static int query_format(struct vf_instance_s* vf, unsigned int fmt){ switch(fmt){ case IMGFMT_YV12: case IMGFMT_I420: case IMGFMT_IYUV: case IMGFMT_422P: return vf_next_query_format(vf,IMGFMT_YUY2) & (~VFCAP_CSP_SUPPORTED_BY_HW); } return 0;}For the more complex case, when you have an N->M colorspace mapping matrix,see vf_scale or vf_rgb2bgr for examples. int (*config)(struct vf_instance_s* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt);The config() is called to initialize/configure the filter before using it.Its parameters are already well-known from libvo: width, height: size of the coded image d_width, d_height: wanted display size (usually aspect corrected w/h) Filters should use width,height as input image dimension, but the resizing filters (crop, expand, scale, rotate, etc) should update d_width/d_height (display size) to preserve the correct aspect ratio! Filters should not rely on d_width, d_height as input parameters, the only exception is when a filter replaces some libvo functionality (like -vf scale with -zoom, or OSD rendering with -vf expand). flags: the "good" old libvo flag set: 0x01 - force fullscreen (-fs) 0x02 - allow mode switching (-vm) 0x04 - allow software scaling (-zoom) 0x08 - flipping (-flip) (Usually you don't have to worry about flags, just pass it to next config.) outfmt: the selected colorspace/pixelformat. You'll receive images in this format.Sample:static int config(struct vf_instance_s* vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ // use d_width/d_height if not set by user: if(vf->priv->w==-1) vf->priv->w=d_width; if(vf->priv->h==-1) vf->priv->h=d_width; // initialize your filter code ... // OK now config the rest of the filter chain, with our output parameters: return vf_next_config(vf,vf->priv->w,vf->priv->h,d_width,d_height,flags,outfmt);} void (*uninit)(struct vf_instance_s* vf);Okey, uninit() is the simplest, it's called at the end. You can free yourprivate buffers etc here. int (*put_image)(struct vf_instance_s* vf, mp_image_t *mpi);Ah, put_image(). This is the main filter function, it should convert/filter/transform the image data from one format/size/color/whatever to another.Its input parameter is an mpi (mplayer image) structure, see mp_image.h.Your filter has to request a new image buffer for the output, using thevf_get_image() function. NOTE: Even if you don't want to modify the image,just pass it to the next filter, you have to either- not implement put_image() at all - then it will be skipped- request a new image with type==EXPORT and copy the pointersNEVER pass the mpi as-is, it's local to the filters and may cause trouble.If you completely copy/transform the image, then you probably want this: dmpi=vf_get_image(vf->next,mpi->imgfmt, MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, vf->priv->w, vf->priv->h);It will allocate a new image, and return an mp_image structure filled bybuffer pointers and stride (bytes per line) values, in size of vf->priv->wtimes vf->priv->h. If your filter cannot handle stride, then leave outMP_IMGFLAG_ACCEPT_STRIDE. Note that you can do this, but it isn't recommended,the whole video path is designed to use strides to get optimal throughput.If your filter allocates output image buffers, then use MP_IMGTYPE_EXPORT,and fill the returned dmpi's planes[], stride[] with your buffer parameters.Note, it is not recommended (no direct rendering), so if you can, usevf_get_image() for buffer allocation!For other image types and flags see mp_image.h, it has comments.If you are unsure, feel free to ask on the -dev-eng mailing list. Pleasedescribe the behavior of your filter, and its limitations, so we cansuggest the optimal buffer type + flags for your code.Now that you have the input (mpi) and output (dmpi) buffers, you can dothe conversion. If you didn't notice yet, mp_image has some useful infofields, may help you a lot creating if() or for() structures: flags: MP_IMGFLAG_PLANAR, MP_IMGFLAG_YUV, MP_IMGFLAG_SWAPPED helps you to handle various pixel formats in single code. bpp: bits per pixel WARNING! It's number of bits _allocated_ to store a pixel, it is not the number of bits actually used to keep colors! So it's 16 for both 15 and 16 bit color depth, and is 32 for 32bpp (actually 24 bit color depth) mode! It's 1 for 1bpp, 9 for YVU9, and is 12 for YV12 mode. Get it? For planar formats, you also have chroma_width, chroma_height and chroma_x_shift, chroma_y_shift too, they specify the chroma subsampling for yuv formats: chroma_width = luma_width >>chroma_x_shift; chroma_height= luma_height>>chroma_y_shift;If you're done, call the rest of the filter chain to process your outputimage: return vf_next_put_image(vf,dmpi);Ok, the rest is for advanced functionality only: int (*control)(struct vf_instance_s* vf, int request, void* data);You can control the filter at runtime from MPlayer/MEncoder/dec_video:#define VFCTRL_QUERY_MAX_PP_LEVEL 4 /* test for postprocessing support (max level) */#define VFCTRL_SET_PP_LEVEL 5 /* set postprocessing level */#define VFCTRL_SET_EQUALIZER 6 /* set color options (brightness,contrast etc) */#define VFCTRL_GET_EQUALIZER 8 /* get color options (brightness,contrast etc) */#define VFCTRL_DRAW_OSD 7#define VFCTRL_CHANGE_RECTANGLE 9 /* Change the rectangle boundaries */ void (*get_image)(struct vf_instance_s* vf, mp_image_t *mpi);This is for direct rendering support, works the same way as in libvo drivers.It makes in-place pixel modifications possible.If you implement it (vf->get_image!=NULL) then it will be called to do thebuffer allocation. You SHOULD check the buffer restrictions (stride, type,readability etc) and if everything is OK, then allocate the requested bufferusing the vf_get_image() function and copying the buffer pointers.NOTE: You HAVE TO save the dmpi pointer, as you'll need it in put_image()later on. It is not guaranteed that you'll get the same mpi for put_image() asin get_image() (think of out-of-order decoding, get_image is called in decodingorder, while put_image is called for display) so the only safe place to saveit is in the mpi struct itself: mpi->priv=(void*)dmpi; void (*draw_slice)(struct vf_instance_s* vf, unsigned char** src, int* stride, int w,int h, int x, int y);It's the good old draw_slice callback, already known from libvo.If your filter can operate on partial images, you can implement this oneto improve performance (cache utilization).Ah, and there are two sets of capability/requirement flags (vfcap.h type)in vf_instance_t, used by the default query_format() implementation, and bythe automatic colorspace/stride matching code (vf_next_config()). // caps: unsigned int default_caps; // used by default query_format() unsigned int default_reqs; // used by default config()BTW, you should avoid using global or static variables to store filter instancespecific stuff, as filters might be used multiple times & in the future evenmultiple streams might be possibleThe AUDIO path:===============TODO!!!
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -