Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Factor color space attributes handling #965

Merged
merged 1 commit into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions include/upipe/uref_pic_flow.h
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,64 @@ static inline int uref_pic_flow_infer_dar(struct uref *uref,
return UBASE_ERR_NONE;
}

/** @This sets colour primaries value to flow def attribute.
*
* @param flow_def flow definition packet
* @param colour_primaries colour primaries value (ISO/IEC 23091-2:2019)
* @return an error code
*/
int uref_pic_flow_set_colour_primaries_val(struct uref *flow_def,
int colour_primaries);

/** @This gets colour primaries value from flow def attribute.
*
* @param flow_def flow definition packet
* @param colour_primaries colour primaries value (ISO/IEC 23091-2:2019)
* @return an error code
*/
int uref_pic_flow_get_colour_primaries_val(struct uref *flow_def,
int *colour_primaries);

/** @This sets transfer characteristics value to flow def attribute.
*
* @param flow_def flow definition packet
* @param transfer_characteristics transfer characteristics value
* (ISO/IEC 23091-2:2019)
* @return an error code
*/
int uref_pic_flow_set_transfer_characteristics_val(struct uref *flow_def,
int transfer_characteristics);

/** @This gets transfer characteristics value from flow def attribute.
*
* @param flow_def flow definition packet
* @param transfer_characteristics transfer characteristics value
* (ISO/IEC 23091-2:2019)
* @return an error code
*/
int uref_pic_flow_get_transfer_characteristics_val(struct uref *flow_def,
int *transfer_characteristics);

/** @This sets matrix coefficients value to flow def attribute.
*
* @param flow_def flow definition packet
* @param matrix_coefficients matrix coefficients value
* (ISO/IEC 23091-2:2019)
* @return an error code
*/
int uref_pic_flow_set_matrix_coefficients_val(struct uref *flow_def,
int matrix_coefficients);

/** @This gets matrix coefficients value from flow def attribute.
*
* @param flow_def flow definition packet
* @param matrix_coefficients matrix coefficients value
* (ISO/IEC 23091-2:2019)
* @return an error code
*/
int uref_pic_flow_get_matrix_coefficients_val(struct uref *flow_def,
int *matrix_coefficients);

#ifdef __cplusplus
}
#endif
Expand Down
94 changes: 14 additions & 80 deletions lib/upipe-av/upipe_avcodec_encode.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,56 +225,6 @@ UPIPE_HELPER_UBUF_MGR(upipe_avcenc, ubuf_mgr, flow_format, ubuf_mgr_request,
UPIPE_HELPER_UPUMP_MGR(upipe_avcenc, upump_mgr)
UPIPE_HELPER_UPUMP(upipe_avcenc, upump_av_deal, upump_mgr)

/** @This allows to convert from Upipe color space to avcenc color space. */
struct upipe_avcenc_color {
/** Upipe color */
const char *upipe_color;
/** avcenc color */
const char *avcenc_color;
};

/** @This converts transfer characteristics from Upipe to avcenc. */
static const struct upipe_avcenc_color upipe_avcenc_color_trc[] = {
{ "bt470m", "gamma22" },
{ "bt470bg", "gamma28" },
{ "log100", "log" },
{ "log316", "log_sqrt" },
{ "iec61966-2-4", "iec61966_2_4" },
{ "bt1361e", "bt1361" },
{ "iec61966-2-1", "iec61966_2_1" },
{ "bt2020-10", "bt2020-10bit" },
{ "bt2020-12", "bt2020-12bit" },
{ NULL, NULL }
};

/** @This converts matrix coefficients from Upipe to avcenc. */
static const struct upipe_avcenc_color upipe_avcenc_color_space[] = {
{ "GBR", "rgb" },
{ "YCgCo", "ycocg" },
{ "bt2020nc", "bt2020_ncl" },
{ "bt2020c", "bt2020_cl" },
{ NULL, NULL }
};

/** @internal @This converts a Upipe color space to avcenc color space.
*
* @param list conversion list
* @param upipe_color Upipe color
* @return avcenc color
*/
static const char *
upipe_avcenc_convert_color(const struct upipe_avcenc_color *list,
const char *upipe_color)
{
int i = 0;
while (list[i].upipe_color != NULL) {
if (!strcmp(list[i].upipe_color, upipe_color))
return list[i].avcenc_color;
i++;
}
return upipe_color;
}

/** @hidden */
static void upipe_avcenc_free(struct upipe *upipe);

Expand Down Expand Up @@ -1560,36 +1510,20 @@ static int upipe_avcenc_set_flow_def(struct upipe *upipe, struct uref *flow_def)
context->sample_aspect_ratio.den = sar.den;
}

