2012-12-11 17:27:34 +00:00
|
|
|
#ifndef MPV_LAVC_H
|
|
|
|
#define MPV_LAVC_H
|
|
|
|
|
2012-12-11 23:43:50 +00:00
|
|
|
#include <stdbool.h>
|
|
|
|
|
2012-12-11 17:27:34 +00:00
|
|
|
#include <libavcodec/avcodec.h>
|
|
|
|
|
2013-03-09 19:50:06 +00:00
|
|
|
#include "config.h"
|
|
|
|
|
2012-12-11 17:27:34 +00:00
|
|
|
#include "demux/stheader.h"
|
|
|
|
#include "video/mp_image.h"
|
2013-11-23 20:26:31 +00:00
|
|
|
#include "video/hwdec.h"
|
2012-12-11 17:27:34 +00:00
|
|
|
|
2013-08-11 21:23:12 +00:00
|
|
|
// keep in sync with --hwdec option
|
|
|
|
enum hwdec_type {
|
|
|
|
HWDEC_AUTO = -1,
|
|
|
|
HWDEC_NONE = 0,
|
|
|
|
HWDEC_VDPAU = 1,
|
|
|
|
HWDEC_VDA = 2,
|
|
|
|
HWDEC_CRYSTALHD = 3,
|
video: add vaapi decode and output support
This is based on the MPlayer VA API patches. To be exact it's based on
a very stripped down version of commit f1ad459a263f8537f6c from
git://gitorious.org/vaapi/mplayer.git.
This doesn't contain useless things like benchmarking hacks and the
demo code for GLX interop. Also, unlike in the original patch, decoding
and video output are split into separate source files (the separation
between decoding and display also makes pixel format hacks unnecessary).
On the other hand, some features not present in the original patch were
added, like screenshot support.
VA API is rather bad for actual video output. Dealing with older libva
versions or the completely broken vdpau backend doesn't help. OSD is
low quality and should be rather slow. In some cases, only either OSD
or subtitles can be shown at the same time (because OSD is drawn first,
OSD is prefered).
Also, libva can't decide whether it accepts straight or premultiplied
alpha for OSD sub-pictures: the vdpau backend seems to assume
premultiplied, while a native vaapi driver uses straight. So I picked
straight alpha. It doesn't matter much, because the blending code for
straight alpha I added to img_convert.c is probably buggy, and ASS
subtitles might be blended incorrectly.
Really good video output with VA API would probably use OpenGL and the
GL interop features, but at this point you might just use vo_opengl.
(Patches for making HW decoding with vo_opengl have a chance of being
accepted.)
Despite these issues, decoding seems to work ok. I still got tearing
on the Intel system I tested (Intel(R) Core(TM) i3-2350M). It was also
tested with the vdpau vaapi wrapper on a nvidia system; however this
was rather broken. (Fortunately, there is no reason to use mpv's VAAPI
support over native VDPAU.)
2013-08-09 12:01:30 +00:00
|
|
|
HWDEC_VAAPI = 4,
|
2013-09-22 20:47:50 +00:00
|
|
|
HWDEC_VAAPI_COPY = 5,
|
2013-08-11 21:23:12 +00:00
|
|
|
};
|
|
|
|
|
vdpau: split off decoder parts, use "new" libavcodec vdpau hwaccel API
Move the decoder parts from vo_vdpau.c to a new file vdpau_old.c. This
file is named so because because it's written against the "old"
libavcodec vdpau pseudo-decoder (e.g. "h264_vdpau").
Add support for the "new" libavcodec vdpau support. This was recently
added and replaces the "old" vdpau parts. (In fact, Libav is about to
deprecate and remove the "old" API without deprecation grace period,
so we have to support it now. Moreover, there will probably be no Libav
release which supports both, so the transition is even less smooth than
we could hope, and we have to support both the old and new API.)
Whether the old or new API is used is checked by a configure test: if
the new API is found, it is used, otherwise the old API is assumed.
Some details might be handled differently. Especially display preemption
is a bit problematic with the "new" libavcodec vdpau support: it wants
to keep a pointer to a specific vdpau API function (which can be driver
specific, because preemption might switch drivers). Also, surface IDs
are now directly stored in AVFrames (and mp_images), so they can't be
forced to VDP_INVALID_HANDLE on preemption. (This changes even with
older libavcodec versions, because mp_image always uses the newer
representation to make vo_vdpau.c simpler.)
Decoder initialization in the new code tries to deal with codec
profiles, while the old code always uses the highest profile per codec.
Surface allocation changes. Since the decoder won't call config() in
vo_vdpau.c on video size change anymore, we allow allocating surfaces
of arbitrary size instead of locking it to what the VO was configured.
The non-hwdec code also has slightly different allocation behavior now.
Enabling the old vdpau special decoders via e.g. --vd=lavc:h264_vdpau
doesn't work anymore (a warning suggesting the --hwdec option is
printed instead).
2013-07-27 23:49:45 +00:00
|
|
|
typedef struct lavc_ctx {
|
2013-11-01 16:14:05 +00:00
|
|
|
struct MPOpts *opts;
|
2012-12-11 17:27:34 +00:00
|
|
|
AVCodecContext *avctx;
|
|
|
|
AVFrame *pic;
|
2013-08-11 21:23:12 +00:00
|
|
|
struct vd_lavc_hwdec *hwdec;
|
2013-11-29 16:39:57 +00:00
|
|
|
enum AVPixelFormat pix_fmt;
|
2013-03-09 19:50:06 +00:00
|
|
|
int do_hw_dr1;
|
2012-12-11 17:27:34 +00:00
|
|
|
int best_csp;
|
|
|
|
enum AVDiscard skip_frame;
|
core: redo how codecs are mapped, remove codecs.conf
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.
2013-02-09 14:15:19 +00:00
|
|
|
const char *software_fallback_decoder;
|
2013-03-09 19:50:06 +00:00
|
|
|
|
vdpau: split off decoder parts, use "new" libavcodec vdpau hwaccel API
Move the decoder parts from vo_vdpau.c to a new file vdpau_old.c. This
file is named so because because it's written against the "old"
libavcodec vdpau pseudo-decoder (e.g. "h264_vdpau").
Add support for the "new" libavcodec vdpau support. This was recently
added and replaces the "old" vdpau parts. (In fact, Libav is about to
deprecate and remove the "old" API without deprecation grace period,
so we have to support it now. Moreover, there will probably be no Libav
release which supports both, so the transition is even less smooth than
we could hope, and we have to support both the old and new API.)
Whether the old or new API is used is checked by a configure test: if
the new API is found, it is used, otherwise the old API is assumed.
Some details might be handled differently. Especially display preemption
is a bit problematic with the "new" libavcodec vdpau support: it wants
to keep a pointer to a specific vdpau API function (which can be driver
specific, because preemption might switch drivers). Also, surface IDs
are now directly stored in AVFrames (and mp_images), so they can't be
forced to VDP_INVALID_HANDLE on preemption. (This changes even with
older libavcodec versions, because mp_image always uses the newer
representation to make vo_vdpau.c simpler.)
Decoder initialization in the new code tries to deal with codec
profiles, while the old code always uses the highest profile per codec.
Surface allocation changes. Since the decoder won't call config() in
vo_vdpau.c on video size change anymore, we allow allocating surfaces
of arbitrary size instead of locking it to what the VO was configured.
The non-hwdec code also has slightly different allocation behavior now.
Enabling the old vdpau special decoders via e.g. --vd=lavc:h264_vdpau
doesn't work anymore (a warning suggesting the --hwdec option is
printed instead).
2013-07-27 23:49:45 +00:00
|
|
|
// From VO
|
|
|
|
struct mp_hwdec_info *hwdec_info;
|
|
|
|
|
|
|
|
// For free use by hwdec implementation
|
|
|
|
void *hwdec_priv;
|
|
|
|
|
|
|
|
// Legacy
|
2013-03-09 19:50:06 +00:00
|
|
|
bool do_dr1;
|
2012-12-11 17:27:34 +00:00
|
|
|
struct FramePool *dr1_buffer_pool;
|
video/filter: change filter API, use refcounting, remove filter DR
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.
2012-11-05 13:25:04 +00:00
|
|
|
struct mp_image_pool *non_dr1_pool;
|
2012-12-11 17:27:34 +00:00
|
|
|
} vd_ffmpeg_ctx;
|
|
|
|
|
2013-08-11 21:23:12 +00:00
|
|
|
struct vd_lavc_hwdec {
|
|
|
|
enum hwdec_type type;
|
|
|
|
// If non-NULL: lists pairs software and hardware decoders. If the current
|
|
|
|
// codec is not one of the listed software decoders, probing fails.
|
|
|
|
// Otherwise, the AVCodecContext is initialized with the associated
|
|
|
|
// hardware decoder.
|
|
|
|
// Useful only if hw decoding requires a special codec, instead of using
|
|
|
|
// the libavcodec hwaccel infrastructure.
|
|
|
|
const char **codec_pairs;
|
|
|
|
// If not-NULL: a 0 terminated list of IMGFMT_ formats, and only one of
|
|
|
|
// these formats is accepted in the libavcodec get_format callback.
|
vdpau: split off decoder parts, use "new" libavcodec vdpau hwaccel API
Move the decoder parts from vo_vdpau.c to a new file vdpau_old.c. This
file is named so because because it's written against the "old"
libavcodec vdpau pseudo-decoder (e.g. "h264_vdpau").
Add support for the "new" libavcodec vdpau support. This was recently
added and replaces the "old" vdpau parts. (In fact, Libav is about to
deprecate and remove the "old" API without deprecation grace period,
so we have to support it now. Moreover, there will probably be no Libav
release which supports both, so the transition is even less smooth than
we could hope, and we have to support both the old and new API.)
Whether the old or new API is used is checked by a configure test: if
the new API is found, it is used, otherwise the old API is assumed.
Some details might be handled differently. Especially display preemption
is a bit problematic with the "new" libavcodec vdpau support: it wants
to keep a pointer to a specific vdpau API function (which can be driver
specific, because preemption might switch drivers). Also, surface IDs
are now directly stored in AVFrames (and mp_images), so they can't be
forced to VDP_INVALID_HANDLE on preemption. (This changes even with
older libavcodec versions, because mp_image always uses the newer
representation to make vo_vdpau.c simpler.)
Decoder initialization in the new code tries to deal with codec
profiles, while the old code always uses the highest profile per codec.
Surface allocation changes. Since the decoder won't call config() in
vo_vdpau.c on video size change anymore, we allow allocating surfaces
of arbitrary size instead of locking it to what the VO was configured.
The non-hwdec code also has slightly different allocation behavior now.
Enabling the old vdpau special decoders via e.g. --vd=lavc:h264_vdpau
doesn't work anymore (a warning suggesting the --hwdec option is
printed instead).
2013-07-27 23:49:45 +00:00
|
|
|
const int *image_formats;
|
2013-08-11 21:23:12 +00:00
|
|
|
int (*probe)(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
|
|
|
|
const char *decoder);
|
vdpau: split off decoder parts, use "new" libavcodec vdpau hwaccel API
Move the decoder parts from vo_vdpau.c to a new file vdpau_old.c. This
file is named so because because it's written against the "old"
libavcodec vdpau pseudo-decoder (e.g. "h264_vdpau").
Add support for the "new" libavcodec vdpau support. This was recently
added and replaces the "old" vdpau parts. (In fact, Libav is about to
deprecate and remove the "old" API without deprecation grace period,
so we have to support it now. Moreover, there will probably be no Libav
release which supports both, so the transition is even less smooth than
we could hope, and we have to support both the old and new API.)
Whether the old or new API is used is checked by a configure test: if
the new API is found, it is used, otherwise the old API is assumed.
Some details might be handled differently. Especially display preemption
is a bit problematic with the "new" libavcodec vdpau support: it wants
to keep a pointer to a specific vdpau API function (which can be driver
specific, because preemption might switch drivers). Also, surface IDs
are now directly stored in AVFrames (and mp_images), so they can't be
forced to VDP_INVALID_HANDLE on preemption. (This changes even with
older libavcodec versions, because mp_image always uses the newer
representation to make vo_vdpau.c simpler.)
Decoder initialization in the new code tries to deal with codec
profiles, while the old code always uses the highest profile per codec.
Surface allocation changes. Since the decoder won't call config() in
vo_vdpau.c on video size change anymore, we allow allocating surfaces
of arbitrary size instead of locking it to what the VO was configured.
The non-hwdec code also has slightly different allocation behavior now.
Enabling the old vdpau special decoders via e.g. --vd=lavc:h264_vdpau
doesn't work anymore (a warning suggesting the --hwdec option is
printed instead).
2013-07-27 23:49:45 +00:00
|
|
|
int (*init)(struct lavc_ctx *ctx);
|
|
|
|
void (*uninit)(struct lavc_ctx *ctx);
|
2013-08-15 16:20:15 +00:00
|
|
|
struct mp_image *(*allocate_image)(struct lavc_ctx *ctx, int fmt,
|
|
|
|
int w, int h);
|
2013-08-15 16:21:54 +00:00
|
|
|
// Process the image returned by the libavcodec decoder.
|
|
|
|
struct mp_image *(*process_image)(struct lavc_ctx *ctx, struct mp_image *img);
|
vdpau: split off decoder parts, use "new" libavcodec vdpau hwaccel API
Move the decoder parts from vo_vdpau.c to a new file vdpau_old.c. This
file is named so because because it's written against the "old"
libavcodec vdpau pseudo-decoder (e.g. "h264_vdpau").
Add support for the "new" libavcodec vdpau support. This was recently
added and replaces the "old" vdpau parts. (In fact, Libav is about to
deprecate and remove the "old" API without deprecation grace period,
so we have to support it now. Moreover, there will probably be no Libav
release which supports both, so the transition is even less smooth than
we could hope, and we have to support both the old and new API.)
Whether the old or new API is used is checked by a configure test: if
the new API is found, it is used, otherwise the old API is assumed.
Some details might be handled differently. Especially display preemption
is a bit problematic with the "new" libavcodec vdpau support: it wants
to keep a pointer to a specific vdpau API function (which can be driver
specific, because preemption might switch drivers). Also, surface IDs
are now directly stored in AVFrames (and mp_images), so they can't be
forced to VDP_INVALID_HANDLE on preemption. (This changes even with
older libavcodec versions, because mp_image always uses the newer
representation to make vo_vdpau.c simpler.)
Decoder initialization in the new code tries to deal with codec
profiles, while the old code always uses the highest profile per codec.
Surface allocation changes. Since the decoder won't call config() in
vo_vdpau.c on video size change anymore, we allow allocating surfaces
of arbitrary size instead of locking it to what the VO was configured.
The non-hwdec code also has slightly different allocation behavior now.
Enabling the old vdpau special decoders via e.g. --vd=lavc:h264_vdpau
doesn't work anymore (a warning suggesting the --hwdec option is
printed instead).
2013-07-27 23:49:45 +00:00
|
|
|
};
|
|
|
|
|
2013-08-11 21:23:12 +00:00
|
|
|
enum {
|
|
|
|
HWDEC_ERR_NO_CTX = -2,
|
|
|
|
HWDEC_ERR_NO_CODEC = -3,
|
|
|
|
};
|
|
|
|
|
2013-11-01 16:14:05 +00:00
|
|
|
struct hwdec_profile_entry {
|
|
|
|
enum AVCodecID av_codec;
|
|
|
|
int ff_profile;
|
|
|
|
uint64_t hw_profile;
|
|
|
|
};
|
|
|
|
|
|
|
|
const struct hwdec_profile_entry *hwdec_find_profile(
|
|
|
|
struct lavc_ctx *ctx, const struct hwdec_profile_entry *table);
|
|
|
|
bool hwdec_check_codec_support(const char *decoder,
|
|
|
|
const struct hwdec_profile_entry *table);
|
|
|
|
int hwdec_get_max_refs(struct lavc_ctx *ctx);
|
|
|
|
|
2013-03-09 19:50:06 +00:00
|
|
|
// lavc_dr1.c
|
2012-12-11 17:27:34 +00:00
|
|
|
int mp_codec_get_buffer(AVCodecContext *s, AVFrame *frame);
|
|
|
|
void mp_codec_release_buffer(AVCodecContext *s, AVFrame *frame);
|
|
|
|
struct FrameBuffer;
|
|
|
|
void mp_buffer_ref(struct FrameBuffer *buffer);
|
|
|
|
void mp_buffer_unref(struct FrameBuffer *buffer);
|
2012-12-11 23:43:50 +00:00
|
|
|
bool mp_buffer_is_unique(struct FrameBuffer *buffer);
|
2012-12-11 17:27:34 +00:00
|
|
|
void mp_buffer_pool_free(struct FramePool **pool);
|
|
|
|
|
|
|
|
#endif
|