mirror of
https://github.com/mpv-player/mpv
synced 2025-03-25 04:38:01 +00:00
Spelling/wording/grammar fixes, convert mixed tabs and spaces indentation to
spaces, some cosmetics. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@15625 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
bed93729f3
commit
241c16ceec
@ -22,97 +22,98 @@ The VIDEO path:
|
|||||||
|______|
|
|______|
|
||||||
|
|
||||||
Short description of video path:
|
Short description of video path:
|
||||||
1. mplayer/mencoder core requests the decoding of a compressed video frame:
|
1. MPlayer/MEncoder core requests the decoding of a compressed video frame:
|
||||||
calls decvideo.c::decode_video()
|
calls decvideo.c::decode_video()
|
||||||
|
|
||||||
2. decode_video() calls the previously ( init_video() ) selected video codec
|
2. decode_video() calls the previously ( init_video() ) selected video codec
|
||||||
(vd_XXXX.c file, where XXXX == vfm name, see the 'driver' line of codecs.conf)
|
(vd_XXX.c file, where XXX == vfm name, see the 'driver' line of codecs.conf)
|
||||||
|
|
||||||
3. the codec should initialize output device before decoding the first frame,
|
3. The codec should initialize the output device before decoding the first
|
||||||
it may happen in init() or at the middle of the first decode(). see 3.a.
|
frame, it may happen in init() or at the middle of the first decode(), see
|
||||||
it means calling vd.c::mpcodecs_config_vo() with the image dimensions,
|
3a. It means calling vd.c::mpcodecs_config_vo() with the image dimensions,
|
||||||
and the _preferred_ (mean: internal, native, best) colorspace.
|
and the _preferred_ (mean: internal, native, best) colorspace.
|
||||||
NOTE: this colorspace may not be equal to the actually used colorspace, it's
|
NOTE: This colorspace may not be equal to the actually used colorspace, it's
|
||||||
just a _hint_ for the csp matching algorithm, and mainly used _only_ when
|
just a _hint_ for the csp matching algorithm, and mainly used _only_ when
|
||||||
csp conversion is required, as input format of the converter.
|
csp conversion is required, as input format of the converter.
|
||||||
|
|
||||||
3.a. selecting the best output colorspace:
|
3a. Selecting the best output colorspace:
|
||||||
the vd.c::mpcodecs_config_vo() function will go through the outfmt list
|
The vd.c::mpcodecs_config_vo() function will go through the outfmt list
|
||||||
defined by codecs.conf's 'out' lines, and query both vd (codec) and vo
|
defined by codecs.conf's 'out' lines, and query both vd (codec) and vo
|
||||||
(output device/filter/encoder) if it's supported or not.
|
(output device/filter/encoder) if it's supported or not.
|
||||||
|
|
||||||
For the vo, it calls the query_format() func of vf_XXX.c or ve_XXX.c.
|
For the vo, it calls the query_format() function of vf_XXX.c or ve_XXX.c.
|
||||||
It should return a set of feature flags, the most important ons for this
|
It should return a set of feature flags, the most important ones for this
|
||||||
stage are: VFCAP_CSP_SUPPORTED (csp supported directly or by conversion)
|
stage are: VFCAP_CSP_SUPPORTED (csp supported directly or by conversion)
|
||||||
and VFCAP_CSP_SUPPORTED_BY_HW (csp supported WITHOUT any conversion).
|
and VFCAP_CSP_SUPPORTED_BY_HW (csp supported WITHOUT any conversion).
|
||||||
|
|
||||||
For the vd (codec), control() with VDCTRL_QUERY_FORMAT will be called.
|
For the vd (codec), control() with VDCTRL_QUERY_FORMAT will be called.
|
||||||
If it doesn't implement VDCTRL_QUERY_FORMAT, (ie answers CONTROL_UNKNOWN
|
If it doesn't implement VDCTRL_QUERY_FORMAT, (i.e. answers CONTROL_UNKNOWN
|
||||||
or CONTROL_NA) it will be assumed to be CONTROL_TRUE (csp supported)!
|
or CONTROL_NA), it will be assumed to be CONTROL_TRUE (csp supported)!
|
||||||
|
|
||||||
So, by default, if the list of supported colorspaces is constant, doesn't
|
So, by default, if the list of supported colorspaces is constant, doesn't
|
||||||
depend on the actual file's/stream's header, it's enough to list them
|
depend on the actual file's/stream's header, it's enough to list them
|
||||||
in codecs.conf ('out' field), and don't implement VDCTRL_QUERY_FORMAT.
|
in codecs.conf ('out' field), and don't implement VDCTRL_QUERY_FORMAT.
|
||||||
It's the case for the most codecs.
|
This is the case for most codecs.
|
||||||
|
|
||||||
If the supported csp list depends on the file being decoded, list the
|
If the supported csp list depends on the file being decoded, list the
|
||||||
possible out formats (colorspaces) in codecs.conf, and implement the
|
possible out formats (colorspaces) in codecs.conf, and implement the
|
||||||
VDCTRL_QUERY_FORMAT to test the availability of the given csp for the
|
VDCTRL_QUERY_FORMAT to test the availability of the given csp for the
|
||||||
given video file/stream.
|
given video file/stream.
|
||||||
|
|
||||||
The vd.c core will find the best matching colorspace, depending on the
|
The vd.c core will find the best matching colorspace, depending on the
|
||||||
VFCAP_CSP_SUPPORTED_BY_HW flag (see vfcap.h). If no match at all, it
|
VFCAP_CSP_SUPPORTED_BY_HW flag (see vfcap.h). If no match at all, it
|
||||||
will try again with the 'scale' filter inserted between vd and vo.
|
will try again with the 'scale' filter inserted between vd and vo.
|
||||||
If still no match, it will fail :(
|
If still no match, it will fail :(
|
||||||
|
|
||||||
4. requesting buffer for the decoded frame:
|
4. Requesting buffer for the decoded frame:
|
||||||
The codec have to call mpcodecs_get_image() with proper imgtype & imgflag.
|
The codec has to call mpcodecs_get_image() with proper imgtype & imgflag.
|
||||||
It will find the optimal buffering setup (preferred stride, alignment etc)
|
It will find the optimal buffering setup (preferred stride, alignment etc)
|
||||||
and return a pointer to the allocated and filled up mpi (mp_image_t*) struct.
|
and return a pointer to the allocated and filled up mpi (mp_image_t*) struct.
|
||||||
The 'imgtype' controls the buffering setup, ie STATIC (just one buffer,
|
The 'imgtype' controls the buffering setup, i.e. STATIC (just one buffer,
|
||||||
it 'remembers' its contents between frames), TEMP (write-only, full update),
|
it 'remembers' its contents between frames), TEMP (write-only, full update),
|
||||||
EXPORT (memory allocation is done by the codec, not recommended) and so on.
|
EXPORT (memory allocation is done by the codec, not recommended) and so on.
|
||||||
The 'imgflags' set up the limits for the buffer, ie stride limitations,
|
The 'imgflags' set up the limits for the buffer, i.e. stride limitations,
|
||||||
readability, remembering content etc. See mp_image.h for the short descr.
|
readability, remembering content etc. See mp_image.h for the short
|
||||||
See dr-methods.txt for the explanation of buffer importing and mpi imgtypes.
|
description. See dr-methods.txt for the explanation of buffer
|
||||||
|
importing and mpi imgtypes.
|
||||||
|
|
||||||
Always try to implement stride support! (stride == bytes per line)
|
Always try to implement stride support! (stride == bytes per line)
|
||||||
If no stride support, then stride==bytes_per_pixel*image_width.
|
If no stride support, then stride==bytes_per_pixel*image_width.
|
||||||
If you have stride supoprt in your decoder, use the mpi->stride[] value
|
If you have stride support in your decoder, use the mpi->stride[] value
|
||||||
for the byte_per_line for each plane.
|
for the byte_per_line for each plane.
|
||||||
Also take care of other imgflags, like MP_IMGFLAG_PRESERVE and
|
Also take care of other imgflags, like MP_IMGFLAG_PRESERVE and
|
||||||
MP_IMGFLAG_READABLE, MP_IMGFLAG_COMMON_STRIDE and MP_IMGFLAG_COMMON_PLANE!
|
MP_IMGFLAG_READABLE, MP_IMGFLAG_COMMON_STRIDE and MP_IMGFLAG_COMMON_PLANE!
|
||||||
The file mp_image.h contains description of flags in comments, read it!
|
The file mp_image.h contains flag descriptions in comments, read it!
|
||||||
Ask for help on -dev-eng, describing the behaviour your codec, if unsure.
|
Ask for help on dev-eng, describing the behaviour your codec, if unsure.
|
||||||
|
|
||||||
4.a. buffer allocation, vd.c::mpcodecs_get_image():
|
4.a. buffer allocation, vd.c::mpcodecs_get_image():
|
||||||
If the requested buffer imgtype!=EXPORT, then vd.c will try to do
|
If the requested buffer imgtype!=EXPORT, then vd.c will try to do
|
||||||
direct rendering, ie. asks the next filter/vo for the buffer allocation.
|
direct rendering, i.e. asks the next filter/vo for the buffer allocation.
|
||||||
It's done by calling get_image() of the vf_XXX.c file.
|
It's done by calling get_image() of the vf_XXX.c file.
|
||||||
If it was successful, the imgflag MP_IMGFLAG_DIRECT will be set, and one
|
If it was successful, the imgflag MP_IMGFLAG_DIRECT will be set, and one
|
||||||
memcpy() will be saved when passing the data from vd to the next filter/vo.
|
memcpy() will be saved when passing the data from vd to the next filter/vo.
|
||||||
See dr-methods.txt for details and examples.
|
See dr-methods.txt for details and examples.
|
||||||
|
|
||||||
5. decode the frame, to the mpi structure requested at 4, then return the mpi
|
5. Decode the frame, to the mpi structure requested in 4., then return the mpi
|
||||||
to decvideo.c. Return NULL if the decoding failed or skipped frame.
|
to decvideo.c. Return NULL if the decoding failed or skipped the frame.
|
||||||
|
|
||||||
6. decvideo.c::decode_video() will now pass the 'mpi' to the next filter (vf_X).
|
6. decvideo.c::decode_video() will now pass the 'mpi' to the next filter (vf_X).
|
||||||
|
|
||||||
7. the filter's (vf_X) put_image() then requests a new mpi buffer by calling
|
7. The filter's (vf_X) put_image() then requests a new mpi buffer by calling
|
||||||
vf.c::vf_get_image().
|
vf.c::vf_get_image().
|
||||||
|
|
||||||
7.a. vf.c::vf_get_image() will try to get direct rendering, by asking the
|
7.a. vf.c::vf_get_image() will try to get direct rendering by asking the
|
||||||
next fliter to do the buffer allocation (calls vf_Y's get_image()).
|
next filter to do the buffer allocation (calls vf_Y's get_image()).
|
||||||
if it fails, it will fallback to normal system memory allocation.
|
If it fails, it will fall back on normal system memory allocation.
|
||||||
|
|
||||||
|
8. When we're past the whole filter chain (multiple filters can be connected,
|
||||||
|
even the same filter multiple times) then the last, 'leaf' filters will be
|
||||||
|
called. The only difference between leaf and non-leaf filters is that leaf
|
||||||
|
filters have to implement the whole filter API.
|
||||||
|
Currently leaf filters are: vf_vo.c (wrapper over libvo) and ve_XXX.c
|
||||||
|
(video encoders used by MEncoder).
|
||||||
|
|
||||||
8. when we're over the whole filter chain (multiple filters can be connected,
|
|
||||||
even the same filter multiple times) then the last, 'leaf' filter will be
|
|
||||||
called. The only difference between leaf and non-leaf filter is that leaf
|
|
||||||
filter have to implement the whole filter api.
|
|
||||||
Leaf filters are now: vf_vo.c (wrapper over libvo) and ve_XXX.c (video
|
|
||||||
encoders used by mencoder).
|
|
||||||
|
|
||||||
|
|
||||||
Video Filters
|
Video Filters
|
||||||
=============
|
=============
|
||||||
|
|
||||||
@ -120,7 +121,7 @@ Video filters are plugin-like code modules implementing the interface
|
|||||||
defined in vf.h.
|
defined in vf.h.
|
||||||
|
|
||||||
Basically it means video output manipulation, i.e. these plugins can
|
Basically it means video output manipulation, i.e. these plugins can
|
||||||
modify the image and the image properties (size, colorspace etc) between
|
modify the image and the image properties (size, colorspace, etc) between
|
||||||
the video decoders (vd.h) and the output layer (libvo or video encoders).
|
the video decoders (vd.h) and the output layer (libvo or video encoders).
|
||||||
|
|
||||||
The actual API is a mixture of the video decoder (vd.h) and libvo
|
The actual API is a mixture of the video decoder (vd.h) and libvo
|
||||||
@ -142,12 +143,12 @@ filename: vf_FILTERNAME.c
|
|||||||
vf_info_t* info;
|
vf_info_t* info;
|
||||||
pointer to the filter description structure:
|
pointer to the filter description structure:
|
||||||
|
|
||||||
const char *info; // description of the filter
|
const char *info; // description of the filter
|
||||||
const char *name; // short name of the filter, must be FILTERNAME
|
const char *name; // short name of the filter, must be FILTERNAME
|
||||||
const char *author; // name and email/url of the author(s)
|
const char *author; // name and email/url of the author(s)
|
||||||
const char *comment;// comment, url to papers describing algo etc.
|
const char *comment; // comment, url to papers describing algo etc.
|
||||||
int (*open)(struct vf_instance_s* vf,char* args);
|
int (*open)(struct vf_instance_s* vf,char* args);
|
||||||
// pointer to the open() function:
|
// pointer to the open() function:
|
||||||
|
|
||||||
Sample:
|
Sample:
|
||||||
|
|
||||||
@ -155,22 +156,22 @@ vf_info_t vf_info_foobar = {
|
|||||||
"Universal Foo and Bar filter",
|
"Universal Foo and Bar filter",
|
||||||
"foobar",
|
"foobar",
|
||||||
"Ms. Foo Bar",
|
"Ms. Foo Bar",
|
||||||
"based on algo described at http://www.foo-bar.org",
|
"based on algorithm described at http://www.foo-bar.org",
|
||||||
open
|
open
|
||||||
};
|
};
|
||||||
|
|
||||||
The open() function:
|
The open() function:
|
||||||
|
|
||||||
open() is called when the filter is appended/inserted to the filter chain.
|
open() is called when the filter is appended/inserted in the filter chain.
|
||||||
it'll receive the handler (vf) and the optional filter parameters as
|
It'll receive the handler (vf) and the optional filter parameters as
|
||||||
char* string. Note, that encoders (ve_*) and vo wrapper (vf_vo.c) have
|
char* string. Note that encoders (ve_*) and vo wrapper (vf_vo.c) have
|
||||||
non-string arg, but it's specially handled by mplayer/mencoder.
|
non-string arg, but it's specially handled by MPlayer/MEncoder.
|
||||||
|
|
||||||
The open() function should fill the vf_instance_t structure, with the
|
The open() function should fill the vf_instance_t structure, with the
|
||||||
implemented functions' pointers (see bellow).
|
implemented functions' pointers (see below).
|
||||||
It can optinally allocate memory for its internal data (vf_priv_t) and
|
It can optionally allocate memory for its internal data (vf_priv_t) and
|
||||||
store the pointer in vf->priv.
|
store the pointer in vf->priv.
|
||||||
|
|
||||||
The open() func should parse (or at least check syntax) of parameters,
|
The open() func should parse (or at least check syntax) of parameters,
|
||||||
and fail (return 0) if error.
|
and fail (return 0) if error.
|
||||||
|
|
||||||
@ -185,26 +186,26 @@ static int open(vf_instance_t *vf, char* args){
|
|||||||
vf->priv->w=
|
vf->priv->w=
|
||||||
vf->priv->h=-1;
|
vf->priv->h=-1;
|
||||||
if(args) // parse args:
|
if(args) // parse args:
|
||||||
if(sscanf(args, "%d:%d", &vf->priv->w, &vf->priv->h)!=2) return 0;
|
if(sscanf(args, "%d:%d", &vf->priv->w, &vf->priv->h)!=2) return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Functions in vf_instance_s:
|
Functions in vf_instance_s:
|
||||||
|
|
||||||
NOTE: All these are optional, their func pointer is either NULL or points to
|
NOTE: All these are optional, their function pointer is either NULL or points
|
||||||
a default implementation. If you implement them, don't forget to set
|
to a default implementation. If you implement them, don't forget to set
|
||||||
vf->FUNCNAME in your open() !
|
vf->FUNCNAME in your open() !
|
||||||
|
|
||||||
int (*query_format)(struct vf_instance_s* vf,
|
int (*query_format)(struct vf_instance_s* vf,
|
||||||
unsigned int fmt);
|
unsigned int fmt);
|
||||||
|
|
||||||
The query_format() func. is called one or more times before the config(),
|
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).
|
to find out the capabilities and/or support status of a given colorspace (fmt).
|
||||||
For the return values, see vfcap.h!
|
For the return values, see vfcap.h!
|
||||||
Normally, a filter should return at least VFCAP_CSP_SUPPORTED for all supported
|
Normally, a filter should return at least VFCAP_CSP_SUPPORTED for all supported
|
||||||
colorspaces it accepts as input, and 0 for the unsupported ones.
|
colorspaces it accepts as input, and 0 for the unsupported ones.
|
||||||
If your filter does linear conversion, it should query the next filter,
|
If your filter does linear conversion, it should query the next filter,
|
||||||
and merge in its capability flags. Note: you should always ensure that the
|
and merge in its capability flags. Note: You should always ensure that the
|
||||||
next filter will accept at least one of your possible output colorspaces!
|
next filter will accept at least one of your possible output colorspaces!
|
||||||
|
|
||||||
Sample:
|
Sample:
|
||||||
@ -215,7 +216,7 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt){
|
|||||||
case IMGFMT_I420:
|
case IMGFMT_I420:
|
||||||
case IMGFMT_IYUV:
|
case IMGFMT_IYUV:
|
||||||
case IMGFMT_422P:
|
case IMGFMT_422P:
|
||||||
return vf_next_query_format(vf,IMGFMT_YUY2) & (~VFCAP_CSP_SUPPORTED_BY_HW);
|
return vf_next_query_format(vf,IMGFMT_YUY2) & (~VFCAP_CSP_SUPPORTED_BY_HW);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -226,23 +227,23 @@ see vf_scale or vf_rgb2bgr for examples.
|
|||||||
|
|
||||||
int (*config)(struct vf_instance_s* vf,
|
int (*config)(struct vf_instance_s* vf,
|
||||||
int width, int height, int d_width, int d_height,
|
int width, int height, int d_width, int d_height,
|
||||||
unsigned int flags, unsigned int outfmt);
|
unsigned int flags, unsigned int outfmt);
|
||||||
|
|
||||||
The config() is called to initialize/confugre the filter before using it.
|
The config() is called to initialize/configure the filter before using it.
|
||||||
Its parameters are already well-known from libvo:
|
Its parameters are already well-known from libvo:
|
||||||
width, height: size of the coded image
|
width, height: size of the coded image
|
||||||
d_width, d_height: wanted display size (usually aspect corrected w/h)
|
d_width, d_height: wanted display size (usually aspect corrected w/h)
|
||||||
Filters should use width,height as input image dimension, but the
|
Filters should use width,height as input image dimension, but the
|
||||||
resizing filters (crop, expand, scale, rotate, etc) should update
|
resizing filters (crop, expand, scale, rotate, etc) should update
|
||||||
d_width/d_height (display size) to preserve the correct aspect ratio!
|
d_width/d_height (display size) to preserve the correct aspect ratio!
|
||||||
Filters should not rely on d_width, d_height as input parameters,
|
Filters should not rely on d_width, d_height as input parameters,
|
||||||
the only exception is when a filter replaces some libvo functionality
|
the only exception is when a filter replaces some libvo functionality
|
||||||
(like -vf scale with -zoom, or OSD rendering wiht -vf expand).
|
(like -vf scale with -zoom, or OSD rendering with -vf expand).
|
||||||
flags: the "good" old flags set of libvo:
|
flags: the "good" old libvo flag set:
|
||||||
0x01 - force fullscreen (-fs)
|
0x01 - force fullscreen (-fs)
|
||||||
0x02 - allow mode switching (-vm)
|
0x02 - allow mode switching (-vm)
|
||||||
0x04 - allow software scaling (-zoom)
|
0x04 - allow software scaling (-zoom)
|
||||||
0x08 - flipping (-flip)
|
0x08 - flipping (-flip)
|
||||||
(Usually you don't have to worry about flags, just pass it to next config.)
|
(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
|
outfmt: the selected colorspace/pixelformat. You'll receive images in this
|
||||||
format.
|
format.
|
||||||
@ -251,13 +252,13 @@ Sample:
|
|||||||
|
|
||||||
static int config(struct vf_instance_s* vf,
|
static int config(struct vf_instance_s* vf,
|
||||||
int width, int height, int d_width, int d_height,
|
int width, int height, int d_width, int d_height,
|
||||||
unsigned int flags, unsigned int outfmt){
|
unsigned int flags, unsigned int outfmt){
|
||||||
// use d_width/d_height if not set by user:
|
// use d_width/d_height if not set by user:
|
||||||
if(vf->priv->w==-1) vf->priv->w=d_width;
|
if(vf->priv->w==-1) vf->priv->w=d_width;
|
||||||
if(vf->priv->h==-1) vf->priv->h=d_width;
|
if(vf->priv->h==-1) vf->priv->h=d_width;
|
||||||
// initialize your filter code
|
// initialize your filter code
|
||||||
...
|
...
|
||||||
// ok now config the rest of the filter chain, with our output parameters:
|
// 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);
|
return vf_next_config(vf,vf->priv->w,vf->priv->h,d_width,d_height,flags,outfmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,85 +270,85 @@ private buffers etc here.
|
|||||||
int (*put_image)(struct vf_instance_s* vf,
|
int (*put_image)(struct vf_instance_s* vf,
|
||||||
mp_image_t *mpi);
|
mp_image_t *mpi);
|
||||||
|
|
||||||
Ah, put_image(). This is the main filter function it should convert/filter/
|
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.
|
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.
|
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 the
|
Your filter has to request a new image buffer for the output, using the
|
||||||
vf_get_image() function. NOTE: even if you don't want to modify the image,
|
vf_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
|
just pass it to the next filter, you have to either
|
||||||
- do not implement put_image() at all - then it will be skipped
|
- not implement put_image() at all - then it will be skipped
|
||||||
- request a new image with type==EXPORT and copy the pointers
|
- request a new image with type==EXPORT and copy the pointers
|
||||||
NEVER pass the mpi as-is, it's local to filters and may cause trouble.
|
NEVER 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:
|
If you completely copy/transform the image, then you probably want this:
|
||||||
|
|
||||||
dmpi=vf_get_image(vf->next,mpi->imgfmt,
|
dmpi=vf_get_image(vf->next,mpi->imgfmt,
|
||||||
MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
|
MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
|
||||||
vf->priv->w, vf->priv->h);
|
vf->priv->w, vf->priv->h);
|
||||||
|
|
||||||
It will allocate a new image, and return an mp_image structure filled by
|
It will allocate a new image, and return an mp_image structure filled by
|
||||||
buffer pointers and stride (bytes per line) values, in size of vf->priv->w
|
buffer pointers and stride (bytes per line) values, in size of vf->priv->w
|
||||||
times vf->priv->h. If your filter cannot handle stride, then left out
|
times vf->priv->h. If your filter cannot handle stride, then leave out
|
||||||
MP_IMGFLAG_ACCEPT_STRIDE. Note, that you can do this, but it isn't recommended,
|
MP_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.
|
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,
|
If your filter allocates output image buffers, then use MP_IMGTYPE_EXPORT,
|
||||||
and fill the returned dmpi's planes[], stride[] with your buffer parameters.
|
and fill the returned dmpi's planes[], stride[] with your buffer parameters.
|
||||||
Note, it is not recommended (no direct rendering), so if you can, use
|
Note, it is not recommended (no direct rendering), so if you can, use
|
||||||
vf_get_image() for buffer allocation!
|
vf_get_image() for buffer allocation!
|
||||||
For other image types and flags see mp_image.h, it has comments.
|
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 maillist. Please
|
If you are unsure, feel free to ask on the -dev-eng mailing list. Please
|
||||||
describe the behaviour of your filter, an dits limitations, so we can
|
describe the behavior of your filter, and its limitations, so we can
|
||||||
suggest the optimal buffer type + flags for your code.
|
suggest the optimal buffer type + flags for your code.
|
||||||
|
|
||||||
Now, that you have the input (mpi) and output (dmpi) buffers, you can do
|
Now that you have the input (mpi) and output (dmpi) buffers, you can do
|
||||||
the conversion. If you didn't notice yet, mp_image has some useful info
|
the conversion. If you didn't notice yet, mp_image has some useful info
|
||||||
fields, may help you a lot creating if() or for() structures:
|
fields, may help you a lot creating if() or for() structures:
|
||||||
flags: MP_IMGFLAG_PLANAR, MP_IMGFLAG_YUV, MP_IMGFLAG_SWAPPED
|
flags: MP_IMGFLAG_PLANAR, MP_IMGFLAG_YUV, MP_IMGFLAG_SWAPPED
|
||||||
helps you to handle various pixel formats in single code.
|
helps you to handle various pixel formats in single code.
|
||||||
bpp: bits per pixel
|
bpp: bits per pixel
|
||||||
WARNING! It's number of bits _allocated_ to store a pixel,
|
WARNING! It's number of bits _allocated_ to store a pixel,
|
||||||
it is not the number of bits actually used to keep colors!
|
it is not the number of bits actually used to keep colors!
|
||||||
So, it's 16 for both 15 and 16bit color depth, and is 32 for
|
So it's 16 for both 15 and 16 bit color depth, and is 32 for
|
||||||
32bpp (actually 24bit color depth) mode!
|
32bpp (actually 24 bit color depth) mode!
|
||||||
It's 1 for 1bpp, 9 for YVU9, and is 12 for YV12 mode. Get it?
|
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
|
For planar formats, you also have chroma_width, chroma_height and
|
||||||
chroma_x_shift, chroma_y_shift too, they specify the chroma subsampling
|
chroma_x_shift, chroma_y_shift too, they specify the chroma subsampling
|
||||||
for yuv formats:
|
for yuv formats:
|
||||||
chroma_width = luma_width >>chroma_x_shift;
|
chroma_width = luma_width >>chroma_x_shift;
|
||||||
chroma_height= luma_height>>chroma_y_shift;
|
chroma_height= luma_height>>chroma_y_shift;
|
||||||
|
|
||||||
If you're done, call the rest of the filter chain to process your output
|
If you're done, call the rest of the filter chain to process your output
|
||||||
image:
|
image:
|
||||||
return vf_next_put_image(vf,dmpi);
|
return vf_next_put_image(vf,dmpi);
|
||||||
|
|
||||||
|
|
||||||
Ok, the rest is for advanced functionality only:
|
Ok, the rest is for advanced functionality only:
|
||||||
|
|
||||||
int (*control)(struct vf_instance_s* vf,
|
int (*control)(struct vf_instance_s* vf,
|
||||||
int request, void* data);
|
int request, void* data);
|
||||||
|
|
||||||
You can control the filter in runtime from mplayer/mencoder/dec_video:
|
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_QUERY_MAX_PP_LEVEL 4 /* test for postprocessing support (max level) */
|
||||||
#define VFCTRL_SET_PP_LEVEL 5 /* set postprocessing level */
|
#define VFCTRL_SET_PP_LEVEL 5 /* set postprocessing level */
|
||||||
#define VFCTRL_SET_EQUALIZER 6 /* set color options (brightness,contrast etc) */
|
#define VFCTRL_SET_EQUALIZER 6 /* set color options (brightness,contrast etc) */
|
||||||
#define VFCTRL_GET_EQUALIZER 8 /* gset color options (brightness,contrast etc) */
|
#define VFCTRL_GET_EQUALIZER 8 /* get color options (brightness,contrast etc) */
|
||||||
#define VFCTRL_DRAW_OSD 7
|
#define VFCTRL_DRAW_OSD 7
|
||||||
#define VFCTRL_CHANGE_RECTANGLE 9 /* Change the rectangle boundaries */
|
#define VFCTRL_CHANGE_RECTANGLE 9 /* Change the rectangle boundaries */
|
||||||
|
|
||||||
|
|
||||||
void (*get_image)(struct vf_instance_s* vf,
|
void (*get_image)(struct vf_instance_s* vf,
|
||||||
mp_image_t *mpi);
|
mp_image_t *mpi);
|
||||||
|
|
||||||
This is for direct rendering support, works the same way as in libvo drivers.
|
This is for direct rendering support, works the same way as in libvo drivers.
|
||||||
It makes in-place pixel modifications possible.
|
It makes in-place pixel modifications possible.
|
||||||
If you implement it (vf->get_image!=NULL) then it will be called to do the
|
If you implement it (vf->get_image!=NULL) then it will be called to do the
|
||||||
buffer allocation. You SHOULD check the buffer restrictions (stride, type,
|
buffer allocation. You SHOULD check the buffer restrictions (stride, type,
|
||||||
readability etc) and if all OK, then allocate the requested buffer using
|
readability etc) and if everything is OK, then allocate the requested buffer
|
||||||
the vf_get_image() func and copying the buffer pointers.
|
using the vf_get_image() function and copying the buffer pointers.
|
||||||
|
|
||||||
NOTE: You HAVE TO save dmpi pointer, as you'll need it in put_image() later.
|
NOTE: You HAVE TO save the dmpi pointer, as you'll need it in put_image()
|
||||||
It is not guaranteed that you'll get the same mpi for put_image() as in
|
later on. It is not guaranteed that you'll get the same mpi for put_image() as
|
||||||
get_image() (think of out-of-order decoding, get_image is called in decoding
|
in get_image() (think of out-of-order decoding, get_image is called in decoding
|
||||||
order, while put_image is called for display) so the only safe place to save
|
order, while put_image is called for display) so the only safe place to save
|
||||||
it is in the mpi struct itself: mpi->priv=(void*)dmpi;
|
it is in the mpi struct itself: mpi->priv=(void*)dmpi;
|
||||||
|
|
||||||
@ -359,15 +360,15 @@ It's the good old draw_slice callback, already known from libvo.
|
|||||||
If your filter can operate on partial images, you can implement this one
|
If your filter can operate on partial images, you can implement this one
|
||||||
to improve performance (cache utilization).
|
to improve performance (cache utilization).
|
||||||
|
|
||||||
Ah, and there is two set of capability/requirement flags (vfcap.h type)
|
Ah, and there are two sets of capability/requirement flags (vfcap.h type)
|
||||||
in vf_instance_t, used by default query_format() implementation, and by
|
in vf_instance_t, used by the default query_format() implementation, and by
|
||||||
the automatic colorspace/stride matching code (vf_next_config()).
|
the automatic colorspace/stride matching code (vf_next_config()).
|
||||||
|
|
||||||
// caps:
|
// caps:
|
||||||
unsigned int default_caps; // used by default query_format()
|
unsigned int default_caps; // used by default query_format()
|
||||||
unsigned int default_reqs; // used by default config()
|
unsigned int default_reqs; // used by default config()
|
||||||
|
|
||||||
btw, u should avoid using global or static variables, to store filter instance
|
BTW, you should avoid using global or static variables to store filter instance
|
||||||
specific stuff, as filters might be used multiple times & in the future even
|
specific stuff, as filters might be used multiple times & in the future even
|
||||||
multiple streams might be possible
|
multiple streams might be possible
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user