const char *content;
int ret;
content = ubase_check(uref_pic_flow_get_full_range(
flow_def)) ? "jpeg" : "mpeg";
if ((ret = av_opt_set(context, "color_range", content,
AV_OPT_SEARCH_CHILDREN)) < 0)
upipe_err_va(upipe, "can't set option %s:%s (%d)",
"color_range", content, ret);
if (ubase_check(uref_pic_flow_get_colour_primaries(
flow_def, &content)) &&
(ret = av_opt_set(context, "color_primaries", content,
AV_OPT_SEARCH_CHILDREN)) < 0)
upipe_err_va(upipe, "can't set option %s:%s (%d)",
"color_primaries", content, ret);
if (ubase_check(uref_pic_flow_get_transfer_characteristics(
flow_def, &content)) &&
(ret = av_opt_set(context, "color_trc",
upipe_avcenc_convert_color(
upipe_avcenc_color_trc, content),
AV_OPT_SEARCH_CHILDREN)) < 0)
upipe_err_va(upipe, "can't set option %s:%s (%d)",
"color_trc", content, ret);
if (ubase_check(uref_pic_flow_get_matrix_coefficients(
flow_def, &content)) &&
(ret = av_opt_set(context, "colorspace",
upipe_avcenc_convert_color(
upipe_avcenc_color_space, content),
AV_OPT_SEARCH_CHILDREN)) < 0)
upipe_err_va(upipe, "can't set option %s:%s (%d)",
"colorspace", content, ret);
context->color_range =
ubase_check(uref_pic_flow_get_full_range(flow_def)) ?
AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;

int val;
if (ubase_check(
uref_pic_flow_get_colour_primaries_val(flow_def, &val)))
context->color_primaries = val;
if (ubase_check(
uref_pic_flow_get_transfer_characteristics_val(flow_def, &val)))
context->color_trc = val;
if (ubase_check(
uref_pic_flow_get_matrix_coefficients_val(flow_def, &val)))
context->colorspace = val;

