Re: [FFmpeg-devel] [PATCH 4/4] avfilter/vf_v360: refactor (i)flat_range for fisheye
On Mon, Apr 12, 2021 at 7:44 AM Daniel Playfair Cal < daniel.playfair@gmail.com> wrote: > > Ok, dfov for width != height in (d)fisheye have been fixed. > > Great, thanks :) > > > The aspect ratio one breaks handling in case input is in equirectangular > format. > > That's not obvious to me - can you provide an example filtergraph > where it breaks, and explain why it's wrong? > > > Dunno what to do with rest of patches. > > The most important one I think is the visibility test for fisheye > input - that is the only one that can't be worked around. > > Going back to your original example: > > `v360=input=e:output=fisheye:h_fov=180:v_fov=180,v360=input=fisheye:output=e:ih_fov=180:iv_fov=180` > > Now that you've added the ability to specify fov settings for the > equirectangular projection, you can apply my patch and still have the > output you expect, for example: > > > v360=input=e:output=fisheye:h_fov=180:v_fov=180,v360=input=fisheye:output=e:ih_fov=180:iv_fov=180:h_fov=180 > > The use of h_fov on the output prevents anything outside of 180 > horizontal field of view from being mapped (because its outside the > bounds of the output image). > That is not same output, The transparent part is completely missing. Perhaps another option should be added somehow. > > At the same time, its possible to map an entire fisheye image > including the corners, for example in my use case of converting > fisheye -> flat. > > On Sun, Apr 11, 2021 at 6:23 PM Paul B Mahol wrote: > > > > Ok, dfov for width != height in (d)fisheye have been fixed. > > > > Dunno what to do with rest of patches. > > > > The aspect ratio one breaks handling in case input is in equirectangular > format. > > > > On Sun, Apr 11, 2021 at 6:48 AM Daniel Playfair Cal < > daniel.playfair@gmail.com> wrote: > >> > >> > AFAIK, the h/v/d fov works fine with fisheye in/out. I used synthetic > fisheye images from paul bourke site. > >> > >> > And diagonal fov from w/h either works with both in and out or not at > all. > >> > >> That doesn't seem correct. If an image with an equidistant projection > >> is of dimensions WxH and has the focal point at the center, then the > >> fields of view are related as follows for some value of f: > >> horizontal: f*W > >> vertical: f*H > >> diagonal: f*sqrt( W^2 + H^2 ) > >> > >> In the example I gave, v360 chooses horizontal/vertical fields of view > >> that are incompatible with the diagonal field of view provided. > >> Therefore (assuming 1:1 pixel aspect ratio), since > >> sqrt(116.66^2+87.5^2) = 145.83, `input=fisheye:id_fov=145.83` should > >> behave the same as `input=fisheye:ih_fov=116.66:iv_fov=87.50` in terms > >> of the focal length. It doesn't, so I think this is a bug. > >> > >> > So you want to not discard pixels out of circle defined by fov? That > generally does not make sense to me as that may not gonna have actual > pixels that belong to output. > >> > >> What circle/FoV are you referring to? The FoV depends on which points > >> on the image you choose to compare (for example the > >> horizontal/vertical/diagonal FoVs are all different). > >> Sometimes/usually there is no circle which describes which points in > >> the image can be correctly mapped. > >> > >> If a pixel in an image lies at a point where the projection of that > >> image is not defined, then yes it should be discarded. I think this is > >> correct in my patches. > >> > >> > Make sure that your files have correct projection, fisheye in v360 is > strict equidistant mapping, and may not be what your input is actually. > >> > >> Yes, I agree we shouldn't assume anything based on the > >> content/appearance of the images from my GoPro. But it's possible to > >> make a rectangular image of 1920x1440 pixels with an equidistant > >> fisheye projection where the horizontal, vertical, and diagonal FoV is > >> 116.66, 87.5, and 145.83. All the pixels in that image are defined in > >> the equidistant projection, so I think it should be possible for v360 > >> to map all the pixels to an appropriate output. If my image is not a > >> real equidistant fisheye projection, or if my FoV measurements are > >> wrong, then the chessboard won't have the right shape in the output. > >> This is not the problem I am trying to solve here. > >> > >> On Sun, Apr 11, 2021 at 9:37 AM Paul B Mahol wrote: > >> > > >> > > >> > > >> > On Mon, Mar 22, 2021 at 1:35 PM Daniel Playfair Cal < > daniel.playfair@gmail.com> wrote: > >> >> > >> >> > I disagree, if I use 180 hfov and 180 vfov it should not have > extra areas but only half of previous input. > >> >> > >> >> Not sure I follow - the ih_fov and vh_fov refer to the input (i.e. > the fisheye image). If you wanted to restrict the FoV of the output, surely > the way to do that would be to implement and use the FoV settings for the > equirectangular projection?. It doesn't seem right that the code for the > input projection is responsible for deciding what appears in the output. My > understanding was tha
Re: [FFmpeg-devel] [PATCH] doc/muxers.texi: fix build issue for unknown command
> -Original Message- > From: ffmpeg-devel On Behalf Of > Gyan Doshi > Sent: 2021年4月18日 13:04 > To: ffmpeg-devel@ffmpeg.org > Subject: Re: [FFmpeg-devel] [PATCH] doc/muxers.texi: fix build issue for > unknown command > > > > On 2021-04-18 10:11, Guo, Yejun wrote: > > The build log: > > ** Unknown command `@code' (left as is) (in src/doc/muxers.texi l. > 2020) > > *** '{' without macro. Before: -map} option with the ffmpeg CLI tool. (in > src/doc/muxers.texi l. 2020) > > *** '}' without opening '{' before: option with the ffmpeg CLI tool. (in > src/doc/muxers.texi l. 2020) > > I get no warnings here. The generated docs have been live for a week now. > > What's the full log? Perl version? My system is ubuntu 18.04, more detail see below. $ perl -v This is perl 5, version 26, subversion 1 (v5.26.1) built for x86_64-linux-gnu-thread-multi $ ../ffmpeg/configure $ make -j8 $ touch src/doc/muxers.texi $ V=1 make perl src/doc/texidep.pl src src/doc/ffmpeg.texi doc/ffmpeg.html >doc/ffmpeg.html.d texi2html -I doc -monolithic --D=config-not-all --init-file src/doc/t2h.init --output doc/ffmpeg.html src/doc/ffmpeg.texi perl src/doc/texidep.pl src src/doc/ffplay.texi doc/ffplay.html >doc/ffplay.html.d texi2html -I doc -monolithic --D=config-not-all --init-file src/doc/t2h.init --output doc/ffplay.html src/doc/ffplay.texi perl src/doc/texidep.pl src src/doc/ffprobe.texi doc/ffprobe.html >doc/ffprobe.html.d texi2html -I doc -monolithic --D=config-not-all --init-file src/doc/t2h.init --output doc/ffprobe.html src/doc/ffprobe.texi perl src/doc/texidep.pl src src/doc/ffmpeg.texi doc/ffmpeg-all.html >doc/ffmpeg-all.html.d texi2html -I doc -monolithic --D=config-all --init-file src/doc/t2h.init --output doc/ffmpeg-all.html src/doc/ffmpeg.texi ** Unknown command `@code' (left as is) (in src/doc/muxers.texi l. 2020) *** '{' without macro. Before: -map} option with the ffmpeg CLI tool. (in src/doc/muxers.texi l. 2020) *** '}' without opening '{' before: option with the ffmpeg CLI tool. (in src/doc/muxers.texi l. 2020) perl src/doc/texidep.pl src src/doc/ffplay.texi doc/ffplay-all.html >doc/ffplay-all.html.d texi2html -I doc -monolithic --D=config-all --init-file src/doc/t2h.init --output doc/ffplay-all.html src/doc/ffplay.texi perl src/doc/texidep.pl src src/doc/ffprobe.texi doc/ffprobe-all.html >doc/ffprobe-all.html.d texi2html -I doc -monolithic --D=config-all --init-file src/doc/t2h.init --output doc/ffprobe-all.html src/doc/ffprobe.texi perl src/doc/texidep.pl src src/doc/ffmpeg-formats.texi doc/ffmpeg-formats.html >doc/ffmpeg-formats.html.d texi2html -I doc -monolithic --D=config-not-all --init-file src/doc/t2h.init --output doc/ffmpeg-formats.html src/doc/ffmpeg-formats.texi ** Unknown command `@code' (left as is) (in src/doc/muxers.texi l. 2020) *** '{' without macro. Before: -map} option with the ffmpeg CLI tool. (in src/doc/muxers.texi l. 2020) *** '}' without opening '{' before: option with the ffmpeg CLI tool. (in src/doc/muxers.texi l. 2020) perl src/doc/texidep.pl src src/doc/ffmpeg.texi doc/ffmpeg.pod >doc/ffmpeg.pod.d perl src/doc/texi2pod.pl -Dconfig-not-all=yes -Idoc src/doc/ffmpeg.texi doc/ffmpeg.pod perl src/doc/texidep.pl src src/doc/ffplay.texi doc/ffplay.pod >doc/ffplay.pod.d perl src/doc/texi2pod.pl -Dconfig-not-all=yes -Idoc src/doc/ffplay.texi doc/ffplay.pod perl src/doc/texidep.pl src src/doc/ffprobe.texi doc/ffprobe.pod >doc/ffprobe.pod.d perl src/doc/texi2pod.pl -Dconfig-not-all=yes -Idoc src/doc/ffprobe.texi doc/ffprobe.pod perl src/doc/texidep.pl src src/doc/ffmpeg.texi doc/ffmpeg-all.pod >doc/ffmpeg-all.pod.d perl src/doc/texi2pod.pl -Dconfig-all=yes -Idoc src/doc/ffmpeg.texi doc/ffmpeg-all.pod perl src/doc/texidep.pl src src/doc/ffplay.texi doc/ffplay-all.pod >doc/ffplay-all.pod.d perl src/doc/texi2pod.pl -Dconfig-all=yes -Idoc src/doc/ffplay.texi doc/ffplay-all.pod perl src/doc/texidep.pl src src/doc/ffprobe.texi doc/ffprobe-all.pod >doc/ffprobe-all.pod.d perl src/doc/texi2pod.pl -Dconfig-all=yes -Idoc src/doc/ffprobe.texi doc/ffprobe-all.pod perl src/doc/texidep.pl src src/doc/ffmpeg-formats.texi doc/ffmpeg-formats.pod >doc/ffmpeg-formats.pod.d perl src/doc/texi2pod.pl -Dconfig-not-all=yes -Idoc src/doc/ffmpeg-formats.texi doc/ffmpeg-formats.pod pod2man --section=1 --center=" " --release=" " --date=" " doc/ffmpeg.pod > doc/ffmpeg.1 pod2man --section=1 --center=" " --release=" " --date=" " doc/ffplay.pod > doc/ffplay.1 pod2man --section=1 --center=" " --release=" " --date=" " doc/ffprobe.pod > doc/ffprobe.1 pod2man --section=1 --center=" " --release=" " --date=" " doc/ffmpeg-all.pod > doc/ffmpeg-all.1 pod2man --section=1 --center=" " --release=" " --date=" " doc/ffplay-all.pod > doc/ffplay-all.1 pod2man --section=1 --center=" " --release=" " --date=" " doc/ffprobe-all.pod > doc/ffprobe-all.1 pod2man --section=1 --center=" " --release=" " --date=" " doc/ffmpeg-formats.pod > doc/ffmpeg-formats.1 __
Re: [FFmpeg-devel] [PATCH 1/1] avcodec/nvenc: move lossless presets after new ones
pushed a refactor of the entire logic, since I realized that another piece of code (the options parsing logic) relies on the new presets being last. smime.p7s Description: S/MIME Cryptographic 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".
Re: [FFmpeg-devel] [PATCH 2/2] avfilter/af_mcompand: check allocation results
On Sat, 10 Apr 2021, Marton Balint wrote: On Sat, 10 Apr 2021, Andreas Rheinhardt wrote: Marton Balint: Fixes the only remaining part of ticket #8931. Signed-off-by: Marton Balint --- libavfilter/af_mcompand.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavfilter/af_mcompand.c b/libavfilter/af_mcompand.c index ce4f366ad7..d1a3dc123a 100644 --- a/libavfilter/af_mcompand.c +++ b/libavfilter/af_mcompand.c @@ -384,6 +384,9 @@ static int config_output(AVFilterLink *outlink) s->bands[i].attack_rate = av_calloc(outlink->channels, sizeof(double)); s->bands[i].decay_rate = av_calloc(outlink->channels, sizeof(double)); s->bands[i].volume = av_calloc(outlink->channels, sizeof(double)); +if (!s->bands[i].attack_rate || !s->bands[i].decay_rate || !s->bands[i].volume) +return AVERROR(ENOMEM); + for (k = 0; k < FFMIN(nb_attacks / 2, outlink->channels); k++) { char *tstr3 = av_strtok(p3, ",", &saveptr3); You are not the first one: https://ffmpeg.org/pipermail/ffmpeg-devel/2020-October/270956.html (I haven't applied this as I thought that Paul as the author/maintainer should do so.) If the maintainer does not seem interested then it is OK to apply, especially if it looks trivial. So feel free to apply whichever version you prefer. Will push this series soon. Regards, Marton ___ 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/6] lavfi/dnn_backend_openvino.c: unify code for infer request for sync/async
--- libavfilter/dnn/dnn_backend_openvino.c | 49 +++--- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/libavfilter/dnn/dnn_backend_openvino.c b/libavfilter/dnn/dnn_backend_openvino.c index 0757727a9c..874354ecef 100644 --- a/libavfilter/dnn/dnn_backend_openvino.c +++ b/libavfilter/dnn/dnn_backend_openvino.c @@ -52,9 +52,6 @@ typedef struct OVModel{ ie_core_t *core; ie_network_t *network; ie_executable_network_t *exe_network; -ie_infer_request_t *infer_request; - -/* for async execution */ SafeQueue *request_queue; // holds RequestItem Queue *task_queue; // holds TaskItem } OVModel; @@ -269,12 +266,9 @@ static void infer_completion_callback(void *args) ie_blob_free(&output_blob); request->task_count = 0; - -if (task->async) { -if (ff_safe_queue_push_back(requestq, request) < 0) { -av_log(ctx, AV_LOG_ERROR, "Failed to push back request_queue.\n"); -return; -} +if (ff_safe_queue_push_back(requestq, request) < 0) { +av_log(ctx, AV_LOG_ERROR, "Failed to push back request_queue.\n"); +return; } } @@ -347,11 +341,6 @@ static DNNReturnType init_model_ov(OVModel *ov_model, const char *input_name, co goto err; } -// create infer_request for sync execution -status = ie_exec_network_create_infer_request(ov_model->exe_network, &ov_model->infer_request); -if (status != OK) -goto err; - // create infer_requests for async execution if (ctx->options.nireq <= 0) { // the default value is a rough estimation @@ -502,10 +491,9 @@ static DNNReturnType get_output_ov(void *model, const char *input_name, int inpu OVModel *ov_model = model; OVContext *ctx = &ov_model->ctx; TaskItem task; -RequestItem request; +RequestItem *request; AVFrame *in_frame = NULL; AVFrame *out_frame = NULL; -TaskItem *ptask = &task; IEStatusCode status; input_shapes_t input_shapes; @@ -557,11 +545,16 @@ static DNNReturnType get_output_ov(void *model, const char *input_name, int inpu task.out_frame = out_frame; task.ov_model = ov_model; -request.infer_request = ov_model->infer_request; -request.task_count = 1; -request.tasks = &ptask; +request = ff_safe_queue_pop_front(ov_model->request_queue); +if (!request) { +av_frame_free(&out_frame); +av_frame_free(&in_frame); +av_log(ctx, AV_LOG_ERROR, "unable to get infer request.\n"); +return DNN_ERROR; +} +request->tasks[request->task_count++] = &task; -ret = execute_model_ov(&request); +ret = execute_model_ov(request); *output_width = out_frame->width; *output_height = out_frame->height; @@ -633,8 +626,7 @@ DNNReturnType ff_dnn_execute_model_ov(const DNNModel *model, const char *input_n OVModel *ov_model = model->model; OVContext *ctx = &ov_model->ctx; TaskItem task; -RequestItem request; -TaskItem *ptask = &task; +RequestItem *request; if (!in_frame) { av_log(ctx, AV_LOG_ERROR, "in frame is NULL when execute model.\n"); @@ -674,11 +666,14 @@ DNNReturnType ff_dnn_execute_model_ov(const DNNModel *model, const char *input_n task.out_frame = out_frame; task.ov_model = ov_model; -request.infer_request = ov_model->infer_request; -request.task_count = 1; -request.tasks = &ptask; +request = ff_safe_queue_pop_front(ov_model->request_queue); +if (!request) { +av_log(ctx, AV_LOG_ERROR, "unable to get infer request.\n"); +return DNN_ERROR; +} +request->tasks[request->task_count++] = &task; -return execute_model_ov(&request); +return execute_model_ov(request); } DNNReturnType ff_dnn_execute_model_async_ov(const DNNModel *model, const char *input_name, AVFrame *in_frame, @@ -821,8 +816,6 @@ void ff_dnn_free_model_ov(DNNModel **model) } ff_queue_destroy(ov_model->task_queue); -if (ov_model->infer_request) -ie_infer_request_free(&ov_model->infer_request); if (ov_model->exe_network) ie_exec_network_free(&ov_model->exe_network); if (ov_model->network) -- 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/6] lavfi/dnn_backend_openvino.c: add InferenceItem between TaskItem and RequestItem
There's one task item for one function call from dnn interface, there's one request item for one call to openvino. For classify, one task might need multiple inference for classification on every bounding box, so add InferenceItem. --- libavfilter/dnn/dnn_backend_openvino.c | 157 ++--- 1 file changed, 115 insertions(+), 42 deletions(-) diff --git a/libavfilter/dnn/dnn_backend_openvino.c b/libavfilter/dnn/dnn_backend_openvino.c index 874354ecef..3692a381e2 100644 --- a/libavfilter/dnn/dnn_backend_openvino.c +++ b/libavfilter/dnn/dnn_backend_openvino.c @@ -54,8 +54,10 @@ typedef struct OVModel{ ie_executable_network_t *exe_network; SafeQueue *request_queue; // holds RequestItem Queue *task_queue; // holds TaskItem +Queue *inference_queue; // holds InferenceItem } OVModel; +// one task for one function call from dnn interface typedef struct TaskItem { OVModel *ov_model; const char *input_name; @@ -64,13 +66,20 @@ typedef struct TaskItem { AVFrame *out_frame; int do_ioproc; int async; -int done; +uint32_t inference_todo; +uint32_t inference_done; } TaskItem; +// one task might have multiple inferences +typedef struct InferenceItem { +TaskItem *task; +} InferenceItem; + +// one request for one call to openvino typedef struct RequestItem { ie_infer_request_t *infer_request; -TaskItem **tasks; -int task_count; +InferenceItem **inferences; +uint32_t inference_count; ie_complete_call_back_t callback; } RequestItem; @@ -127,7 +136,12 @@ static DNNReturnType fill_model_input_ov(OVModel *ov_model, RequestItem *request IEStatusCode status; DNNData input; ie_blob_t *input_blob = NULL; -TaskItem *task = request->tasks[0]; +InferenceItem *inference; +TaskItem *task; + +inference = ff_queue_peek_front(ov_model->inference_queue); +av_assert0(inference); +task = inference->task; status = ie_infer_request_get_blob(request->infer_request, task->input_name, &input_blob); if (status != OK) { @@ -159,9 +173,14 @@ static DNNReturnType fill_model_input_ov(OVModel *ov_model, RequestItem *request // change to be an option when necessary. input.order = DCO_BGR; -av_assert0(request->task_count <= dims.dims[0]); -for (int i = 0; i < request->task_count; ++i) { -task = request->tasks[i]; +for (int i = 0; i < ctx->options.batch_size; ++i) { +inference = ff_queue_pop_front(ov_model->inference_queue); +if (!inference) { +break; +} +request->inferences[i] = inference; +request->inference_count = i + 1; +task = inference->task; if (task->do_ioproc) { if (ov_model->model->frame_pre_proc != NULL) { ov_model->model->frame_pre_proc(task->in_frame, &input, ov_model->model->filter_ctx); @@ -183,7 +202,8 @@ static void infer_completion_callback(void *args) precision_e precision; IEStatusCode status; RequestItem *request = args; -TaskItem *task = request->tasks[0]; +InferenceItem *inference = request->inferences[0]; +TaskItem *task = inference->task; SafeQueue *requestq = task->ov_model->request_queue; ie_blob_t *output_blob = NULL; ie_blob_buffer_t blob_buffer; @@ -229,10 +249,11 @@ static void infer_completion_callback(void *args) output.dt = precision_to_datatype(precision); output.data = blob_buffer.buffer; -av_assert0(request->task_count <= dims.dims[0]); -av_assert0(request->task_count >= 1); -for (int i = 0; i < request->task_count; ++i) { -task = request->tasks[i]; +av_assert0(request->inference_count <= dims.dims[0]); +av_assert0(request->inference_count >= 1); +for (int i = 0; i < request->inference_count; ++i) { +task = request->inferences[i]->task; +task->inference_done++; switch (task->ov_model->model->func_type) { case DFT_PROCESS_FRAME: @@ -259,13 +280,13 @@ static void infer_completion_callback(void *args) break; } -task->done = 1; +av_freep(&request->inferences[i]); output.data = (uint8_t *)output.data + output.width * output.height * output.channels * get_datatype_size(output.dt); } ie_blob_free(&output_blob); -request->task_count = 0; +request->inference_count = 0; if (ff_safe_queue_push_back(requestq, request) < 0) { av_log(ctx, AV_LOG_ERROR, "Failed to push back request_queue.\n"); return; @@ -370,11 +391,11 @@ static DNNReturnType init_model_ov(OVModel *ov_model, const char *input_name, co goto err; } -item->tasks = av_malloc_array(ctx->options.batch_size, sizeof(*item->tasks)); -if (!item->tasks) { +item->inferences = av_malloc_array(ctx->options.batch_size, sizeof(*item->inferences)); +if (!item->inferences) {
[FFmpeg-devel] [PATCH 3/6] lavfi/dnn_backend_openvino.c: move the logic for batch mode earlier
--- libavfilter/dnn/dnn_backend_openvino.c | 12 +--- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/libavfilter/dnn/dnn_backend_openvino.c b/libavfilter/dnn/dnn_backend_openvino.c index 3692a381e2..a695d863b5 100644 --- a/libavfilter/dnn/dnn_backend_openvino.c +++ b/libavfilter/dnn/dnn_backend_openvino.c @@ -432,13 +432,6 @@ static DNNReturnType execute_model_ov(RequestItem *request, Queue *inferenceq) ctx = &task->ov_model->ctx; if (task->async) { -if (ff_queue_size(inferenceq) < ctx->options.batch_size) { -if (ff_safe_queue_push_front(task->ov_model->request_queue, request) < 0) { -av_log(ctx, AV_LOG_ERROR, "Failed to push back request_queue.\n"); -return DNN_ERROR; -} -return DNN_SUCCESS; -} ret = fill_model_input_ov(task->ov_model, request); if (ret != DNN_SUCCESS) { return ret; @@ -793,6 +786,11 @@ DNNReturnType ff_dnn_execute_model_async_ov(const DNNModel *model, const char *i return DNN_ERROR; } +if (ff_queue_size(ov_model->inference_queue) < ctx->options.batch_size) { +// not enough inference items queued for a batch +return DNN_SUCCESS; +} + request = ff_safe_queue_pop_front(ov_model->request_queue); if (!request) { av_log(ctx, AV_LOG_ERROR, "unable to get infer request.\n"); -- 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 4/6] lavfi/dnn: refine dnn interface to add DNNExecBaseParams
Different function type of model requires different parameters, for example, object detection detects lots of objects (cat/dog/...) in the frame, and classifcation needs to know which object (cat or dog) it is going to classify. The current interface needs to add a new function with more parameters to support new requirement, with this change, we can just add a new struct (for example DNNExecClassifyParams) based on DNNExecBaseParams, and so we can continue to use the current interface execute_model just with params changed. --- libavfilter/dnn/Makefile | 1 + libavfilter/dnn/dnn_backend_common.c | 51 ++ libavfilter/dnn/dnn_backend_common.h | 31 libavfilter/dnn/dnn_backend_native.c | 15 +++- libavfilter/dnn/dnn_backend_native.h | 3 +- libavfilter/dnn/dnn_backend_openvino.c | 50 - libavfilter/dnn/dnn_backend_openvino.h | 6 +-- libavfilter/dnn/dnn_backend_tf.c | 18 +++-- libavfilter/dnn/dnn_backend_tf.h | 3 +- libavfilter/dnn_filter_common.c| 20 -- libavfilter/dnn_interface.h| 14 +-- 11 files changed, 139 insertions(+), 73 deletions(-) create mode 100644 libavfilter/dnn/dnn_backend_common.c create mode 100644 libavfilter/dnn/dnn_backend_common.h diff --git a/libavfilter/dnn/Makefile b/libavfilter/dnn/Makefile index d6d58f4b61..4cfbce0efc 100644 --- a/libavfilter/dnn/Makefile +++ b/libavfilter/dnn/Makefile @@ -2,6 +2,7 @@ OBJS-$(CONFIG_DNN) += dnn/dnn_interface.o OBJS-$(CONFIG_DNN) += dnn/dnn_io_proc.o OBJS-$(CONFIG_DNN) += dnn/queue.o OBJS-$(CONFIG_DNN) += dnn/safe_queue.o +OBJS-$(CONFIG_DNN) += dnn/dnn_backend_common.o OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native.o OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layers.o OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layer_avgpool.o diff --git a/libavfilter/dnn/dnn_backend_common.c b/libavfilter/dnn/dnn_backend_common.c new file mode 100644 index 00..a522ab5650 --- /dev/null +++ b/libavfilter/dnn/dnn_backend_common.c @@ -0,0 +1,51 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * DNN common functions different backends. + */ + +#include "dnn_backend_common.h" + +int ff_check_exec_params(void *ctx, DNNBackendType backend, DNNFunctionType func_type, DNNExecBaseParams *exec_params) +{ +if (!exec_params) { +av_log(ctx, AV_LOG_ERROR, "exec_params is null when execute model.\n"); +return AVERROR(EINVAL); +} + +if (!exec_params->in_frame) { +av_log(ctx, AV_LOG_ERROR, "in frame is NULL when execute model.\n"); +return AVERROR(EINVAL); +} + +if (!exec_params->out_frame) { +av_log(ctx, AV_LOG_ERROR, "out frame is NULL when execute model.\n"); +return AVERROR(EINVAL); +} + +if (exec_params->nb_output != 1 && backend != DNN_TF) { +// currently, the filter does not need multiple outputs, +// so we just pending the support until we really need it. +avpriv_report_missing_feature(ctx, "multiple outputs"); +return AVERROR(EINVAL); +} + +return 0; +} diff --git a/libavfilter/dnn/dnn_backend_common.h b/libavfilter/dnn/dnn_backend_common.h new file mode 100644 index 00..cd9c0f5339 --- /dev/null +++ b/libavfilter/dnn/dnn_backend_common.h @@ -0,0 +1,31 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Found
[FFmpeg-devel] [PATCH 5/6] lavfi/dnn: add classify support with openvino backend
Signed-off-by: Guo, Yejun --- libavfilter/dnn/dnn_backend_openvino.c | 143 + libavfilter/dnn/dnn_io_proc.c | 60 +++ libavfilter/dnn/dnn_io_proc.h | 1 + libavfilter/dnn_filter_common.c| 21 libavfilter/dnn_filter_common.h| 2 + libavfilter/dnn_interface.h| 10 +- 6 files changed, 218 insertions(+), 19 deletions(-) diff --git a/libavfilter/dnn/dnn_backend_openvino.c b/libavfilter/dnn/dnn_backend_openvino.c index fcdd738f8a..4bdd6a3a6d 100644 --- a/libavfilter/dnn/dnn_backend_openvino.c +++ b/libavfilter/dnn/dnn_backend_openvino.c @@ -29,6 +29,7 @@ #include "libavutil/avassert.h" #include "libavutil/opt.h" #include "libavutil/avstring.h" +#include "libavutil/detection_bbox.h" #include "../internal.h" #include "queue.h" #include "safe_queue.h" @@ -74,6 +75,7 @@ typedef struct TaskItem { // one task might have multiple inferences typedef struct InferenceItem { TaskItem *task; +uint32_t bbox_index; } InferenceItem; // one request for one call to openvino @@ -182,12 +184,23 @@ static DNNReturnType fill_model_input_ov(OVModel *ov_model, RequestItem *request request->inferences[i] = inference; request->inference_count = i + 1; task = inference->task; -if (task->do_ioproc) { -if (ov_model->model->frame_pre_proc != NULL) { -ov_model->model->frame_pre_proc(task->in_frame, &input, ov_model->model->filter_ctx); -} else { -ff_proc_from_frame_to_dnn(task->in_frame, &input, ov_model->model->func_type, ctx); +switch (task->ov_model->model->func_type) { +case DFT_PROCESS_FRAME: +case DFT_ANALYTICS_DETECT: +if (task->do_ioproc) { +if (ov_model->model->frame_pre_proc != NULL) { +ov_model->model->frame_pre_proc(task->in_frame, &input, ov_model->model->filter_ctx); +} else { +ff_proc_from_frame_to_dnn(task->in_frame, &input, ov_model->model->func_type, ctx); +} } +break; +case DFT_ANALYTICS_CLASSIFY: +ff_frame_to_dnn_classify(task->in_frame, &input, inference->bbox_index, ctx); +break; +default: +av_assert0(!"should not reach here"); +break; } input.data = (uint8_t *)input.data + input.width * input.height * input.channels * get_datatype_size(input.dt); @@ -276,6 +289,13 @@ static void infer_completion_callback(void *args) } task->ov_model->model->detect_post_proc(task->out_frame, &output, 1, task->ov_model->model->filter_ctx); break; +case DFT_ANALYTICS_CLASSIFY: +if (!task->ov_model->model->classify_post_proc) { +av_log(ctx, AV_LOG_ERROR, "classify filter needs to provide post proc\n"); +return; +} +task->ov_model->model->classify_post_proc(task->out_frame, &output, request->inferences[i]->bbox_index, task->ov_model->model->filter_ctx); +break; default: av_assert0(!"should not reach here"); break; @@ -513,7 +533,44 @@ static DNNReturnType get_input_ov(void *model, DNNData *input, const char *input return DNN_ERROR; } -static DNNReturnType extract_inference_from_task(DNNFunctionType func_type, TaskItem *task, Queue *inference_queue) +static int contain_valid_detection_bbox(AVFrame *frame) +{ +AVFrameSideData *sd; +const AVDetectionBBoxHeader *header; +const AVDetectionBBox *bbox; + +sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DETECTION_BBOXES); +if (!sd) { // this frame has nothing detected +return 0; +} + +if (!sd->size) { +return 0; +} + +header = (const AVDetectionBBoxHeader *)sd->data; +if (!header->nb_bboxes) { +return 0; +} + +for (uint32_t i = 0; i < header->nb_bboxes; i++) { +bbox = av_get_detection_bbox(header, i); +if (bbox->x < 0 || bbox->w < 0 || bbox->x + bbox->w >= frame->width) { +return 0; +} +if (bbox->y < 0 || bbox->h < 0 || bbox->y + bbox->h >= frame->width) { +return 0; +} + +if (bbox->classify_count == AV_NUM_DETECTION_BBOX_CLASSIFY) { +return 0; +} +} + +return 1; +} + +static DNNReturnType extract_inference_from_task(DNNFunctionType func_type, TaskItem *task, Queue *inference_queue, DNNExecBaseParams *exec_params) { switch (func_type) { case DFT_PROCESS_FRAME: @@ -532,6 +589,45 @@ static DNNReturnType extract_inference_from_task(DNNFunctionType func_type, Task } return DNN_SUCCESS; } +case DFT_ANALYTICS_CLASSIFY: +{ +const AVDetectionBBoxHeader *header; +AVFrame *frame = task->in_frame; +AVFrameSideData *sd; +DNNExecClassific
[FFmpeg-devel] [PATCH 6/6] lavfi/dnn_classify: add filter dnn_classify for classification based on detection bounding boxes
classification is done on every detection bounding box in frame's side data, which are the results of object detection (filter dnn_detect). Please refer to commit log of dnn_detect for the material for detection, and see below for classification. - download material for classifcation: wget https://github.com/guoyejun/ffmpeg_dnn/raw/main/models/openvino/2021.1/emotions-recognition-retail-0003.bin wget https://github.com/guoyejun/ffmpeg_dnn/raw/main/models/openvino/2021.1/emotions-recognition-retail-0003.xml wget https://github.com/guoyejun/ffmpeg_dnn/raw/main/models/openvino/2021.1/emotions-recognition-retail-0003.label - run command as: ./ffmpeg -i cici.jpg -vf dnn_detect=dnn_backend=openvino:model=face-detection-adas-0001.xml:input=data:output=detection_out:confidence=0.6:labels=face-detection-adas-0001.label,dnn_classify=dnn_backend=openvino:model=emotions-recognition-retail-0003.xml:input=data:output=prob_emotion:confidence=0.3:labels=emotions-recognition-retail-0003.label:target=face,showinfo -f null - We'll see the detect&classify result as below: [Parsed_showinfo_2 @ 0x55b7d25e77c0] side data - detection bounding boxes: [Parsed_showinfo_2 @ 0x55b7d25e77c0] source: face-detection-adas-0001.xml, emotions-recognition-retail-0003.xml [Parsed_showinfo_2 @ 0x55b7d25e77c0] index: 0, region: (1005, 813) -> (1086, 905), label: face, confidence: 1/1. [Parsed_showinfo_2 @ 0x55b7d25e77c0]classify: label: happy, confidence: 6757/1. [Parsed_showinfo_2 @ 0x55b7d25e77c0] index: 1, region: (888, 839) -> (967, 926), label: face, confidence: 6917/1. [Parsed_showinfo_2 @ 0x55b7d25e77c0]classify: label: anger, confidence: 4320/1. Signed-off-by: Guo, Yejun --- configure | 1 + doc/filters.texi | 36 libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/vf_dnn_classify.c | 330 ++ 5 files changed, 369 insertions(+) create mode 100644 libavfilter/vf_dnn_classify.c diff --git a/configure b/configure index cc1013fb1d..d1fc0d05a7 100755 --- a/configure +++ b/configure @@ -3555,6 +3555,7 @@ derain_filter_select="dnn" deshake_filter_select="pixelutils" deshake_opencl_filter_deps="opencl" dilation_opencl_filter_deps="opencl" +dnn_classify_filter_select="dnn" dnn_detect_filter_select="dnn" dnn_processing_filter_select="dnn" drawtext_filter_deps="libfreetype" diff --git a/doc/filters.texi b/doc/filters.texi index 68f17dd563..9975db7326 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -10127,6 +10127,42 @@ ffmpeg -i INPUT -f lavfi -i nullsrc=hd720,geq='r=128+80*(sin(sqrt((X-W/2)*(X-W/2 @end example @end itemize +@section dnn_classify + +Do classification with deep neural networks based on bounding boxes. + +The filter accepts the following options: + +@table @option +@item dnn_backend +Specify which DNN backend to use for model loading and execution. This option accepts +only openvino now, tensorflow backends will be added. + +@item model +Set path to model file specifying network architecture and its parameters. +Note that different backends use different file formats. + +@item input +Set the input name of the dnn network. + +@item output +Set the output name of the dnn network. + +@item confidence +Set the confidence threshold (default: 0.5). + +@item labels +Set path to label file specifying the mapping between label id and name. +Each label name is written in one line, tailing spaces and empty lines are skipped. +The first line is the name of label id 0, +and the second line is the name of label id 1, etc. +The label id is considered as name if the label file is not provided. + +@item backend_configs +Set the configs to be passed into backend + +@end table + @section dnn_detect Do object detection with deep neural networks. diff --git a/libavfilter/Makefile b/libavfilter/Makefile index b77f2276a4..dd4decdd71 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -245,6 +245,7 @@ OBJS-$(CONFIG_DILATION_FILTER) += vf_neighbor.o OBJS-$(CONFIG_DILATION_OPENCL_FILTER)+= vf_neighbor_opencl.o opencl.o \ opencl/neighbor.o OBJS-$(CONFIG_DISPLACE_FILTER) += vf_displace.o framesync.o +OBJS-$(CONFIG_DNN_CLASSIFY_FILTER) += vf_dnn_classify.o OBJS-$(CONFIG_DNN_DETECT_FILTER) += vf_dnn_detect.o OBJS-$(CONFIG_DNN_PROCESSING_FILTER) += vf_dnn_processing.o OBJS-$(CONFIG_DOUBLEWEAVE_FILTER)+= vf_weave.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 0d2bf7bbee..9b24a2da29 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -230,6 +230,7 @@ extern AVFilter ff_vf_detelecine; extern AVFilter ff_vf_dilation; extern AVFilter ff_vf_dilation_opencl; extern AVFilter ff_vf_displace; +extern AVFilter ff_vf_dnn_classify; extern AVFilter ff_vf_dnn_detect; extern AVFilter ff
Re: [FFmpeg-devel] [PATCH] doc/muxers.texi: fix build issue for unknown command
On 2021-04-18 15:25, Guo, Yejun wrote: -Original Message- From: ffmpeg-devel On Behalf Of Gyan Doshi Sent: 2021年4月18日 13:04 To: ffmpeg-devel@ffmpeg.org Subject: Re: [FFmpeg-devel] [PATCH] doc/muxers.texi: fix build issue for unknown command Ok. Will apply. On 2021-04-18 10:11, Guo, Yejun wrote: The build log: ** Unknown command `@code' (left as is) (in src/doc/muxers.texi l. 2020) *** '{' without macro. Before: -map} option with the ffmpeg CLI tool. (in src/doc/muxers.texi l. 2020) *** '}' without opening '{' before: option with the ffmpeg CLI tool. (in src/doc/muxers.texi l. 2020) I get no warnings here. The generated docs have been live for a week now. What's the full log? Perl version? My system is ubuntu 18.04, more detail see below. $ perl -v This is perl 5, version 26, subversion 1 (v5.26.1) built for x86_64-linux-gnu-thread-multi $ ../ffmpeg/configure $ make -j8 $ touch src/doc/muxers.texi $ V=1 make perl src/doc/texidep.pl src src/doc/ffmpeg.texi doc/ffmpeg.html >doc/ffmpeg.html.d texi2html -I doc -monolithic --D=config-not-all --init-file src/doc/t2h.init --output doc/ffmpeg.html src/doc/ffmpeg.texi perl src/doc/texidep.pl src src/doc/ffplay.texi doc/ffplay.html >doc/ffplay.html.d texi2html -I doc -monolithic --D=config-not-all --init-file src/doc/t2h.init --output doc/ffplay.html src/doc/ffplay.texi perl src/doc/texidep.pl src src/doc/ffprobe.texi doc/ffprobe.html >doc/ffprobe.html.d texi2html -I doc -monolithic --D=config-not-all --init-file src/doc/t2h.init --output doc/ffprobe.html src/doc/ffprobe.texi perl src/doc/texidep.pl src src/doc/ffmpeg.texi doc/ffmpeg-all.html >doc/ffmpeg-all.html.d texi2html -I doc -monolithic --D=config-all --init-file src/doc/t2h.init --output doc/ffmpeg-all.html src/doc/ffmpeg.texi ** Unknown command `@code' (left as is) (in src/doc/muxers.texi l. 2020) *** '{' without macro. Before: -map} option with the ffmpeg CLI tool. (in src/doc/muxers.texi l. 2020) *** '}' without opening '{' before: option with the ffmpeg CLI tool. (in src/doc/muxers.texi l. 2020) perl src/doc/texidep.pl src src/doc/ffplay.texi doc/ffplay-all.html >doc/ffplay-all.html.d texi2html -I doc -monolithic --D=config-all --init-file src/doc/t2h.init --output doc/ffplay-all.html src/doc/ffplay.texi perl src/doc/texidep.pl src src/doc/ffprobe.texi doc/ffprobe-all.html >doc/ffprobe-all.html.d texi2html -I doc -monolithic --D=config-all --init-file src/doc/t2h.init --output doc/ffprobe-all.html src/doc/ffprobe.texi perl src/doc/texidep.pl src src/doc/ffmpeg-formats.texi doc/ffmpeg-formats.html >doc/ffmpeg-formats.html.d texi2html -I doc -monolithic --D=config-not-all --init-file src/doc/t2h.init --output doc/ffmpeg-formats.html src/doc/ffmpeg-formats.texi ** Unknown command `@code' (left as is) (in src/doc/muxers.texi l. 2020) *** '{' without macro. Before: -map} option with the ffmpeg CLI tool. (in src/doc/muxers.texi l. 2020) *** '}' without opening '{' before: option with the ffmpeg CLI tool. (in src/doc/muxers.texi l. 2020) perl src/doc/texidep.pl src src/doc/ffmpeg.texi doc/ffmpeg.pod >doc/ffmpeg.pod.d perl src/doc/texi2pod.pl -Dconfig-not-all=yes -Idoc src/doc/ffmpeg.texi doc/ffmpeg.pod perl src/doc/texidep.pl src src/doc/ffplay.texi doc/ffplay.pod >doc/ffplay.pod.d perl src/doc/texi2pod.pl -Dconfig-not-all=yes -Idoc src/doc/ffplay.texi doc/ffplay.pod perl src/doc/texidep.pl src src/doc/ffprobe.texi doc/ffprobe.pod >doc/ffprobe.pod.d perl src/doc/texi2pod.pl -Dconfig-not-all=yes -Idoc src/doc/ffprobe.texi doc/ffprobe.pod perl src/doc/texidep.pl src src/doc/ffmpeg.texi doc/ffmpeg-all.pod >doc/ffmpeg-all.pod.d perl src/doc/texi2pod.pl -Dconfig-all=yes -Idoc src/doc/ffmpeg.texi doc/ffmpeg-all.pod perl src/doc/texidep.pl src src/doc/ffplay.texi doc/ffplay-all.pod >doc/ffplay-all.pod.d perl src/doc/texi2pod.pl -Dconfig-all=yes -Idoc src/doc/ffplay.texi doc/ffplay-all.pod perl src/doc/texidep.pl src src/doc/ffprobe.texi doc/ffprobe-all.pod >doc/ffprobe-all.pod.d perl src/doc/texi2pod.pl -Dconfig-all=yes -Idoc src/doc/ffprobe.texi doc/ffprobe-all.pod perl src/doc/texidep.pl src src/doc/ffmpeg-formats.texi doc/ffmpeg-formats.pod >doc/ffmpeg-formats.pod.d perl src/doc/texi2pod.pl -Dconfig-not-all=yes -Idoc src/doc/ffmpeg-formats.texi doc/ffmpeg-formats.pod pod2man --section=1 --center=" " --release=" " --date=" " doc/ffmpeg.pod > doc/ffmpeg.1 pod2man --section=1 --center=" " --release=" " --date=" " doc/ffplay.pod > doc/ffplay.1 pod2man --section=1 --center=" " --release=" " --date=" " doc/ffprobe.pod > doc/ffprobe.1 pod2man --section=1 --center=" " --release=" " --date=" " doc/ffmpeg-all.pod > doc/ffmpeg-all.1 pod2man --section=1 --center=" " --release=" " --date=" " doc/ffplay-all.pod > doc/ffplay-all.1 pod2man --section=1 --center=" " --release=" " --date=" " doc/ffprobe-all.pod > doc/ffprobe-all.1 pod2man --section=1 --center=" " --release=" " --date=" " doc/ffmpeg-formats.pod > doc/ffmpeg-formats.1 ___
Re: [FFmpeg-devel] [PATCH] doc/muxers.texi: fix build issue for unknown command
On 2021-04-18 17:01, Gyan Doshi wrote: On 2021-04-18 15:25, Guo, Yejun wrote: -Original Message- From: ffmpeg-devel On Behalf Of Gyan Doshi Sent: 2021年4月18日 13:04 To: ffmpeg-devel@ffmpeg.org Subject: Re: [FFmpeg-devel] [PATCH] doc/muxers.texi: fix build issue for unknown command Ok. Will apply. I don't see this patch on Patchwork --> https://patchwork.ffmpeg.org/project/ffmpeg/list/?submitter=600 On 2021-04-18 10:11, Guo, Yejun wrote: The build log: ** Unknown command `@code' (left as is) (in src/doc/muxers.texi l. 2020) *** '{' without macro. Before: -map} option with the ffmpeg CLI tool. (in src/doc/muxers.texi l. 2020) *** '}' without opening '{' before: option with the ffmpeg CLI tool. (in src/doc/muxers.texi l. 2020) I get no warnings here. The generated docs have been live for a week now. What's the full log? Perl version? My system is ubuntu 18.04, more detail see below. $ perl -v This is perl 5, version 26, subversion 1 (v5.26.1) built for x86_64-linux-gnu-thread-multi $ ../ffmpeg/configure $ make -j8 $ touch src/doc/muxers.texi $ V=1 make perl src/doc/texidep.pl src src/doc/ffmpeg.texi doc/ffmpeg.html >doc/ffmpeg.html.d texi2html -I doc -monolithic --D=config-not-all --init-file src/doc/t2h.init --output doc/ffmpeg.html src/doc/ffmpeg.texi perl src/doc/texidep.pl src src/doc/ffplay.texi doc/ffplay.html >doc/ffplay.html.d texi2html -I doc -monolithic --D=config-not-all --init-file src/doc/t2h.init --output doc/ffplay.html src/doc/ffplay.texi perl src/doc/texidep.pl src src/doc/ffprobe.texi doc/ffprobe.html >doc/ffprobe.html.d texi2html -I doc -monolithic --D=config-not-all --init-file src/doc/t2h.init --output doc/ffprobe.html src/doc/ffprobe.texi perl src/doc/texidep.pl src src/doc/ffmpeg.texi doc/ffmpeg-all.html >doc/ffmpeg-all.html.d texi2html -I doc -monolithic --D=config-all --init-file src/doc/t2h.init --output doc/ffmpeg-all.html src/doc/ffmpeg.texi ** Unknown command `@code' (left as is) (in src/doc/muxers.texi l. 2020) *** '{' without macro. Before: -map} option with the ffmpeg CLI tool. (in src/doc/muxers.texi l. 2020) *** '}' without opening '{' before: option with the ffmpeg CLI tool. (in src/doc/muxers.texi l. 2020) perl src/doc/texidep.pl src src/doc/ffplay.texi doc/ffplay-all.html >doc/ffplay-all.html.d texi2html -I doc -monolithic --D=config-all --init-file src/doc/t2h.init --output doc/ffplay-all.html src/doc/ffplay.texi perl src/doc/texidep.pl src src/doc/ffprobe.texi doc/ffprobe-all.html >doc/ffprobe-all.html.d texi2html -I doc -monolithic --D=config-all --init-file src/doc/t2h.init --output doc/ffprobe-all.html src/doc/ffprobe.texi perl src/doc/texidep.pl src src/doc/ffmpeg-formats.texi doc/ffmpeg-formats.html >doc/ffmpeg-formats.html.d texi2html -I doc -monolithic --D=config-not-all --init-file src/doc/t2h.init --output doc/ffmpeg-formats.html src/doc/ffmpeg-formats.texi ** Unknown command `@code' (left as is) (in src/doc/muxers.texi l. 2020) *** '{' without macro. Before: -map} option with the ffmpeg CLI tool. (in src/doc/muxers.texi l. 2020) *** '}' without opening '{' before: option with the ffmpeg CLI tool. (in src/doc/muxers.texi l. 2020) perl src/doc/texidep.pl src src/doc/ffmpeg.texi doc/ffmpeg.pod >doc/ffmpeg.pod.d perl src/doc/texi2pod.pl -Dconfig-not-all=yes -Idoc src/doc/ffmpeg.texi doc/ffmpeg.pod perl src/doc/texidep.pl src src/doc/ffplay.texi doc/ffplay.pod >doc/ffplay.pod.d perl src/doc/texi2pod.pl -Dconfig-not-all=yes -Idoc src/doc/ffplay.texi doc/ffplay.pod perl src/doc/texidep.pl src src/doc/ffprobe.texi doc/ffprobe.pod >doc/ffprobe.pod.d perl src/doc/texi2pod.pl -Dconfig-not-all=yes -Idoc src/doc/ffprobe.texi doc/ffprobe.pod perl src/doc/texidep.pl src src/doc/ffmpeg.texi doc/ffmpeg-all.pod >doc/ffmpeg-all.pod.d perl src/doc/texi2pod.pl -Dconfig-all=yes -Idoc src/doc/ffmpeg.texi doc/ffmpeg-all.pod perl src/doc/texidep.pl src src/doc/ffplay.texi doc/ffplay-all.pod >doc/ffplay-all.pod.d perl src/doc/texi2pod.pl -Dconfig-all=yes -Idoc src/doc/ffplay.texi doc/ffplay-all.pod perl src/doc/texidep.pl src src/doc/ffprobe.texi doc/ffprobe-all.pod >doc/ffprobe-all.pod.d perl src/doc/texi2pod.pl -Dconfig-all=yes -Idoc src/doc/ffprobe.texi doc/ffprobe-all.pod perl src/doc/texidep.pl src src/doc/ffmpeg-formats.texi doc/ffmpeg-formats.pod >doc/ffmpeg-formats.pod.d perl src/doc/texi2pod.pl -Dconfig-not-all=yes -Idoc src/doc/ffmpeg-formats.texi doc/ffmpeg-formats.pod pod2man --section=1 --center=" " --release=" " --date=" " doc/ffmpeg.pod > doc/ffmpeg.1 pod2man --section=1 --center=" " --release=" " --date=" " doc/ffplay.pod > doc/ffplay.1 pod2man --section=1 --center=" " --release=" " --date=" " doc/ffprobe.pod > doc/ffprobe.1 pod2man --section=1 --center=" " --release=" " --date=" " doc/ffmpeg-all.pod > doc/ffmpeg-all.1 pod2man --section=1 --center=" " --release=" " --date=" " doc/ffplay-all.pod > doc/ffplay-all.1 pod2man --section=1 --center=" " --release=" " --date=" " doc/ffprobe-all
Re: [FFmpeg-devel] [PATCH 3/4] avformat/rmdec: Use 64bit for intermediate for DEINT_ID_INT4
On Fri, Apr 16, 2021 at 08:37:51PM -0300, James Almer wrote: > On 4/16/2021 7:45 PM, James Almer wrote: > > On 4/16/2021 7:24 PM, Andreas Rheinhardt wrote: > > > James Almer: > > > > On 4/16/2021 4:04 PM, Michael Niedermayer wrote: > > > > > On Thu, Apr 15, 2021 at 06:22:10PM -0300, James Almer wrote: > > > > > > On 4/15/2021 5:44 PM, Michael Niedermayer wrote: > > > > > > > Fixes: runtime error: signed integer overflow: 65312 * 65535 > > > > > > > cannot > > > > > > > be represented in type 'int' > > > > > > > Fixes: > > > > > > > 32832/clusterfuzz-testcase-minimized-ffmpeg_dem_RM_fuzzer-4817710040088576 > > > > > > > > > > > > > > > > > > > > > > > > > > > > Found-by: continuous fuzzing process > > > > > > > https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg > > > > > > > Signed-off-by: Michael Niedermayer > > > > > > > --- > > > > > > > libavformat/rmdec.c | 4 ++-- > > > > > > > 1 file changed, 2 insertions(+), 2 deletions(-) > > > > > > > > > > > > > > diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c > > > > > > > index fc3bff4859..af032ed90a 100644 > > > > > > > --- a/libavformat/rmdec.c > > > > > > > +++ b/libavformat/rmdec.c > > > > > > > @@ -269,9 +269,9 @@ static int > > > > > > > rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, > > > > > > > case DEINT_ID_INT4: > > > > > > > if (ast->coded_framesize > ast->audio_framesize || > > > > > > > sub_packet_h <= 1 || > > > > > > > - ast->coded_framesize * sub_packet_h > (2 + > > > > > > > (sub_packet_h & 1)) * ast->audio_framesize) > > > > > > > + ast->coded_framesize * (uint64_t)sub_packet_h > > > > > > > > (2 > > > > > > > + (sub_packet_h & 1)) * ast->audio_framesize) > > > > > > > > > > > > This check seems superfluous with the one below right after it. > > > > > > ast->coded_framesize * sub_packet_h must be equal to 2 * > > > > > > ast->audio_framesize. It can be removed. > > > > > > > > > > > > > return AVERROR_INVALIDDATA; > > > > > > > - if (ast->coded_framesize * sub_packet_h != > > > > > > > 2*ast->audio_framesize) { > > > > > > > + if (ast->coded_framesize * (uint64_t)sub_packet_h != > > > > > > > 2*ast->audio_framesize) { > > > > > > > avpriv_request_sample(s, "mismatching > > > > > > > interleaver > > > > > > > parameters"); > > > > > > > return AVERROR_INVALIDDATA; > > > > > > > } > > > > > > > > > > > > How about something like > > > > > > > > > > > > > diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c > > > > > > > index fc3bff4859..09880ee3fe 100644 > > > > > > > --- a/libavformat/rmdec.c > > > > > > > +++ b/libavformat/rmdec.c > > > > > > > @@ -269,7 +269,7 @@ static int > > > > > > > rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, > > > > > > > case DEINT_ID_INT4: > > > > > > > if (ast->coded_framesize > ast->audio_framesize || > > > > > > > sub_packet_h <= 1 || > > > > > > > - ast->coded_framesize * sub_packet_h > (2 + > > > > > > > (sub_packet_h & 1)) * ast->audio_framesize) > > > > > > > + ast->audio_framesize > INT_MAX / sub_packet_h) > > > > > > > return AVERROR_INVALIDDATA; > > > > > > > if (ast->coded_framesize * sub_packet_h != > > > > > > > 2*ast->audio_framesize) { > > > > > > > avpriv_request_sample(s, "mismatching > > > > > > > interleaver > > > > > > > parameters"); > > > > > > > > > > > > Instead? > > > > > > > > > > The 2 if() execute different things, the 2nd requests a > > > > > sample, the first > > > > > not. I think this suggestion would change when we request a sample > > > > > > > > Why are we returning INVALIDDATA after requesting a sample, for that > > > > matter? If it's considered an invalid scenario, do we really > > > > need a sample? > > > > > > > > In any case, if you don't want more files where "ast->coded_framesize * > > > > sub_packet_h != 2*ast->audio_framesize" would print a sample request, > > > > then maybe something like the following could be used instead? > > > > > > > > > diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c > > > > > index fc3bff4859..10c1699a81 100644 > > > > > --- a/libavformat/rmdec.c > > > > > +++ b/libavformat/rmdec.c > > > > > @@ -269,6 +269,7 @@ static int > > > > > rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, > > > > > case DEINT_ID_INT4: > > > > > if (ast->coded_framesize > ast->audio_framesize || > > > > > sub_packet_h <= 1 || > > > > > + ast->audio_framesize > INT_MAX / sub_packet_h || > > > > > ast->coded_framesize * sub_packet_h > (2 + > > > > > (sub_packet_h & 1)) * ast->audio_framesize) > > > > > return AVERROR_INVALIDDATA; > > > > > if (ast->coded_framesize * sub_p
Re: [FFmpeg-devel] [PATCH] avformat/mpegtsenc: private_stream_1 is not asynchronous KLV
On Sat, 17 Apr 2021, Mao Hata wrote: According to ISO/IEC 13818-1, private_stream_1 is a synchronous (has PTS/DTS) stream. Asynchronous one is private_stream_2. Which section describes this? Also keep in mind that code was added so that AV_CODEC_ID_SMPTE_KLV is handled in mpegts, and SMPTE RP 217 promotes the usage of private_stream_1, so I don't think this can be simply changed. Regards, Marton ___ 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 v1 1/3] libavformat/rtsp.h : Add member ignore_rtcp to RTSPState
On Sun, Apr 18, 2021 at 00:55:26 +0800, su...@epoint.com.cn wrote: > From: Minlei Sun > > Signed-off-by: Minlei Sun These three patches can certainly be squashed - they are of no use individually. And you need to amend the documentation (doc/protocols.texi). Also, I'm not sure whether ignore_rtcp should be one of rtsp_flags. (I haven't figured out when boolean options are made flags and when not.) Cheers, Moritz ___ 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] [ffmpeg-web][PATCH] Drop my entry from the consulting list
Hi, I've not been really active in the last period and this patch clarifies this condition. Best regards, Stefano >From 38bc43827b9a6b2d967514323a718abee7e7211d Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Sun, 18 Apr 2021 22:23:20 +0200 Subject: [PATCH] consulting: remove my entry from the list of consultants --- src/consulting | 12 1 file changed, 12 deletions(-) diff --git a/src/consulting b/src/consulting index 8a06e24..20d847a 100644 --- a/src/consulting +++ b/src/consulting @@ -106,18 +106,6 @@ E.g.: - - - Stefano Sabatini - -Stefano is located in Italy and is available for contracting -work. He has worked on FFmpeg since 2007 and has been a maintainer since -2008. He has special expertise in libavfilter, ff* tools usage and -usability issues. You can contact him by email at -stefa...@gmail.com. - - - -- 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".
Re: [FFmpeg-devel] [PATCH] avutil/cpu: Use HW_NCPUONLINE to detect # of online CPUs with OpenBSD
On Fri, 16 Apr 2021, Brad Smith wrote: ping. Will apply, thanks. Marton On 4/3/2021 2:49 PM, Brad Smith wrote: avutil/cpu: Use HW_NCPUONLINE to detect # of online CPUs with OpenBSD Signed-off-by: Brad Smith --- libavutil/cpu.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/libavutil/cpu.c b/libavutil/cpu.c index 8e3576a1f3..9d249737df 100644 --- a/libavutil/cpu.c +++ b/libavutil/cpu.c @@ -291,6 +291,12 @@ int av_cpu_count(void) DWORD_PTR proc_aff, sys_aff; if (GetProcessAffinityMask(GetCurrentProcess(), &proc_aff, &sys_aff)) nb_cpus = av_popcount64(proc_aff); +#elif HAVE_SYSCTL && defined(HW_NCPUONLINE) +int mib[2] = { CTL_HW, HW_NCPUONLINE }; +size_t len = sizeof(nb_cpus); + +if (sysctl(mib, 2, &nb_cpus, &len, NULL, 0) == -1) +nb_cpus = 0; #elif HAVE_SYSCTL && defined(HW_NCPU) int mib[2] = { CTL_HW, HW_NCPU }; size_t len = sizeof(nb_cpus); ___ 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/2] lavf/avio: add avio_vprintf()
This new function makes it possible to use avio_printf() functionality from a function taking a variable list of arguments. --- doc/APIchanges| 3 +++ libavformat/avio.h| 6 ++ libavformat/aviobuf.c | 17 + libavformat/version.h | 2 +- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index b41dadee8d..08fec7c234 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,9 @@ libavutil: 2017-10-21 API changes, most recent first: +2021-04-18 - xx - lavf 58.78.100 - avio.h + Add avio_vprintf(), similar to avio_printf(). + 2021-03-21 - xx - lavu 56.72.100 - frame.h Deprecated av_get_colorspace_name(). Use av_color_space_name() instead. diff --git a/libavformat/avio.h b/libavformat/avio.h index d022820a6e..24f6839522 100644 --- a/libavformat/avio.h +++ b/libavformat/avio.h @@ -571,6 +571,12 @@ int64_t avio_size(AVIOContext *s); */ int avio_feof(AVIOContext *s); +/** + * Writes a formatted string to the context taking a va_list. + * @return number of bytes written, < 0 on error. + */ +int avio_vprintf(AVIOContext *s, const char *fmt, va_list ap); + /** * Writes a formatted string to the context. * @return number of bytes written, < 0 on error. diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index 518cb11129..289da796c8 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -1196,15 +1196,12 @@ int avio_closep(AVIOContext **s) return ret; } -int avio_printf(AVIOContext *s, const char *fmt, ...) +int avio_vprintf(AVIOContext *s, const char *fmt, va_list ap) { -va_list ap; AVBPrint bp; av_bprint_init(&bp, 0, INT_MAX); -va_start(ap, fmt); av_vbprintf(&bp, fmt, ap); -va_end(ap); if (!av_bprint_is_complete(&bp)) { av_bprint_finalize(&bp, NULL); s->error = AVERROR(ENOMEM); @@ -1215,6 +1212,18 @@ int avio_printf(AVIOContext *s, const char *fmt, ...) return bp.len; } +int avio_printf(AVIOContext *s, const char *fmt, ...) +{ +va_list ap; +int ret; + +va_start(ap, fmt); +ret = avio_vprintf(s, fmt, ap); +va_end(ap); + +return ret; +} + void avio_print_string_array(AVIOContext *s, const char *strings[]) { for(; *strings; strings++) diff --git a/libavformat/version.h b/libavformat/version.h index ced5600034..b6023f9d2e 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ // Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium) // Also please add any ticket numbers that you believe might be affected here #define LIBAVFORMAT_VERSION_MAJOR 58 -#define LIBAVFORMAT_VERSION_MINOR 77 +#define LIBAVFORMAT_VERSION_MINOR 78 #define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ -- 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 2/2] ffprobe: add -o option
This enables printing to a resource specified with -o OUTPUT. Address issue: http://trac.ffmpeg.org/ticket/8024 --- doc/ffprobe.texi | 7 ++ fftools/ffprobe.c | 174 ++ 2 files changed, 120 insertions(+), 61 deletions(-) diff --git a/doc/ffprobe.texi b/doc/ffprobe.texi index d7fab4ff40..f57b46a8fd 100644 --- a/doc/ffprobe.texi +++ b/doc/ffprobe.texi @@ -28,6 +28,9 @@ If a url is specified in input, ffprobe will try to open and probe the url content. If the url cannot be opened or recognized as a multimedia file, a positive exit code is returned. +If no output is specified as output with @option{o} ffprobe will write +to stdout. + ffprobe may be employed both as a standalone application or in combination with a textual filter, which may perform more sophisticated processing, e.g. statistical processing or plotting. @@ -342,6 +345,10 @@ on the specific build. @item -i @var{input_url} Read @var{input_url}. +@item -o @var{output_url} +Write output to @var{output_url}. If not specified, the output is sent +to stdout. + @end table @c man end diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c index 38462e1ff3..cdec261f29 100644 --- a/fftools/ffprobe.c +++ b/fftools/ffprobe.c @@ -258,6 +258,7 @@ static const OptionDef *options; static const char *input_filename; static const char *print_input_filename; static AVInputFormat *iformat = NULL; +static const char *output_filename = NULL; static struct AVHashContext *hash; @@ -453,6 +454,7 @@ typedef struct Writer { struct WriterContext { const AVClass *class; ///< class of the writer const Writer *writer; ///< the Writer of which this is an instance +AVIOContext *avio; /// the I/O context used to write char *name; ///< name of this writer instance void *priv; ///< private data for use by the filter @@ -530,6 +532,10 @@ static void writer_close(WriterContext **wctx) av_opt_free((*wctx)->priv); av_freep(&((*wctx)->priv)); av_opt_free(*wctx); +if ((*wctx)->avio) { +avio_flush((*wctx)->avio); +avio_close((*wctx)->avio); +} av_freep(wctx); } @@ -543,7 +549,7 @@ static void bprint_bytes(AVBPrint *bp, const uint8_t *ubuf, size_t ubuf_size) static int writer_open(WriterContext **wctx, const Writer *writer, const char *args, - const struct section *sections, int nb_sections) + const struct section *sections, int nb_sections, const char *url) { int i, ret = 0; @@ -614,6 +620,9 @@ static int writer_open(WriterContext **wctx, const Writer *writer, const char *a } } +if ((ret = avio_open(&(*wctx)->avio, url, AVIO_FLAG_WRITE)) < 0) +goto fail; + for (i = 0; i < SECTION_MAX_NB_LEVELS; i++) av_bprint_init(&(*wctx)->section_pbuf[i], 1, AV_BPRINT_SIZE_UNLIMITED); @@ -879,6 +888,25 @@ static void writer_print_integers(WriterContext *wctx, const char *name, av_bprint_finalize(&bp, NULL); } +static inline void writer_w8(WriterContext *wctx, int b) +{ +avio_w8(wctx->avio, b); +} + +static inline void writer_put_str(WriterContext *wctx, const char *str) +{ +avio_put_str(wctx->avio, str); +} + +static inline void writer_printf(WriterContext *wctx, const char *fmt, ...) +{ +va_list ap; + +va_start(ap, fmt); +avio_vprintf(wctx->avio, fmt, ap); +va_end(ap); +} + #define MAX_REGISTERED_WRITERS_NB 64 static const Writer *registered_writers[MAX_REGISTERED_WRITERS_NB + 1]; @@ -973,7 +1001,7 @@ static void default_print_section_header(WriterContext *wctx) return; if (!(section->flags & (SECTION_FLAG_IS_WRAPPER|SECTION_FLAG_IS_ARRAY))) -printf("[%s]\n", upcase_string(buf, sizeof(buf), section->name)); +writer_printf(wctx, "[%s]\n", upcase_string(buf, sizeof(buf), section->name)); } static void default_print_section_footer(WriterContext *wctx) @@ -986,7 +1014,7 @@ static void default_print_section_footer(WriterContext *wctx) return; if (!(section->flags & (SECTION_FLAG_IS_WRAPPER|SECTION_FLAG_IS_ARRAY))) -printf("[/%s]\n", upcase_string(buf, sizeof(buf), section->name)); +writer_printf(wctx, "[/%s]\n", upcase_string(buf, sizeof(buf), section->name)); } static void default_print_str(WriterContext *wctx, const char *key, const char *value) @@ -994,8 +1022,8 @@ static void default_print_str(WriterContext *wctx, const char *key, const char * DefaultContext *def = wctx->priv; if (!def->nokey) -printf("%s%s=", wctx->section_pbuf[wctx->level].str, key); -printf("%s\n", value); +writer_printf(wctx, "%s%s=", wctx->section_pbuf[wctx->level].str, key); +writer_printf(wctx, "%s\n", value); } static void default_print_int(WriterContext *wctx, const char *key, long long int value) @@ -1003,8 +1031,8 @@ static void default_print_int(WriterC
Re: [FFmpeg-devel] [PATCH v2] avformat/wavdec: Fix reading files with id3v2 apic before fmt tag
Paul B Mahol: > Why you put nonsense regression part in log. > > That is very unfriendly behavior from you. > > Noted. > Before your patch, the audio in the files in question would work; with your patch it doesn't any longer. That's a regression. > On Sun, Apr 18, 2021 at 1:50 AM Andreas Rheinhardt < > andreas.rheinha...@outlook.com> wrote: > >> Andreas Rheinhardt: >>> Up until now the cover images will get the stream index 0 in this case, >>> violating the hardcoded assumption that this is the index of the audio >>> stream. Fix this by creating the audio stream first; this is also in >>> line with the expectations of ff_pcm_read_seek() and >>> ff_spdif_read_packet(). It also simplifies the code to parse the fmt and >>> xma2 tags. >>> >>> Fixes #8540; regression since f5aad350d3695b5b16e7d135154a4c61e4dce9d8. >>> >>> Signed-off-by: Andreas Rheinhardt >>> --- >>> libavformat/wavdec.c | 78 ++-- >>> 1 file changed, 39 insertions(+), 39 deletions(-) >>> >>> diff --git a/libavformat/wavdec.c b/libavformat/wavdec.c >>> index 8214ab8498..791ae23b4a 100644 >>> --- a/libavformat/wavdec.c >>> +++ b/libavformat/wavdec.c >>> @@ -49,6 +49,7 @@ typedef struct WAVDemuxContext { >>> const AVClass *class; >>> int64_t data_end; >>> int w64; >>> +AVStream *vst; >>> int64_t smv_data_ofs; >>> int smv_block_size; >>> int smv_frames_per_jpeg; >>> @@ -170,30 +171,26 @@ static void handle_stream_probing(AVStream *st) >>> } >>> } >>> >>> -static int wav_parse_fmt_tag(AVFormatContext *s, int64_t size, AVStream >> **st) >>> +static int wav_parse_fmt_tag(AVFormatContext *s, int64_t size, AVStream >> *st) >>> { >>> AVIOContext *pb = s->pb; >>> WAVDemuxContext *wav = s->priv_data; >>> int ret; >>> >>> /* parse fmt header */ >>> -*st = avformat_new_stream(s, NULL); >>> -if (!*st) >>> -return AVERROR(ENOMEM); >>> - >>> -ret = ff_get_wav_header(s, pb, (*st)->codecpar, size, wav->rifx); >>> +ret = ff_get_wav_header(s, pb, st->codecpar, size, wav->rifx); >>> if (ret < 0) >>> return ret; >>> -handle_stream_probing(*st); >>> +handle_stream_probing(st); >>> >>> -(*st)->need_parsing = AVSTREAM_PARSE_FULL_RAW; >>> +st->need_parsing = AVSTREAM_PARSE_FULL_RAW; >>> >>> -avpriv_set_pts_info(*st, 64, 1, (*st)->codecpar->sample_rate); >>> +avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); >>> >>> return 0; >>> } >>> >>> -static int wav_parse_xma2_tag(AVFormatContext *s, int64_t size, >> AVStream **st) >>> +static int wav_parse_xma2_tag(AVFormatContext *s, int64_t size, >> AVStream *st) >>> { >>> AVIOContext *pb = s->pb; >>> int version, num_streams, i, channels = 0, ret; >>> @@ -201,13 +198,9 @@ static int wav_parse_xma2_tag(AVFormatContext *s, >> int64_t size, AVStream **st) >>> if (size < 36) >>> return AVERROR_INVALIDDATA; >>> >>> -*st = avformat_new_stream(s, NULL); >>> -if (!*st) >>> -return AVERROR(ENOMEM); >>> - >>> -(*st)->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; >>> -(*st)->codecpar->codec_id = AV_CODEC_ID_XMA2; >>> -(*st)->need_parsing = AVSTREAM_PARSE_FULL_RAW; >>> +st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; >>> +st->codecpar->codec_id = AV_CODEC_ID_XMA2; >>> +st->need_parsing = AVSTREAM_PARSE_FULL_RAW; >>> >>> version = avio_r8(pb); >>> if (version != 3 && version != 4) >>> @@ -216,26 +209,26 @@ static int wav_parse_xma2_tag(AVFormatContext *s, >> int64_t size, AVStream **st) >>> if (size != (32 + ((version==3)?0:8) + 4*num_streams)) >>> return AVERROR_INVALIDDATA; >>> avio_skip(pb, 10); >>> -(*st)->codecpar->sample_rate = avio_rb32(pb); >>> +st->codecpar->sample_rate = avio_rb32(pb); >>> if (version == 4) >>> avio_skip(pb, 8); >>> avio_skip(pb, 4); >>> -(*st)->duration = avio_rb32(pb); >>> +st->duration = avio_rb32(pb); >>> avio_skip(pb, 8); >>> >>> for (i = 0; i < num_streams; i++) { >>> channels += avio_r8(pb); >>> avio_skip(pb, 3); >>> } >>> -(*st)->codecpar->channels = channels; >>> +st->codecpar->channels = channels; >>> >>> -if ((*st)->codecpar->channels <= 0 || (*st)->codecpar->sample_rate >> <= 0) >>> +if (st->codecpar->channels <= 0 || st->codecpar->sample_rate <= 0) >>> return AVERROR_INVALIDDATA; >>> >>> -avpriv_set_pts_info(*st, 64, 1, (*st)->codecpar->sample_rate); >>> +avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); >>> >>> avio_seek(pb, -size, SEEK_CUR); >>> -if ((ret = ff_get_extradata(s, (*st)->codecpar, pb, size)) < 0) >>> +if ((ret = ff_get_extradata(s, st->codecpar, pb, size)) < 0) >>> return ret; >>> >>> return 0; >>> @@ -407,6 +400,11 @@ static int wav_read_header(AVFormatContext *s) >>> >>> } >>> >>> +/* Create the audio stream now so that its index is always zero */ >>>
Re: [FFmpeg-devel] [PATCH] doc/muxers.texi: fix build issue for unknown command
> -Original Message- > From: ffmpeg-devel On Behalf Of > Gyan Doshi > Sent: 2021年4月18日 23:45 > To: ffmpeg-devel@ffmpeg.org > Subject: Re: [FFmpeg-devel] [PATCH] doc/muxers.texi: fix build issue for > unknown command > > > > On 2021-04-18 17:01, Gyan Doshi wrote: > > > > On 2021-04-18 15:25, Guo, Yejun wrote: > >> > >>> -Original Message- > >>> From: ffmpeg-devel On Behalf Of > >>> Gyan Doshi > >>> Sent: 2021年4月18日 13:04 > >>> To: ffmpeg-devel@ffmpeg.org > >>> Subject: Re: [FFmpeg-devel] [PATCH] doc/muxers.texi: fix build issue > >>> for > >>> unknown command > > Ok. Will apply. > > I don't see this patch on Patchwork --> > https://patchwork.ffmpeg.org/project/ffmpeg/list/?submitter=600 > Me too, looks that the patchwork does not work, the last patch I could see at https://patchwork.ffmpeg.org/project/ffmpeg/list/ is 2021-04-16, no more new patches there. I also attach the patch file for your convenient. thanks. 0001-doc-muxers.texi-fix-build-issue-for-unknown-command.patch Description: 0001-doc-muxers.texi-fix-build-issue-for-unknown-command.patch ___ 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/7] avcodec/avcodec: Actually honour the documentation of subtitle_header
It is only supposed to be freed by libavcodec for decoders, yet avcodec_open2() always frees it on failure. Furthermore, avcodec_close() doesn't free it for decoders. Both of this has been changed. Signed-off-by: Andreas Rheinhardt --- This might be squashed with the next patch. libavcodec/avcodec.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c index 760a98d8ef..24f6922d4f 100644 --- a/libavcodec/avcodec.c +++ b/libavcodec/avcodec.c @@ -418,7 +418,8 @@ FF_ENABLE_DEPRECATION_WARNINGS av_dict_free(&tmp); av_freep(&avctx->priv_data); -av_freep(&avctx->subtitle_header); +if (av_codec_is_decoder(avctx->codec)) +av_freep(&avctx->subtitle_header); #if FF_API_OLD_ENCDEC av_frame_free(&avci->to_free); @@ -589,7 +590,9 @@ FF_DISABLE_DEPRECATION_WARNINGS av_frame_free(&avctx->coded_frame); FF_ENABLE_DEPRECATION_WARNINGS #endif -} +} else if (av_codec_is_decoder(avctx->codec)) +av_freep(&avctx->subtitle_header); + avctx->codec = NULL; avctx->active_thread_type = 0; -- 2.27.0 ___ 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/7] avcodec/avcodec: Document current behaviour of subtitle_header
Mention that avcodec_free_context() always frees it even when encoding. And mention that freeing is of course performed in avcodec_close() when decoding and not necessarily in avcodec_open2(). Signed-off-by: Andreas Rheinhardt --- libavcodec/avcodec.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 8a71c04230..9b68aecd31 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -2011,7 +2011,9 @@ typedef struct AVCodecContext { * [Script Info] and [V4+ Styles] section, plus the [Events] line and * the Format line following. It shouldn't include any Dialogue line. * - encoding: Set/allocated/freed by user (before avcodec_open2()) - * - decoding: Set/allocated/freed by libavcodec (by avcodec_open2()) + * - decoding: Set/allocated/freed by libavcodec (by avcodec_open2() + * resp. avcodec_close()) + * Furthermore, avcodec_free_context() always frees it even when encoding. */ uint8_t *subtitle_header; int subtitle_header_size; -- 2.27.0 ___ 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/7] avcodec/avcodec: Remove unnecessary forward declaration
Forgotten in ba6cada92eb7c3446bfb1d4525031d405a052516. Signed-off-by: Andreas Rheinhardt --- libavcodec/avcodec.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 9b68aecd31..b9b487be41 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -2420,8 +2420,6 @@ attribute_deprecated void av_codec_set_chroma_intra_matrix(AVCodecContext *avctx, uint16_t *val); #endif -struct AVSubtitle; - #if FF_API_CODEC_GET_SET attribute_deprecated int av_codec_get_max_lowres(const AVCodec *codec); -- 2.27.0 ___ 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/7] avcodec/avcodec: Store whether AVCodec->close needs to be called
Right now all AVCodecContexts except those using frame-threaded decoding call the codec's init function and expect its close function to be called. In order to make sure that the close function is not called for frame-threaded decoding ff_frame_thread_free() resets AVCodecContext.codec (and because of this it has to free the private AVOptions of the main AVCodecContext itself). This is not obvious and potentially fragile. Instead add a field to AVCodecInternal that indicates whether close should be called for this AVCodecContext. It is always zero when using frame-threaded decoding, so that resetting the codec is no longer necessary and has been removed. Signed-off-by: Andreas Rheinhardt --- libavcodec/avcodec.c | 23 +++ libavcodec/internal.h | 6 ++ libavcodec/pthread_frame.c | 4 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c index 6cff596f6a..c7a8001608 100644 --- a/libavcodec/avcodec.c +++ b/libavcodec/avcodec.c @@ -142,7 +142,6 @@ static int64_t get_bit_rate(AVCodecContext *ctx) int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options) { int ret = 0; -int codec_init_ok = 0; AVDictionary *tmp = NULL; AVCodecInternal *avci; @@ -336,14 +335,16 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code if (!HAVE_THREADS && !(codec->caps_internal & FF_CODEC_CAP_AUTO_THREADS)) avctx->thread_count = 1; -if ( avctx->codec->init && (!(avctx->active_thread_type&FF_THREAD_FRAME) -|| avci->frame_thread_encoder)) { -ret = avctx->codec->init(avctx); -if (ret < 0) { -codec_init_ok = -1; -goto free_and_end; +if (!(avctx->active_thread_type & FF_THREAD_FRAME) || +avci->frame_thread_encoder) { +if (avctx->codec->init) { +ret = avctx->codec->init(avctx); +if (ret < 0) { +avci->needs_close = avctx->codec->caps_internal & FF_CODEC_CAP_INIT_CLEANUP; +goto free_and_end; +} } -codec_init_ok = 1; +avci->needs_close = 1; } ret=0; @@ -394,9 +395,7 @@ end: return ret; free_and_end: -if (avctx->codec && avctx->codec->close && -(codec_init_ok > 0 || (codec_init_ok < 0 && - avctx->codec->caps_internal & FF_CODEC_CAP_INIT_CLEANUP))) +if (avci->needs_close && avctx->codec->close) avctx->codec->close(avctx); if (CONFIG_FRAME_THREAD_ENCODER && avci->frame_thread_encoder) @@ -539,7 +538,7 @@ av_cold int avcodec_close(AVCodecContext *avctx) } if (HAVE_THREADS && avci->thread_ctx) ff_thread_free(avctx); -if (avctx->codec && avctx->codec->close) +if (avci->needs_close && avctx->codec->close) avctx->codec->close(avctx); avci->byte_buffer_size = 0; av_freep(&avci->byte_buffer); diff --git a/libavcodec/internal.h b/libavcodec/internal.h index b57b996816..85d52dda07 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -164,6 +164,12 @@ typedef struct AVCodecInternal { EncodeSimpleContext es; +/** + * If this is set, then AVCodec->close (if existing) needs to be called + * for the parent AVCodecContext. + */ +int needs_close; + /** * Number of audio samples to skip at the start of the next decoded frame */ diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index ae5b000d97..250b0068ab 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -806,10 +806,6 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) free_pthread(fctx, thread_ctx_offsets); av_freep(&avctx->internal->thread_ctx); - -if (avctx->priv_data && avctx->codec && avctx->codec->priv_class) -av_opt_free(avctx->priv_data); -avctx->codec = NULL; } static av_cold int init_thread(PerThreadContext *p, int *threads_to_free, -- 2.27.0 ___ 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 6/7] avcodec/avcodec: Use avcodec_close() on avcodec_open2() failure
Compared to the earlier behaviour the following changes: a) AVCodecInternal.byte_buffer is freed. b) The last_pkt_props FIFO is emptied before freeing it. c) If set AVCodecContext.hwaccel is uninitialized and its private data is freed; hw_frames_ctx and hw_device_ctx are also unreferenced. d) coded_side_data is freed. e) active_thread_type is reset. a), b), d) should be no-ops as the buffer/fifo should be empty and no coded_side_data should exist at any point of avcodec_open2(). e) is obviously not bad. c) is in accordance with the documentation of hw_(frames|device)_ctx which states that libacodec takes over ownership of these references. At least in the case of VC-1 it is possible for the hw acceleration to be set during init and in this case freeing it actually fixes a memleak. Signed-off-by: Andreas Rheinhardt --- The VC-1 decoder actually does not want to init hardware acceleration in its init function; it just wants to initialize some static data during its init function for safety. It actually needs only very few of the static tables that are initialized during init; its initialization could easily be factored out. libavcodec/avcodec.c | 46 ++-- 1 file changed, 2 insertions(+), 44 deletions(-) diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c index c7a8001608..b054303afd 100644 --- a/libavcodec/avcodec.c +++ b/libavcodec/avcodec.c @@ -395,51 +395,8 @@ end: return ret; free_and_end: -if (avci->needs_close && avctx->codec->close) -avctx->codec->close(avctx); - -if (CONFIG_FRAME_THREAD_ENCODER && avci->frame_thread_encoder) -ff_frame_thread_encoder_free(avctx); -if (HAVE_THREADS && avci->thread_ctx) -ff_thread_free(avctx); - -if (codec->priv_class && avctx->priv_data) -av_opt_free(avctx->priv_data); -av_opt_free(avctx); - -if (av_codec_is_encoder(avctx->codec)) { -#if FF_API_CODED_FRAME -FF_DISABLE_DEPRECATION_WARNINGS -av_frame_free(&avctx->coded_frame); -FF_ENABLE_DEPRECATION_WARNINGS -#endif -av_freep(&avctx->extradata); -avctx->extradata_size = 0; -} - +avcodec_close(avctx); av_dict_free(&tmp); -av_freep(&avctx->priv_data); -if (av_codec_is_decoder(avctx->codec)) -av_freep(&avctx->subtitle_header); - -#if FF_API_OLD_ENCDEC -av_frame_free(&avci->to_free); -av_frame_free(&avci->compat_decode_frame); -av_packet_free(&avci->compat_encode_packet); -#endif -av_frame_free(&avci->buffer_frame); -av_packet_free(&avci->buffer_pkt); -av_packet_free(&avci->last_pkt_props); -av_fifo_freep(&avci->pkt_props); - -av_packet_free(&avci->ds.in_pkt); -av_frame_free(&avci->es.in_frame); -av_bsf_free(&avci->bsf); - -av_buffer_unref(&avci->pool); -av_freep(&avci); -avctx->internal = NULL; -avctx->codec = NULL; goto end; } @@ -586,6 +543,7 @@ av_cold int avcodec_close(AVCodecContext *avctx) av_freep(&avctx->priv_data); if (av_codec_is_encoder(avctx->codec)) { av_freep(&avctx->extradata); +avctx->extradata_size = 0; #if FF_API_CODED_FRAME FF_DISABLE_DEPRECATION_WARNINGS av_frame_free(&avctx->coded_frame); -- 2.27.0 ___ 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/7] avcodec/avcodec: Free frame_thread_encoder on avcodec_open2() error
The frame_thread_encoder has so far not been freed in case an error happened in avcodec_open2() after ff_frame_thread_encoder_init(). This commit changes this. Signed-off-by: Andreas Rheinhardt --- libavcodec/avcodec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c index 24f6922d4f..6cff596f6a 100644 --- a/libavcodec/avcodec.c +++ b/libavcodec/avcodec.c @@ -399,6 +399,8 @@ free_and_end: avctx->codec->caps_internal & FF_CODEC_CAP_INIT_CLEANUP))) avctx->codec->close(avctx); +if (CONFIG_FRAME_THREAD_ENCODER && avci->frame_thread_encoder) +ff_frame_thread_encoder_free(avctx); if (HAVE_THREADS && avci->thread_ctx) ff_thread_free(avctx); -- 2.27.0 ___ 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 7/7] avcodec/exr: Return correct error code on allocation failure
Signed-off-by: Andreas Rheinhardt --- libavcodec/exr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/exr.c b/libavcodec/exr.c index 49c4774145..4f55609b0c 100644 --- a/libavcodec/exr.c +++ b/libavcodec/exr.c @@ -2245,7 +2245,7 @@ static av_cold int decode_init(AVCodecContext *avctx) // allocate thread data, used for non EXR_RAW compression types s->thread_data = av_mallocz_array(avctx->thread_count, sizeof(EXRThreadData)); if (!s->thread_data) -return AVERROR_INVALIDDATA; +return AVERROR(ENOMEM); return 0; } -- 2.27.0 ___ 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 1/1] avformat/mpegtsenc: Write necessary descriptors into PMT for arib_caption muxing
Is there anyone who could review this patch? Best regards, zheng ___ 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] doc/muxers.texi: fix build issue for unknown command
Hi, On Mon, 19. Apr 01:10, Guo, Yejun wrote: > > > > -Original Message- > > From: ffmpeg-devel On Behalf Of > > Gyan Doshi > > Sent: 2021年4月18日 23:45 > > To: ffmpeg-devel@ffmpeg.org > > Subject: Re: [FFmpeg-devel] [PATCH] doc/muxers.texi: fix build issue for > > unknown command > > > > > > > > On 2021-04-18 17:01, Gyan Doshi wrote: > > > > > > On 2021-04-18 15:25, Guo, Yejun wrote: > > >> > > >>> -Original Message- > > >>> From: ffmpeg-devel On Behalf Of > > >>> Gyan Doshi > > >>> Sent: 2021年4月18日 13:04 > > >>> To: ffmpeg-devel@ffmpeg.org > > >>> Subject: Re: [FFmpeg-devel] [PATCH] doc/muxers.texi: fix build issue > > >>> for > > >>> unknown command > > > Ok. Will apply. > > > > I don't see this patch on Patchwork --> > > https://patchwork.ffmpeg.org/project/ffmpeg/list/?submitter=600 > > > > Me too, looks that the patchwork does not work, the last patch I could see at > https://patchwork.ffmpeg.org/project/ffmpeg/list/ is 2021-04-16, no more new > patches there. > Patchwork should be up to date now. -- Andriy ___ 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] doc/muxers.texi: fix build issue for unknown command
On 2021-04-19 11:02, Andriy Gelman wrote: Hi, On Mon, 19. Apr 01:10, Guo, Yejun wrote: -Original Message- From: ffmpeg-devel On Behalf Of Gyan Doshi Sent: 2021年4月18日 23:45 To: ffmpeg-devel@ffmpeg.org Subject: Re: [FFmpeg-devel] [PATCH] doc/muxers.texi: fix build issue for unknown command On 2021-04-18 17:01, Gyan Doshi wrote: On 2021-04-18 15:25, Guo, Yejun wrote: -Original Message- From: ffmpeg-devel On Behalf Of Gyan Doshi Sent: 2021年4月18日 13:04 To: ffmpeg-devel@ffmpeg.org Subject: Re: [FFmpeg-devel] [PATCH] doc/muxers.texi: fix build issue for unknown command Ok. Will apply. I don't see this patch on Patchwork --> https://patchwork.ffmpeg.org/project/ffmpeg/list/?submitter=600 Me too, looks that the patchwork does not work, the last patch I could see at https://patchwork.ffmpeg.org/project/ffmpeg/list/ is 2021-04-16, no more new patches there. Patchwork should be up to date now. Applied as ffa39eb975b14b19cb70f3a7f47e2fa5b8268e40 Thanks, 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".