mirror of https://github.com/mpv-player/mpv
image_writer: share some code between write_lavc and write_avif
As a consequence: - write_avif now respects tag-colorspace=no - write_lavc additionally sets colorspace and chroma_location (of no consequence for png or jpeg)
This commit is contained in:
parent
8f26d99fbd
commit
f95339c02a
|
@ -124,6 +124,43 @@ static enum AVPixelFormat replace_j_format(enum AVPixelFormat fmt)
|
||||||
return fmt;
|
return fmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void prepare_avframe(AVFrame *pic, AVCodecContext *avctx,
|
||||||
|
mp_image_t *image, bool tag_csp,
|
||||||
|
struct mp_log *log)
|
||||||
|
{
|
||||||
|
for (int n = 0; n < 4; n++) {
|
||||||
|
pic->data[n] = image->planes[n];
|
||||||
|
pic->linesize[n] = image->stride[n];
|
||||||
|
}
|
||||||
|
pic->format = avctx->pix_fmt;
|
||||||
|
pic->width = avctx->width;
|
||||||
|
pic->height = avctx->height;
|
||||||
|
avctx->color_range = pic->color_range =
|
||||||
|
mp_csp_levels_to_avcol_range(image->params.color.levels);
|
||||||
|
|
||||||
|
if (!tag_csp)
|
||||||
|
return;
|
||||||
|
avctx->color_primaries = pic->color_primaries =
|
||||||
|
mp_csp_prim_to_avcol_pri(image->params.color.primaries);
|
||||||
|
avctx->color_trc = pic->color_trc =
|
||||||
|
mp_csp_trc_to_avcol_trc(image->params.color.gamma);
|
||||||
|
avctx->colorspace = pic->colorspace =
|
||||||
|
mp_csp_to_avcol_spc(image->params.color.space);
|
||||||
|
avctx->chroma_sample_location = pic->chroma_location =
|
||||||
|
mp_chroma_location_to_av(image->params.chroma_location);
|
||||||
|
mp_dbg(log, "mapped color params:\n"
|
||||||
|
" trc = %s\n"
|
||||||
|
" primaries = %s\n"
|
||||||
|
" range = %s\n"
|
||||||
|
" colorspace = %s\n"
|
||||||
|
" chroma_location = %s\n",
|
||||||
|
av_color_transfer_name(avctx->color_trc),
|
||||||
|
av_color_primaries_name(avctx->color_primaries),
|
||||||
|
av_color_range_name(avctx->color_range),
|
||||||
|
av_color_space_name(avctx->colorspace),
|
||||||
|
av_chroma_location_name(avctx->chroma_sample_location)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
static bool write_lavc(struct image_writer_ctx *ctx, mp_image_t *image, const char *filename)
|
static bool write_lavc(struct image_writer_ctx *ctx, mp_image_t *image, const char *filename)
|
||||||
{
|
{
|
||||||
|
@ -154,7 +191,6 @@ static bool write_lavc(struct image_writer_ctx *ctx, mp_image_t *image, const ch
|
||||||
avctx->time_base = AV_TIME_BASE_Q;
|
avctx->time_base = AV_TIME_BASE_Q;
|
||||||
avctx->width = image->w;
|
avctx->width = image->w;
|
||||||
avctx->height = image->h;
|
avctx->height = image->h;
|
||||||
avctx->color_range = mp_csp_levels_to_avcol_range(image->params.color.levels);
|
|
||||||
avctx->pix_fmt = imgfmt2pixfmt(image->imgfmt);
|
avctx->pix_fmt = imgfmt2pixfmt(image->imgfmt);
|
||||||
if (codec->id == AV_CODEC_ID_MJPEG) {
|
if (codec->id == AV_CODEC_ID_MJPEG) {
|
||||||
// Annoying deprecated garbage for the jpg encoder.
|
// Annoying deprecated garbage for the jpg encoder.
|
||||||
|
@ -198,24 +234,11 @@ static bool write_lavc(struct image_writer_ctx *ctx, mp_image_t *image, const ch
|
||||||
pic = av_frame_alloc();
|
pic = av_frame_alloc();
|
||||||
if (!pic)
|
if (!pic)
|
||||||
goto error_exit;
|
goto error_exit;
|
||||||
for (int n = 0; n < 4; n++) {
|
prepare_avframe(pic, avctx, image, ctx->opts->tag_csp, ctx->log);
|
||||||
pic->data[n] = image->planes[n];
|
|
||||||
pic->linesize[n] = image->stride[n];
|
|
||||||
}
|
|
||||||
pic->format = avctx->pix_fmt;
|
|
||||||
pic->width = avctx->width;
|
|
||||||
pic->height = avctx->height;
|
|
||||||
pic->color_range = avctx->color_range;
|
|
||||||
if (codec->id == AV_CODEC_ID_MJPEG) {
|
if (codec->id == AV_CODEC_ID_MJPEG) {
|
||||||
int qscale = 1 + (100 - ctx->opts->jpeg_quality) * 30 / 100;
|
int qscale = 1 + (100 - ctx->opts->jpeg_quality) * 30 / 100;
|
||||||
pic->quality = qscale * FF_QP2LAMBDA;
|
pic->quality = qscale * FF_QP2LAMBDA;
|
||||||
}
|
}
|
||||||
if (ctx->opts->tag_csp) {
|
|
||||||
avctx->color_primaries = pic->color_primaries =
|
|
||||||
mp_csp_prim_to_avcol_pri(image->params.color.primaries);
|
|
||||||
avctx->color_trc = pic->color_trc =
|
|
||||||
mp_csp_trc_to_avcol_trc(image->params.color.gamma);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ret = avcodec_send_frame(avctx, pic);
|
int ret = avcodec_send_frame(avctx, pic);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -390,26 +413,10 @@ static bool write_avif(struct image_writer_ctx *ctx, mp_image_t *image,
|
||||||
goto free_data;
|
goto free_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int n = 0; n < 4; n++) {
|
prepare_avframe(pic, avctx, image, ctx->opts->tag_csp, ctx->log);
|
||||||
pic->data[n] = image->planes[n];
|
|
||||||
pic->linesize[n] = image->stride[n];
|
|
||||||
}
|
|
||||||
pic->format = avctx->pix_fmt;
|
|
||||||
pic->width = avctx->width;
|
|
||||||
pic->height = avctx->height;
|
|
||||||
// Not setting this flag caused ffmpeg to output avif that was not passing
|
// Not setting this flag caused ffmpeg to output avif that was not passing
|
||||||
// standard checks but ffmpeg would still read and not complain...
|
// standard checks but ffmpeg would still read and not complain...
|
||||||
avctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
avctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
||||||
avctx->color_range = pic->color_range =
|
|
||||||
mp_csp_levels_to_avcol_range(image->params.color.levels);
|
|
||||||
avctx->color_primaries = pic->color_primaries =
|
|
||||||
mp_csp_prim_to_avcol_pri(image->params.color.primaries);
|
|
||||||
avctx->color_trc = pic->color_trc =
|
|
||||||
mp_csp_trc_to_avcol_trc(image->params.color.gamma);
|
|
||||||
avctx->colorspace = pic->colorspace =
|
|
||||||
mp_csp_to_avcol_spc(image->params.color.space);
|
|
||||||
avctx->chroma_sample_location = pic->chroma_location =
|
|
||||||
mp_chroma_location_to_av(image->params.chroma_location);
|
|
||||||
|
|
||||||
ret = avcodec_open2(avctx, codec, NULL);
|
ret = avcodec_open2(avctx, codec, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -443,19 +450,6 @@ static bool write_avif(struct image_writer_ctx *ctx, mp_image_t *image,
|
||||||
goto free_data;
|
goto free_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
MP_DBG(ctx, "write_avif() Codec Context:\n"
|
|
||||||
" color_trc = %s\n"
|
|
||||||
" color_primaries = %s\n"
|
|
||||||
" color_range = %s\n"
|
|
||||||
" colorspace = %s\n"
|
|
||||||
" chroma_sample_location = %s\n",
|
|
||||||
av_color_transfer_name(avctx->color_trc),
|
|
||||||
av_color_primaries_name(avctx->color_primaries),
|
|
||||||
av_color_range_name(avctx->color_range),
|
|
||||||
av_color_space_name(avctx->colorspace),
|
|
||||||
av_chroma_location_name(avctx->chroma_sample_location)
|
|
||||||
);
|
|
||||||
|
|
||||||
ret = avformat_init_output(fmtctx, NULL);
|
ret = avformat_init_output(fmtctx, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
MP_ERR(ctx, "Could not initialize output\n");
|
MP_ERR(ctx, "Could not initialize output\n");
|
||||||
|
|
Loading…
Reference in New Issue