summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
Diffstat (limited to 'video')
-rw-r--r--video/decode/vd_lavc.c3
-rw-r--r--video/fmt-conversion.c9
-rw-r--r--video/sws_utils.c36
-rw-r--r--video/sws_utils.h2
4 files changed, 45 insertions, 5 deletions
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index ff2fa71131..109099e382 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -45,6 +45,7 @@
#include "demux/stheader.h"
#include "demux/packet.h"
#include "video/csputils.h"
+#include "video/sws_utils.h"
#include "lavc.h"
@@ -648,7 +649,7 @@ static int decode(struct dec_video *vd, struct demux_packet *packet,
if (ctx->hwdec && ctx->hwdec->process_image)
mpi = ctx->hwdec->process_image(ctx, mpi);
- *out_image = mpi;
+ *out_image = mp_img_swap_to_native(mpi);
return 1;
}
diff --git a/video/fmt-conversion.c b/video/fmt-conversion.c
index dc278054f3..9ed9777736 100644
--- a/video/fmt-conversion.c
+++ b/video/fmt-conversion.c
@@ -88,29 +88,30 @@ static const struct {
{IMGFMT_XYZ12, AV_PIX_FMT_XYZ12},
- // ffmpeg only
-#if LIBAVUTIL_VERSION_MICRO >= 100
+#ifdef AV_PIX_FMT_YUV420P12
{IMGFMT_420P12, AV_PIX_FMT_YUV420P12},
{IMGFMT_420P14, AV_PIX_FMT_YUV420P14},
{IMGFMT_422P12, AV_PIX_FMT_YUV422P12},
{IMGFMT_422P14, AV_PIX_FMT_YUV422P14},
{IMGFMT_444P12, AV_PIX_FMT_YUV444P12},
{IMGFMT_444P14, AV_PIX_FMT_YUV444P14},
+#endif
+#ifdef AV_PIX_FMT_RGBA64
{IMGFMT_RGBA64, AV_PIX_FMT_RGBA64},
{IMGFMT_BGRA64, AV_PIX_FMT_BGRA64},
+#endif
+#if LIBAVUTIL_VERSION_MICRO >= 100
{IMGFMT_BGR0, AV_PIX_FMT_BGR0},
{IMGFMT_0RGB, AV_PIX_FMT_0RGB},
{IMGFMT_RGB0, AV_PIX_FMT_RGB0},
{IMGFMT_0BGR, AV_PIX_FMT_0BGR},
- {IMGFMT_BGR0, AV_PIX_FMT_BGR0},
#else
{IMGFMT_BGR0, AV_PIX_FMT_BGRA},
{IMGFMT_0RGB, AV_PIX_FMT_ARGB},
{IMGFMT_RGB0, AV_PIX_FMT_RGBA},
{IMGFMT_0BGR, AV_PIX_FMT_ABGR},
- {IMGFMT_BGR0, AV_PIX_FMT_BGRA},
#endif
#ifdef AV_PIX_FMT_YA16
diff --git a/video/sws_utils.c b/video/sws_utils.c
index 8937799f09..7f3cd089ac 100644
--- a/video/sws_utils.c
+++ b/video/sws_utils.c
@@ -20,6 +20,7 @@
#include <libswscale/swscale.h>
#include <libavcodec/avcodec.h>
+#include <libavutil/bswap.h>
#include <libavutil/opt.h>
#include "config.h"
@@ -34,6 +35,7 @@
#include "csputils.h"
#include "common/msg.h"
#include "video/filter/vf.h"
+#include "osdep/endian.h"
//global sws_flags from the command line
struct sws_opts {
@@ -317,4 +319,38 @@ int mp_sws_set_vf_equalizer(struct mp_sws_context *sws, struct vf_seteq *eq)
return mp_sws_reinit(sws) >= 0 ? 1 : -1;
}
+static const int endian_swaps[][2] = {
+#if BYTE_ORDER == LITTLE_ENDIAN
+#if defined(AV_PIX_FMT_YA16) && defined(AV_PIX_FMT_RGBA64)
+ {AV_PIX_FMT_YA16BE, AV_PIX_FMT_YA16LE},
+ {AV_PIX_FMT_RGBA64BE, AV_PIX_FMT_RGBA64LE},
+ {AV_PIX_FMT_GRAY16BE, AV_PIX_FMT_GRAY16LE},
+ {AV_PIX_FMT_RGB48BE, AV_PIX_FMT_RGB48LE},
+#endif
+#endif
+ {AV_PIX_FMT_NONE, AV_PIX_FMT_NONE}
+};
+
+// Swap _some_ non-native endian formats to native. We do this specifically
+// for pixel formats used by PNG, to avoid going through libswscale, which
+// might reduce the effective bit depth in some cases.
+struct mp_image *mp_img_swap_to_native(struct mp_image *img)
+{
+ int to = AV_PIX_FMT_NONE;
+ for (int n = 0; endian_swaps[n][0] != AV_PIX_FMT_NONE; n++) {
+ if (endian_swaps[n][0] == img->fmt.avformat)
+ to = endian_swaps[n][1];
+ }
+ if (to == AV_PIX_FMT_NONE || !mp_image_make_writeable(img))
+ return img;
+ int elems = img->fmt.bytes[0] / 2 * img->w;
+ for (int y = 0; y < img->h; y++) {
+ uint16_t *p = (uint16_t *)(img->planes[0] + y * img->stride[0]);
+ for (int i = 0; i < elems; i++)
+ p[i] = av_be2ne16(p[i]);
+ }
+ mp_image_setfmt(img, pixfmt2imgfmt(to));
+ return img;
+}
+
// vim: ts=4 sw=4 et tw=80
diff --git a/video/sws_utils.h b/video/sws_utils.h
index 7c7c1af34b..ac643dd7cf 100644
--- a/video/sws_utils.h
+++ b/video/sws_utils.h
@@ -59,6 +59,8 @@ struct vf_seteq;
int mp_sws_set_vf_equalizer(struct mp_sws_context *sws, struct vf_seteq *eq);
int mp_sws_get_vf_equalizer(struct mp_sws_context *sws, struct vf_seteq *eq);
+struct mp_image *mp_img_swap_to_native(struct mp_image *img);
+
#endif /* MP_SWS_UTILS_H */
// vim: ts=4 sw=4 et tw=80