summaryrefslogtreecommitdiffstats
path: root/video/image_writer.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/image_writer.c')
-rw-r--r--video/image_writer.c43
1 files changed, 38 insertions, 5 deletions
diff --git a/video/image_writer.c b/video/image_writer.c
index eda02bef81..9855839262 100644
--- a/video/image_writer.c
+++ b/video/image_writer.c
@@ -79,6 +79,16 @@ struct image_writer_ctx {
struct mp_imgfmt_desc original_format;
};
+static enum AVPixelFormat replace_j_format(enum AVPixelFormat fmt)
+{
+ switch (fmt) {
+ case AV_PIX_FMT_YUV420P: return AV_PIX_FMT_YUVJ420P;
+ case AV_PIX_FMT_YUV422P: return AV_PIX_FMT_YUVJ422P;
+ case AV_PIX_FMT_YUV444P: return AV_PIX_FMT_YUVJ444P;
+ }
+ return fmt;
+}
+
static bool write_lavc(struct image_writer_ctx *ctx, mp_image_t *image, FILE *fp)
{
bool success = 0;
@@ -99,7 +109,11 @@ static bool write_lavc(struct image_writer_ctx *ctx, mp_image_t *image, FILE *fp
avctx->time_base = AV_TIME_BASE_Q;
avctx->width = image->w;
avctx->height = image->h;
+ avctx->color_range = mp_csp_levels_to_avcol_range(image->params.color.levels);
avctx->pix_fmt = imgfmt2pixfmt(image->imgfmt);
+ // Annoying deprecated garbage for the jpg encoder.
+ if (image->params.color.levels == MP_CSP_LEVELS_PC)
+ avctx->pix_fmt = replace_j_format(avctx->pix_fmt);
if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
MP_ERR(ctx, "Image format %s not supported by lavc.\n",
mp_imgfmt_to_name(image->imgfmt));
@@ -127,6 +141,7 @@ static bool write_lavc(struct image_writer_ctx *ctx, mp_image_t *image, FILE *fp
pic->format = avctx->pix_fmt;
pic->width = avctx->width;
pic->height = avctx->height;
+ pic->color_range = avctx->color_range;
if (ctx->opts->tag_csp) {
pic->color_primaries = mp_csp_prim_to_avcol_pri(image->params.color.primaries);
pic->color_trc = mp_csp_trc_to_avcol_trc(image->params.color.gamma);
@@ -281,20 +296,38 @@ struct mp_image *convert_image(struct mp_image *image, int destfmt,
{
int d_w, d_h;
mp_image_params_get_dsize(&image->params, &d_w, &d_h);
- bool is_anamorphic = image->w != d_w || image->h != d_h;
- // Caveat: no colorspace/levels conversion done if pixel formats equal
- // it's unclear what colorspace/levels the target wants
- if (image->imgfmt == destfmt && !is_anamorphic)
+ struct mp_image_params p = {
+ .imgfmt = destfmt,
+ .w = d_w,
+ .h = d_h,
+ .p_w = 1,
+ .p_h = 1,
+ };
+ mp_image_params_guess_csp(&p);
+
+ // If RGB, just assume everything is correct.
+ if (p.color.space != MP_CSP_RGB) {
+ // Currently, assume what FFmpeg's jpg encoder needs.
+ // Of course this works only for non-HDR (no HDR support in libswscale).
+ p.color.levels = MP_CSP_LEVELS_PC;
+ p.color.space = MP_CSP_BT_601;
+ p.chroma_location = MP_CHROMA_CENTER;
+ mp_image_params_guess_csp(&p);
+ }
+
+ if (mp_image_params_equal(&p, &image->params))
return mp_image_new_ref(image);
- struct mp_image *dst = mp_image_alloc(destfmt, d_w, d_h);
+ struct mp_image *dst = mp_image_alloc(p.imgfmt, p.w, p.h);
if (!dst) {
mp_err(log, "Out of memory.\n");
return NULL;
}
mp_image_copy_attributes(dst, image);
+ dst->params = p;
+
if (mp_image_swscale(dst, image, mp_sws_hq_flags) < 0) {
mp_err(log, "Error when converting image.\n");
talloc_free(dst);