diff options
Diffstat (limited to 'video/sws_utils.c')
-rw-r--r-- | video/sws_utils.c | 36 |
1 files changed, 36 insertions, 0 deletions
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 |