[FFmpeg-devel] [PATCH v4 1/5] avutil/hwcontext: add a function to get the AVHWDeviceType
Add a function to get the corresponding AVHWDeviceType from a given hardware pixel format. Signed-off-by: Tong Wu --- libavutil/hwcontext.c | 11 +++ libavutil/hwcontext.h | 12 2 files changed, 23 insertions(+) diff --git a/libavutil/hwcontext.c b/libavutil/hwcontext.c index ab9ad3703e..4d14cb2cb4 100644 --- a/libavutil/hwcontext.c +++ b/libavutil/hwcontext.c @@ -80,6 +80,17 @@ static const char *const hw_type_names[] = { [AV_HWDEVICE_TYPE_VULKAN] = "vulkan", }; +enum AVHWDeviceType av_hwdevice_get_type_by_pix_fmt(enum AVPixelFormat fmt) +{ +for (int i = 0; hw_table[i]; i++) { +for (int j = 0; hw_table[i]->pix_fmts[j] != AV_PIX_FMT_NONE; j++) { +if (hw_table[i]->pix_fmts[j] == fmt) +return hw_table[i]->type; +} +} +return AV_HWDEVICE_TYPE_NONE; +} + enum AVHWDeviceType av_hwdevice_find_type_by_name(const char *name) { int type; diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h index c18b7e1e8b..49f3a799ed 100644 --- a/libavutil/hwcontext.h +++ b/libavutil/hwcontext.h @@ -229,6 +229,18 @@ typedef struct AVHWFramesContext { int width, height; } AVHWFramesContext; +/** + * Get the device type by a given pixel format. + * + * This function only returns a preferred device type which supports the given + * pixel format. There is no guarantee that the device type is unique. + * + * @param fmt Pixel format from enum AVPixelFormat. + * @return The type from enum AVHWDeviceType, or AV_HWDEVICE_TYPE_NONE if + * not found. + */ +enum AVHWDeviceType av_hwdevice_get_type_by_pix_fmt(enum AVPixelFormat fmt); + /** * Look up an AVHWDeviceType by name. * -- 2.35.1.windows.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v4 2/5] avfilter/vf_hwmap: get the AVHWDeviceType from outlink format
When a derive_device_type is not specified, the hwmap filter should be able to retrieve AVHWDeviceType from outlink->format and create corresponding hwdevice context. Signed-off-by: Tong Wu --- libavfilter/vf_hwmap.c | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/libavfilter/vf_hwmap.c b/libavfilter/vf_hwmap.c index 2e03dfc1fe..328395e352 100644 --- a/libavfilter/vf_hwmap.c +++ b/libavfilter/vf_hwmap.c @@ -70,18 +70,27 @@ static int hwmap_config_output(AVFilterLink *outlink) device_is_derived = 0; if (inlink->hw_frames_ctx) { +enum AVHWDeviceType type; hwfc = (AVHWFramesContext*)inlink->hw_frames_ctx->data; if (ctx->derive_device_type) { -enum AVHWDeviceType type; - type = av_hwdevice_find_type_by_name(ctx->derive_device_type); if (type == AV_HWDEVICE_TYPE_NONE) { av_log(avctx, AV_LOG_ERROR, "Invalid device type.\n"); err = AVERROR(EINVAL); goto fail; } +} else { +type = av_hwdevice_get_type_by_pix_fmt(outlink->format); +if (type == AV_HWDEVICE_TYPE_NONE) { +av_log(avctx, AV_LOG_ERROR, "Could not get device type from " + "format %s.\n", av_get_pix_fmt_name(outlink->format)); +err = AVERROR(EINVAL); +goto fail; +} +} +if (!device || ctx->derive_device_type) { err = av_hwdevice_ctx_create_derived(&device, type, hwfc->device_ref, 0); if (err < 0) { -- 2.35.1.windows.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v4 3/5] lavfi/avfiltergraph: move convert codes into functions
This patch moves the auto-insert filter codes into two functions. Signed-off-by: Tong Wu --- libavfilter/avfiltergraph.c | 128 ++-- 1 file changed, 79 insertions(+), 49 deletions(-) diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index b7dbfc063b..2e6938b049 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -393,6 +393,74 @@ static int formats_declared(AVFilterContext *f) return 1; } +static int insert_auto_filter(AVFilterContext **convert, AVFilterGraph *graph, + AVFilterLink *link, const AVFilterNegotiation *neg, + int *converter_count, void *log_ctx) +{ +int ret; +const AVFilter *filter; +AVFilterContext *ctx; +AVFilterLink *inlink, *outlink; +char inst_name[30]; +const char *opts; + +if (!(filter = avfilter_get_by_name(neg->conversion_filter))) { +av_log(log_ctx, AV_LOG_ERROR, + "'%s' filter not present, cannot convert formats.\n", + neg->conversion_filter); +return AVERROR(EINVAL); +} +snprintf(inst_name, sizeof(inst_name), "auto_%s_%d", + neg->conversion_filter, (*converter_count)++); +opts = FF_FIELD_AT(char *, neg->conversion_opts_offset, *graph); +ret = avfilter_graph_create_filter(&ctx, filter, inst_name, opts, NULL, graph); +if (ret < 0) +return ret; + +if ((ret = avfilter_insert_filter(link, ctx, 0, 0)) < 0) +return ret; + +if ((ret = filter_query_formats(ctx)) < 0) +return ret; + +inlink = ctx->inputs[0]; +outlink = ctx->outputs[0]; +av_assert0( inlink->incfg.formats->refcount > 0); +av_assert0( inlink->outcfg.formats->refcount > 0); +av_assert0(outlink->incfg.formats->refcount > 0); +av_assert0(outlink->outcfg.formats->refcount > 0); +if (outlink->type == AVMEDIA_TYPE_AUDIO) { +av_assert0( inlink-> incfg.samplerates->refcount > 0); +av_assert0( inlink->outcfg.samplerates->refcount > 0); +av_assert0(outlink-> incfg.samplerates->refcount > 0); +av_assert0(outlink->outcfg.samplerates->refcount > 0); +av_assert0( inlink-> incfg.channel_layouts->refcount > 0); +av_assert0( inlink->outcfg.channel_layouts->refcount > 0); +av_assert0(outlink-> incfg.channel_layouts->refcount > 0); +av_assert0(outlink->outcfg.channel_layouts->refcount > 0); +} + +*convert = ctx; +return 0; +} + +static int merge_auto_filter(AVFilterContext *convert, const AVFilterNegotiation *neg) +{ +int ret; +AVFilterLink *inlink = convert->inputs[0]; +AVFilterLink *outlink = convert->outputs[0]; +#define MERGE(merger, link) \ +((merger)->merge(FF_FIELD_AT(void *, (merger)->offset, (link)->incfg), \ + FF_FIELD_AT(void *, (merger)->offset, (link)->outcfg))) +for (unsigned neg_step = 0; neg_step < neg->nb_mergers; neg_step++) { +const AVFilterFormatsMerger *m = &neg->mergers[neg_step]; +if ((ret = MERGE(m, inlink)) <= 0 || +(ret = MERGE(m, outlink)) <= 0) +break; +} +return ret; +} + /** * Perform one round of query_formats() and merging formats lists on the * filter graph. @@ -470,10 +538,6 @@ static int query_formats(AVFilterGraph *graph, void *log_ctx) if (convert_needed) { AVFilterContext *convert; -const AVFilter *filter; -AVFilterLink *inlink, *outlink; -char inst_name[30]; -const char *opts; if (graph->disable_auto_convert) { av_log(log_ctx, AV_LOG_ERROR, @@ -484,54 +548,20 @@ static int query_formats(AVFilterGraph *graph, void *log_ctx) } /* couldn't merge format lists. auto-insert conversion filter */ -if (!(filter = avfilter_get_by_name(neg->conversion_filter))) { -av_log(log_ctx, AV_LOG_ERROR, - "'%s' filter not present, cannot convert formats.\n", - neg->conversion_filter); -return AVERROR(EINVAL); -} -snprintf(inst_name, sizeof(inst_name), "auto_%s_%d", - neg->conversion_filter, converter_count++); -opts = FF_FIELD_AT(char *, neg->conversion_opts_offset, *graph); -ret = avfilter_graph_create_filter(&convert, filter, inst_name, opts, NULL, graph); -if (ret < 0) -return ret; -if ((ret = avfilter_insert_filter(link, convert, 0, 0)) < 0) +ret = insert_auto_filter(&convert, graph, link, neg, &converter_count, log_ctx); +if (ret < 0) { +av_log(log_ctx, AV_LOG_ERROR, "Failed to insert an auto filter.\n");
[FFmpeg-devel] [PATCH v4 4/5] lavfi/format: wrap auto filters into structures
This patch wraps auto conversion filters into new structures, making it easier to add more auto filters. And it adds a loop to automatically insert every possible conversion filter until merge succeeds. Signed-off-by: Tong Wu --- libavfilter/avfiltergraph.c | 76 + libavfilter/formats.c | 22 +-- libavfilter/formats.h | 10 - 3 files changed, 78 insertions(+), 30 deletions(-) diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index 2e6938b049..102c1f7693 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -395,24 +395,22 @@ static int formats_declared(AVFilterContext *f) static int insert_auto_filter(AVFilterContext **convert, AVFilterGraph *graph, AVFilterLink *link, const AVFilterNegotiation *neg, - int *converter_count, void *log_ctx) + unsigned conv_step, int *converter_count, void *log_ctx) { int ret; const AVFilter *filter; AVFilterContext *ctx; AVFilterLink *inlink, *outlink; char inst_name[30]; -const char *opts; +const char *opts = FF_FIELD_AT(char *, neg->conversion_filters[conv_step].conversion_opts_offset, *graph); +const char *name = neg->conversion_filters[conv_step].conversion_filter; -if (!(filter = avfilter_get_by_name(neg->conversion_filter))) { +if (!(filter = avfilter_get_by_name(name))) { av_log(log_ctx, AV_LOG_ERROR, - "'%s' filter not present, cannot convert formats.\n", - neg->conversion_filter); + "'%s' filter not present, cannot convert formats.\n", name); return AVERROR(EINVAL); } -snprintf(inst_name, sizeof(inst_name), "auto_%s_%d", - neg->conversion_filter, (*converter_count)++); -opts = FF_FIELD_AT(char *, neg->conversion_opts_offset, *graph); +snprintf(inst_name, sizeof(inst_name), "auto_%s_%d", name, (*converter_count)++); ret = avfilter_graph_create_filter(&ctx, filter, inst_name, opts, NULL, graph); if (ret < 0) return ret; @@ -501,7 +499,7 @@ static int query_formats(AVFilterGraph *graph, void *log_ctx) for (j = 0; j < filter->nb_inputs; j++) { AVFilterLink *link = filter->inputs[j]; const AVFilterNegotiation *neg; -unsigned neg_step; +unsigned neg_step, conv_step; int convert_needed = 0; if (!link) @@ -537,8 +535,6 @@ static int query_formats(AVFilterGraph *graph, void *log_ctx) } if (convert_needed) { -AVFilterContext *convert; - if (graph->disable_auto_convert) { av_log(log_ctx, AV_LOG_ERROR, "The filters '%s' and '%s' do not have a common format " @@ -548,20 +544,52 @@ static int query_formats(AVFilterGraph *graph, void *log_ctx) } /* couldn't merge format lists. auto-insert conversion filter */ -ret = insert_auto_filter(&convert, graph, link, neg, &converter_count, log_ctx); -if (ret < 0) { -av_log(log_ctx, AV_LOG_ERROR, "Failed to insert an auto filter.\n"); -return ret; -} +for (conv_step = 0; conv_step < neg->nb_conversion_filters; conv_step++) { +AVFilterContext *convert; +ret = insert_auto_filter(&convert, graph, link, neg, + conv_step, &converter_count, log_ctx); +if (ret < 0) { +av_log(log_ctx, AV_LOG_ERROR, "Failed to insert an auto filter.\n"); +return ret; +} -ret = merge_auto_filter(convert, neg); -if (ret < 0) -return ret; -else if (ret == 0) { -av_log(log_ctx, AV_LOG_ERROR, - "Impossible to convert between the formats supported by the filter " - "'%s' and the filter '%s'\n", link->src->name, link->dst->name); -return AVERROR(ENOSYS); +ret = merge_auto_filter(convert, neg); +if (ret < 0) +return ret; +else if (ret > 0) +break; +else if (conv_step < neg->nb_conversion_filters - 1) { +AVFilterLink *inlink = convert->inputs[0]; +AVFilterLink *outlink = convert->outputs[0]; +av_log(log_ctx, AV_LOG_VERBOSE, + "Impossible to convert between the formats supported by the filter " + "'%s' and the filter '%s', try another conversion filter.\n", + link-
[FFmpeg-devel] [PATCH v4 5/5] lavfi/format: add a hwmap auto conversion filter
When two formats lists cannot be merged, a scale filter is auto-inserted. However, when it comes to hardware map, we have to manually add a hwmap filter to do the conversion. This patch introduces an auto hwmap filter to do the hwmap conversion automatically. Signed-off-by: Tong Wu --- libavfilter/avfiltergraph.c | 3 ++- libavfilter/formats.c | 4 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index 102c1f7693..8e63007cac 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -402,7 +402,8 @@ static int insert_auto_filter(AVFilterContext **convert, AVFilterGraph *graph, AVFilterContext *ctx; AVFilterLink *inlink, *outlink; char inst_name[30]; -const char *opts = FF_FIELD_AT(char *, neg->conversion_filters[conv_step].conversion_opts_offset, *graph); +const char *opts = neg->conversion_filters[conv_step].conversion_opts_offset == 0 ? NULL : + FF_FIELD_AT(char *, neg->conversion_filters[conv_step].conversion_opts_offset, *graph); const char *name = neg->conversion_filters[conv_step].conversion_filter; if (!(filter = avfilter_get_by_name(name))) { diff --git a/libavfilter/formats.c b/libavfilter/formats.c index c8e20e5b20..fee10fa0ee 100644 --- a/libavfilter/formats.c +++ b/libavfilter/formats.c @@ -331,6 +331,10 @@ static const AVFilterFormatsFilter filters_video[] = { .conversion_filter = "scale", .conversion_opts_offset = offsetof(AVFilterGraph, scale_sws_opts), }, +{ +.conversion_filter = "hwmap", +.conversion_opts_offset = 0, +} }; static const AVFilterFormatsFilter filters_audio[] = { -- 2.35.1.windows.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v2 2/2] ffmpeg: add option -isync
On 2022-07-04 11:51 am, Anton Khirnov wrote: Quoting Gyan Doshi (2022-07-02 11:51:53) On 2022-07-02 02:12 pm, Anton Khirnov wrote: Quoting Gyan Doshi (2022-07-01 13:03:04) On 2022-07-01 03:33 pm, Anton Khirnov wrote: Quoting Gyan Doshi (2022-06-25 10:29:51) This is a per-file input option that adjusts an input's timestamps with reference to another input, so that emitted packet timestamps account for the difference between the start times of the two inputs. Typical use case is to sync two or more live inputs such as from capture devices. Both the target and reference input source timestamps should be based on the same clock source. If both streams are using the same clock, then why is any extra synchronization needed? Because ffmpeg.c normalizes timestamps by default. We can keep timestamps using -copyts, but these inputs are usually preprocessed using single-input filters which won't have access to the reference inputs, No idea what you mean by "reference inputs" here. The reference input is the one the target is being synced against. e.g. in a karaoke session - the music track from a DAW would be ref and the user's voice via mic is the target. or the merge filters like e.g. amix don't sync by timestamp. amix does seem to look at timestamps. amix does not *sync* by timestamp. If one input starts at 4 and the other at 7, the 2nd isn't aligned by timestamp. So maybe it should? My concern generally with this patchset is that it seems like you're changing things where it's easier to do rather than where it's correct. There are many multi=input filters which may be used. amix is just one example. The basic 'deficiency' here is that filters operate upon frames and only look at single frames for the most part, even though frames are part of streams. These streams may have companion streams (which may be part of programs) which are part of a single input. These inputs may have companion inputs. Anything in this tree may be relevant for a particular operation as a reference, e.g. we have a bespoke filter scale2ref so that we can look at another stream's frames. But we don't have pad2ref, crop2ref ..etc. So, the absolutely correct thing to do would be to supply a global context to processing modules like filtergraphs , maybe an array of dicts, containing attributes of all inputs like starting time stamps, resolution, string metadata..etc. That would obviate need for these bespoke fields and even filters. But that's a much larger design undertaking and I'm just addressing one specific practical need here. This patch is currently being used successfully by commercial users in a private build. Many users have posted to ffmpeg-users and popular forums over the years asking for something that achieves this. Actually, this functionality sounds like it sort of existed earlier in the form of map sync (i.e. -map 1:a,0:a:1). Although the assignment syntax still remains (and doesn't warn/error out), it's a no-op now since the application code was removed in 2012 by Michael, who said he based it off an idea from one of your commits, presumably in Libav. Regards, Gyan ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v3] libavcodec/qsvenc: Enable fixed QP configure in qsv CQP runtime
> Quoting Chen, Wenbin (2022-07-04 08:33:49) > > > Why is this using frame metadata rather than the AVVideoEncParams > side > > > data? > > > > The usage of AVVideoEncParams relates to the "qp" variable in > mfxEncodeCtrl which is passed > > to MFXVideoENCODE_encoderFrameAsync(). This variable in qsv is for per- > frame QP > > configuration. > > There are other parameter changing supports I want to add besides QP, for > > example, gop_size, max_frame_size, intra_refresh. These parameter > configurations are not > > all included in mfxEncodeCtrl, so I choose to use MFXVideoENCODE_Reset() > to do this. This > > code changes the encoding parameters which means these changes are > applied to all > > the following frames, but AVVideoEncParams is per-frame configuration, > so I think > > AVVideoEncParams is not suitable for this. > > AVFrame metadata is also per-frame, so your logic does not make sense to > me. > > You could also just update the AVCodecContext/private context values > directly or using AVOptions. This is a possible way. I will change it. Thanks for your advice. > > -- > Anton Khirnov > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v5 00/25] Subtitle Filtering 2022
On Sun, 3 Jul 2022, at 12:42, Paul B Mahol wrote: >> But here, the discussion goes nowhere "I'm right", "No, I'm right", "No, >> I'm correct" and will only evolve in insults and slander. >> > Why should I do this work? > > I will just create my own fork. (Already did.) History shows that it's very hard to do a successful FFmpeg fork. Working together is more powerful, IMVHO. -- Jean-Baptiste Kempf - President +33 672 704 734 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/2] avcodec/dv: Remove unnecessary header
Forgotten in 6d484671ecb612c32cbda0fab65f961743aff5f8. Signed-off-by: Andreas Rheinhardt --- libavcodec/dv.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libavcodec/dv.h b/libavcodec/dv.h index 19290aa382..855afcc758 100644 --- a/libavcodec/dv.h +++ b/libavcodec/dv.h @@ -30,7 +30,6 @@ #include "avcodec.h" #include "dv_profile.h" #include "me_cmp.h" -#include "vlc.h" #include "idctdsp.h" typedef struct DVwork_chunk { -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/2] avcodec/dvenc: Don't set chroma_sample_location
The documentation specifies that it is set by the user for encoders. Given that ff_dvvideo_init() is so extremely simple, the fix consists of inlining the function into its two callers, with setting chroma_sample_location omitted in dvenc.c. This unfortunately leads to the color siting element written in the mxf_dv25 test being unknown. Signed-off-by: Andreas Rheinhardt --- libavcodec/dv.c | 13 ++--- libavcodec/dv.h | 2 -- libavcodec/dvdec.c | 5 - libavcodec/dvenc.c | 4 +++- tests/ref/lavf/mxf_dv25 | 2 +- 5 files changed, 10 insertions(+), 16 deletions(-) diff --git a/libavcodec/dv.c b/libavcodec/dv.c index e2550c4cc1..731e6227cd 100644 --- a/libavcodec/dv.c +++ b/libavcodec/dv.c @@ -38,8 +38,9 @@ * DV codec. */ -#include "avcodec.h" +#include "libavutil/pixfmt.h" #include "dv.h" +#include "dv_profile.h" static inline void dv_calc_mb_coordinates(const AVDVProfile *d, int chan, int seq, int slot, uint16_t *tbl) @@ -184,13 +185,3 @@ int ff_dv_init_dynamic_tables(DVVideoContext *ctx, const AVDVProfile *d) return 0; } - -av_cold int ff_dvvideo_init(AVCodecContext *avctx) -{ -DVVideoContext *s = avctx->priv_data; - -s->avctx = avctx; -avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT; - -return 0; -} diff --git a/libavcodec/dv.h b/libavcodec/dv.h index 855afcc758..f8f1c0c283 100644 --- a/libavcodec/dv.h +++ b/libavcodec/dv.h @@ -97,8 +97,6 @@ enum dv_pack_type { int ff_dv_init_dynamic_tables(DVVideoContext *s, const AVDVProfile *d); -int ff_dvvideo_init(AVCodecContext *avctx); - static inline int dv_work_pool_size(const AVDVProfile *d) { int size = d->n_difchan * d->difseg_size * 27; diff --git a/libavcodec/dvdec.c b/libavcodec/dvdec.c index d6f073058c..b282705653 100644 --- a/libavcodec/dvdec.c +++ b/libavcodec/dvdec.c @@ -240,6 +240,9 @@ static av_cold int dvvideo_decode_init(AVCodecContext *avctx) DVVideoContext *s = avctx->priv_data; int i; +s->avctx = avctx; +avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT; + ff_idctdsp_init(&s->idsp, avctx); for (i = 0; i < 64; i++) @@ -258,7 +261,7 @@ static av_cold int dvvideo_decode_init(AVCodecContext *avctx) ff_thread_once(&init_static_once, dv_init_static); -return ff_dvvideo_init(avctx); +return 0; } /* decode AC coefficients */ diff --git a/libavcodec/dvenc.c b/libavcodec/dvenc.c index 2922829dc5..5108c3d2e7 100644 --- a/libavcodec/dvenc.c +++ b/libavcodec/dvenc.c @@ -55,6 +55,8 @@ static av_cold int dvvideo_encode_init(AVCodecContext *avctx) PixblockDSPContext pdsp; int ret; +s->avctx = avctx; + s->sys = av_dv_codec_profile2(avctx->width, avctx->height, avctx->pix_fmt, avctx->time_base); if (!s->sys) { av_log(avctx, AV_LOG_ERROR, "Found no DV profile for %ix%i %s video. " @@ -91,7 +93,7 @@ static av_cold int dvvideo_encode_init(AVCodecContext *avctx) } #endif -return ff_dvvideo_init(avctx); +return 0; } /* bit budget for AC only in 5 MBs */ diff --git a/tests/ref/lavf/mxf_dv25 b/tests/ref/lavf/mxf_dv25 index 5022f1f62d..95a58906a0 100644 --- a/tests/ref/lavf/mxf_dv25 +++ b/tests/ref/lavf/mxf_dv25 @@ -1,3 +1,3 @@ -3339def72599c79ad5860c6860cc3123 *tests/data/lavf/lavf.mxf_dv25 +59d632e097e6f45c28445b2ab862ffe8 *tests/data/lavf/lavf.mxf_dv25 3834413 tests/data/lavf/lavf.mxf_dv25 tests/data/lavf/lavf.mxf_dv25 CRC=0xbdaf7f52 -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] Make execute() and execute2() return FFMIN() of thread return codes
lör 2022-07-02 klockan 11:43 +0200 skrev Anton Khirnov: > Quoting Tomas Härdin (2022-06-30 14:42:42) > > Hi > > > > Previous version of this patch failed fate-fic-avi with > > THREAD_TYPE=slice THREADS=2 due to thread_execute() always > > returning 0. > > Fixed in this version. > > > > The fic sample appears to indeed be broken. Some packets are > > truncated, > > including one zero-length packet. > > maybe mention this fact for posterity above the relevant test in > tests/fate/scren.mak Sure > > > diff --git a/libavutil/slicethread.h b/libavutil/slicethread.h > > index f6f6f302c4..5c8f197932 100644 > > --- a/libavutil/slicethread.h > > +++ b/libavutil/slicethread.h > > @@ -31,8 +31,8 @@ typedef struct AVSliceThread AVSliceThread; > > * @return return number of threads or negative AVERROR on failure > > */ > > int avpriv_slicethread_create(AVSliceThread **pctx, void *priv, > > - void (*worker_func)(void *priv, int > > jobnr, int threadnr, int nb_jobs, int nb_threads), > > - void (*main_func)(void *priv), > > + int (*worker_func)(void *priv, int > > jobnr, int threadnr, int nb_jobs, int nb_threads), > > + int (*main_func)(void *priv), > > This is an ABI break. > You're right. I was under the impression that avpriv functions could be changed more freely but obviously not when they're shared between libraries. This could be worked around with a new function called say avpriv_slicethread_create2() and a minor bump. Another approach is to av_fast_malloc() an array for rets when none is given. The number of allocations would thereby be quite limited. I'd like to see all users of execute() and execute2() start checking their return values, and making that easier to do is another step toward more correctness of the code /Tomas ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/4] avformat/(mpeg|mpegts|mxf|sup)enc: Use const uint8_t* to access pkt data
The packets muxers receive are not guaranteed to be writable, so they must not be modified. Ergo only access the packet's data via a const uint8_t*. Signed-off-by: Andreas Rheinhardt --- libavformat/mpegenc.c | 2 +- libavformat/mpegtsenc.c | 2 +- libavformat/mxfenc.c| 4 ++-- libavformat/supenc.c| 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libavformat/mpegenc.c b/libavformat/mpegenc.c index 62692bfcd1..3ab4bd3f9b 100644 --- a/libavformat/mpegenc.c +++ b/libavformat/mpegenc.c @@ -1145,7 +1145,7 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt) { int stream_index = pkt->stream_index; int size = pkt->size; -uint8_t *buf = pkt->data; +const uint8_t *buf = pkt->data; MpegMuxContext *s = ctx->priv_data; AVStream *st = ctx->streams[stream_index]; StreamInfo *stream = st->priv_data; diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 18e8f7e45f..c964d58c8e 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -1836,7 +1836,7 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) { AVStream *st = s->streams[pkt->stream_index]; int size = pkt->size; -uint8_t *buf = pkt->data; +const uint8_t *buf = pkt->data; uint8_t *data = NULL; MpegTSWrite *ts = s->priv_data; MpegTSWriteStream *ts_st = st->priv_data; diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c index 7041659143..2d08dd6d40 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -2806,8 +2806,8 @@ static void mxf_write_d10_audio_packet(AVFormatContext *s, AVStream *st, AVPacke MXFContext *mxf = s->priv_data; AVIOContext *pb = s->pb; int frame_size = pkt->size / st->codecpar->block_align; -uint8_t *samples = pkt->data; -uint8_t *end = pkt->data + pkt->size; +const uint8_t *samples = pkt->data; +const uint8_t *const end = pkt->data + pkt->size; int i; klv_encode_ber4_length(pb, 4 + frame_size*4*8); diff --git a/libavformat/supenc.c b/libavformat/supenc.c index 1ca19fa161..c45d8a5321 100644 --- a/libavformat/supenc.c +++ b/libavformat/supenc.c @@ -27,7 +27,7 @@ static int sup_write_packet(AVFormatContext *s, AVPacket *pkt) { -uint8_t *data = pkt->data; +const uint8_t *data = pkt->data; size_t size = pkt->size; uint32_t pts = 0, dts = 0; -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/4] avcodec/dcadec: Treat the input packet's data as const
A decoder's input packet need not be writable, so we must not modify the data. Signed-off-by: Andreas Rheinhardt --- libavcodec/dca_core.c | 4 ++-- libavcodec/dca_core.h | 4 ++-- libavcodec/dca_lbr.c | 2 +- libavcodec/dca_lbr.h | 2 +- libavcodec/dca_xll.c | 10 +- libavcodec/dca_xll.h | 2 +- libavcodec/dcadec.c | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/libavcodec/dca_core.c b/libavcodec/dca_core.c index 34b5b63159..2b19807ef4 100644 --- a/libavcodec/dca_core.c +++ b/libavcodec/dca_core.c @@ -1797,7 +1797,7 @@ static int parse_optional_info(DCACoreDecoder *s) return 0; } -int ff_dca_core_parse(DCACoreDecoder *s, uint8_t *data, int size) +int ff_dca_core_parse(DCACoreDecoder *s, const uint8_t *data, int size) { int ret; @@ -1830,7 +1830,7 @@ int ff_dca_core_parse(DCACoreDecoder *s, uint8_t *data, int size) return 0; } -int ff_dca_core_parse_exss(DCACoreDecoder *s, uint8_t *data, DCAExssAsset *asset) +int ff_dca_core_parse_exss(DCACoreDecoder *s, const uint8_t *data, DCAExssAsset *asset) { AVCodecContext *avctx = s->avctx; DCAContext *dca = avctx->priv_data; diff --git a/libavcodec/dca_core.h b/libavcodec/dca_core.h index cb8e38a94b..a01d642e77 100644 --- a/libavcodec/dca_core.h +++ b/libavcodec/dca_core.h @@ -245,8 +245,8 @@ static inline void ff_dca_core_dequantize(int32_t *output, const int32_t *input, } } -int ff_dca_core_parse(DCACoreDecoder *s, uint8_t *data, int size); -int ff_dca_core_parse_exss(DCACoreDecoder *s, uint8_t *data, DCAExssAsset *asset); +int ff_dca_core_parse(DCACoreDecoder *s, const uint8_t *data, int size); +int ff_dca_core_parse_exss(DCACoreDecoder *s, const uint8_t *data, DCAExssAsset *asset); int ff_dca_core_filter_fixed(DCACoreDecoder *s, int x96_synth); int ff_dca_core_filter_frame(DCACoreDecoder *s, AVFrame *frame); av_cold void ff_dca_core_flush(DCACoreDecoder *s); diff --git a/libavcodec/dca_lbr.c b/libavcodec/dca_lbr.c index 06c10b96f5..2b8594cd75 100644 --- a/libavcodec/dca_lbr.c +++ b/libavcodec/dca_lbr.c @@ -1156,7 +1156,7 @@ static int parse_decoder_init(DCALbrDecoder *s, GetByteContext *gb) return 0; } -int ff_dca_lbr_parse(DCALbrDecoder *s, uint8_t *data, DCAExssAsset *asset) +int ff_dca_lbr_parse(DCALbrDecoder *s, const uint8_t *data, DCAExssAsset *asset) { struct { LBRChunklfe; diff --git a/libavcodec/dca_lbr.h b/libavcodec/dca_lbr.h index db7a676c31..9e1abec0b4 100644 --- a/libavcodec/dca_lbr.h +++ b/libavcodec/dca_lbr.h @@ -124,7 +124,7 @@ typedef struct DCALbrDecoder { DCADSPContext *dcadsp; } DCALbrDecoder; -int ff_dca_lbr_parse(DCALbrDecoder *s, uint8_t *data, DCAExssAsset *asset); +int ff_dca_lbr_parse(DCALbrDecoder *s, const uint8_t *data, DCAExssAsset *asset); int ff_dca_lbr_filter_frame(DCALbrDecoder *s, AVFrame *frame); av_cold void ff_dca_lbr_flush(DCALbrDecoder *s); av_cold void ff_dca_lbr_init_tables(void); diff --git a/libavcodec/dca_xll.c b/libavcodec/dca_xll.c index aaccb7a43d..17626b3614 100644 --- a/libavcodec/dca_xll.c +++ b/libavcodec/dca_xll.c @@ -1040,7 +1040,7 @@ static int parse_band_data(DCAXllDecoder *s) return 0; } -static int parse_frame(DCAXllDecoder *s, uint8_t *data, int size, DCAExssAsset *asset) +static int parse_frame(DCAXllDecoder *s, const uint8_t *data, int size, DCAExssAsset *asset) { int ret; @@ -1067,7 +1067,7 @@ static void clear_pbr(DCAXllDecoder *s) s->pbr_delay = 0; } -static int copy_to_pbr(DCAXllDecoder *s, uint8_t *data, int size, int delay) +static int copy_to_pbr(DCAXllDecoder *s, const uint8_t *data, int size, int delay) { if (size > DCA_XLL_PBR_BUFFER_MAX) return AVERROR(ENOSPC); @@ -1081,7 +1081,7 @@ static int copy_to_pbr(DCAXllDecoder *s, uint8_t *data, int size, int delay) return 0; } -static int parse_frame_no_pbr(DCAXllDecoder *s, uint8_t *data, int size, DCAExssAsset *asset) +static int parse_frame_no_pbr(DCAXllDecoder *s, const uint8_t *data, int size, DCAExssAsset *asset) { int ret = parse_frame(s, data, size, asset); @@ -1119,7 +1119,7 @@ static int parse_frame_no_pbr(DCAXllDecoder *s, uint8_t *data, int size, DCAExss return 0; } -static int parse_frame_pbr(DCAXllDecoder *s, uint8_t *data, int size, DCAExssAsset *asset) +static int parse_frame_pbr(DCAXllDecoder *s, const uint8_t *data, int size, DCAExssAsset *asset) { int ret; @@ -1160,7 +1160,7 @@ fail: return ret; } -int ff_dca_xll_parse(DCAXllDecoder *s, uint8_t *data, DCAExssAsset *asset) +int ff_dca_xll_parse(DCAXllDecoder *s, const uint8_t *data, DCAExssAsset *asset) { int ret; diff --git a/libavcodec/dca_xll.h b/libavcodec/dca_xll.h index d223133019..d7c1a13ec8 100644 --- a/libavcodec/dca_xll.h +++ b/libavcodec/dca_xll.h @@ -139,7 +139,7 @@ typedef struct DCAXllDecoder { int32_t *output_samples[DCA_SPEAKER_COUNT]; } DCAXllDecoder; -int ff_dca_xll_parse(DCAXllDecoder *s, uint8_t *data, DCAExssAs
[FFmpeg-devel] [PATCH 3/4] avcodec/decoders: Use const uint8_t* to access input packet data
These packets need not be writable, so we must not modify them. Signed-off-by: Andreas Rheinhardt --- libavcodec/ansi.c | 2 +- libavcodec/cllc.c | 2 +- libavcodec/diracdec.c | 2 +- libavcodec/fic.c| 8 libavcodec/hqx.c| 2 +- libavcodec/hqx.h| 2 +- libavcodec/libdavs2.c | 2 +- libavcodec/libjxldec.c | 2 +- libavcodec/libopenjpegdec.c | 2 +- libavcodec/msrle.c | 2 +- libavcodec/mwsc.c | 2 +- libavcodec/v410dec.c| 4 ++-- libavcodec/y41pdec.c| 2 +- 13 files changed, 17 insertions(+), 17 deletions(-) diff --git a/libavcodec/ansi.c b/libavcodec/ansi.c index 909ebe7396..ff4437cc61 100644 --- a/libavcodec/ansi.c +++ b/libavcodec/ansi.c @@ -358,7 +358,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *rframe, int *got_frame, AVPacket *avpkt) { AnsiContext *s = avctx->priv_data; -uint8_t *buf = avpkt->data; +const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; const uint8_t *buf_end = buf+buf_size; int ret, i, count; diff --git a/libavcodec/cllc.c b/libavcodec/cllc.c index f7283ca4f8..4866c5b2d4 100644 --- a/libavcodec/cllc.c +++ b/libavcodec/cllc.c @@ -359,7 +359,7 @@ static int cllc_decode_frame(AVCodecContext *avctx, AVFrame *pic, int *got_picture_ptr, AVPacket *avpkt) { CLLCContext *ctx = avctx->priv_data; -uint8_t *src = avpkt->data; +const uint8_t *src = avpkt->data; uint32_t info_tag, info_offset; int data_size; GetBitContext gb; diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c index 9f3c930913..50d1d2e1d3 100644 --- a/libavcodec/diracdec.c +++ b/libavcodec/diracdec.c @@ -2264,7 +2264,7 @@ static int dirac_decode_frame(AVCodecContext *avctx, AVFrame *picture, int *got_frame, AVPacket *pkt) { DiracContext *s = avctx->priv_data; -uint8_t *buf= pkt->data; +const uint8_t *buf = pkt->data; int buf_size= pkt->size; int i, buf_idx = 0; int ret; diff --git a/libavcodec/fic.c b/libavcodec/fic.c index e56a1a323c..491f63ea0c 100644 --- a/libavcodec/fic.c +++ b/libavcodec/fic.c @@ -32,7 +32,7 @@ typedef struct FICThreadContext { DECLARE_ALIGNED(16, int16_t, block)[64]; -uint8_t *src; +const uint8_t *src; int slice_h; int src_size; int y_off; @@ -174,7 +174,7 @@ static int fic_decode_slice(AVCodecContext *avctx, void *tdata) FICContext *ctx= avctx->priv_data; FICThreadContext *tctx = tdata; GetBitContext gb; -uint8_t *src = tctx->src; +const uint8_t *src = tctx->src; int slice_h = tctx->slice_h; int src_size = tctx->src_size; int y_off= tctx->y_off; @@ -271,14 +271,14 @@ static int fic_decode_frame(AVCodecContext *avctx, AVFrame *rframe, int *got_frame, AVPacket *avpkt) { FICContext *ctx = avctx->priv_data; -uint8_t *src = avpkt->data; +const uint8_t *src = avpkt->data; int ret; int slice, nslices; int msize; int tsize; int cur_x, cur_y; int skip_cursor = ctx->skip_cursor; -uint8_t *sdata; +const uint8_t *sdata; if ((ret = ff_reget_buffer(avctx, ctx->frame, 0)) < 0) return ret; diff --git a/libavcodec/hqx.c b/libavcodec/hqx.c index c41fe61387..596b8a7ed3 100644 --- a/libavcodec/hqx.c +++ b/libavcodec/hqx.c @@ -404,7 +404,7 @@ static int hqx_decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_picture_ptr, AVPacket *avpkt) { HQXContext *ctx = avctx->priv_data; -uint8_t *src = avpkt->data; +const uint8_t *src = avpkt->data; uint32_t info_tag; int data_start; int i, ret; diff --git a/libavcodec/hqx.h b/libavcodec/hqx.h index 3eddaafb29..155ec7f84f 100644 --- a/libavcodec/hqx.h +++ b/libavcodec/hqx.h @@ -70,7 +70,7 @@ typedef struct HQXContext { int format, dcb, width, height; int interlaced; -uint8_t *src; +const uint8_t *src; unsigned int data_size; uint32_t slice_off[17]; diff --git a/libavcodec/libdavs2.c b/libavcodec/libdavs2.c index c2040775ae..918e48502c 100644 --- a/libavcodec/libdavs2.c +++ b/libavcodec/libdavs2.c @@ -190,7 +190,7 @@ static int davs2_decode_frame(AVCodecContext *avctx, AVFrame *frame, { DAVS2Context *cad = avctx->priv_data; int buf_size = avpkt->size; -uint8_t *buf_ptr = avpkt->data; +const uint8_t *buf_ptr = avpkt->data; int ret = DAVS2_DEFAULT; /* end of stream, output what is still in the buffers */ diff --git a/libavcodec/libjxldec.c b/libavcodec/libjxldec.c index d516d3b0ac..829478bbde 100644 --- a/libavcodec/libjxldec.c +++ b/libavcodec/libjxldec.c @@ -321,7 +321,7 @@ static int libjxl_color_encoding_event(AVCodecContext *avctx, AVFrame *frame) static int libjxl_decode_frame(AVCodecContext *a
[FFmpeg-devel] [PATCH 4/4] avcodec/mscc: Don't modify input packet
This packet may not be writable, hence we must not write to it. Signed-off-by: Andreas Rheinhardt --- libavcodec/mscc.c | 25 - 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/libavcodec/mscc.c b/libavcodec/mscc.c index ac67ec9c47..3666b881a1 100644 --- a/libavcodec/mscc.c +++ b/libavcodec/mscc.c @@ -134,7 +134,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame, { MSCCContext *s = avctx->priv_data; z_stream *const zstream = &s->zstream.zstream; -uint8_t *buf = avpkt->data; +const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; GetByteContext gb; PutByteContext pb; @@ -146,12 +146,6 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame, if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; -if (avctx->codec_id == AV_CODEC_ID_MSCC) { -avpkt->data[2] ^= avpkt->data[0]; -buf += 2; -buf_size -= 2; -} - if (avctx->pix_fmt == AV_PIX_FMT_PAL8) { size_t size; const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, &size); @@ -172,12 +166,25 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame, av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", ret); return AVERROR_UNKNOWN; } -zstream->next_in = buf; -zstream->avail_in = buf_size; zstream->next_out = s->decomp_buf; zstream->avail_out = s->decomp_size; +if (avctx->codec_id == AV_CODEC_ID_MSCC) { +const uint8_t start = avpkt->data[2] ^ avpkt->data[0]; + +zstream->next_in = &start; +zstream->avail_in = 1; +ret = inflate(zstream, Z_NO_FLUSH); +if (ret != Z_OK || zstream->avail_in != 0) +goto inflate_error; + +buf += 3; +buf_size -= 3; +} +zstream->next_in = buf; +zstream->avail_in = buf_size; ret = inflate(zstream, Z_FINISH); if (ret != Z_STREAM_END) { +inflate_error: av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", ret); return AVERROR_UNKNOWN; } -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 1/4] avformat/(mpeg|mpegts|mxf|sup)enc: Use const uint8_t* to access pkt data
lgtm for set ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 2/2] avcodec/libopusdec: Enable FEC/PLC
Hello, Please find attached a new version of the patchset, with the required corrections. I also added the following changes: - remove use of avc->channels (deprecated) in favor of avc->ch_layout - rebase on master The patches have been tested against FATE, and validated in use on a rtp stream with packet loss inserted by `tc`, with up to 50% packet loss. I'll keep pinging, I wasn't sure what the etiquette was :) Thanks for yout time. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 1/2] avcodec/libopusenc: reload packet loss at encode
An estimation of packet loss is required by libopus to compute its FEC data. Currently, this estimation is constant, and can not be changed after configuration. This means an application using libopus through ffmpeg can not adapt the packet loss estimation when the network quality degrades. This patch makes the encoder reload the packet_loss AVOption before encoding samples, if fec is enabled and the packet loss estimation set is different than the current one. This way an application can modify the packet loss estimation by changing the AVOption. Typical use-case is a RTP stream, where packet loss can be estimated from RTCP packets. Signed-off-by: Philip-Dylan Gleonec --- libavcodec/libopusenc.c | 17 + 1 file changed, 17 insertions(+) diff --git a/libavcodec/libopusenc.c b/libavcodec/libopusenc.c index c884075ffe..26d2082ffa 100644 --- a/libavcodec/libopusenc.c +++ b/libavcodec/libopusenc.c @@ -462,6 +462,23 @@ static int libopus_encode(AVCodecContext *avctx, AVPacket *avpkt, uint8_t *audio; int ret; int discard_padding; +int32_t opus_packet_loss = 0; + +ret = opus_multistream_encoder_ctl(opus->enc, +OPUS_GET_PACKET_LOSS_PERC(&opus_packet_loss)); +if (ret != OPUS_OK) +av_log(avctx, AV_LOG_WARNING, +"Unable to get expected packet loss percentage: %s\n", +opus_strerror(ret)); + +if (opus->opts.fec && (opus_packet_loss != opus->opts.packet_loss)) { +ret = opus_multistream_encoder_ctl(opus->enc, + OPUS_SET_PACKET_LOSS_PERC(opus->opts.packet_loss)); +if (ret != OPUS_OK) +av_log(avctx, AV_LOG_WARNING, +"Unable to set expected packet loss percentage: %s\n", +opus_strerror(ret)); +} if (frame) { ret = ff_af_queue_add(&opus->afq, frame); -- 2.25.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 2/2] avcodec/libopusdec: Enable FEC/PLC
Adds FEC/PLC support to libopus. The lost packets are detected as a discontinuity in the audio stream. When a discontinuity is used, this patch tries to decode the FEC data. If FEC data is present in the packet, it is decoded, otherwise audio is re-created through PLC. This patch is based on Steinar H. Gunderson contribution, and corrects the pts computation: all pts are expressed in samples instead of time. This patch also adds an option "decode_fec" which enables or disables FEC decoding. This option is disabled by default to keep consistent behaviour with former versions. A number of checks are made to ensure compatibility with different containers. Indeed, video containers seem to have a pts expressed in ms while it is expressed in samples for audio containers. It also manages the cases where pkt->duration is 0, in some RTP streams. This patch ignores data it can not reconstruct, i.e. packets received twice and packets with a length that is not a multiple of 2.5ms. Signed-off-by: Philip-Dylan Gleonec Co-developed-by: Steinar H. Gunderson --- libavcodec/libopusdec.c | 105 +++- 1 file changed, 94 insertions(+), 11 deletions(-) diff --git a/libavcodec/libopusdec.c b/libavcodec/libopusdec.c index 316ab0f2a7..f5d0e95fc8 100644 --- a/libavcodec/libopusdec.c +++ b/libavcodec/libopusdec.c @@ -44,10 +44,15 @@ struct libopus_context { #ifdef OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST int apply_phase_inv; #endif +int decode_fec; +int64_t expected_next_pts; }; #define OPUS_HEAD_SIZE 19 +// Sample rate is constant as libopus always output at 48kHz +static const AVRational opus_timebase = { 1, 48000 }; + static av_cold int libopus_decode_init(AVCodecContext *avc) { struct libopus_context *opus = avc->priv_data; @@ -140,6 +145,8 @@ static av_cold int libopus_decode_init(AVCodecContext *avc) /* Decoder delay (in samples) at 48kHz */ avc->delay = avc->internal->skip_samples = opus->pre_skip; +opus->expected_next_pts = AV_NOPTS_VALUE; + return 0; } @@ -160,25 +167,100 @@ static int libopus_decode(AVCodecContext *avc, AVFrame *frame, int *got_frame_ptr, AVPacket *pkt) { struct libopus_context *opus = avc->priv_data; -int ret, nb_samples; +uint8_t *outptr; +int ret, nb_samples = 0, nb_lost_samples = 0, nb_samples_left; + +// If FEC is enabled, calculate number of lost samples +if (opus->decode_fec && +opus->expected_next_pts != AV_NOPTS_VALUE && +pkt->pts != AV_NOPTS_VALUE && +pkt->pts != opus->expected_next_pts) { +// Cap at recovering 120 ms of lost audio. +nb_lost_samples = pkt->pts - opus->expected_next_pts; +nb_lost_samples = FFMIN(nb_lost_samples, MAX_FRAME_SIZE); +// pts is expressed in ms for some containers (e.g. mkv) +// FEC only works for SILK frames (> 10ms) +// Detect if nb_lost_samples is in ms, and convert in samples if it is +if (nb_lost_samples > 0) { +if (avc->pkt_timebase.den != 48000) { +nb_lost_samples = av_rescale_q(nb_lost_samples, avc->pkt_timebase, opus_timebase); +} +// For FEC/PLC, frame_size has to be to have a multiple of 2.5 ms +if (nb_lost_samples % (5LL * opus_timebase.den / 2000)) { +nb_lost_samples -= nb_lost_samples % (5LL * opus_timebase.den / 2000); +} +} +} -frame->nb_samples = MAX_FRAME_SIZE; +frame->nb_samples = MAX_FRAME_SIZE + nb_lost_samples; if ((ret = ff_get_buffer(avc, frame, 0)) < 0) return ret; +outptr = frame->data[0]; +nb_samples_left = frame->nb_samples; + +if (opus->decode_fec && nb_lost_samples > 0) { +// Try to recover the lost samples with FEC data from this one. +// If there's no FEC data, the decoder will do loss concealment instead. +if (avc->sample_fmt == AV_SAMPLE_FMT_S16) +ret = opus_multistream_decode(opus->dec, pkt->data, pkt->size, + (opus_int16 *)outptr, + nb_lost_samples, 1); +else +ret = opus_multistream_decode_float(opus->dec, pkt->data, pkt->size, + (float *)outptr, + nb_lost_samples, 1); + +if (ret < 0) { +if (opus->decode_fec) opus->expected_next_pts = pkt->pts + pkt->duration; +av_log(avc, AV_LOG_ERROR, "Decoding error: %s\n", + opus_strerror(ret)); +return ff_opus_error_to_averror(ret); +} + +av_log(avc, AV_LOG_WARNING, "Recovered %d samples with FEC/PLC\n", + ret); + +outptr += ret * avc->ch_layout.nb_channels * av_get_bytes_per_sample(avc->sample_fmt); +nb_samples_left -= ret; +nb_samples += ret; +
[FFmpeg-devel] [PATCH 1/5] avcodec/apng: Add APNG_FCTL_CHUNK_SIZE define
Also use it where appropriate. Signed-off-by: Andreas Rheinhardt --- libavcodec/apng.h | 3 +++ libavcodec/pngdec.c | 2 +- libavcodec/pngenc.c | 6 +++--- libavformat/apngdec.c | 4 ++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/libavcodec/apng.h b/libavcodec/apng.h index 41249e0df0..abd8795334 100644 --- a/libavcodec/apng.h +++ b/libavcodec/apng.h @@ -38,4 +38,7 @@ enum { APNG_BLEND_OP_OVER = 1, }; +/* Only the payload data, not including length, fourcc and CRC-32. */ +#define APNG_FCTL_CHUNK_SIZE26 + #endif /* AVCODEC_APNG_H */ diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index 6b44af59f2..87b0c639e3 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -972,7 +972,7 @@ static int decode_fctl_chunk(AVCodecContext *avctx, PNGDecContext *s, uint32_t sequence_number; int cur_w, cur_h, x_offset, y_offset, dispose_op, blend_op; -if (bytestream2_get_bytes_left(gb) != 26) +if (bytestream2_get_bytes_left(gb) != APNG_FCTL_CHUNK_SIZE) return AVERROR_INVALIDDATA; if (!(s->hdr_state & PNG_IHDR)) { diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c index d79b4e3895..93463dd341 100644 --- a/libavcodec/pngenc.c +++ b/libavcodec/pngenc.c @@ -988,7 +988,7 @@ static int encode_apng(AVCodecContext *avctx, AVPacket *pkt, // to have the image data write to the correct place in the buffer fctl_chunk.sequence_number = s->sequence_number; ++s->sequence_number; -s->bytestream += 26 + 12; +s->bytestream += APNG_FCTL_CHUNK_SIZE + 12; ret = apng_encode_frame(avctx, pict, &fctl_chunk, &s->last_frame_fctl); if (ret < 0) @@ -1002,7 +1002,7 @@ static int encode_apng(AVCodecContext *avctx, AVPacket *pkt, if (s->last_frame) { uint8_t* last_fctl_chunk_start = pkt->data; -uint8_t buf[26]; +uint8_t buf[APNG_FCTL_CHUNK_SIZE]; if (!s->extra_data_updated) { uint8_t *side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, s->extra_data_size); if (!side_data) @@ -1020,7 +1020,7 @@ static int encode_apng(AVCodecContext *avctx, AVPacket *pkt, AV_WB16(buf + 22, s->last_frame_fctl.delay_den); buf[24] = s->last_frame_fctl.dispose_op; buf[25] = s->last_frame_fctl.blend_op; -png_write_chunk(&last_fctl_chunk_start, MKTAG('f', 'c', 'T', 'L'), buf, 26); +png_write_chunk(&last_fctl_chunk_start, MKTAG('f', 'c', 'T', 'L'), buf, sizeof(buf)); *got_packet = 1; } diff --git a/libavformat/apngdec.c b/libavformat/apngdec.c index e84f74e9d0..47cdbfcbfb 100644 --- a/libavformat/apngdec.c +++ b/libavformat/apngdec.c @@ -222,7 +222,7 @@ static int apng_read_header(AVFormatContext *s) ctx->num_frames, ctx->num_play); break; case MKTAG('f', 'c', 'T', 'L'): -if (!acTL_found || len != 26) { +if (!acTL_found || len != APNG_FCTL_CHUNK_SIZE) { return AVERROR_INVALIDDATA; } if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0) @@ -336,7 +336,7 @@ static int apng_read_packet(AVFormatContext *s, AVPacket *pkt) switch (tag) { case MKTAG('f', 'c', 'T', 'L'): -if (len != 26) +if (len != APNG_FCTL_CHUNK_SIZE) return AVERROR_INVALIDDATA; if ((ret = decode_fctl_chunk(s, ctx, pkt)) < 0) -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/5] avformat/apngenc: Check for incomplete chunks
Signed-off-by: Andreas Rheinhardt --- libavformat/apngenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/apngenc.c b/libavformat/apngenc.c index 88d4a41462..7443c77504 100644 --- a/libavformat/apngenc.c +++ b/libavformat/apngenc.c @@ -50,7 +50,7 @@ typedef struct APNGMuxContext { static uint8_t *apng_find_chunk(uint32_t tag, uint8_t *buf, size_t length) { size_t b; -for (b = 0; b < length; b += AV_RB32(buf + b) + 12) +for (b = 0; AV_RB32(buf + b) + 12ULL <= length - b; b += AV_RB32(buf + b) + 12ULL) if (AV_RB32(&buf[b + 4]) == tag) return &buf[b]; return NULL; -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 3/5] avformat/apngenc: Check fcTL size
The remaining code relies on it having the value it should have. Signed-off-by: Andreas Rheinhardt --- libavformat/apngenc.c | 4 1 file changed, 4 insertions(+) diff --git a/libavformat/apngenc.c b/libavformat/apngenc.c index 7443c77504..1c039685f2 100644 --- a/libavformat/apngenc.c +++ b/libavformat/apngenc.c @@ -27,6 +27,7 @@ #include "libavutil/intreadwrite.h" #include "libavutil/log.h" #include "libavutil/opt.h" +#include "libavcodec/apng.h" #include "libavcodec/png.h" typedef struct APNGMuxContext { @@ -181,6 +182,9 @@ static int flush_packet(AVFormatContext *format_context, AVPacket *packet) if (existing_fcTL_chunk) { AVRational delay; +if (AV_RB32(existing_fcTL_chunk) != APNG_FCTL_CHUNK_SIZE) +return AVERROR_INVALIDDATA; + existing_fcTL_chunk += 8; delay.num = AV_RB16(existing_fcTL_chunk + 20); delay.den = AV_RB16(existing_fcTL_chunk + 22); -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 4/5] avformat/apngenc: Don't modify input packet
It might not be writable at this point. Signed-off-by: Andreas Rheinhardt --- libavformat/apngenc.c | 17 + 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/libavformat/apngenc.c b/libavformat/apngenc.c index 1c039685f2..c219b80161 100644 --- a/libavformat/apngenc.c +++ b/libavformat/apngenc.c @@ -159,6 +159,7 @@ static int flush_packet(AVFormatContext *format_context, AVPacket *packet) avio_write(io_context, apng->prev_packet->data, apng->prev_packet->size); } } else { +const uint8_t *data, *data_end; uint8_t *existing_fcTL_chunk; if (apng->frame_number == 0) { @@ -178,6 +179,8 @@ static int flush_packet(AVFormatContext *format_context, AVPacket *packet) } } +data = apng->prev_packet->data; +data_end = data + apng->prev_packet->size; existing_fcTL_chunk = apng_find_chunk(MKBETAG('f', 'c', 'T', 'L'), apng->prev_packet->data, apng->prev_packet->size); if (existing_fcTL_chunk) { AVRational delay; @@ -190,6 +193,8 @@ static int flush_packet(AVFormatContext *format_context, AVPacket *packet) delay.den = AV_RB16(existing_fcTL_chunk + 22); if (delay.num == 0 && delay.den == 0) { +uint8_t new_fcTL_chunk[APNG_FCTL_CHUNK_SIZE]; + if (packet) { int64_t delay_num_raw = (packet->dts - apng->prev_packet->dts) * codec_stream->time_base.num; int64_t delay_den_raw = codec_stream->time_base.den; @@ -205,16 +210,20 @@ static int flush_packet(AVFormatContext *format_context, AVPacket *packet) delay = apng->prev_delay; } +avio_write(io_context, data, (existing_fcTL_chunk - 8) - data); +data = existing_fcTL_chunk + APNG_FCTL_CHUNK_SIZE + 4 /* CRC-32 */; // Update frame control header with new delay -AV_WB16(existing_fcTL_chunk + 20, delay.num); -AV_WB16(existing_fcTL_chunk + 22, delay.den); -AV_WB32(existing_fcTL_chunk + 26, ~av_crc(av_crc_get_table(AV_CRC_32_IEEE_LE), ~0U, existing_fcTL_chunk - 4, 26 + 4)); +memcpy(new_fcTL_chunk, existing_fcTL_chunk, sizeof(new_fcTL_chunk)); +AV_WB16(new_fcTL_chunk + 20, delay.num); +AV_WB16(new_fcTL_chunk + 22, delay.den); +apng_write_chunk(io_context, MKBETAG('f', 'c', 'T', 'L'), + new_fcTL_chunk, sizeof(new_fcTL_chunk)); } apng->prev_delay = delay; } // Write frame data -avio_write(io_context, apng->prev_packet->data, apng->prev_packet->size); +avio_write(io_context, data, data_end - data); } ++apng->frame_number; -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 5/5] avformat/apngenc: Add const where possible
Signed-off-by: Andreas Rheinhardt --- libavformat/apngenc.c | 15 --- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/libavformat/apngenc.c b/libavformat/apngenc.c index c219b80161..cddb148d50 100644 --- a/libavformat/apngenc.c +++ b/libavformat/apngenc.c @@ -48,7 +48,8 @@ typedef struct APNGMuxContext { int extra_data_size; } APNGMuxContext; -static uint8_t *apng_find_chunk(uint32_t tag, uint8_t *buf, size_t length) +static const uint8_t *apng_find_chunk(uint32_t tag, const uint8_t *buf, + size_t length) { size_t b; for (b = 0; AV_RB32(buf + b) + 12ULL <= length - b; b += AV_RB32(buf + b) + 12ULL) @@ -134,15 +135,15 @@ static int flush_packet(AVFormatContext *format_context, AVPacket *packet) } if (apng->frame_number == 0 && !packet) { -uint8_t *existing_acTL_chunk; -uint8_t *existing_fcTL_chunk; +const uint8_t *existing_acTL_chunk; +const uint8_t *existing_fcTL_chunk; av_log(format_context, AV_LOG_INFO, "Only a single frame so saving as a normal PNG.\n"); // Write normal PNG headers without acTL chunk existing_acTL_chunk = apng_find_chunk(MKBETAG('a', 'c', 'T', 'L'), apng->extra_data, apng->extra_data_size); if (existing_acTL_chunk) { -uint8_t *chunk_after_acTL = existing_acTL_chunk + AV_RB32(existing_acTL_chunk) + 12; +const uint8_t *chunk_after_acTL = existing_acTL_chunk + AV_RB32(existing_acTL_chunk) + 12; avio_write(io_context, apng->extra_data, existing_acTL_chunk - apng->extra_data); avio_write(io_context, chunk_after_acTL, apng->extra_data + apng->extra_data_size - chunk_after_acTL); } else { @@ -152,7 +153,7 @@ static int flush_packet(AVFormatContext *format_context, AVPacket *packet) // Write frame data without fcTL chunk existing_fcTL_chunk = apng_find_chunk(MKBETAG('f', 'c', 'T', 'L'), apng->prev_packet->data, apng->prev_packet->size); if (existing_fcTL_chunk) { -uint8_t *chunk_after_fcTL = existing_fcTL_chunk + AV_RB32(existing_fcTL_chunk) + 12; +const uint8_t *chunk_after_fcTL = existing_fcTL_chunk + AV_RB32(existing_fcTL_chunk) + 12; avio_write(io_context, apng->prev_packet->data, existing_fcTL_chunk - apng->prev_packet->data); avio_write(io_context, chunk_after_fcTL, apng->prev_packet->data + apng->prev_packet->size - chunk_after_fcTL); } else { @@ -160,10 +161,10 @@ static int flush_packet(AVFormatContext *format_context, AVPacket *packet) } } else { const uint8_t *data, *data_end; -uint8_t *existing_fcTL_chunk; +const uint8_t *existing_fcTL_chunk; if (apng->frame_number == 0) { -uint8_t *existing_acTL_chunk; +const uint8_t *existing_acTL_chunk; // Write normal PNG headers avio_write(io_context, apng->extra_data, apng->extra_data_size); -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 1/6] avcodec/wnv1: Check for width =1
On Sun, Jul 03, 2022 at 08:38:15AM +0200, Andreas Rheinhardt wrote: > Michael Niedermayer: > > The decoder only outputs pixels for width >1 images, fail early > > > > Fixes: Timeout > > Fixes: > > 48298/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_WNV1_fuzzer-6198626319204352 > > > > Found-by: continuous fuzzing process > > https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg > > Signed-off-by: Michael Niedermayer > > --- > > libavcodec/wnv1.c | 3 +++ > > 1 file changed, 3 insertions(+) > > > > diff --git a/libavcodec/wnv1.c b/libavcodec/wnv1.c > > index 0cf2181a48..f1223493fe 100644 > > --- a/libavcodec/wnv1.c > > +++ b/libavcodec/wnv1.c > > @@ -129,6 +129,9 @@ static av_cold int decode_init(AVCodecContext *avctx) > > > > ff_thread_once(&init_static_once, wnv1_init_static); > > > > +if (avctx->width <= 1) > > +return AVERROR_INVALIDDATA; > > + > > return 0; > > } > > > > If you want to fail early, then why don't you do so before initializing > the static data? "early" in the sense of costly operations causing timeouts but will apply with it moved up thx [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Frequently ignored answer#1 FFmpeg bugs should be sent to our bugtracker. User questions about the command line tools should be sent to the ffmpeg-user ML. And questions about how to use libav* should be sent to the libav-user ML. signature.asc Description: PGP signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] fftools/ffmpeg: use the sync queues to handle -frames
Same issues apply to it as to -shortest. Changes the results of the following tests: - matroska-flac-extradata-update The test reencodes two input FLAC streams into three output FLAC streams. The last output stream is limited to 8 frames. The current code results in the first two output streams having 12 frames, after this commit all three streams have 8 frames and are the same length. This new result is better, since it is predictable. - mkv-1242 The test streamcopies one video and one audio stream, video is limited to 11 frames. The new result shortens the audio stream so that it is not longer than the video. --- fftools/ffmpeg.c | 6 fftools/ffmpeg_mux.c | 10 +- fftools/ffmpeg_opt.c | 24 +++--- fftools/sync_queue.c | 33 --- fftools/sync_queue.h | 11 ++- tests/ref/fate/matroska-flac-extradata-update | 16 +++-- tests/ref/fate/mkv-1242 | 3 -- 7 files changed, 63 insertions(+), 40 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 15e350f8fd..503a148103 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -3467,12 +3467,6 @@ static int need_output(void) if (ost->finished || of_finished(of)) continue; -if (ost->frame_number >= ost->max_frames) { -int j; -for (j = 0; j < of->ctx->nb_streams; j++) -close_output_stream(output_streams[of->ost_index + j]); -continue; -} return 1; } diff --git a/fftools/ffmpeg_mux.c b/fftools/ffmpeg_mux.c index 641bdb98b0..56444770bf 100644 --- a/fftools/ffmpeg_mux.c +++ b/fftools/ffmpeg_mux.c @@ -237,19 +237,11 @@ void of_submit_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost) if (pkt) { /* - * Audio encoders may split the packets -- #frames in != #packets out. - * But there is no reordering, so we can limit the number of output packets - * by simply dropping them here. * Counting encoded video frames needs to be done separately because of * reordering, see do_video_out(). */ -if (!(st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && ost->encoding_needed)) { -if (ost->frame_number >= ost->max_frames) { -av_packet_unref(pkt); -return; -} +if (!(st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && ost->encoding_needed)) ost->frame_number++; -} } if (of->mux->header_written) { diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c index be88743463..12f5d16157 100644 --- a/fftools/ffmpeg_opt.c +++ b/fftools/ffmpeg_opt.c @@ -2336,6 +2336,7 @@ static int init_complex_filters(void) static int setup_sync_queues(OutputFile *of, AVFormatContext *oc, int64_t buf_size_us) { int nb_av_enc = 0, nb_interleaved = 0; +int limit_frames = 0, limit_frames_av_enc = 0; #define IS_AV_ENC(ost, type) \ (ost->encoding_needed && (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO)) @@ -2350,14 +2351,19 @@ static int setup_sync_queues(OutputFile *of, AVFormatContext *oc, int64_t buf_si nb_interleaved += IS_INTERLEAVED(type); nb_av_enc += IS_AV_ENC(ost, type); + +limit_frames|= ost->max_frames < INT64_MAX; +limit_frames_av_enc |= (ost->max_frames < INT64_MAX) && IS_AV_ENC(ost, type); } -if (!(nb_interleaved > 1 && of->shortest)) +if (!((nb_interleaved > 1 && of->shortest) || + (nb_interleaved > 0 && limit_frames))) return 0; -/* if we have more than one encoded audio/video streams, then we +/* if we have more than one encoded audio/video streams, or at least + * one encoded audio/video stream is frame-limited, then we * synchronize them before encoding */ -if (nb_av_enc > 1) { +if ((of->shortest && nb_av_enc > 1) || limit_frames_av_enc) { of->sq_encode = sq_alloc(SYNC_QUEUE_FRAMES, buf_size_us); if (!of->sq_encode) return AVERROR(ENOMEM); @@ -2369,13 +2375,17 @@ static int setup_sync_queues(OutputFile *of, AVFormatContext *oc, int64_t buf_si if (!IS_AV_ENC(ost, type)) continue; -ost->sq_idx_encode = sq_add_stream(of->sq_encode); +ost->sq_idx_encode = sq_add_stream(of->sq_encode, + of->shortest || ost->max_frames < INT64_MAX); if (ost->sq_idx_encode < 0) return ost->sq_idx_encode; ost->sq_frame = av_frame_alloc(); if (!ost->sq_frame) return AVERROR(ENOMEM); + +if (ost->max_frames != INT64_MAX) +sq_limit_frames(of->sq_encode, ost->sq_idx_encode, ost->max_frames); } } @@ -2393,9 +2403,13 @@ static int
[FFmpeg-devel] [PATCH v3] ffmpeg: add option -isync
This is a per-file input option that adjusts an input's timestamps with reference to another input, so that emitted packet timestamps account for the difference between the start times of the two inputs. Typical use case is to sync two or more live inputs such as from capture devices. Both the target and reference input source timestamps should be based on the same clock source. If not all inputs have timestamps, the wallclock times at the time of reception of inputs shall be used. FFmpeg must have been compiled with thread support for this last case. --- This is a single patch with the reception wallclock stored only in fftools. I find this sub-optimal because find_stream_info will have demuxed an indeterminate number of frames by the time the wallclock is stored. But it's better than nothing. doc/ffmpeg.texi | 16 ++ fftools/ffmpeg.c | 4 +++ fftools/ffmpeg.h | 3 ++ fftools/ffmpeg_opt.c | 69 4 files changed, 92 insertions(+) diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi index 1a534ff1cc..1fe0a559c0 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -518,6 +518,22 @@ see @ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) Like the @code{-ss} option but relative to the "end of file". That is negative values are earlier in the file, 0 is at EOF. +@item -isync @var{input_index} (@emph{input}) +Assign an input as a sync source. + +This will take the difference between the start times of the target and referenced inputs and +offset the timestamps of the target file by that difference. The source timestamps of the two +inputs should derive from the same clock source for expected results. If @code{copyts} is set +then @code{start_at_zero} must also be set. If at least one of the inputs has no starting +timestamp then the wallclock time at time of reception of the inputs is used as a best-effort +sync basis. + +Acceptable values are those that refer to a valid ffmpeg input index. If the sync reference is +the target index itself or @var{-1}, then no adjustment is made to target timestamps. A sync +reference may not itself be synced to any other input. + +Default value is @var{-1}. + @item -itsoffset @var{offset} (@emph{input}) Set the input time offset. diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index e7384f052a..290b8228b8 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -3658,6 +3658,10 @@ static void *input_thread(void *arg) av_thread_message_queue_set_err_recv(f->in_thread_queue, ret); break; } + +if (f->first_pkt_wallclock == AV_NOPTS_VALUE) +f->first_pkt_wallclock = av_gettime(); + queue_pkt = av_packet_alloc(); if (!queue_pkt) { av_packet_unref(pkt); diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index 99d31c346e..760e94d1e5 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -118,6 +118,7 @@ typedef struct OptionsContext { float readrate; int accurate_seek; int thread_queue_size; +int input_sync_ref; SpecifierOpt *ts_scale; intnb_ts_scale; @@ -409,7 +410,9 @@ typedef struct InputFile { int64_t duration; /* actual duration of the longest stream in a file at the moment when looping happens */ AVRational time_base; /* time base of the duration */ +int64_t first_pkt_wallclock; int64_t input_ts_offset; +int input_sync_ref; int64_t ts_offset; int64_t last_ts; diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c index e08455478f..b586f3e6b0 100644 --- a/fftools/ffmpeg_opt.c +++ b/fftools/ffmpeg_opt.c @@ -235,6 +235,7 @@ static void init_options(OptionsContext *o) o->chapters_input_file = INT_MAX; o->accurate_seek = 1; o->thread_queue_size = -1; +o->input_sync_ref = -1; } static int show_hwaccels(void *optctx, const char *opt, const char *arg) @@ -287,6 +288,67 @@ static int parse_and_set_vsync(const char *arg, int *vsync_var, int file_idx, in return 0; } +static int apply_sync_offsets(void) +{ +for (int i = 0; i < nb_input_files; i++) { +InputFile *ref, *self = input_files[i]; +int64_t adjustment; +int64_t self_start_time, ref_start_time, self_seek_start, ref_seek_start; +int sync_fpw = 0, start_times_set = 1; + +if (self->input_sync_ref == -1 || self->input_sync_ref == i) continue; +if (self->input_sync_ref >= nb_input_files || self->input_sync_ref < -1) { +av_log(NULL, AV_LOG_FATAL, "-isync for input %d references non-existent input %d.\n", i, self->input_sync_ref); +exit_program(1); +} + +if (copy_ts && !start_at_zero) { +av_log(NULL, AV_LOG_FATAL, "Use of -isync requires that start_at_zero be set if copyts is set.\n"); +exit_program(1); +} + +ref = input_files[self->input_sync_ref]; +if (ref->input_sync_r
Re: [FFmpeg-devel] [PATCH] avutil/channel_layout: don't error out on truncated strings
On Sun, Jul 03, 2022 at 09:27:31PM -0300, James Almer wrote: > On 7/3/2022 7:00 AM, Nicolas George wrote: > > Andreas Rheinhardt (12022-07-03): > > > > if (!av_bprint_is_complete(bp)) > > > > -return AVERROR(ENOMEM); > > > > +break; > > > > > Isn't this actually still against the API? av_channel_layout_describe() > > > will not return the correct number of bytes necessary to write the > > > string for the channel layout. > > > > You are both right. > > > > BPrint-based APIs are not supposed to check for truncation, because > > printing into a bounded buffer to determine the necessary size is a > > valid use (see AV_BPRINT_SIZE_COUNT_ONLY). > > > > What is wrong is Michael's original fix: > > > > > > commit 8154cb7c2ff2afcb1a0842de8c215b7714c814d0 > > > > Author: Michael Niedermayer > > > > Date: 2022-06-30 00:00:32 +0200 > > > > > > > > avutil/channel_layout: av_channel_layout_describe_bprint: Check > > > > for buffer end > > > > > > > > Fixes: Timeout printing a billion channels > > > > Fixes: > > > > 48099/clusterfuzz-testcase-minimized-ffmpeg_dem_MATROSKA_fuzzer-6754782204788736 > > > > > > > > Found-by: continuous fuzzing process > > > > https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg > > > > Signed-off-by: Michael Niedermayer > > > > > > > > diff --git a/libavutil/channel_layout.c b/libavutil/channel_layout.c > > > > index 21b70173b7..1887987789 100644 > > > > --- a/libavutil/channel_layout.c > > > > +++ b/libavutil/channel_layout.c > > > > @@ -757,6 +757,10 @@ int av_channel_layout_describe_bprint(const > > > > AVChannelLayout *channel_layout, > > > > if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM && > > > > > > channel_layout->u.map[i].name[0]) > > > > If the channel count is insanely high, then this will cause invalid > > reads. > > > > > > av_bprintf(bp, "@%s", channel_layout->u.map[i].name); > > > > + > > > > +if (!av_bprint_is_complete(bp)) > > > > +return AVERROR(ENOMEM); > > > > + > > > > } > > > > if (channel_layout->nb_channels) { > > > > av_bprintf(bp, ")"); > > > > Obviously, this fuzzer found a case where a demuxer or a decoder > > constructs an invalid channel layout in memory without proper > > validation. There is a bug, possibly an security-related one, and this > > only hides it from the test suite. > > The Matroska demuxer could in theory generate a native layout with more than > 64 channels where popcnt(mask) != channels, and nothing seems to validate > what a demuxer's read_header() callback returns if you just call lavf API > functions like target_dem_fuzzer.c seems to do. > > Maybe: > > > diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c > > index 73ded761fd..ad7ee390a2 100644 > > --- a/libavformat/matroskadec.c > > +++ b/libavformat/matroskadec.c > > @@ -2950,10 +2950,10 @@ static int matroska_parse_tracks(AVFormatContext *s) > > st->codecpar->codec_tag = fourcc; > > st->codecpar->sample_rate = track->audio.out_samplerate; > > // channel layout may be already set by codec private checks > > above > > -if (st->codecpar->ch_layout.order == AV_CHANNEL_ORDER_NATIVE && > > -!st->codecpar->ch_layout.u.mask) > > +if (!av_channel_layout_check(&st->codecpar->ch_layout)) { > > st->codecpar->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; > > -st->codecpar->ch_layout.nb_channels = track->audio.channels; > > +st->codecpar->ch_layout.nb_channels = > > track->audio.channels; > > +} > > if (!st->codecpar->bits_per_coded_sample) > > st->codecpar->bits_per_coded_sample = > > track->audio.bitdepth; > > if (st->codecpar->codec_id == AV_CODEC_ID_MP3 || > > is enough to ensure a valid layout is propagated. This assumes parameters > set by codec private parsing are correct (only FLAC seem to be present right > now, and it is). > > Assuming i got this right, in this fuzzing sample's case it would still have > a billion channels (since that's what track->audio.channels contains, as > read from the container), but using the unspec layout, which is technically > valid even if nothing will really handle it, and > av_channel_layout_describe() will print a small string. seems this is fixing it thanks > > Still, i think a check in avformat_open_input() might also be a good idea, yes, i agree > especially once (and if) demuxers start propagating custom layouts, where > the map array will be allocated. [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB No great genius has ever existed without some touch of madness. -- Aristotle signature.asc Description: PGP signature ___ ffmpeg-devel mailing list ffmpeg-d
Re: [FFmpeg-devel] [PATCH] avutil/channel_layout: don't error out on truncated strings
On 7/4/2022 1:55 PM, Michael Niedermayer wrote: On Sun, Jul 03, 2022 at 09:27:31PM -0300, James Almer wrote: On 7/3/2022 7:00 AM, Nicolas George wrote: Andreas Rheinhardt (12022-07-03): if (!av_bprint_is_complete(bp)) -return AVERROR(ENOMEM); +break; Isn't this actually still against the API? av_channel_layout_describe() will not return the correct number of bytes necessary to write the string for the channel layout. You are both right. BPrint-based APIs are not supposed to check for truncation, because printing into a bounded buffer to determine the necessary size is a valid use (see AV_BPRINT_SIZE_COUNT_ONLY). What is wrong is Michael's original fix: commit 8154cb7c2ff2afcb1a0842de8c215b7714c814d0 Author: Michael Niedermayer Date: 2022-06-30 00:00:32 +0200 avutil/channel_layout: av_channel_layout_describe_bprint: Check for buffer end Fixes: Timeout printing a billion channels Fixes: 48099/clusterfuzz-testcase-minimized-ffmpeg_dem_MATROSKA_fuzzer-6754782204788736 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer diff --git a/libavutil/channel_layout.c b/libavutil/channel_layout.c index 21b70173b7..1887987789 100644 --- a/libavutil/channel_layout.c +++ b/libavutil/channel_layout.c @@ -757,6 +757,10 @@ int av_channel_layout_describe_bprint(const AVChannelLayout *channel_layout, if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM && channel_layout->u.map[i].name[0]) If the channel count is insanely high, then this will cause invalid reads. av_bprintf(bp, "@%s", channel_layout->u.map[i].name); + +if (!av_bprint_is_complete(bp)) +return AVERROR(ENOMEM); + } if (channel_layout->nb_channels) { av_bprintf(bp, ")"); Obviously, this fuzzer found a case where a demuxer or a decoder constructs an invalid channel layout in memory without proper validation. There is a bug, possibly an security-related one, and this only hides it from the test suite. The Matroska demuxer could in theory generate a native layout with more than 64 channels where popcnt(mask) != channels, and nothing seems to validate what a demuxer's read_header() callback returns if you just call lavf API functions like target_dem_fuzzer.c seems to do. Maybe: diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 73ded761fd..ad7ee390a2 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -2950,10 +2950,10 @@ static int matroska_parse_tracks(AVFormatContext *s) st->codecpar->codec_tag = fourcc; st->codecpar->sample_rate = track->audio.out_samplerate; // channel layout may be already set by codec private checks above -if (st->codecpar->ch_layout.order == AV_CHANNEL_ORDER_NATIVE && -!st->codecpar->ch_layout.u.mask) +if (!av_channel_layout_check(&st->codecpar->ch_layout)) { st->codecpar->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; -st->codecpar->ch_layout.nb_channels = track->audio.channels; +st->codecpar->ch_layout.nb_channels = track->audio.channels; +} if (!st->codecpar->bits_per_coded_sample) st->codecpar->bits_per_coded_sample = track->audio.bitdepth; if (st->codecpar->codec_id == AV_CODEC_ID_MP3 || is enough to ensure a valid layout is propagated. This assumes parameters set by codec private parsing are correct (only FLAC seem to be present right now, and it is). Assuming i got this right, in this fuzzing sample's case it would still have a billion channels (since that's what track->audio.channels contains, as read from the container), but using the unspec layout, which is technically valid even if nothing will really handle it, and av_channel_layout_describe() will print a small string. seems this is fixing it thanks Ok, will apply it and revert 8154cb7c2f. Still, i think a check in avformat_open_input() might also be a good idea, yes, i agree especially once (and if) demuxers start propagating custom layouts, where the map array will be allocated. [...] ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/4] av(format|device): Add const to muxer packet data pointers
The packets given to muxers need not be writable, so it is best to access them via const uint8_t*. Signed-off-by: Andreas Rheinhardt --- libavdevice/alsa_enc.c | 2 +- libavdevice/fbdev_enc.c | 3 ++- libavdevice/oss_enc.c| 2 +- libavdevice/sndio_enc.c | 2 +- libavformat/dvenc.c | 2 +- libavformat/gif.c| 2 +- libavformat/movenc.h | 2 +- libavformat/movenchint.c | 2 +- libavformat/mxfenc.c | 2 +- libavformat/oggenc.c | 4 ++-- libavformat/spdifenc.c | 4 ++-- libavformat/swfenc.c | 4 ++-- 12 files changed, 16 insertions(+), 15 deletions(-) diff --git a/libavdevice/alsa_enc.c b/libavdevice/alsa_enc.c index 3d6bccdc2a..ac09e33c49 100644 --- a/libavdevice/alsa_enc.c +++ b/libavdevice/alsa_enc.c @@ -86,7 +86,7 @@ static int audio_write_packet(AVFormatContext *s1, AVPacket *pkt) AlsaData *s = s1->priv_data; int res; int size = pkt->size; -uint8_t *buf = pkt->data; +const uint8_t *buf = pkt->data; size /= s->frame_size; if (pkt->dts != AV_NOPTS_VALUE) diff --git a/libavdevice/fbdev_enc.c b/libavdevice/fbdev_enc.c index 898a630aa1..84ec6733ff 100644 --- a/libavdevice/fbdev_enc.c +++ b/libavdevice/fbdev_enc.c @@ -100,7 +100,8 @@ static av_cold int fbdev_write_header(AVFormatContext *h) static int fbdev_write_packet(AVFormatContext *h, AVPacket *pkt) { FBDevContext *fbdev = h->priv_data; -uint8_t *pin, *pout; +const uint8_t *pin; +uint8_t *pout; enum AVPixelFormat fb_pix_fmt; int disp_height; int bytes_to_copy; diff --git a/libavdevice/oss_enc.c b/libavdevice/oss_enc.c index d6a512a264..704f434c53 100644 --- a/libavdevice/oss_enc.c +++ b/libavdevice/oss_enc.c @@ -55,9 +55,9 @@ static int audio_write_header(AVFormatContext *s1) static int audio_write_packet(AVFormatContext *s1, AVPacket *pkt) { OSSAudioData *s = s1->priv_data; +const uint8_t *buf = pkt->data; int len, ret; int size= pkt->size; -uint8_t *buf= pkt->data; while (size > 0) { len = FFMIN(OSS_AUDIO_BLOCK_SIZE - s->buffer_ptr, size); diff --git a/libavdevice/sndio_enc.c b/libavdevice/sndio_enc.c index a595438d8a..0cf58fdc6a 100644 --- a/libavdevice/sndio_enc.c +++ b/libavdevice/sndio_enc.c @@ -46,7 +46,7 @@ static av_cold int audio_write_header(AVFormatContext *s1) static int audio_write_packet(AVFormatContext *s1, AVPacket *pkt) { SndioData *s = s1->priv_data; -uint8_t *buf= pkt->data; +const uint8_t *buf = pkt->data; int size = pkt->size; int len, ret; diff --git a/libavformat/dvenc.c b/libavformat/dvenc.c index 1917c00694..7ef9692302 100644 --- a/libavformat/dvenc.c +++ b/libavformat/dvenc.c @@ -245,7 +245,7 @@ static void dv_inject_metadata(DVMuxContext *c, uint8_t* frame) static int dv_assemble_frame(AVFormatContext *s, DVMuxContext *c, AVStream* st, - uint8_t* data, int data_size, uint8_t** frame) + const uint8_t *data, int data_size, uint8_t **frame) { int i, reqasize; diff --git a/libavformat/gif.c b/libavformat/gif.c index cba87d3eae..b52ff4dd39 100644 --- a/libavformat/gif.c +++ b/libavformat/gif.c @@ -54,7 +54,7 @@ static int gif_write_header(AVFormatContext *s) return 0; } -static int gif_parse_packet(AVFormatContext *s, uint8_t *data, int size) +static int gif_parse_packet(AVFormatContext *s, const uint8_t *data, int size) { GetByteContext gb; int x; diff --git a/libavformat/movenc.h b/libavformat/movenc.h index e4550f7900..c6b3313deb 100644 --- a/libavformat/movenc.h +++ b/libavformat/movenc.h @@ -62,7 +62,7 @@ typedef struct MOVIentry { } MOVIentry; typedef struct HintSample { -uint8_t *data; +const uint8_t *data; int size; int sample_number; int offset; diff --git a/libavformat/movenchint.c b/libavformat/movenchint.c index a3ac7b..0169341189 100644 --- a/libavformat/movenchint.c +++ b/libavformat/movenchint.c @@ -96,7 +96,7 @@ static void sample_queue_free(HintSampleQueue *queue) * not copied. sample_queue_retain should be called before pkt->data * is reused/freed. */ -static void sample_queue_push(HintSampleQueue *queue, uint8_t *data, int size, +static void sample_queue_push(HintSampleQueue *queue, const uint8_t *data, int size, int sample) { /* No need to keep track of smaller samples, since describing them diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c index 2d08dd6d40..9a9acbfa08 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -2139,7 +2139,7 @@ static int mxf_parse_dv_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt) { MXFContext *mxf = s->priv_data; MXFStreamContext *sc = st->priv_data; -uint8_t *vs_pack, *vsc_pack; +const uint8_t *vs_pack, *vsc_pack; int apt, ul_index, stype, pal; if (mxf->header_written) diff --git a/libavformat/oggenc.c b/libavformat/oggenc.c index 016047f616..ae0705ba54 100
[FFmpeg-devel] [PATCH 2/4] avcodec: Add const to muxer packet data pointers
The packets given to decoder need not be writable, so it is best to access them via const uint8_t*. Signed-off-by: Andreas Rheinhardt --- libavcodec/cpia.c| 4 ++-- libavcodec/dfpwmdec.c| 3 ++- libavcodec/hnm4video.c | 8 libavcodec/libcodec2.c | 2 +- libavcodec/libvpxdec.c | 2 +- libavcodec/libzvbi-teletextdec.c | 2 +- libavcodec/pafvideo.c| 2 +- libavcodec/pixlet.c | 4 ++-- libavcodec/webp.c| 8 libavcodec/yop.c | 6 +++--- 10 files changed, 21 insertions(+), 20 deletions(-) diff --git a/libavcodec/cpia.c b/libavcodec/cpia.c index 2f4ad1fb5b..fcf2621e61 100644 --- a/libavcodec/cpia.c +++ b/libavcodec/cpia.c @@ -54,8 +54,8 @@ static int cpia_decode_frame(AVCodecContext *avctx, AVFrame *rframe, CpiaContext* const cpia = avctx->priv_data; int i,j,ret; -uint8_t* const header = avpkt->data; -uint8_t* src; +const uint8_t *const header = avpkt->data; +const uint8_t *src; int src_size; uint16_t linelength; uint8_t skip; diff --git a/libavcodec/dfpwmdec.c b/libavcodec/dfpwmdec.c index 77c6d2cb18..d013d4c215 100644 --- a/libavcodec/dfpwmdec.c +++ b/libavcodec/dfpwmdec.c @@ -38,7 +38,8 @@ typedef struct { // DFPWM codec from https://github.com/ChenThread/dfpwm/blob/master/1a/ // Licensed in the public domain -static void au_decompress(DFPWMState *state, int fs, int len, uint8_t *outbuf, uint8_t *inbuf) +static void au_decompress(DFPWMState *state, int fs, int len, + uint8_t *outbuf, const uint8_t *inbuf) { unsigned d; for (int i = 0; i < len; i++) { diff --git a/libavcodec/hnm4video.c b/libavcodec/hnm4video.c index 9eb9f3a694..1326d5f872 100644 --- a/libavcodec/hnm4video.c +++ b/libavcodec/hnm4video.c @@ -64,7 +64,7 @@ static int getbit(GetByteContext *gb, uint32_t *bitbuf, int *bits) return ret; } -static void unpack_intraframe(AVCodecContext *avctx, uint8_t *src, +static void unpack_intraframe(AVCodecContext *avctx, const uint8_t *src, uint32_t size) { Hnm4VideoContext *hnm = avctx->priv_data; @@ -147,7 +147,7 @@ static void copy_processed_frame(AVCodecContext *avctx, AVFrame *frame) } } -static int decode_interframe_v4(AVCodecContext *avctx, uint8_t *src, uint32_t size) +static int decode_interframe_v4(AVCodecContext *avctx, const uint8_t *src, uint32_t size) { Hnm4VideoContext *hnm = avctx->priv_data; GetByteContext gb; @@ -276,7 +276,7 @@ static int decode_interframe_v4(AVCodecContext *avctx, uint8_t *src, uint32_t si return 0; } -static void decode_interframe_v4a(AVCodecContext *avctx, uint8_t *src, +static void decode_interframe_v4a(AVCodecContext *avctx, const uint8_t *src, uint32_t size) { Hnm4VideoContext *hnm = avctx->priv_data; @@ -355,7 +355,7 @@ static void decode_interframe_v4a(AVCodecContext *avctx, uint8_t *src, } } -static void hnm_update_palette(AVCodecContext *avctx, uint8_t *src, +static void hnm_update_palette(AVCodecContext *avctx, const uint8_t *src, uint32_t size) { Hnm4VideoContext *hnm = avctx->priv_data; diff --git a/libavcodec/libcodec2.c b/libavcodec/libcodec2.c index 9064b823ee..abb1130e80 100644 --- a/libavcodec/libcodec2.c +++ b/libavcodec/libcodec2.c @@ -135,7 +135,7 @@ static int libcodec2_decode(AVCodecContext *avctx, AVFrame *frame, { LibCodec2Context *c2 = avctx->priv_data; int ret, nframes, i; -uint8_t *input; +const uint8_t *input; int16_t *output; nframes = pkt->size / avctx->block_align; diff --git a/libavcodec/libvpxdec.c b/libavcodec/libvpxdec.c index ef690a7093..0b279e7eda 100644 --- a/libavcodec/libvpxdec.c +++ b/libavcodec/libvpxdec.c @@ -199,7 +199,7 @@ static int set_pix_fmt(AVCodecContext *avctx, struct vpx_image *img, } static int decode_frame(AVCodecContext *avctx, vpx_codec_ctx_t *decoder, -uint8_t *data, uint32_t data_sz) +const uint8_t *data, uint32_t data_sz) { if (vpx_codec_decode(decoder, data, data_sz, NULL, 0) != VPX_CODEC_OK) { const char *error = vpx_codec_error(decoder); diff --git a/libavcodec/libzvbi-teletextdec.c b/libavcodec/libzvbi-teletextdec.c index 92466cc11e..514e76f1b6 100644 --- a/libavcodec/libzvbi-teletextdec.c +++ b/libavcodec/libzvbi-teletextdec.c @@ -581,7 +581,7 @@ static void handler(vbi_event *ev, void *user_data) vbi_unref_page(&page); } -static int slice_to_vbi_lines(TeletextContext *ctx, uint8_t* buf, int size) +static int slice_to_vbi_lines(TeletextContext *ctx, const uint8_t *buf, int size) { int lines = 0; while (size >= 2 && lines < MAX_SLICES) { diff --git a/libavcodec/pafvideo.c b/libavcodec/pafvideo.c index a0bd22e8fd..60cdd34add 100644 --- a/libavcodec/pafvideo.c +++ b/libavcodec/pafvideo.c @@ -159,7 +159,7 @@
[FFmpeg-devel] [PATCH 3/4] fftools/ffprobe: Add const to AVPacket data pointers
These packets need not be writable (and are not modified by us), so it is best to access them via const uint8_t*. Signed-off-by: Andreas Rheinhardt --- fftools/ffprobe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c index 5020ba484c..2f110efcb7 100644 --- a/fftools/ffprobe.c +++ b/fftools/ffprobe.c @@ -901,7 +901,7 @@ static void writer_print_ts(WriterContext *wctx, const char *key, int64_t ts, in } static void writer_print_data(WriterContext *wctx, const char *name, - uint8_t *data, int size) + const uint8_t *data, int size) { AVBPrint bp; int offset = 0, l, i; @@ -929,7 +929,7 @@ static void writer_print_data(WriterContext *wctx, const char *name, } static void writer_print_data_hash(WriterContext *wctx, const char *name, - uint8_t *data, int size) + const uint8_t *data, int size) { char *p, buf[AV_HASH_MAX_SIZE * 2 + 64] = { 0 }; -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 4/4] avformat/movenc: Ensure packet is writable before modifying it
Fixes e.g. ffmpeg -i fate-suite/h264/bbc2.sample.h264 -c:v rawvideo -map 0:v -frames:v 10 -pix_fmt gray8 -f tee "first.mov|second.mov" Signed-off-by: Andreas Rheinhardt --- libavformat/movenc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index a4dace7c1d..5608afde42 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -6513,6 +6513,9 @@ static int mov_write_packet(AVFormatContext *s, AVPacket *pkt) } else if (trk->par->codec_id == AV_CODEC_ID_RAWVIDEO && (trk->par->format == AV_PIX_FMT_GRAY8 || trk->par->format == AV_PIX_FMT_MONOBLACK)) { +ret = av_packet_make_writable(pkt); +if (ret < 0) +goto fail; for (i = 0; i < pkt->size; i++) pkt->data[i] = ~pkt->data[i]; } -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/3] tools/target_dec_fuzzer: Adjust threshold for CFHD
Fixes: Timeout Fixes: 46504/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_CFHD_fuzzer-6376835606249472 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- tools/target_dec_fuzzer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/target_dec_fuzzer.c b/tools/target_dec_fuzzer.c index fefc8514f0..9a4e2136eb 100644 --- a/tools/target_dec_fuzzer.c +++ b/tools/target_dec_fuzzer.c @@ -211,7 +211,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { case AV_CODEC_ID_AGM: maxpixels /= 1024; break; case AV_CODEC_ID_ARBC:maxpixels /= 1024; break; case AV_CODEC_ID_BINKVIDEO: maxpixels /= 32;break; -case AV_CODEC_ID_CFHD:maxpixels /= 128; break; +case AV_CODEC_ID_CFHD:maxpixels /= 16384; break; case AV_CODEC_ID_COOK:maxsamples /= 1<<20; break; case AV_CODEC_ID_DFA: maxpixels /= 1024; break; case AV_CODEC_ID_DIRAC: maxpixels /= 8192; break; -- 2.17.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 3/3] avformat/iff: simplify duration calculation
Fixes: signed integer overflow: 315680096256 * 134215943 cannot be represented in type 'long long' Fixes: 48713/clusterfuzz-testcase-minimized-ffmpeg_dem_IFF_fuzzer-5886272312311808 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavformat/iff.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libavformat/iff.c b/libavformat/iff.c index 3c861ef34d..b37600605a 100644 --- a/libavformat/iff.c +++ b/libavformat/iff.c @@ -384,7 +384,7 @@ static int read_dst_frame(AVFormatContext *s, AVPacket *pkt) avio_skip(pb, 1); pkt->flags |= AV_PKT_FLAG_KEY; pkt->stream_index = 0; -pkt->duration = 588LL * s->streams[0]->codecpar->sample_rate / 44100; +pkt->duration = s->streams[0]->codecpar->sample_rate / 75; pkt->pos = chunk_pos; chunk_pos = avio_tell(pb); @@ -397,7 +397,8 @@ static int read_dst_frame(AVFormatContext *s, AVPacket *pkt) case ID_FRTE: if (data_size < 4) return AVERROR_INVALIDDATA; -s->streams[0]->duration = avio_rb32(pb) * 588LL * s->streams[0]->codecpar->sample_rate / 44100; +s->streams[0]->duration = avio_rb32(pb) * (uint64_t)s->streams[0]->codecpar->sample_rate / 75; + break; } -- 2.17.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/3] tools/target_dec_fuzzer: Adjust threshold for MVC2
Fixes: Timeout Fixes: 48689/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_MVC2_fuzzer-6436301427048448 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- tools/target_dec_fuzzer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/target_dec_fuzzer.c b/tools/target_dec_fuzzer.c index 9a4e2136eb..adafc977e4 100644 --- a/tools/target_dec_fuzzer.c +++ b/tools/target_dec_fuzzer.c @@ -245,6 +245,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { case AV_CODEC_ID_MSRLE: maxpixels /= 16;break; case AV_CODEC_ID_MSS2:maxpixels /= 16384; break; case AV_CODEC_ID_MSZH:maxpixels /= 128; break; +case AV_CODEC_ID_MVC2:maxpixels /= 128; break; case AV_CODEC_ID_MXPEG: maxpixels /= 128; break; case AV_CODEC_ID_OPUS:maxsamples /= 16384; break; case AV_CODEC_ID_PNG: maxpixels /= 128; break; -- 2.17.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] avformat/concat: fix missing metadata
I'm not sure we're on the same page, so let me try and clarify. The files have multiple tracks, the standard audio and video and 3 metadata tracks. I'm using the command line option -map 0:m:handler_name:"" to identify the tracks to copy. Given a single file this works as expected, but as soon as concat has multiple files the track metadata is lost and the handler_name match fails due to this early return. Each of the tracks I'm selected are able to be concatenated just fine, much like the a/v tracks. It's not about the file metadata, it's the track metadata which is needed for track identification which I'm looking to preserve. Does that make sense? Regards Steve On Sun, 3 Jul 2022 at 14:50, Nicolas George wrote: > Andreas Rheinhardt (12022-07-03): > > > For example, with your change, if you concatenate a file with metadata > > > "start_time=12:00" and another with "start_time=12:01", it will > generate > > > a file with both metadata entries instead of just the first one as > would > > > be desirable. > > > Actually, the newer entry will overwrite the older entry; if you want > > multiple keys with the same value, you have to use the AV_DICT_MULTIKEY > > flag. > > I stand corrected, thanks. This is still not the most logical behavior, > though. > > Regards, > > -- > Nicolas George > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] lavu: always provide symbols from hwcontext_vulkan.h
From: Niklas Haas This header is unconditionally installed, even though the utility functions defined by it may be missing from the built library. A precedent set by e.g. libavcodec/qsv.h (and others) is to always provide these functions by compiling stub functions in the absence of CONFIG_*. Make hwcontext_vulkan.h match this convention. Fixes downstream issues, e.g. https://github.com/haasn/libplacebo/issues/120 Signed-off-by: Niklas Haas --- libavutil/Makefile | 2 +- libavutil/hwcontext_vulkan.c | 26 -- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/libavutil/Makefile b/libavutil/Makefile index 29c170214c..66017a33a2 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -136,6 +136,7 @@ OBJS = adler32.o \ hdr_dynamic_vivid_metadata.o \ hmac.o \ hwcontext.o \ + hwcontext_vulkan.o \ imgutils.o \ integer.o\ intmath.o\ @@ -194,7 +195,6 @@ OBJS-$(CONFIG_QSV) += hwcontext_qsv.o OBJS-$(CONFIG_VAAPI)+= hwcontext_vaapi.o OBJS-$(CONFIG_VIDEOTOOLBOX) += hwcontext_videotoolbox.o OBJS-$(CONFIG_VDPAU)+= hwcontext_vdpau.o -OBJS-$(CONFIG_VULKAN) += hwcontext_vulkan.o OBJS += $(COMPAT_OBJS:%=../compat/%) diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c index 237caa4bc0..f7944a321c 100644 --- a/libavutil/hwcontext_vulkan.c +++ b/libavutil/hwcontext_vulkan.c @@ -16,6 +16,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include + +#include "config.h" +#include "pixdesc.h" + +#if CONFIG_VULKAN + #define VK_NO_PROTOTYPES #define VK_ENABLE_BETA_EXTENSIONS @@ -29,8 +36,6 @@ #include -#include "config.h" -#include "pixdesc.h" #include "avstring.h" #include "imgutils.h" #include "hwcontext.h" @@ -4161,3 +4166,20 @@ const HWContextType ff_hwcontext_type_vulkan = { AV_PIX_FMT_NONE }, }; + +#else /* !CONFIG_VULKAN */ + +struct AVVkFrame *av_vk_frame_alloc(void); +const enum VkFormat *av_vkfmt_from_pixfmt(enum AVPixelFormat p); + +struct AVVkFrame *av_vk_frame_alloc(void) +{ +return NULL; +} + +const enum VkFormat *av_vkfmt_from_pixfmt(enum AVPixelFormat p) +{ +return NULL; +} + +#endif -- 2.36.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".