Skip to content

Commit

Permalink
brutal mapping of ffmpeg7 api: channel layout with n channels and no …
Browse files Browse the repository at this point in the history
…additional information still leads to errors
  • Loading branch information
rbouqueau committed Apr 7, 2024
1 parent abc4000 commit 9b2cb52
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 23 deletions.
32 changes: 26 additions & 6 deletions src/filters/ff_avf.c
Expand Up @@ -582,8 +582,13 @@ static GF_Err ffavf_process(GF_Filter *filter)
ctx->frame->sample_aspect_ratio.num = ipid->sar.num;
ctx->frame->sample_aspect_ratio.den = ipid->sar.den;
} else {
#if AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, LIBAFILTER_VERSION_MINOR, 0) < AV_VERSION_INT(8, 28, 0)
ctx->frame->channel_layout = ipid->ch_layout;
ctx->frame->channels = ipid->nb_ch;
#else
ctx->frame->ch_layout.u.mask = ipid->ch_layout;
ctx->frame->ch_layout.nb_channels = ipid->nb_ch;
#endif
ctx->frame->sample_rate = ipid->sr;
ctx->frame->format = ipid->pfmt;
ctx->frame->nb_samples = data_size / ipid->nb_ch / ipid->bps;
Expand Down Expand Up @@ -727,25 +732,32 @@ static GF_Err ffavf_process(GF_Filter *filter)
u32 j, out_size;
GF_FilterPacket *pck;
Bool update_props=GF_TRUE;
#if AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, LIBAFILTER_VERSION_MINOR, 0) < AV_VERSION_INT(8, 28, 0)
u64 ffmpeg_channel_layout = frame->channel_layout;
u32 ffmpeg_channels = frame->channels;
#else
u64 ffmpeg_channel_layout = frame->ch_layout.u.mask;
u32 ffmpeg_channels = frame->ch_layout.nb_channels;
#endif
if (frame->sample_rate!=opid->sr) {}
else if (frame->channel_layout!=opid->ch_layout) {}
else if (frame->channels != opid->nb_ch) {}
else if (ffmpeg_channel_layout!=opid->ch_layout) {}
else if (ffmpeg_channels != opid->nb_ch) {}
else if (frame->format != opid->pfmt) {}
else {
update_props = GF_FALSE;
}
if (update_props) {
u64 gpac_ch_layout = ffmpeg_channel_layout_to_gpac(frame->channel_layout);
u64 gpac_ch_layout = ffmpeg_channel_layout_to_gpac(ffmpeg_channel_layout);
gf_filter_pid_set_property(opid->io_pid, GF_PROP_PID_SAMPLE_RATE, &PROP_UINT(frame->sample_rate));
gf_filter_pid_set_property(opid->io_pid, GF_PROP_PID_CHANNEL_LAYOUT, &PROP_LONGUINT(gpac_ch_layout));
gf_filter_pid_set_property(opid->io_pid, GF_PROP_PID_NUM_CHANNELS, &PROP_UINT(frame->channels));
gf_filter_pid_set_property(opid->io_pid, GF_PROP_PID_NUM_CHANNELS, &PROP_UINT(ffmpeg_channels));
opid->gf_pfmt = ffmpeg_audio_fmt_to_gpac(frame->format);
gf_filter_pid_set_property(opid->io_pid, GF_PROP_PID_AUDIO_FORMAT, &PROP_UINT(opid->gf_pfmt));
gf_filter_pid_set_property(opid->io_pid, GF_PROP_PID_TIMESCALE, &PROP_UINT(opid->io_filter_ctx->inputs[0]->time_base.den) );

opid->sr = frame->sample_rate;
opid->ch_layout = frame->channel_layout;
opid->nb_ch = frame->channels;
opid->ch_layout = ffmpeg_channel_layout;
opid->nb_ch = ffmpeg_channels;
opid->pfmt = frame->format;
opid->tb_num = opid->io_filter_ctx->inputs[0]->time_base.num;
opid->bps = gf_audio_fmt_bit_depth(opid->gf_pfmt) / 8;
Expand Down Expand Up @@ -890,7 +902,15 @@ static GF_Err ffavf_configure_pid(GF_Filter *filter, GF_FilterPid *pid, Bool is_
p = gf_filter_pid_get_property(pid, GF_PROP_PID_NUM_CHANNELS);
if (!p) return GF_OK; //not ready yet
nb_ch = p->value.uint;
#if AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, LIBAFILTER_VERSION_MINOR, 0) < AV_VERSION_INT(8, 28, 0)
if (!ch_layout) ch_layout = av_get_default_channel_layout(p->value.uint);
#else
if (!ch_layout) {
AVChannelLayout avcl = {0};
av_channel_layout_default(&avcl, p->value.uint);
ch_layout = avcl.u.mask;
}
#endif

p = gf_filter_pid_get_property(pid, GF_PROP_PID_SAMPLE_RATE);
if (!p) return GF_OK; //not ready yet
Expand Down
23 changes: 22 additions & 1 deletion src/filters/ff_common.c
Expand Up @@ -809,7 +809,9 @@ GF_FilterArgs ffmpeg_arg_translate(const struct AVOption *opt)
switch (opt->type) {
case AV_OPT_TYPE_INT64:
case AV_OPT_TYPE_INT:
case AV_OPT_TYPE_CHANNEL_LAYOUT:
#if AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, LIBAFORMAT_VERSION_MINOR, 0) < AV_VERSION_INT(59,19, 0)
case case AV_OPT_TYPE_CHANNEL_LAYOUT:
#endif
if (opt->type==AV_OPT_TYPE_INT64) arg.arg_type = GF_PROP_LSINT;
else if (opt->type==AV_OPT_TYPE_INT) arg.arg_type = GF_PROP_SINT;
else arg.arg_type = GF_PROP_UINT; //channel layout, map to int
Expand Down Expand Up @@ -2096,7 +2098,12 @@ GF_Err ffmpeg_codec_par_from_gpac(GF_FilterPid *pid, AVCodecParameters *codecpar
p = gf_filter_pid_get_property(pid, GF_PROP_PID_SAMPLE_RATE);
if (p) codecpar->sample_rate = samplerate = p->value.uint;
p = gf_filter_pid_get_property(pid, GF_PROP_PID_NUM_CHANNELS);

#if AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, LIBAFORMAT_VERSION_MINOR, 0) < AV_VERSION_INT(59,19, 0)
if (p) codecpar->channels = p->value.uint;
#else
if (p) codecpar->ch_layout.nb_channels = p->value.uint;
#endif
p = gf_filter_pid_get_property(pid, GF_PROP_PID_SAMPLES_PER_FRAME);
if (p) codecpar->frame_size = p->value.uint;
p = gf_filter_pid_get_property(pid, GF_PROP_PID_AUDIO_BPS);
Expand All @@ -2110,9 +2117,15 @@ GF_Err ffmpeg_codec_par_from_gpac(GF_FilterPid *pid, AVCodecParameters *codecpar
p = gf_filter_pid_get_property(pid, GF_PROP_PID_CHANNEL_LAYOUT);
if (p)
ch_layout = p->value.longuint;
#if AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, LIBAFORMAT_VERSION_MINOR, 0) < AV_VERSION_INT(59,19, 0)
else if (codecpar->channels==2)
ch_layout = GF_AUDIO_CH_FRONT_LEFT|GF_AUDIO_CH_FRONT_RIGHT;
codecpar->channel_layout = ffmpeg_channel_layout_from_gpac(ch_layout);
#else
else if (codecpar->ch_layout.nb_channels==2)
ch_layout = GF_AUDIO_CH_FRONT_LEFT|GF_AUDIO_CH_FRONT_RIGHT;
codecpar->ch_layout.u.mask = ffmpeg_channel_layout_from_gpac(ch_layout);
#endif

p = gf_filter_pid_get_property(pid, GF_PROP_PID_DELAY);
if (p && (p->value.sint<0) && samplerate) {
Expand Down Expand Up @@ -2173,11 +2186,19 @@ GF_Err ffmpeg_codec_par_to_gpac(AVCodecParameters *codecpar, GF_FilterPid *opid,
if (codecpar->sample_rate)
gf_filter_pid_set_property(opid, GF_PROP_PID_SAMPLE_RATE, &PROP_UINT(codecpar->sample_rate));

#if AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, LIBAFORMAT_VERSION_MINOR, 0) < AV_VERSION_INT(59,19, 0)
if (codecpar->channels) {
gf_filter_pid_set_property(opid, GF_PROP_PID_NUM_CHANNELS, &PROP_UINT(codecpar->channels));
if (codecpar->channel_layout) {
gf_filter_pid_set_property(opid, GF_PROP_PID_CHANNEL_LAYOUT, &PROP_LONGUINT( ffmpeg_channel_layout_to_gpac(codecpar->channel_layout) ));
}
#else
if (codecpar->ch_layout.nb_channels) {
gf_filter_pid_set_property(opid, GF_PROP_PID_NUM_CHANNELS, &PROP_UINT(codecpar->ch_layout.nb_channels));
if (codecpar->ch_layout.u.mask) {
gf_filter_pid_set_property(opid, GF_PROP_PID_CHANNEL_LAYOUT, &PROP_LONGUINT( ffmpeg_channel_layout_to_gpac(codecpar->ch_layout.u.mask) ));
}
#endif

if (codecpar->frame_size)
gf_filter_pid_set_property(opid, GF_PROP_PID_SAMPLES_PER_FRAME, &PROP_UINT(codecpar->frame_size));
Expand Down
11 changes: 11 additions & 0 deletions src/filters/ff_dec.c
Expand Up @@ -713,8 +713,13 @@ static GF_Err ffdec_process_audio(GF_Filter *filter, struct _gf_ffdec_ctx *ctx)
FF_RELEASE_PCK(pkt);


#if LIBAVUTIL_VERSION_MAJOR < 59
FF_CHECK_PROP(channels, channels, GF_PROP_PID_NUM_CHANNELS)
FF_CHECK_PROPL(channel_layout, channel_layout, GF_PROP_PID_CHANNEL_LAYOUT)
#else
FF_CHECK_PROP(channels, ch_layout.nb_channels, GF_PROP_PID_NUM_CHANNELS)
FF_CHECK_PROPL(channel_layout, ch_layout.u.mask, GF_PROP_PID_CHANNEL_LAYOUT)
#endif
FF_CHECK_PROP(sample_rate, sample_rate, GF_PROP_PID_SAMPLE_RATE)

if (prev_afmt != ctx->decoder->sample_fmt) {
Expand Down Expand Up @@ -1202,7 +1207,11 @@ static GF_Err ffdec_configure_pid(GF_Filter *filter, GF_FilterPid *pid, Bool is_
}
if (ctx->sample_rate && ctx->channels) {
ctx->decoder->sample_rate = ctx->sample_rate;
#if LIBAVUTIL_VERSION_MAJOR < 59
ctx->decoder->channels = ctx->channels;
#else
ctx->decoder->ch_layout.nb_channels = ctx->channels;
#endif
}
}

Expand Down Expand Up @@ -1353,6 +1362,7 @@ static GF_Err ffdec_configure_pid(GF_Filter *filter, GF_FilterPid *pid, Bool is_
}

//override PID props with what decoder gives us
#if LIBAVUTIL_VERSION_MAJOR < 59
if (ctx->decoder->channels) {
ctx->channels = 0;
FF_CHECK_PROP(channels, channels, GF_PROP_PID_NUM_CHANNELS)
Expand All @@ -1364,6 +1374,7 @@ static GF_Err ffdec_configure_pid(GF_Filter *filter, GF_FilterPid *pid, Bool is_
ctx->channel_layout = ch_lay;
}
}
#endif
if (ctx->decoder->sample_rate) {
ctx->sample_rate = 0;
FF_CHECK_PROP(sample_rate, sample_rate, GF_PROP_PID_SAMPLE_RATE)
Expand Down
14 changes: 13 additions & 1 deletion src/filters/ff_dmx.c
Expand Up @@ -438,6 +438,7 @@ static GF_Err ffdmx_flush_input(GF_Filter *filter, GF_FFDemuxCtx *ctx)
return GF_OK;
}

#include <libavcodec/packet.h>
static GF_Err ffdmx_process(GF_Filter *filter)
{
GF_Err e;
Expand Down Expand Up @@ -599,6 +600,8 @@ static GF_Err ffdmx_process(GF_Filter *filter)
GF_BitStream *bs = gf_bs_new(sd->data, sd->size, GF_BITSTREAM_READ);

u32 flags = gf_bs_read_u32_le(bs);

#if LIBAVUTIL_VERSION_MAJOR < 59
if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT) {
u32 new_ch = gf_bs_read_u32_le(bs);
gf_filter_pid_set_property(pctx->pid, GF_PROP_PID_NUM_CHANNELS, &PROP_UINT(new_ch) );
Expand All @@ -608,6 +611,7 @@ static GF_Err ffdmx_process(GF_Filter *filter)
new_lay = ffmpeg_channel_layout_to_gpac(new_lay);
gf_filter_pid_set_property(pctx->pid, GF_PROP_PID_CHANNEL_LAYOUT, &PROP_LONGUINT(new_lay) );
}
#endif
if (flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) {
u32 new_sr = gf_bs_read_u32_le(bs);
gf_filter_pid_set_property(pctx->pid, GF_PROP_PID_SAMPLE_RATE, &PROP_UINT(new_sr) );
Expand Down Expand Up @@ -978,7 +982,11 @@ GF_Err ffdmx_init_common(GF_Filter *filter, GF_FFDemuxCtx *ctx, u32 grab_type)
u32 exdata_size = stream->codecpar->extradata_size;
u32 codec_sample_rate = stream->codecpar->sample_rate;
u32 codec_frame_size = stream->codecpar->frame_size;
#if LIBAVUTIL_VERSION_MAJOR < 59
u32 codec_channels = stream->codecpar->channels;
#else
u32 codec_channels = stream->codecpar->ch_layout.nb_channels;
#endif
u32 codec_width = stream->codecpar->width;
u32 codec_height = stream->codecpar->height;
u32 codec_field_order = stream->codecpar->field_order;
Expand Down Expand Up @@ -1068,7 +1076,11 @@ GF_Err ffdmx_init_common(GF_Filter *filter, GF_FFDemuxCtx *ctx, u32 grab_type)
if (grab_type)
gf_filter_pid_set_property(pid, GF_PROP_PID_RAWGRAB, &PROP_UINT(grab_type) );
else if (ctx->demuxer->iformat) {
if ((ctx->demuxer->iformat->flags & AVFMT_SEEK_TO_PTS) || ctx->demuxer->iformat->read_seek)
if ((ctx->demuxer->iformat->flags & AVFMT_SEEK_TO_PTS)
#if (LIBAVFORMAT_VERSION_MAJOR < 59)
|| ctx->demuxer->iformat->read_seek
#endif
)
gf_filter_pid_set_property(pid, GF_PROP_PID_PLAYBACK_MODE, &PROP_UINT(GF_PLAYBACK_MODE_FASTFORWARD ) );
}

Expand Down
59 changes: 53 additions & 6 deletions src/filters/ff_enc.c
Expand Up @@ -590,7 +590,11 @@ static GF_Err ffenc_process_video(GF_Filter *filter, struct _gf_ffenc_ctx *ctx)
ctx->frame->top_field_first = (ilaced==2) ? 1 : 0;
}
ctx->frame->pts = ffenc_get_cts(ctx, pck);
#if AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, LIBAVCODEC_VERSION_MINOR, 0) < AV_VERSION_INT(59, 24, 0)
ctx->frame->pkt_duration = gf_filter_pck_get_duration(pck);
#else
ctx->frame->duration = gf_filter_pck_get_duration(pck);
#endif
}

//use signed version of timestamp rescale since we may have negative dts
Expand All @@ -601,7 +605,11 @@ static GF_Err ffenc_process_video(GF_Filter *filter, struct _gf_ffenc_ctx *ctx)
if (ctx->remap_ts) {
SCALE_TS(ctx->frame->pts);

#if AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, LIBAVCODEC_VERSION_MINOR, 0) < AV_VERSION_INT(59, 24, 0)
SCALE_TS(ctx->frame->pkt_duration);
#else
SCALE_TS(ctx->frame->duration);
#endif
}

//store first frame CTS as will be seen after rescaling (to cope with rounding errors
Expand Down Expand Up @@ -673,7 +681,11 @@ static GF_Err ffenc_process_video(GF_Filter *filter, struct _gf_ffenc_ctx *ctx)

if (ctx->remap_ts) {
UNSCALE_TS(ctx->frame->pts);
#if AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, LIBAVCODEC_VERSION_MINOR, 0) < AV_VERSION_INT(59, 24, 0)
UNSCALE_TS(ctx->frame->pkt_duration);
#else
UNSCALE_TS(ctx->frame->duration);
#endif
if (gotpck) {
UNSCALE_TS(pkt->dts);
UNSCALE_TS(pkt->pts);
Expand Down Expand Up @@ -857,7 +869,12 @@ static GF_Err ffenc_process_video(GF_Filter *filter, struct _gf_ffenc_ctx *ctx)
if (pkt->duration) {
gf_filter_pck_set_duration(dst_pck, (u32) pkt->duration);
} else {

#if AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, LIBAVCODEC_VERSION_MINOR, 0) < AV_VERSION_INT(59, 24, 0)
gf_filter_pck_set_duration(dst_pck, (u32) ctx->frame->pkt_duration);
#else
gf_filter_pck_set_duration(dst_pck, (u32) ctx->frame->duration);
#endif
}
}
if (ctx->gen_dsi) {
Expand Down Expand Up @@ -1118,8 +1135,14 @@ static GF_Err ffenc_process_audio(GF_Filter *filter, struct _gf_ffenc_ctx *ctx)
if (pck)
ctx->frame->nb_samples = ctx->encoder->frame_size;
ctx->frame->format = ctx->encoder->sample_fmt;
#if LIBAVUTIL_VERSION_MAJOR < 59
ctx->frame->channels = ctx->encoder->channels;
ctx->frame->channel_layout = ctx->encoder->channel_layout;
#else
ctx->frame->ch_layout.nb_channels = ctx->encoder->ch_layout.nb_channels;
ctx->frame->ch_layout.u.mask = ctx->encoder->ch_layout.u.mask;
#endif

gotpck = 0;
if (pck || ctx->samples_in_audio_buffer) {
#if (LIBAVFORMAT_VERSION_MAJOR<59)
Expand Down Expand Up @@ -1525,8 +1548,12 @@ static GF_Err ffenc_configure_pid_ex(GF_Filter *filter, GF_FilterPid *pid, Bool
codec_id = ffmpeg_codecid_from_gpac(ctx->codecid, &ff_codectag);

if ((type==GF_STREAM_AUDIO)
&& (ctx->encoder->codec->id==codec_id) && (ctx->encoder->sample_rate==ctx->sample_rate)
&& (ctx->encoder->channels==ctx->channels) && (ctx->gpac_audio_fmt == afmt )
&& (ctx->encoder->codec->id==codec_id) && (ctx->encoder->sample_rate==ctx->sample_rate) && (ctx->gpac_audio_fmt == afmt)
#if LIBAVUTIL_VERSION_MAJOR < 59
&& (ctx->encoder->channels==ctx->channels)
#else
&& (ctx->encoder->ch_layout.u.mask==ctx->channels)
#endif
) {
reuse = GF_TRUE;
} else if ((ctx->encoder->codec->id==codec_id)
Expand Down Expand Up @@ -1680,13 +1707,20 @@ static GF_Err ffenc_configure_pid_ex(GF_Filter *filter, GF_FilterPid *pid, Bool
ctx->channel_layout = gf_audio_fmt_get_layout_from_cicp(gf_audio_fmt_get_cicp_layout(ctx->channels, 0, 0));
}
u64 ff_ch_layout = ffmpeg_channel_layout_from_gpac(ctx->channel_layout);
if (!codec->channel_layouts)
if (!codec->ch_layouts)
change_chan_layout = ctx->channel_layout;

#if LIBAVUTIL_VERSION_MAJOR < 59
while (codec->channel_layouts) {
if (!codec->channel_layouts[i]) break;
if (codec->channel_layouts[i] == ff_ch_layout) {
change_chan_layout = ctx->channel_layout;
#else
while (codec->ch_layouts) { //Romain: is NULL
if (!codec->ch_layouts[i].u.mask) break;
if (codec->ch_layouts[i].u.mask == ff_ch_layout) {
change_chan_layout = ctx->channel_layout;
#endif
break;
}
i++;
Expand All @@ -1711,7 +1745,11 @@ static GF_Err ffenc_configure_pid_ex(GF_Filter *filter, GF_FilterPid *pid, Bool
}
if (ctx->channel_layout != change_chan_layout) {
if (!change_chan_layout)
#if LIBAVUTIL_VERSION_MAJOR < 59
change_chan_layout = ffmpeg_channel_layout_to_gpac(codec->channel_layouts[0]);
#else
change_chan_layout = ffmpeg_channel_layout_to_gpac(codec->ch_layouts[0].u.mask);
#endif
u32 nb_chans = gf_audio_fmt_get_num_channels_from_layout(change_chan_layout);
gf_filter_pid_negotiate_property(ctx->in_pid, GF_PROP_PID_NUM_CHANNELS, &PROP_UINT(nb_chans) );
gf_filter_pid_negotiate_property(ctx->in_pid, GF_PROP_PID_CHANNEL_LAYOUT, &PROP_LONGUINT(change_chan_layout) );
Expand Down Expand Up @@ -1869,16 +1907,25 @@ static GF_Err ffenc_configure_pid_ex(GF_Filter *filter, GF_FilterPid *pid, Bool
av_dict_set(&ctx->options, "strict", "experimental", 0);
} else if (type==GF_STREAM_AUDIO) {
ctx->encoder->sample_rate = ctx->sample_rate;
#if LIBAVUTIL_VERSION_MAJOR < 59
ctx->encoder->channels = ctx->channels;
#else
ctx->encoder->ch_layout.nb_channels = ctx->channels;
#endif

//TODO
prop = gf_filter_pid_get_property(pid, GF_PROP_PID_CHANNEL_LAYOUT);
#if LIBAVUTIL_VERSION_MAJOR < 59
u64 *channel_layout = &ctx->encoder->channel_layout;
#else
u64 *channel_layout = &ctx->encoder->ch_layout.u.mask;
#endif
if (prop) {
ctx->encoder->channel_layout = ffmpeg_channel_layout_from_gpac(prop->value.longuint);
*channel_layout = ffmpeg_channel_layout_from_gpac(prop->value.longuint);
} else if (ctx->channels==1) {
ctx->encoder->channel_layout = AV_CH_LAYOUT_MONO;
*channel_layout = AV_CH_LAYOUT_MONO;
} else if (ctx->channels==2) {
ctx->encoder->channel_layout = AV_CH_LAYOUT_STEREO;
*channel_layout = AV_CH_LAYOUT_STEREO;
}

prop = gf_filter_pid_get_property(pid, GF_PROP_PID_TIMESCALE);
Expand Down

0 comments on commit 9b2cb52

Please sign in to comment.