if (!ubase_check(uref_pic_get_progressive(flow_def))) {
context->flags |= AV_CODEC_FLAG_INTERLACED_DCT |
Expand Down
149 changes: 13 additions & 136 deletions lib/upipe-av/upipe_avfilter.c
Original file line number Diff line number Diff line change
Expand Up @@ -2153,74 +2153,14 @@ static void upipe_avfilt_output_frame(struct upipe *upipe,
if (frame->color_range == AVCOL_RANGE_JPEG)
UBASE_ERROR(upipe, uref_pic_flow_set_full_range(flow_def_attr))

const char *str = NULL;
switch (frame->color_primaries) {
case AVCOL_PRI_BT709: str = "bt709"; break;
case AVCOL_PRI_BT470M: str = "bt470m"; break;
case AVCOL_PRI_BT470BG: str = "bt470bg"; break;
case AVCOL_PRI_SMPTE170M: str = "smpte170m"; break;
case AVCOL_PRI_SMPTE240M: str = "smpte240m"; break;
case AVCOL_PRI_FILM: str = "film"; break;
case AVCOL_PRI_BT2020: str = "bt2020"; break;
case AVCOL_PRI_SMPTE428: str = "smpte428"; break;
case AVCOL_PRI_SMPTE431: str = "smpte431"; break;
case AVCOL_PRI_SMPTE432: str = "smpte432"; break;
#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(56, 34, 100)
case AVCOL_PRI_EBU3213: str = "ebu3213"; break;
#endif
default: break;
}
if (str != NULL) {
UBASE_ERROR(upipe, uref_pic_flow_set_colour_primaries(
flow_def_attr, str))
}
UBASE_ERROR(upipe, uref_pic_flow_set_colour_primaries_val(
flow_def_attr, frame->color_primaries))

str = NULL;
switch (frame->color_trc) {
case AVCOL_TRC_BT709: str = "bt709"; break;
case AVCOL_TRC_GAMMA22: str = "bt470m"; break;
case AVCOL_TRC_GAMMA28: str = "bt470bg"; break;
case AVCOL_TRC_SMPTE170M: str = "smpte170m"; break;
case AVCOL_TRC_SMPTE240M: str = "smpte240m"; break;
case AVCOL_TRC_LINEAR: str = "linear"; break;
case AVCOL_TRC_LOG: str = "log100"; break;
case AVCOL_TRC_LOG_SQRT: str = "log316"; break;
case AVCOL_TRC_IEC61966_2_4: str = "iec61966-2-4"; break;
case AVCOL_TRC_BT1361_ECG: str = "bt1361e"; break;
case AVCOL_TRC_IEC61966_2_1: str = "iec61966-2-1"; break;
case AVCOL_TRC_BT2020_10: str = "bt2020-10"; break;
case AVCOL_TRC_BT2020_12: str = "bt2020-12"; break;
case AVCOL_TRC_SMPTE2084: str = "smpte2084"; break;
case AVCOL_TRC_SMPTE428: str = "smpte428"; break;
case AVCOL_TRC_ARIB_STD_B67: str = "arib-std-b67"; break;
default: break;
}
if (str != NULL) {
UBASE_ERROR(upipe, uref_pic_flow_set_transfer_characteristics(
flow_def_attr, str))
}
UBASE_ERROR(upipe, uref_pic_flow_set_transfer_characteristics_val(
flow_def_attr, frame->color_trc))

str = NULL;
switch (frame->colorspace) {
case AVCOL_SPC_RGB: str = "GBR"; break;
case AVCOL_SPC_BT709: str = "bt709"; break;
case AVCOL_SPC_FCC: str = "fcc"; break;
case AVCOL_SPC_BT470BG: str = "bt470bg"; break;
case AVCOL_SPC_SMPTE170M: str = "smpte170m"; break;
case AVCOL_SPC_SMPTE240M: str = "smpte240m"; break;
case AVCOL_SPC_YCGCO: str = "YCgCo"; break;
case AVCOL_SPC_BT2020_NCL: str = "bt2020nc"; break;
case AVCOL_SPC_BT2020_CL: str = "bt2020c"; break;
case AVCOL_SPC_SMPTE2085: str = "smpte2085"; break;
case AVCOL_SPC_CHROMA_DERIVED_NCL: str = "chroma-nc"; break;
case AVCOL_SPC_CHROMA_DERIVED_CL: str = "chroma-c"; break;
case AVCOL_SPC_ICTCP: str = "ictcp"; break;
default: break;
}
if (str != NULL) {
UBASE_ERROR(upipe, uref_pic_flow_set_matrix_coefficients(
flow_def_attr, str))
}
UBASE_ERROR(upipe, uref_pic_flow_set_matrix_coefficients_val(
flow_def_attr, frame->colorspace))

struct uref *flow_def =
upipe_avfilt_store_flow_def_attr(upipe, flow_def_attr);
Expand Down Expand Up @@ -2323,54 +2263,6 @@ static void upipe_avfilt_output_frame(struct upipe *upipe,
upipe_avfilt_output(upipe, uref, upump_p);
}

/** @This allows to convert from Upipe color space to av color space. */
struct upipe_av_color {
/** Upipe color */
const char *upipe_color;
/** av color */
const char *av_color;
};

/** @This converts transfer characteristics from Upipe to av. */
static const struct upipe_av_color upipe_av_color_transfer[] = {
{ "bt470m", "gamma22" },
{ "bt470bg", "gamma28" },
{ "log100", "log" },
{ "log316", "log_sqrt" },
{ "iec61966-2-4", "iec61966_2_4" },
{ "bt1361e", "bt1361" },
{ "iec61966-2-1", "iec61966_2_1" },
{ "bt2020-10", "bt2020-10bit" },
{ "bt2020-12", "bt2020-12bit" },
{ NULL, NULL }
};

/** @This converts matrix coefficients from Upipe to av. */
static const struct upipe_av_color upipe_av_color_space[] = {
{ "GBR", "rgb" },
{ "YCgCo", "ycocg" },
{ "bt2020nc", "bt2020_ncl" },
{ "bt2020c", "bt2020_cl" },
{ NULL, NULL }
};

/** @internal @This converts a Upipe color space to av color space.
*
* @param list conversion list
* @param upipe_color Upipe color
* @return av color
*/
static const char *upipe_av_convert_color(
const struct upipe_av_color *list,
const char *upipe_color)
{
for (int i = 0; list[i].upipe_color != NULL; i++)
if (!strcmp(list[i].upipe_color, upipe_color))
return list[i].av_color;

return upipe_color;
}

/** @internal @This converts an uref pic to an avframe.
*
* @param upipe description structure of the pipe
Expand Down Expand Up @@ -2429,33 +2321,18 @@ static int upipe_avfilt_avframe_from_uref_pic(struct upipe *upipe,
frame->interlaced_frame = !ubase_check(uref_pic_get_progressive(uref));
frame->top_field_first = ubase_check(uref_pic_get_tff(uref));

#define frame_set(name, api, content) \
if (ubase_check(ret)) { \
if ((err = av_ ## api ## _from_name(content)) < 0) \
upipe_err_va(upipe, "can't set option " #name "=%s: %s", \
content, av_err2str(err)); \
else frame->name = err; \
}

struct uref *flow_def = upipe_avfilt->flow_def_input;
const char *content;
int err, ret = UBASE_ERR_NONE;

frame->color_range = ubase_check(uref_pic_flow_get_full_range(
flow_def)) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;

ret = uref_pic_flow_get_colour_primaries(flow_def, &content);
frame_set(color_primaries, color_primaries, content);

ret = uref_pic_flow_get_transfer_characteristics(flow_def, &content);
frame_set(color_trc, color_transfer,
upipe_av_convert_color(upipe_av_color_transfer, content));

ret = uref_pic_flow_get_matrix_coefficients(flow_def, &content);
frame_set(colorspace, color_space,
upipe_av_convert_color(upipe_av_color_space, content));

#undef frame_set
int val;
if (ubase_check(uref_pic_flow_get_colour_primaries_val(flow_def, &val)))
frame->color_primaries = val;
if (ubase_check(uref_pic_flow_get_transfer_characteristics_val(flow_def, &val)))
frame->color_trc = val;
if (ubase_check(uref_pic_flow_get_matrix_coefficients_val(flow_def, &val)))
frame->colorspace = val;

uint64_t number;
if (ubase_check(uref_pic_get_number(uref, &number)))
Expand Down
Loading