Skip to content

Commit d4dd457

Browse files
committed
Add colorspace normalize filter
This filter can force the color TRC to whatever the consumer requests.
1 parent 0e0b634 commit d4dd457

14 files changed

Lines changed: 454 additions & 3 deletions

src/framework/chain_normalizers.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ rescaler=movit.resample,swscale,gtkrescale,rescale
1414
resizer=movit.resize,resize
1515
movitconvert=movit.convert
1616
imageconvert=avcolor_space,imageconvert
17+
colorspace=colorspace
1718

1819
# audio links
1920
audioconvert=audioconvert

src/framework/mlt.vers

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,4 +677,5 @@ MLT_7.34.0 {
677677
mlt_image_colorspace_id;
678678
mlt_image_color_pri_name;
679679
mlt_image_color_pri_id;
680+
mlt_image_default_trc;
680681
} MLT_7.32.0;

src/framework/mlt_consumer.c

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* \brief abstraction for all consumer services
44
* \see mlt_consumer_s
55
*
6-
* Copyright (C) 2003-2023 Meltytech, LLC
6+
* Copyright (C) 2003-2025 Meltytech, LLC
77
*
88
* This library is free software; you can redistribute it and/or
99
* modify it under the terms of the GNU Lesser General Public
@@ -21,6 +21,7 @@
2121
*/
2222

2323
#include "mlt_consumer.h"
24+
#include "mlt_cache.h"
2425
#include "mlt_factory.h"
2526
#include "mlt_frame.h"
2627
#include "mlt_log.h"
@@ -682,12 +683,43 @@ mlt_frame mlt_consumer_get_frame(mlt_consumer self)
682683
mlt_properties_set(frame_properties,
683684
"consumer.color_trc",
684685
mlt_properties_get(properties, "color_trc"));
686+
mlt_properties_set(frame_properties,
687+
"consumer.mlt_color_trc",
688+
mlt_properties_get(properties, "mlt_color_trc"));
685689
mlt_properties_set(frame_properties,
686690
"consumer.channel_layout",
687691
mlt_properties_get(properties, "channel_layout"));
688692
mlt_properties_set(frame_properties,
689693
"consumer.color_range",
690694
mlt_properties_get(properties, "color_range"));
695+
696+
if (mlt_properties_get(properties, "mlt_color_trc")) {
697+
// Add a normalize filter to convert the mlt_color_trc to color_trc
698+
mlt_cache_item cache_item = mlt_service_cache_get(service, "cs_filter");
699+
if (!cache_item) {
700+
mlt_profile profile = mlt_service_profile(service);
701+
mlt_filter cs_filter = mlt_factory_filter(profile, "colorspace", NULL);
702+
mlt_properties cs_properties = MLT_FILTER_PROPERTIES(cs_filter);
703+
if (cs_filter) {
704+
const char *color_trc_str = mlt_properties_get(properties, "color_trc");
705+
mlt_color_trc trc = mlt_image_color_trc_id(color_trc_str);
706+
if (trc == mlt_color_trc_none)
707+
trc = mlt_image_default_trc(profile->colorspace);
708+
mlt_properties_set_int(cs_properties, "force_trc", trc);
709+
mlt_service_cache_put(service,
710+
"cs_filter",
711+
cs_filter,
712+
0,
713+
(mlt_destructor) mlt_filter_close);
714+
}
715+
cache_item = mlt_service_cache_get(service, "cs_filter");
716+
}
717+
if (cache_item) {
718+
mlt_filter cs_filter = mlt_cache_item_data(cache_item, NULL);
719+
mlt_filter_process(cs_filter, frame);
720+
mlt_cache_item_close(cache_item);
721+
}
722+
}
691723
}
692724

693725
// Return the frame
@@ -1716,6 +1748,7 @@ void mlt_consumer_close(mlt_consumer self)
17161748

17171749
pthread_mutex_destroy(&priv->position_mutex);
17181750

1751+
mlt_service_cache_purge(&self->parent);
17191752
mlt_service_close(&self->parent);
17201753
free(priv);
17211754
}

src/framework/mlt_image.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,43 @@ mlt_color_primaries mlt_image_color_pri_id(const char *name)
472472
return mlt_color_pri_none;
473473
}
474474

