Use the video decoder chroma location flags and render chroma locations
other than centered. Until now, we've always used the intuitive and
obvious centered chroma location, but H.264 uses something else.
FFmpeg provides a small overview in libavcodec/avcodec.h:
-----------
/**
* X X 3 4 X X are luma samples,
* 1 2 1-6 are possible chroma positions
* X X 5 6 X 0 is undefined/unknown position
*/
enum AVChromaLocation{
AVCHROMA_LOC_UNSPECIFIED = 0,
AVCHROMA_LOC_LEFT = 1, ///< mpeg2/4, h264 default
AVCHROMA_LOC_CENTER = 2, ///< mpeg1, jpeg, h263
AVCHROMA_LOC_TOPLEFT = 3, ///< DV
AVCHROMA_LOC_TOP = 4,
AVCHROMA_LOC_BOTTOMLEFT = 5,
AVCHROMA_LOC_BOTTOM = 6,
AVCHROMA_LOC_NB , ///< Not part of ABI
};
-----------
The visual difference is literally minimal, but since videophiles
apparently consider this detail as quality mark of a video renderer,
support it anyway. We don't bother with chroma locations other than
centered and left, though.
Not sure about correctness, but it's probably ok.
The filter chain and the video ouputs have config() functions. They are
strictly limited to transfering the video size and format. Other
parameters (like color levels) have to be transferred separately.
Improve upon this by introducing a separate set of reconfig() functions,
which use mp_image_params to carry format parameters. This struct
contains all image format related parameters from config(), plus
additional parameters such as colorspace.
Change vf_rotate to use it, as well as vo_opengl. vf_rotate is just
an example/test case, but vo_opengl will need it later.
The intention is also to get rid of VOCTRL_SET_YUV_COLORSPACE. This
information is now handed to the VOs via reconfig(). The getter,
VOCTRL_GET_YUV_COLORSPACE, will still be needed though.
Audio and video had their own (very similar) functions to initialize an
AVPacket (ffmpeg's packet struct) from a demux_packet (mplayer's packet
struct). Add a common function for these.
Also use this function for sd_lavc_conv. This is actually a functional
change, as some libavfilter subtitle demuxers add weird out-of-band
stuff as side-data.
Most of these are rather questionable, the rest you rarely need to set
manually. You still can set all of them with -lavdopts-o (because
libavcodec has AVOptions for them).
libavcodec generally shouldn't have this problem anymore (if libavcodec
ever had it). All other video decoders are gone. In any case, if this
commit actually causes regressions, these are libavcodec bugs and should
be fixed there instead.
Add the "vf" command, which allows changing the video filter chain at
runtime. For example, the 'y' key could be bound to toggle deinterlacing
by adding 'y vf toggle yadif' to the input.conf.
Reconfiguring the video filter chain normally resets the VO, so that it
will be "stuck" until a new video frame is rendered. To mitigate this, a
seek to the current position is issued when the filter chain is changed.
This is done only if playback is paused, because normal playback will
show an actual new frame quickly enough.
If vdpau hardware decoding is used, filter insertion (whether it fails
or not) will break the video for a while. This is because vo_vdpau
resets decoding related things on vo_config().
This tried to use ctx->pic (last decoded AVFrame) for the frame bounds.
However, if av_frame_unref() on the AVFrame is called, the function will
reset _all_ AVFrame fields, even those which are not involved with
memory management. As result, mpcodecs_config_vo() was called with 0
width/height, which made the function exit early, instead of
reconfiguring the filter chain.
Go back to using mpcodecs_config_vo() directly. (That's what it did
before this VDCTRL was originally introduced; the original reason for
it disappeared.)
This changes the code so that it does the same as MPlayer, mplayer2
and mpv before ref-counted AVFrame. The problem is that get_buffer2
is called with aligned frame dimensions, while get_buffer didn't. This
breaks the mpv video frame size change detection.
This allows using the vdpau decoders with -vd without having to use
the -hwdec switch (basically like in mplayer).
Note that this way of selecting the hardware decoder is still
deprecated. libavcodec went away from adding special decoder entries
for hardware decoding, and instead makes use of the "hwaccel"
architecture, where hardware decoders use the same decoder names as
the software decoders. The old vdpau special decoders will probably
be deprecated and removed in the future.
libavcodec decoder initialization failure caused a segfault, because it
wasn't properly reported back in init().
Also remove the return value from init_avctx(), which actually makes
things simpler. Instead, ctx->avctx can be checked to see whether
initialization was ok.
Makes the code a bit simpler to follow, at least in the "modern"
decoding path (update_video_nocorrect_pts() is used with old demuxers,
which don't return proper packets and need further parsing, so this code
looks less simple now).
Removes almost every global variabel in vo.h and puts them in a special struct
in MPOpts for video output related options.
Also we completly remove the options/globals pts and refresh rate because
they were unused.
OPT_BASE_STRUCT defines which struct the OPT_ macros (like OPT_INT etc.)
reference implicitly, since these macros take struct member names but no
struct type. Normally, only cfg-mplayer.h should need this, and other
places shouldn't be bothered with having to #undef it.
(Some files, like demux_lavf.c, still store their options in MPOpts. In
the long term, this should be removed, and handled like e.g. with VO
suboptions instead.)
This allowed making the player switch the monitor video mode when
creating the video window. This was a questionable feature, and with
today's LCD screens certainly not useful anymore. Switching to a random
video mode (going by video width/height) doesn't sound too useful
either.
I'm not sure about the win32 implementation, but the X part had several
bugs. Even in mplayer-svn (where x11_common.c hasn't been receiving any
larger changes for a long time), this code is buggy and doesn't do the
right thing anyway. (And what the hell _did_ it do when using multiple
physical monitors?)
If you really want this, write a shell script that calls xrandr before
and after calling mpv.
vo_sdl still can do mode switching, because SDL has native support for
it, and using it is trivial. Add a new sub-option for this.
The string is deallocated by the callee after initialization, so
fallback at runtime passes a deallocated string to libavcodec, which
results in random crashes. Regression introduced by commit 4d016a9.
Instead of putting codec header data into WAVEFORMATEX and
BITMAPINFOHEADER, pass it directly via AVCodecContext. To do this, we
add mp_copy_lav_codec_headers(), which copies the codec header data
from one AVCodecContext to another (originally, the plan was to use
avcodec_copy_context() for this, but it looks like this would turn
decoder initialization into an even worse mess).
Get rid of the silly CodecID <-> codec_tag mapping. This was originally
needed for codecs.conf: codec tags were used to identify codecs, but
libavformat didn't always return useful codec tags (different file
formats can have different, overlapping tag numbers). Since we don't
go through WAVEFORMATEX etc. and pass all header data directly via
AVCodecContext, we can be absolutely sure that the codec tag mapping is
not needed anymore.
Note that this also destroys the "standard" MPlayer method of exporting
codec header data. WAVEFORMATEX and BITMAPINFOHEADER made sure that
other non-libavcodec decoders could be initialized. However, all these
decoders have been removed, so this is just cruft full of old hacks that
are not needed anymore. There's still ad_spdif and ad_mpg123, bu neither
of these need codec header data. Should we ever add non-libavcodec
decoders, better data structures without the past hacks could be added
to export the headers.
Rearrange some code to make it easier readable. Remove some dead code,
and stop printing AVI headers in demux_lavf. (These are not actual AVI
headers, just for internal use.)
There should be no functional changes, other than reducing output in
verbose mode.
Use codec names instead of FourCCs to identify codecs. Rewrite how
codecs are selected and initialized. Now each decoder exports a list
of decoders (and the codec it supports) via add_decoders(). The order
matters, and the first decoder for a given decoder is preferred over
the other decoders. E.g. all ad_mpg123 decoders are preferred over
ad_lavc, because it comes first in the mpcodecs_ad_drivers array.
Likewise, decoders within ad_lavc that are enumerated first by
libavcodec (using av_codec_next()) are preferred. (This is actually
critical to select h264 software decoding by default instead of vdpau.
libavcodec and ffmpeg/avconv use the same method to select decoders by
default, so we hope this is sane.)
The codec names follow libavcodec's codec names as defined by
AVCodecDescriptor.name (see libavcodec/codec_desc.c). Some decoders
have names different from the canonical codec name. The AVCodecDescriptor
API is relatively new, so we need a compatibility layer for older
libavcodec versions for codec names that are referenced internally,
and which are different from the decoder name. (Add a configure check
for that, because checking versions is getting way too messy.)
demux/codec_tags.c is generated from the former codecs.conf (minus
"special" decoders like vdpau, and excluding the mappings that are the
same as the mappings libavformat's exported RIFF tables). It contains
all the mappings from FourCCs to codec name. This is needed for
demux_mkv, demux_mpg, demux_avi and demux_asf. demux_lavf will set the
codec as determined by libavformat, while the other demuxers have to do
this on their own, using the mp_set_audio/video_codec_from_tag()
functions. Note that the sh_audio/video->format members don't uniquely
identify the codec anymore, and sh->codec takes over this role.
Replace the --ac/--vc/--afm/--vfm with new --vd/--ad options, which
provide cover the functionality of the removed switched.
Note: there's no CODECS_FLAG_FLIP flag anymore. This means some obscure
container/video combinations (e.g. the sample Film_200_zygo_pro.mov)
are played flipped. ffplay/avplay doesn't handle this properly either,
so we don't care and blame ffmeg/libav instead.
OPT_MAKE_FLAGS() used to emit two options (one with "no" prefixed),
but that has been long removed by special casing flag options in the
option parser. OPT_FLAG_ON() used to imply that there's no "no-"
prefixed option, but this hasn't been the case for a while either.
(Conceptually, it has been replaced by OPT_FLAG_STORE().)
Remove OPT_FLAG_OFF, which was unused.
The decoder returns with AVFrame.format not correctly set for some h264
files (strangely only some). We have to access AVCodecContext.pix_fmt
instead. On newer libavcodec versions, it's the other way around: the
AVCodecContext.pix_fmt may be incorrectly set on pixel format changes,
and you are supposed to use AVFrame.format.
The same problem probably exists on older ffmpeg versions too.
Now the calculations of the final display size are done after the filter
chain. This makes the difference between display aspect ratio and window
size a bit more clear, especially in the -xy case.
With an empty filter chain, the behavior of the options should be the
same, except that they don't affect vo_image and vo_lavc anymore.
This printed per-frame statistics into a file, like bitrate or frame
type. Not very useful and accesses obscure AVCodecContext fields
(danger of deprecation/breakage), so get rid of it.
This was a "broken misfeature" according to Libav developers. It wasn't
implemented for modern codecs (like h264), and has been removed from
Libav a while ago (the AVCodecContext field has been marked as
deprecated and its value is ignored). FFmpeg still supports it, but
isn't much useful due to aforementioned reasons.
Remove the code to enable it.
This is more correct. Not all frame specific fields are in AVFrame,
such as colorspace and color_range, and these are still queried
through the decoder context.
mplayer's video chain traditionally used FourCCs for pixel formats. For
example, it used IMGFMT_YV12 for 4:2:0 YUV, which was defined to the
string 'YV12' interpreted as unsigned int. Additionally, it used to
encode information into the numeric values of some formats. The RGB
formats had their bit depth and endian encoded into the least
significant byte. Extended planar formats (420P10 etc.) had chroma
shift, endian, and component bit depth encoded. (This has been removed
in recent commits.)
Replace the FourCC mess with a simple enum. Remove all the redundant
formats like YV12/I420/IYUV. Replace some image format names by
something more intuitive, most importantly IMGFMT_YV12 -> IMGFMT_420P.
Add img_fourcc.h, which contains the old IDs for code that actually uses
FourCCs. Change the way demuxers, that output raw video, identify the
video format: they set either MP_FOURCC_RAWVIDEO or MP_FOURCC_IMGFMT to
request the rawvideo decoder, and sh_video->imgfmt specifies the pixel
format. Like the previous hack, this is supposed to avoid the need for
a complete codecs.cfg entry per format, or other lookup tables. (Note
that the RGB raw video FourCCs mostly rely on ffmpeg's mappings for NUT
raw video, but this is still considered better than adding a raw video
decoder - even if trivial, it would be full of annoying lookup tables.)
The TV code has not been tested.
Some corrective changes regarding endian and other image format flags
creep in.
According to DOCS/OUTDATED-tech/colorspaces.txt, the following formats
are supposed to be palettized:
IMGFMT_BGR8
IMGFMT_RGB8,
IMGFMT_BGR4_CHAR
IMGFMT_RGB4_CHAR
IMGFMT_BGR4
IMGFMT_RGB4
Of these, only BGR8 and RGB8 are actually treated as palettized in some
way. ffmpeg has only one palettized format (AV_PIX_FMT_PAL8), and
IMGFMT_BGR8 was inconsistently mapped to packed non-palettized RGB
formats too (AV_PIX_FMT_BGR8). Moreover, vf_scale.c contained messy
hacks to generate a palette when AV_PIX_FMT_BGR8 is output. (libswscale
does not support AV_PIX_FMT_PAL8 output in the first place.)
Get rid of all of this, and introduce IMGFMT_PAL8, which directly maps
to AV_PIX_FMT_PAL8. Remove the palette creation code from vf_scale.c.
IMGFMT_BGR8 maps to AV_PIX_FMT_RGB8 (don't ask me why it's swapped),
without any palette use. Enabling it in vo_x11 or using it as vf_scale
input seems to give correct results.
mp_image_alloc_planes() allocated images with minimal stride, even if
the resulting stride was unaligned. It was the responsibility of
vf_get_image() to set an image's width to something larger than
required to get an aligned stride, and then crop it. Always allocate
with aligned strides instead.
Get rid of IMGFMT_IF09 special handling. This format is not used
anymore. (IF09 has 4x4 chroma sub-sampling, and that is what it was
mainly used for - this is still supported.) Get rid of swapped chroma
plane allocation. This is not used anywhere, and VOs like vo_xv,
vo_direct3d and vo_sdl do their own swapping.
Always round chroma width/height up instead of down. Consider 4:2:0 and
an uneven image size. For luma, the size was left uneven, and the chroma
size was rounded down. This doesn't make sense, because chroma would be
missing for the bottom/right border.
Remove mp_image_new_empty() and mp_image_alloc_planes(), they were not
used anymore, except in draw_bmp.c. (It's still allowed to setup
mp_images manually, you just can't allocate image data with them
anymore - this is also done in draw_bmp.c.)
This allows avoiding a copy.
The logic about using the AVFrame.reference field if buffer hints are
not available is similar to mplayer-svn's direct rendering code. This is
needed because h264 decoding doesn't set buffer hints.
<wm4> michaelni: couldn't it set buffer hints from AVFrame.reference then?
<michaelni> i see no reason ATM why that wouldnt be possible
OK...
Change the entire filter API to use reference counted images instead
of vf_get_image().
Remove filter "direct rendering". This was useful for vf_expand and (in
rare cases) vf_sub: DR allowed these filters to pass a cropped image to
the filters before them. Then, on filtering, the image was "uncropped",
so that black bars could be added around the image without copying. This
means that in some cases, vf_expand will be slower (-vf gradfun,expand
for example).
Note that another form of DR used for in-place filters has been replaced
by simpler logic. Instead of trying to do DR, filters can check if the
image is writeable (with mp_image_is_writeable()), and do true in-place
if that's the case. This affects filters like vf_gradfun and vf_sub.
Everything has to support strides now. If something doesn't, making a
copy of the image data is required.
Setting the size of a mp_image must be done with mp_image_set_size()
now. Do this to guarantee that the redundant fields (like chroma_width)
are updated consistently. Replacing the redundant fields by function
calls would probably be better, but there are too many uses of them,
and is a bit less convenient.
Most code actually called mp_image_setfmt(), which did this as well.
This commit just makes things a bit more explicit.
Warning: the video filter chain still sets up mp_images manually,
and vf_get_image() is not updated.
Note that if the codec doesn't support DR1, the image has to be copied.
There is no other way to guarantee that the image will be valid after
decoding the next image.
The only important codec that doesn't support DR1 yet is rawvideo. It's
likely that ffmpeg/Libav will fix this at some time. For now, this
decoder uses an evil hack and puts pointers to the packet data into the
returned frame. This means the image will actually get invalid as soon
as the corresponding video packet is free'd, so copying the image is the
only reasonable thing anyway.
Replace libavcodec's native buffer allocation with code taken from
ffplay/ffmpeg's libavfilter support. The code in lavc_dr1.c is directly
copied from cmdutils.c. Note that this is quite arcane code, which
contains some workarounds for decoder bugs and the like. This is not
really a maintainance burden, since fixes from ffmpeg can be directly
applied to the code in lavc_dr1.c.
It's unknown why libavcodec doesn't provide such a function directly.
avcodec_default_get_buffer() can't be reused for various reasons.
There's some hope that the work known as The Evil Plan [1] will make
custom get_buffer implementations unneeded.
The DR1 support as of this commit does nothing. A future commit will
use it to implement ref-counting for mp_image (similar to how AVFrame
will be ref-counted with The Evil Plan.)
[1] http://lists.libav.org/pipermail/libav-devel/2012-December/039781.html
Deprecate the hardware specific video codec entries (like ffh264vdpau).
Replace them with the --hwdec switch, which requests that a specific
hardware decoding API should be used. The codecs.conf entries will be
removed at a later time, but for now they are useful for testing and
compatibility.
Instead of --vc=ffh264vdpau, --hwdec=vdpau should be used.
Add a fallback if hardware decoding fails. Most hardware decoders
(including vdpau) support only a subset of h264, and having such a
fallback is supposed to enable a better user experience.
This was buggy and didn't even work in the simplest cases. It was
disabled when multithreading was used, and always disabled for h264.
A better alternative (reference counting) will be added later.
Hardware decoding still uses the ffmpeg DR mechanism, but has been
decoupled from mpv's DR in the previous commit.
vdpau hardware decoding used the DR (direct rendering) path to let the
decoder query a surface from the VO. Special-case the HW decoding path
instead, to make it separate from DR.
This mutated the variable for the thread count option
(lavc_param->threads) on decoder initialization. This didn't have any
practical relevance, unless formats supporting hardware video decoding
and other formats were played in the same mpv instance. In this case,
hardware decoding would set threads to 1, and all files played after
that would use only one thread as well even with software decoding.
Remove XvMC leftover (CODEC_CAP_HWACCEL).
Simplify the decoder pixel format handling by making it handle only
the case vd_lavc needs: a video stream always decodes to a single
pixel format.
Remove the handling for multiple pixel formats, and remove the
codecs.conf pixel format declarations that are left.
Remove the handling of "ambiguous" pixel formats like YV12 vs. I420 (via
VDCTRL_QUERY_FORMAT etc.). This is only a problem if the video chain
supports I420, but not YV12, which doesn't seem to be the case anywhere,
and in fact would not have any advantage.
Make the "flip" flag a global per-codec flag, rather than a pixel format
specific flag. (Some ffmpeg decoders still return a flipped image, so
this has to be done manually.) Also fix handling of the flip operation:
do not overwrite the global flip option, and make the --flip option
invert the codec flip option rather than overriding it.