1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-11-23 21:54:53 +02:00

fftools/ffmpeg: add alpha_mode support

The implementation exactly mirrors the existing plumbing for color_ranges
and color_spaces.
This commit is contained in:
Niklas Haas
2025-08-13 14:13:21 +02:00
parent 2e2ca4e740
commit f07573f496
5 changed files with 35 additions and 3 deletions

View File

@@ -330,6 +330,7 @@ typedef struct OutputFilterOptions {
int height; int height;
enum AVColorSpace color_space; enum AVColorSpace color_space;
enum AVColorRange color_range; enum AVColorRange color_range;
enum AVAlphaMode alpha_mode;
enum VideoSyncMethod vsync_method; enum VideoSyncMethod vsync_method;
AVRational frame_rate; AVRational frame_rate;
@@ -344,6 +345,7 @@ typedef struct OutputFilterOptions {
const AVRational *frame_rates; const AVRational *frame_rates;
const enum AVColorSpace *color_spaces; const enum AVColorSpace *color_spaces;
const enum AVColorRange *color_ranges; const enum AVColorRange *color_ranges;
const enum AVAlphaMode *alpha_modes;
// for simple filtergraphs only, view specifier passed // for simple filtergraphs only, view specifier passed
// along to the decoder // along to the decoder

View File

@@ -1635,6 +1635,7 @@ static int dec_open(DecoderPriv *dp, AVDictionary **dec_opts,
param_out->sample_aspect_ratio = dp->dec_ctx->sample_aspect_ratio; param_out->sample_aspect_ratio = dp->dec_ctx->sample_aspect_ratio;
param_out->colorspace = dp->dec_ctx->colorspace; param_out->colorspace = dp->dec_ctx->colorspace;
param_out->color_range = dp->dec_ctx->color_range; param_out->color_range = dp->dec_ctx->color_range;
param_out->alpha_mode = dp->dec_ctx->alpha_mode;
} }
av_frame_side_data_free(&param_out->side_data, &param_out->nb_side_data); av_frame_side_data_free(&param_out->side_data, &param_out->nb_side_data);

View File

@@ -274,6 +274,7 @@ int enc_open(void *opaque, const AVFrame *frame)
enc_ctx->color_primaries = frame->color_primaries; enc_ctx->color_primaries = frame->color_primaries;
enc_ctx->color_trc = frame->color_trc; enc_ctx->color_trc = frame->color_trc;
enc_ctx->colorspace = frame->colorspace; enc_ctx->colorspace = frame->colorspace;
enc_ctx->alpha_mode = frame->alpha_mode;
/* Video properties which are not part of filter graph negotiation */ /* Video properties which are not part of filter graph negotiation */
if (enc_ctx->chroma_sample_location == AVCHROMA_LOC_UNSPECIFIED) { if (enc_ctx->chroma_sample_location == AVCHROMA_LOC_UNSPECIFIED) {

View File

@@ -125,6 +125,7 @@ typedef struct InputFilterPriv {
AVRational sample_aspect_ratio; AVRational sample_aspect_ratio;
enum AVColorSpace color_space; enum AVColorSpace color_space;
enum AVColorRange color_range; enum AVColorRange color_range;
enum AVAlphaMode alpha_mode;
int sample_rate; int sample_rate;
AVChannelLayout ch_layout; AVChannelLayout ch_layout;
@@ -196,6 +197,7 @@ typedef struct OutputFilterPriv {
AVChannelLayout ch_layout; AVChannelLayout ch_layout;
enum AVColorSpace color_space; enum AVColorSpace color_space;
enum AVColorRange color_range; enum AVColorRange color_range;
enum AVAlphaMode alpha_mode;
AVFrameSideData **side_data; AVFrameSideData **side_data;
int nb_side_data; int nb_side_data;
@@ -219,6 +221,7 @@ typedef struct OutputFilterPriv {
const int *sample_rates; const int *sample_rates;
const enum AVColorSpace *color_spaces; const enum AVColorSpace *color_spaces;
const enum AVColorRange *color_ranges; const enum AVColorRange *color_ranges;
const enum AVAlphaMode *alpha_modes;
AVRational enc_timebase; AVRational enc_timebase;
int64_t trim_start_us; int64_t trim_start_us;
@@ -268,6 +271,7 @@ static int sub2video_get_blank_frame(InputFilterPriv *ifp)
frame->format = ifp->format; frame->format = ifp->format;
frame->colorspace = ifp->color_space; frame->colorspace = ifp->color_space;
frame->color_range = ifp->color_range; frame->color_range = ifp->color_range;
frame->alpha_mode = ifp->alpha_mode;
ret = av_frame_get_buffer(frame, 0); ret = av_frame_get_buffer(frame, 0);
if (ret < 0) if (ret < 0)
@@ -401,6 +405,9 @@ DEF_CHOOSE_FORMAT(color_spaces, enum AVColorSpace, color_space, color_spaces,
DEF_CHOOSE_FORMAT(color_ranges, enum AVColorRange, color_range, color_ranges, DEF_CHOOSE_FORMAT(color_ranges, enum AVColorRange, color_range, color_ranges,
AVCOL_RANGE_UNSPECIFIED, "%s", av_color_range_name); AVCOL_RANGE_UNSPECIFIED, "%s", av_color_range_name);
DEF_CHOOSE_FORMAT(alpha_modes, enum AVAlphaMode, alpha_mode, alpha_modes,
AVALPHA_MODE_UNSPECIFIED, "%s", av_alpha_mode_name);
static void choose_channel_layouts(OutputFilterPriv *ofp, AVBPrint *bprint) static void choose_channel_layouts(OutputFilterPriv *ofp, AVBPrint *bprint)
{ {
if (av_channel_layout_check(&ofp->ch_layout)) { if (av_channel_layout_check(&ofp->ch_layout)) {
@@ -650,6 +657,7 @@ static OutputFilter *ofilter_alloc(FilterGraph *fg, enum AVMediaType type)
ofp->format = -1; ofp->format = -1;
ofp->color_space = AVCOL_SPC_UNSPECIFIED; ofp->color_space = AVCOL_SPC_UNSPECIFIED;
ofp->color_range = AVCOL_RANGE_UNSPECIFIED; ofp->color_range = AVCOL_RANGE_UNSPECIFIED;
ofp->alpha_mode = AVALPHA_MODE_UNSPECIFIED;
ofilter->index = fg->nb_outputs - 1; ofilter->index = fg->nb_outputs - 1;
snprintf(ofp->log_name, sizeof(ofp->log_name), "%co%d", snprintf(ofp->log_name, sizeof(ofp->log_name), "%co%d",
@@ -854,6 +862,11 @@ int ofilter_bind_enc(OutputFilter *ofilter, unsigned sched_idx_enc,
else else
ofp->color_ranges = opts->color_ranges; ofp->color_ranges = opts->color_ranges;
if (opts->alpha_mode != AVALPHA_MODE_UNSPECIFIED)
ofp->alpha_mode = opts->alpha_mode;
else
ofp->alpha_modes = opts->alpha_modes;
fgp->disable_conversions |= !!(ofp->flags & OFILTER_FLAG_DISABLE_CONVERT); fgp->disable_conversions |= !!(ofp->flags & OFILTER_FLAG_DISABLE_CONVERT);
ofp->fps.last_frame = av_frame_alloc(); ofp->fps.last_frame = av_frame_alloc();
@@ -977,6 +990,7 @@ static InputFilter *ifilter_alloc(FilterGraph *fg)
ifp->format = -1; ifp->format = -1;
ifp->color_space = AVCOL_SPC_UNSPECIFIED; ifp->color_space = AVCOL_SPC_UNSPECIFIED;
ifp->color_range = AVCOL_RANGE_UNSPECIFIED; ifp->color_range = AVCOL_RANGE_UNSPECIFIED;
ifp->alpha_mode = AVALPHA_MODE_UNSPECIFIED;
ifp->frame_queue = av_fifo_alloc2(8, sizeof(AVFrame*), AV_FIFO_FLAG_AUTO_GROW); ifp->frame_queue = av_fifo_alloc2(8, sizeof(AVFrame*), AV_FIFO_FLAG_AUTO_GROW);
if (!ifp->frame_queue) if (!ifp->frame_queue)
@@ -1553,6 +1567,7 @@ static int configure_output_video_filter(FilterGraphPriv *fgp, AVFilterGraph *gr
choose_pix_fmts(ofp, &bprint); choose_pix_fmts(ofp, &bprint);
choose_color_spaces(ofp, &bprint); choose_color_spaces(ofp, &bprint);
choose_color_ranges(ofp, &bprint); choose_color_ranges(ofp, &bprint);
choose_alpha_modes(ofp, &bprint);
if (!av_bprint_is_complete(&bprint)) if (!av_bprint_is_complete(&bprint))
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
@@ -1723,6 +1738,7 @@ static int configure_input_video_filter(FilterGraph *fg, AVFilterGraph *graph,
ifp->sample_aspect_ratio : (AVRational){ 0, 1 }; ifp->sample_aspect_ratio : (AVRational){ 0, 1 };
par->color_space = ifp->color_space; par->color_space = ifp->color_space;
par->color_range = ifp->color_range; par->color_range = ifp->color_range;
par->alpha_mode = ifp->alpha_mode;
par->hw_frames_ctx = ifp->hw_frames_ctx; par->hw_frames_ctx = ifp->hw_frames_ctx;
par->side_data = ifp->side_data; par->side_data = ifp->side_data;
par->nb_side_data = ifp->nb_side_data; par->nb_side_data = ifp->nb_side_data;
@@ -2000,6 +2016,7 @@ static int configure_filtergraph(FilterGraph *fg, FilterGraphThread *fgt)
ofp->height = av_buffersink_get_h(sink); ofp->height = av_buffersink_get_h(sink);
ofp->color_space = av_buffersink_get_colorspace(sink); ofp->color_space = av_buffersink_get_colorspace(sink);
ofp->color_range = av_buffersink_get_color_range(sink); ofp->color_range = av_buffersink_get_color_range(sink);
ofp->alpha_mode = av_buffersink_get_alpha_mode(sink);
// If the timing parameters are not locked yet, get the tentative values // If the timing parameters are not locked yet, get the tentative values
// here but don't lock them. They will only be used if no output frames // here but don't lock them. They will only be used if no output frames
@@ -2096,6 +2113,7 @@ static int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *fr
ifp->sample_aspect_ratio = frame->sample_aspect_ratio; ifp->sample_aspect_ratio = frame->sample_aspect_ratio;
ifp->color_space = frame->colorspace; ifp->color_space = frame->colorspace;
ifp->color_range = frame->color_range; ifp->color_range = frame->color_range;
ifp->alpha_mode = frame->alpha_mode;
ifp->sample_rate = frame->sample_rate; ifp->sample_rate = frame->sample_rate;
ret = av_channel_layout_copy(&ifp->ch_layout, &frame->ch_layout); ret = av_channel_layout_copy(&ifp->ch_layout, &frame->ch_layout);
@@ -2809,6 +2827,7 @@ static int send_eof(FilterGraphThread *fgt, InputFilter *ifilter,
ifp->sample_aspect_ratio = ifp->opts.fallback->sample_aspect_ratio; ifp->sample_aspect_ratio = ifp->opts.fallback->sample_aspect_ratio;
ifp->color_space = ifp->opts.fallback->colorspace; ifp->color_space = ifp->opts.fallback->colorspace;
ifp->color_range = ifp->opts.fallback->color_range; ifp->color_range = ifp->opts.fallback->color_range;
ifp->alpha_mode = ifp->opts.fallback->alpha_mode;
ifp->time_base = ifp->opts.fallback->time_base; ifp->time_base = ifp->opts.fallback->time_base;
ret = av_channel_layout_copy(&ifp->ch_layout, ret = av_channel_layout_copy(&ifp->ch_layout,
@@ -2877,7 +2896,8 @@ static int send_frame(FilterGraph *fg, FilterGraphThread *fgt,
ifp->width != frame->width || ifp->width != frame->width ||
ifp->height != frame->height || ifp->height != frame->height ||
ifp->color_space != frame->colorspace || ifp->color_space != frame->colorspace ||
ifp->color_range != frame->color_range) ifp->color_range != frame->color_range ||
ifp->alpha_mode != frame->alpha_mode)
need_reinit |= VIDEO_CHANGED; need_reinit |= VIDEO_CHANGED;
break; break;
} }
@@ -2951,9 +2971,11 @@ static int send_frame(FilterGraph *fg, FilterGraphThread *fgt,
const char *pixel_format_name = av_get_pix_fmt_name(frame->format); const char *pixel_format_name = av_get_pix_fmt_name(frame->format);
const char *color_space_name = av_color_space_name(frame->colorspace); const char *color_space_name = av_color_space_name(frame->colorspace);
const char *color_range_name = av_color_range_name(frame->color_range); const char *color_range_name = av_color_range_name(frame->color_range);
av_bprintf(&reason, "video parameters changed to %s(%s, %s), %dx%d, ", const char *alpha_mode = av_alpha_mode_name(frame->alpha_mode);
av_bprintf(&reason, "video parameters changed to %s(%s, %s), %dx%d, %s alpha,",
unknown_if_null(pixel_format_name), unknown_if_null(color_range_name), unknown_if_null(pixel_format_name), unknown_if_null(color_range_name),
unknown_if_null(color_space_name), frame->width, frame->height); unknown_if_null(color_space_name), frame->width, frame->height,
unknown_if_null(alpha_mode));
} }
if (need_reinit & MATRIX_CHANGED) if (need_reinit & MATRIX_CHANGED)
av_bprintf(&reason, "display matrix changed, "); av_bprintf(&reason, "display matrix changed, ");

View File

@@ -917,6 +917,7 @@ ost_bind_filter(const Muxer *mux, MuxStream *ms, OutputFilter *ofilter,
.height = enc_ctx->height, .height = enc_ctx->height,
.color_space = enc_ctx->colorspace, .color_space = enc_ctx->colorspace,
.color_range = enc_ctx->color_range, .color_range = enc_ctx->color_range,
.alpha_mode = enc_ctx->alpha_mode,
.vsync_method = vsync_method, .vsync_method = vsync_method,
.frame_rate = ms->frame_rate, .frame_rate = ms->frame_rate,
.max_frame_rate = ms->max_frame_rate, .max_frame_rate = ms->max_frame_rate,
@@ -964,6 +965,11 @@ ost_bind_filter(const Muxer *mux, MuxStream *ms, OutputFilter *ofilter,
(const void **) &opts.color_ranges, NULL); (const void **) &opts.color_ranges, NULL);
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = avcodec_get_supported_config(enc_ctx, NULL,
AV_CODEC_CONFIG_ALPHA_MODE, 0,
(const void **) &opts.alpha_modes, NULL);
if (ret < 0)
return ret;
} else { } else {
ret = avcodec_get_supported_config(enc_ctx, NULL, ret = avcodec_get_supported_config(enc_ctx, NULL,
AV_CODEC_CONFIG_SAMPLE_FORMAT, 0, AV_CODEC_CONFIG_SAMPLE_FORMAT, 0,