475+
/** Get the default color transfer characteristics for a given colorspace.
476+
*
477+
* \public \memberof mlt_image_s
478+
* \param colorspace the colorspace
479+
* \return a color trc
480+
*/
481+
482+
mlt_color_trc mlt_image_default_trc(mlt_colorspace colorspace)
483+
{
484+
switch (colorspace) {
485+
case mlt_colorspace_rgb:
486+
return mlt_color_trc_iec61966_2_1;
487+
case mlt_colorspace_bt709:
488+
return mlt_color_trc_bt709;
489+
case mlt_colorspace_bt470bg:
490+
return mlt_color_trc_gamma28;
491+
case mlt_colorspace_smpte170m:
492+
return mlt_color_trc_smpte170m;
493+
case mlt_colorspace_smpte240m:
494+
return mlt_color_trc_smpte240m;
495+
case mlt_colorspace_bt2020_ncl:
496+
return mlt_color_trc_bt2020_10;
497+
case mlt_colorspace_bt2020_cl:
498+
return mlt_color_trc_bt2020_10;
499+
case mlt_colorspace_bt601:
500+
return mlt_color_trc_smpte170m;
501+
case mlt_colorspace_smpte2085:
502+
case mlt_colorspace_fcc:
503+
case mlt_colorspace_ycgco:
504+
case mlt_colorspace_unspecified:
505+
case mlt_colorspace_reserved:
506+
case mlt_colorspace_invalid:
507+
break;
508+
}
509+
return mlt_color_trc_bt709;
510+
}
511+
475512
/** Fill an image with black.
476513
*
477514
* \bug This does not respect full range YUV if needed.

src/framework/mlt_image.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ MLT_EXPORT const char *mlt_image_colorspace_name(mlt_colorspace colorspace);
6969
MLT_EXPORT mlt_colorspace mlt_image_colorspace_id(const char *name);
7070
MLT_EXPORT const char *mlt_image_color_pri_name(mlt_color_primaries primaries);
7171
MLT_EXPORT mlt_color_primaries mlt_image_color_pri_id(const char *name);
72+
MLT_EXPORT mlt_color_trc mlt_image_default_trc(mlt_colorspace colorspace);
7273
MLT_EXPORT int mlt_image_rgba_opaque(uint8_t *image, int width, int height);
7374
MLT_EXPORT int mlt_image_full_range(const char *color_range);
7475

src/modules/avformat/common.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,11 @@ int mlt_to_av_color_range(int full_range)
615615
return full_range ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
616616
}
617617

618+
int av_to_mlt_full_range(int color_range)
619+
{
620+
return color_range == AVCOL_RANGE_JPEG;
621+
}
622+
618623
void mlt_image_to_avframe(mlt_image image, mlt_frame mltframe, AVFrame *avframe)
619624
{
620625
mlt_properties frame_properties = MLT_FRAME_PROPERTIES(mltframe);

src/modules/avformat/common.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* common.h
3-
* Copyright (C) 2018-2024 Meltytech, LLC
3+
* Copyright (C) 2018-2025 Meltytech, LLC
44
*
55
* This library is free software; you can redistribute it and/or
66
* modify it under the terms of the GNU Lesser General Public
@@ -52,6 +52,7 @@ int mlt_to_av_color_primaries(mlt_color_primaries primaries);
5252
mlt_color_primaries av_to_mlt_color_primaries(int primaries);
5353
mlt_color_primaries mlt_color_primaries_from_colorspace(mlt_colorspace colorspace, int height);
5454
int mlt_to_av_color_range(int full_range);
55+
int av_to_mlt_full_range(int color_range);
5556
void mlt_image_to_avframe(mlt_image image, mlt_frame mltframe, AVFrame *avframe);
5657
void avframe_to_mlt_image(AVFrame *avframe, mlt_image image);
5758

src/modules/avformat/filter_avfilter.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,20 @@ static int filter_get_image(mlt_frame frame,
953953
src += pdata->avoutframe->linesize[0];
954954
}
955955
}
956+
mlt_properties_set_int(frame_properties,
957+
"color_trc",
958+
av_to_mlt_color_trc(pdata->avoutframe->color_trc));
959+
mlt_properties_set_int(frame_properties,
960+
"colorspace",
961+
av_to_mlt_colorspace(pdata->avoutframe->colorspace,
962+
pdata->avoutframe->width,
963+
pdata->avoutframe->height));
964+
mlt_properties_set_int(frame_properties,
965+
"color_primaries",
966+
av_to_mlt_color_primaries(pdata->avoutframe->color_primaries));
967+
mlt_properties_set_int(frame_properties,
968+
"full_range",
969+
av_to_mlt_full_range(pdata->avoutframe->color_range));
956970
}
957971

958972
exit:

src/modules/avformat/link_avfilter.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,6 +1039,20 @@ static int link_get_image(mlt_frame frame,
10391039
src += pdata->avoutframe->linesize[0];
10401040
}
10411041
}
1042+
mlt_properties_set_int(frame_properties,
1043+
"color_trc",
1044+
av_to_mlt_color_trc(pdata->avoutframe->color_trc));
1045+
mlt_properties_set_int(frame_properties,
1046+
"colorspace",
1047+
av_to_mlt_colorspace(pdata->avoutframe->colorspace,
1048+
pdata->avoutframe->width,
1049+
pdata->avoutframe->height));
1050+
mlt_properties_set_int(frame_properties,
1051+
"color_primaries",
1052+
av_to_mlt_color_primaries(pdata->avoutframe->color_primaries));
1053+
mlt_properties_set_int(frame_properties,
1054+
"full_range",
1055+
av_to_mlt_full_range(pdata->avoutframe->color_range));
10421056
}
10431057

10441058
exit:

src/modules/core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ add_library(mltcore MODULE
1212
filter_brightness.c
1313
filter_channelcopy.c
1414
filter_choppy.c
15+
filter_colorspace.c
1516
filter_crop.c
1617
filter_fieldorder.c
1718
filter_gamma.c

0 commit comments

Comments
 (0)