[FFmpeg-devel] Possibly a little bug in af_loudnorm.c

2022-08-20 Thread jagad hariseno
Hi All,

at af_loudnorm.c in line number 188:
double this, next, max_peak;

max_peak is not initialized with 0. and could be contains any value or
noise.
I could be wrong but I think init with 0. should be better:

double this, next, max_peak=0.;

Best Regards

jagad.
___
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] Possibly a little bug in af_loudnorm.c

2022-08-20 Thread Jack Waller
Please check the code:line 209

if (c == 0 || fabs(buf[index + c]) > max_peak)
max_peak = fabs(buf[index + c]);

'max_peak' is initialized.


On Sat, Aug 20, 2022 at 5:39 PM jagad hariseno 
wrote:

> Hi All,
>
> at af_loudnorm.c in line number 188:
> double this, next, max_peak;
>
> max_peak is not initialized with 0. and could be contains any value or
> noise.
> I could be wrong but I think init with 0. should be better:
>
> double this, next, max_peak=0.;
>
> Best Regards
>
> jagad.
> ___
> 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] Possibly a little bug in af_loudnorm.c

2022-08-20 Thread jagad hariseno
yes you're right.
Thanks for your fast response

Best Regards

jagad

On Sat, Aug 20, 2022 at 4:53 PM Jack Waller  wrote:

> Please check the code:line 209
>
> if (c == 0 || fabs(buf[index + c]) > max_peak)
> max_peak = fabs(buf[index + c]);
>
> 'max_peak' is initialized.
>
>
> On Sat, Aug 20, 2022 at 5:39 PM jagad hariseno 
> wrote:
>
> > Hi All,
> >
> > at af_loudnorm.c in line number 188:
> > double this, next, max_peak;
> >
> > max_peak is not initialized with 0. and could be contains any value or
> > noise.
> > I could be wrong but I think init with 0. should be better:
> >
> > double this, next, max_peak=0.;
> >
> > Best Regards
> >
> > jagad.
> > ___
> > 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 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] framepool width and potential patch for bug 9873

2022-08-20 Thread Brendan Hack

Hi,

I reported https://trac.ffmpeg.org/ticket/9873 last week and have since 
been digging into the code to see if I can get a patch together. I've 
found the underlying issue in ff_frame_pool_video_init at line 77 of 
libavfilter/framepool.c:


    ret = av_image_fill_linesizes(pool->linesize, pool->format,
  FFALIGN(pool->width, align));

When creating frames for frei0r filtering an align value of 16 gets 
passed in. This works fine for widths like 400 where FFALIGN just 
returns 400 since it's a multiple of 16. But for values like 1800 it 
pushes the width up to 1808 which then generates linesizes for that 
width which breaks the frei0r requirement that the stride matches width 
* 4 since width is now too large.


Initially I put together a patch that adds an extra parameter to 
ff_frame_pool_video_init that tells it just to use the width directly 
and not try to align it. This seemed a bit awkward though, especially 
when I tried to figure our why the code is even trying to make the width 
a multiple of the align value (which is effectively what it's doing) to 
start with. I can't make sense of why it's calling FFALIGN there at all 
and checking the commit history didn't provide any hints. If anything I 
would have thought that you would want to increase the width so that the 
final line size would be aligned, EG: FFALIGN(pool->width*4, align)/4, 
rather than the width itself.


In any case I have patches that work both ways, either an extra flag to 
not do the aligned width or the FFALIGN(pool->width*4, align)/4 fix. The 
former I'm confident of but am not so sure about the latter since I 
don't understand why it's there to start with, nor whether it may break 
other filters. The fate tests all pass with it though on my system. It 
will certainly work with frei0r though since it requires width to be a 
multiple of 8 which will always give a line size that's aligned to 16.


Any advice on which one I should submit would be great.

thanks

Brendan


___
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] framepool width and potential patch for bug 9873

2022-08-20 Thread Timo Rothenpieler

On 20.08.2022 13:21, Brendan Hack wrote:

Hi,

I reported https://trac.ffmpeg.org/ticket/9873 last week and have since 
been digging into the code to see if I can get a patch together. I've 
found the underlying issue in ff_frame_pool_video_init at line 77 of 
libavfilter/framepool.c:


     ret = av_image_fill_linesizes(pool->linesize, pool->format,
   FFALIGN(pool->width, align));

When creating frames for frei0r filtering an align value of 16 gets 
passed in. This works fine for widths like 400 where FFALIGN just 
returns 400 since it's a multiple of 16. But for values like 1800 it 
pushes the width up to 1808 which then generates linesizes for that 
width which breaks the frei0r requirement that the stride matches width 
* 4 since width is now too large.


Not sure what you mean. The code you quoted does not touch width. It 
just bumps up the linesize, to align the start of every line on the 
desired align value.


Initially I put together a patch that adds an extra parameter to 
ff_frame_pool_video_init that tells it just to use the width directly 
and not try to align it. This seemed a bit awkward though, especially 


That parameter already exists. It's called the align.

when I tried to figure our why the code is even trying to make the width 
a multiple of the align value (which is effectively what it's doing) to 
start with. I can't make sense of why it's calling FFALIGN there at all 
and checking the commit history didn't provide any hints. If anything I 
would have thought that you would want to increase the width so that the 
final line size would be aligned, EG: FFALIGN(pool->width*4, align)/4, 
rather than the width itself.


In any case I have patches that work both ways, either an extra flag to 
not do the aligned width or the FFALIGN(pool->width*4, align)/4 fix. The 
former I'm confident of but am not so sure about the latter since I 
don't understand why it's there to start with, nor whether it may break 


You mean you don't understand the concept of aligning lines?
The whole point is that a lot of hardware instructions require the data 
they work on to be aligned properly. Hence the linesize needs to be 
larger than width, to make sure every line starts well aligned.


other filters. The fate tests all pass with it though on my system. It 
will certainly work with frei0r though since it requires width to be a 
multiple of 8 which will always give a line size that's aligned to 16.


Any advice on which one I should submit would be great.


If frei0r tells it to align it to 16 bytes, but then fails because it 
expects it to be packed without gaps, it's just passing the wrong 
alignment, and should pass 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] framepool width and potential patch for bug 9873

2022-08-20 Thread Timo Rothenpieler

On 20.08.2022 14:27, Brendan Hack wrote:
Oh, I think I've got the wrong end of the stick here in regards to what 
align does in ff_frame_pool_video_init. Frei0r only needs the start of 
the buffer to be aligned to 16 bytes. It doesn't need each _line_ to be 
explicitly aligned to 16 bytes since its requirement that the width be a 
multiple of 8 enforces that (since every 8 pixels is 32 bytes).


Now that sounds like the align should be 8, not 16 or 1, in order for 
frames with odd sizes still work?

___
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] framepool width and potential patch for bug 9873

2022-08-20 Thread Paul B Mahol
On Sat, Aug 20, 2022 at 2:30 PM Timo Rothenpieler 
wrote:

> On 20.08.2022 14:27, Brendan Hack wrote:
> > Oh, I think I've got the wrong end of the stick here in regards to what
> > align does in ff_frame_pool_video_init. Frei0r only needs the start of
> > the buffer to be aligned to 16 bytes. It doesn't need each _line_ to be
> > explicitly aligned to 16 bytes since its requirement that the width be a
> > multiple of 8 enforces that (since every 8 pixels is 32 bytes).
>
> Now that sounds like the align should be 8, not 16 or 1, in order for
> frames with odd sizes still work?
>

IIRC michael have wrote fix for frei0r filter, dunno if its merged.


> ___
> 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 v2 2/4] ffmpeg: Add display_matrix option

2022-08-20 Thread Thilo Borgmann



On 18 Aug 2022, at 12:58, Gyan Doshi wrote:


On 2022-08-17 05:55 pm, Anton Khirnov wrote:

Quoting Gyan Doshi (2022-08-17 12:53:11)


On 2022-08-17 02:35 pm, Anton Khirnov wrote:

Quoting Gyan Doshi (2022-08-17 10:50:43)

On 2022-08-17 01:48 pm, Anton Khirnov wrote:

Quoting Thilo Borgmann (2022-08-16 20:48:57)

Am 16.08.22 um 16:10 schrieb Anton Khirnov:

Quoting Thilo Borgmann (2022-08-15 22:02:09)

$subject

-Thilo
From fe2ff114cb004f897c7774753d9cf28298eba82d Mon Sep 17 
00:00:00 2001

From: =?UTF-8?q?Jan=20Ekstr=C3=B6m?= 
Date: Mon, 15 Aug 2022 21:09:27 +0200
Subject: [PATCH v2 2/4] ffmpeg: Add display_matrix option

This enables overriding the rotation as well as 
horizontal/vertical

flip state of a specific video stream on the input side.

Additionally, switch the singular test that was utilizing the 
rotation
metadata to instead override the input display rotation, thus 
leading

to the same result.
---
I still don't see how it's better to squash multiple options 
into a

single option.

It requires all this extra infrastructure and in the end it's 
less
user-friendly, because user-understandable things like rotation 
or flips
are now hidden under "display matrix". How many users would 
know what a

display matrix is?
FWIW I think Gyan's request to do this all in one option that 
effect one thing (the display matrix) is valid.

I don't.

It may be one thing internally, but modeling user interfaces 
based on
internal representation is a sinful malpractice. More 
importantly, I see
no advantage from doing it - it only makes the option parsing 
more

complicated.
It's not based on ffmpeg's 'internal representation'. All 
transform

attributes are stored as a composite in one mathematical object.
Keyword "stored". It is internal representation. Users should not 
care
how it is stored, the entire point point of our project is to 
shield

them from that as much as possible.


Evaluating the matrix values will need to look at all sources of
contribution. So gathering and presenting all these attributes in 
a single
option (+ docs) makes it clearer to the user at the cost of an 
initial

learning curve.

Are you seriously expecting all users who want to mark a video as
rotated or flipped to learn about display matrices?
They don't need to know how to encode or decode the matrix if they 
don't

want to. Only that it is the container.

The difference is between

   -rotate:v:0 90 -hflip:v:0 1 -scale:v:0 2

and

   -display_matrix:v:0 rotate=90:hflip=1:scale=2

The latter syntax is all too familiar to users from AVFrame filters 
and

BSFs.
The syntax similarity is misleading - filters are applied in the 
order

you list them, while these options are always applied in fixed order.
The analogous filters are also called rotate, [vf]flip, and scale -
there is no display_matrix filter.


The display matrix is effected as a single matrix multiplication to 
obtain output pixel co-ordinates which incorporates all the
encoded transforms so it is analogous to multiple options within a 
filter like eq or hue, not multiple filters.


About SEI messaging,  the h264 metadata BSF still obtains (and 
extracts) those attributes as a display matrix as that is the internal 
messaging format regardless of ultimate storage form.


Thanks for all your comments! Unfortunately, I don’t see real 
consensus emerging here.


I see a single option finds more acceptance (3:1),
I see using to use AVDict is frowned upon by 1, though the alternative 
suggestion with a parser for SVG-style (new syntax)  is not backup up by 
s.o. else.


Therefore my interpretation would be to go with majority and stick with 
one option and stick with AVDict.
However, I don’t want to shortcut the discussion or override s.o. 
opinion. Going to pick this up next week and if no more arguments 
emerge, I’ll continue with that.


Thanks,
Thilo
___
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/4] ffmpeg: Add display_matrix option

2022-08-20 Thread Nicolas George
Thilo Borgman (12022-08-20):
> suggestion with a parser for SVG-style (new syntax)  is not backup up by
> s.o. else.

I feel it was somewhat drowned by the rest of the discussion. Do YOU
like it?

Regards,

-- 
  Nicolas George


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".


Re: [FFmpeg-devel] [PATCH v2 2/4] ffmpeg: Add display_matrix option

2022-08-20 Thread Thilo Borgmann

Am 20.08.22 um 15:39 schrieb Nicolas George:

Thilo Borgman (12022-08-20):

suggestion with a parser for SVG-style (new syntax)  is not backup up by
s.o. else.


I feel it was somewhat drowned by the rest of the discussion. Do YOU
like it?


My two cents about it that the a=b:c=d syntax from AVDict is at least known and 
used in filters already.
The function style a(b,c,d) thing from SVG would be completely new. Instead of 
the AVDict overhead, it adds a simplistic parser overhead.
Also, maybe I'm just unaware, these style of options appears not to be often 
used in the command line world.

But as I said I usually don't touch ffmpeg / it's options, so I think my 
opinion should not be of much value here where we talk of the contextual 
effects of this patch.

-Thilo
___
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/1] lavf/dashdec: Multithreaded DASH initialization

2022-08-20 Thread Lukas Fellechner
This patch adds multithreading support to DASH initialization. Initializing 
DASH streams is currently slow, because each individual stream is opened and 
probed sequentially. With DASH streams often having somewhere between 10-20 
substreams, this can easily take up to half a minute on slow connections. This 
patch adds an "init-threads" option, specifying the max number of threads to 
use for parallel probing and initialization of substreams. If "init-threads" is 
set to a value larger than 1, multiple worker threads are spun up to massively 
bring down init times.

Here is a free DASH stream for testing:

http://www.bok.net/dash/tears_of_steel/cleartext/stream.mpd

It has 7 substreams. I currently get init times of 3.5 seconds without patch. 
The patch brings it down to about 0.5 seconds, so using 7 threads nearly cut 
down init times by factor 7. On a slower connection (100mbit), the same stream 
took 7-8 seconds to initialize, the patch brought it down to just over 1 second.

In the current patch, the behavior is disabled by default (init-threads = 0). 
But I think it could make sense to enable it by default, maybe with a 
reasonable value of 8? Not sure though, open for discussion.

Some notes on the actual implementation:
- DASH streams sometimes share a common init section. If this is the case, a 
mutex and condition is used, to make sure that the first stream reads the 
common section before the following streams start initialization.
- Only the init and probing part is done in parallel. After all threads are 
joined, I collect the results and add the AVStreams to the parent 
AVFormatContext. That is why I split open_demux_for_component() into 
begin_open_demux_for_component() and end_open_demux_for_component().
- I tried to do this as clean as possible and added multiple comments.
- Multithreading is never simple, so a proper review is needed.

If this gets merged, I might try to do the same for HLS.

This is my first PR by the way, so please be nice :)

Lukas

0001-lavf-dashdec-Multithreaded-DASH-initialization.patch
Description: Binary data
___
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/1] lavf/dashdec: Multithreaded DASH initialization

2022-08-20 Thread Lukas Fellechner
Trying with inline PATCH since attached file was not showing up...

---

From: Lukas Fellechner 
Subject: [PATCH 1/1] lavf/dashdec: Multithreaded DASH initialization

Initializing DASH streams is currently slow, because each individual stream is 
opened and probed sequentially. With DASH streams often having somewhere 
between 10-20 streams, this can easily take up to half a minute. This patch 
adds an "init-threads" option, specifying the max number of threads to use. 
Multiple worker threads are spun up to massively bring down init times.
---
 libavformat/dashdec.c | 421 +-
 1 file changed, 375 insertions(+), 46 deletions(-)

diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c
index 63bf7e96a5..69a6c2ba79 100644
--- a/libavformat/dashdec.c
+++ b/libavformat/dashdec.c
@@ -24,6 +24,7 @@
 #include "libavutil/opt.h"
 #include "libavutil/time.h"
 #include "libavutil/parseutils.h"
+#include "libavutil/thread.h"
 #include "internal.h"
 #include "avio_internal.h"
 #include "dash.h"
@@ -152,6 +153,8 @@ typedef struct DASHContext {
 int max_url_size;
 char *cenc_decryption_key;

+int init_threads;
+
 /* Flags for init section*/
 int is_init_section_common_video;
 int is_init_section_common_audio;
@@ -1918,22 +1921,40 @@ fail:
 return ret;
 }

-static int open_demux_for_component(AVFormatContext *s, struct representation 
*pls)
+static int open_demux_for_component(AVFormatContext* s, struct representation* 
pls)
+{
+int ret = 0;
+
+ret = begin_open_demux_for_component(s, pls);
+if (ret < 0)
+return ret;
+
+ret = end_open_demux_for_component(s, pls);
+
+return ret;
+}
+
+static int begin_open_demux_for_component(AVFormatContext* s, struct 
representation* pls)
 {
 int ret = 0;
-int i;

 pls->parent = s;
-pls->cur_seq_no  = calc_cur_seg_no(s, pls);
+pls->cur_seq_no = calc_cur_seg_no(s, pls);

 if (!pls->last_seq_no) {
 pls->last_seq_no = calc_max_seg_no(pls, s->priv_data);
 }

 ret = reopen_demux_for_component(s, pls);
-if (ret < 0) {
-goto fail;
-}
+
+return ret;
+}
+
+static int end_open_demux_for_component(AVFormatContext* s, struct 
representation* pls)
+{
+int ret = 0;
+int i;
+
 for (i = 0; i < pls->ctx->nb_streams; i++) {
 AVStream *st = avformat_new_stream(s, NULL);
 AVStream *ist = pls->ctx->streams[i];
@@ -2015,6 +2036,131 @@ static void move_metadata(AVStream *st, const char 
*key, char **value)
 }
 }

+struct work_pool_data
+{
+AVFormatContext* ctx;
+struct representation* pls;
+struct representation* common_pls;
+pthread_mutex_t* common_mutex;
+pthread_cond_t* common_condition;
+int is_common;
+int is_started;
+int result;
+};
+
+struct thread_data
+{
+pthread_t thread;
+pthread_mutex_t* mutex;
+struct work_pool_data* work_pool;
+int work_pool_size;
+int is_started;
+};
+
+static void *worker_thread(void *ptr)
+{
+int ret = 0;
+int i;
+struct thread_data* thread_data = (struct thread_data*)ptr;
+struct work_pool_data* work_pool = NULL;
+struct work_pool_data* data = NULL;
+for (;;) {
+
+// get next work item
+pthread_mutex_lock(thread_data->mutex);
+data = NULL;
+work_pool = thread_data->work_pool;
+for (i = 0; i < thread_data->work_pool_size; i++) {
+if (!work_pool->is_started) {
+data = work_pool;
+data->is_started = 1;
+break;
+}
+work_pool++;
+}
+pthread_mutex_unlock(thread_data->mutex);
+
+if (!data) {
+// no more work to do
+return NULL;
+}
+
+// if we are common section provider, init and signal
+if (data->is_common) {
+data->pls->parent = data->ctx;
+ret = update_init_section(data->pls);
+if (ret < 0) {
+pthread_cond_signal(data->common_condition);
+goto end;
+}
+else
+ret = AVERROR(pthread_cond_signal(data->common_condition));
+}
+
+// if we depend on common section provider, wait for signal and copy
+if (data->common_pls) {
+ret = AVERROR(pthread_cond_wait(data->common_condition, 
data->common_mutex));
+if (ret < 0)
+goto end;
+
+if (!data->common_pls->init_sec_buf) {
+goto end;
+ret = AVERROR(EFAULT);
+}
+
+ret = copy_init_section(data->pls, data->common_pls);
+if (ret < 0)
+goto end;
+}
+
+ret = begin_open_demux_for_component(data->ctx, data->pls);
+if (ret < 0)
+goto end;
+
+end:
+data->result = ret;
+}
+
+
+return NULL;
+}
+
+static void create_work_pool_data(AVFormatContext* ctx, int stream_index,
+struct repr

[FFmpeg-devel] [PATCH 1/4] avcodec/pngdec: Fix APNG_DISPOSE_OP_BACKGROUND

2022-08-20 Thread Andreas Rheinhardt
APNG works with a single reference frame and an output frame.
According to the spec, decoding APNG works by decoding
the current IDAT/fdAT chunks (which decodes to a rectangular
subregion of the whole image region), followed by either
overwriting the region of the output frame with the newly
decoded data or by blending the newly decoded data with
the data from the reference frame onto the current subregion
of the output frame. The remainder of the output frame
is just copied from the reference frame.
Then the reference frame might be left untouched
(APNG_DISPOSE_OP_PREVIOUS), it might be replaced by the output
frame (APNG_DISPOSE_OP_NONE) or the rectangular subregion
corresponding to the just decoded frame has to be reset
to black (APNG_DISPOSE_OP_BACKGROUND).

The latter case is not handled correctly by our decoder:
It only performs resetting the rectangle in the reference frame
when decoding the next frame; and since commit
b593abda6c642cb0c3959752dd235c2faf66837f it does not reset
the reference frame permanently, but only temporarily (i.e.
it only affects decoding the frame after the frame with
APNG_DISPOSE_OP_BACKGROUND). This is a problem if the
frame after the APNG_DISPOSE_OP_BACKGROUND frame uses
APNG_DISPOSE_OP_PREVIOUS, because then the frame after
the APNG_DISPOSE_OP_PREVIOUS frame has an incorrect reference
frame. (If it is not followed by an APNG_DISPOSE_OP_PREVIOUS
frame, the decoder only keeps a reference to the output frame,
which is ok.)

This commit fixes this by being much closer to the spec
than the earlier code: Resetting the background is no longer
postponed until the next frame; instead it is applied to
the reference frame.

Fixes ticket #9602.

(For multithreaded decoding it was actually already broken
since commit 5663301560d77486c7f7c03c1aa5f542fab23c24.)

Signed-off-by: Andreas Rheinhardt 
---
Btw: If we had a function that only references a frame's data
(and leaves the dst frame's side data completely untouched),
we could apply the side data directly to the output frame,
making 8d74baccff59192d395735036cd40a131a140391 unnecessary.

I also wonder whether the handle_p_frame stuff should be moved
out of decode_frame_common() and in the codec-specific code.

 libavcodec/pngdec.c | 98 ++---
 1 file changed, 48 insertions(+), 50 deletions(-)

diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c
index 3b888199d4..8a197d038d 100644
--- a/libavcodec/pngdec.c
+++ b/libavcodec/pngdec.c
@@ -78,11 +78,8 @@ typedef struct PNGDecContext {
 enum PNGImageState pic_state;
 int width, height;
 int cur_w, cur_h;
-int last_w, last_h;
 int x_offset, y_offset;
-int last_x_offset, last_y_offset;
 uint8_t dispose_op, blend_op;
-uint8_t last_dispose_op;
 int bit_depth;
 int color_type;
 int compression_type;
@@ -94,8 +91,6 @@ typedef struct PNGDecContext {
 int has_trns;
 uint8_t transparent_color_be[6];
 
-uint8_t *background_buf;
-unsigned background_buf_allocated;
 uint32_t palette[256];
 uint8_t *crow_buf;
 uint8_t *last_row;
@@ -725,9 +720,30 @@ static int decode_idat_chunk(AVCodecContext *avctx, 
PNGDecContext *s,
 }
 
 ff_thread_release_ext_buffer(avctx, &s->picture);
-if ((ret = ff_thread_get_ext_buffer(avctx, &s->picture,
-AV_GET_BUFFER_FLAG_REF)) < 0)
-return ret;
+if (s->dispose_op == APNG_DISPOSE_OP_PREVIOUS) {
+/* We only need a buffer for the current picture. */
+ret = ff_thread_get_buffer(avctx, p, 0);
+if (ret < 0)
+return ret;
+} else if (s->dispose_op == APNG_DISPOSE_OP_BACKGROUND) {
+/* We need a buffer for the current picture as well as
+ * a buffer for the reference to retain. */
+ret = ff_thread_get_ext_buffer(avctx, &s->picture,
+   AV_GET_BUFFER_FLAG_REF);
+if (ret < 0)
+return ret;
+ret = ff_thread_get_buffer(avctx, p, 0);
+if (ret < 0)
+return ret;
+} else {
+/* The picture output this time and the reference to retain 
coincide. */
+if ((ret = ff_thread_get_ext_buffer(avctx, &s->picture,
+AV_GET_BUFFER_FLAG_REF)) < 0)
+return ret;
+ret = av_frame_ref(p, s->picture.f);
+if (ret < 0)
+return ret;
+}
 
 p->pict_type= AV_PICTURE_TYPE_I;
 p->key_frame= 1;
@@ -985,12 +1001,6 @@ static int decode_fctl_chunk(AVCodecContext *avctx, 
PNGDecContext *s,
 return AVERROR_INVALIDDATA;
 }
 
-s->last_w = s->cur_w;
-s->last_h = s->cur_h;
-s->last_x_offset = s->x_offset;
-s->last_y_offset = s->y_offset;
-s->last_dispose_op = s->dispose_op;
-
 sequence_number = bytestream2_get_be32(gb);
 c

[FFmpeg-devel] [PATCH 2/4] avcodec/pngdec: Use internal AVBPrint string when parsing chunks

2022-08-20 Thread Andreas Rheinhardt
One saves an allocation in case the string fits into the buffer.

Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/pngdec.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c
index 8a197d038d..189c3eee89 100644
--- a/libavcodec/pngdec.c
+++ b/libavcodec/pngdec.c
@@ -543,10 +543,8 @@ static int decode_text_chunk(PNGDecContext *s, 
GetByteContext *gb, int compresse
 return AVERROR_INVALIDDATA;
 if ((ret = decode_zbuf(&bp, data, data_end, s->avctx)) < 0)
 return ret;
+text = bp.str;
 text_len = bp.len;
-ret = av_bprint_finalize(&bp, (char **)&text);
-if (ret < 0)
-return ret;
 } else {
 text = (uint8_t *)data;
 text_len = data_end - text;
@@ -554,8 +552,8 @@ static int decode_text_chunk(PNGDecContext *s, 
GetByteContext *gb, int compresse
 
 kw_utf8  = iso88591_to_utf8(keyword, keyword_end - keyword);
 txt_utf8 = iso88591_to_utf8(text, text_len);
-if (text != data)
-av_free(text);
+if (compressed)
+av_bprint_finalize(&bp, NULL);
 if (!(kw_utf8 && txt_utf8)) {
 av_free(kw_utf8);
 av_free(txt_utf8);
-- 
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/4] avcodec/pngdec: Use char* instead of uint8_t* for text

2022-08-20 Thread Andreas Rheinhardt
Also stop casting const away.

Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/pngdec.c | 19 ++-
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c
index 189c3eee89..132ad40dc9 100644
--- a/libavcodec/pngdec.c
+++ b/libavcodec/pngdec.c
@@ -496,20 +496,20 @@ fail:
 return ret;
 }
 
-static uint8_t *iso88591_to_utf8(const uint8_t *in, size_t size_in)
+static char *iso88591_to_utf8(const char *in, size_t size_in)
 {
 size_t extra = 0, i;
-uint8_t *out, *q;
+char *out, *q;
 
 for (i = 0; i < size_in; i++)
-extra += in[i] >= 0x80;
+extra += !!(in[i] & 0x80);
 if (size_in == SIZE_MAX || extra > SIZE_MAX - size_in - 1)
 return NULL;
 q = out = av_malloc(size_in + extra + 1);
 if (!out)
 return NULL;
 for (i = 0; i < size_in; i++) {
-if (in[i] >= 0x80) {
+if (in[i] & 0x80) {
 *(q++) = 0xC0 | (in[i] >> 6);
 *(q++) = 0x80 | (in[i] & 0x3F);
 } else {
@@ -525,9 +525,10 @@ static int decode_text_chunk(PNGDecContext *s, 
GetByteContext *gb, int compresse
 int ret, method;
 const uint8_t *data= gb->buffer;
 const uint8_t *data_end= gb->buffer_end;
-const uint8_t *keyword = data;
-const uint8_t *keyword_end = memchr(keyword, 0, data_end - keyword);
-uint8_t *kw_utf8 = NULL, *text, *txt_utf8 = NULL;
+const char *keyword = data;
+const char *keyword_end = memchr(keyword, 0, data_end - data);
+char *kw_utf8 = NULL, *txt_utf8 = NULL;
+const char *text;
 unsigned text_len;
 AVBPrint bp;
 
@@ -546,8 +547,8 @@ static int decode_text_chunk(PNGDecContext *s, 
GetByteContext *gb, int compresse
 text = bp.str;
 text_len = bp.len;
 } else {
-text = (uint8_t *)data;
-text_len = data_end - text;
+text = data;
+text_len = data_end - data;
 }
 
 kw_utf8  = iso88591_to_utf8(keyword, keyword_end - keyword);
-- 
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] avcodec/pngdec: Improve decoding text chunks

2022-08-20 Thread Andreas Rheinhardt
By checking immediately whether the first allocation was successfull
one can simplify the cleanup code in case of errors.

Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/pngdec.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c
index 132ad40dc9..1d6ca7f4c3 100644
--- a/libavcodec/pngdec.c
+++ b/libavcodec/pngdec.c
@@ -551,12 +551,13 @@ static int decode_text_chunk(PNGDecContext *s, 
GetByteContext *gb, int compresse
 text_len = data_end - data;
 }
 
-kw_utf8  = iso88591_to_utf8(keyword, keyword_end - keyword);
 txt_utf8 = iso88591_to_utf8(text, text_len);
 if (compressed)
 av_bprint_finalize(&bp, NULL);
-if (!(kw_utf8 && txt_utf8)) {
-av_free(kw_utf8);
+if (!txt_utf8)
+return AVERROR(ENOMEM);
+kw_utf8  = iso88591_to_utf8(keyword, keyword_end - keyword);
+if (!kw_utf8) {
 av_free(txt_utf8);
 return AVERROR(ENOMEM);
 }
-- 
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/1] lavf/dashdec: Multithreaded DASH initialization

2022-08-20 Thread Steven Liu
Lukas Fellechner  于2022年8月21日周日 05:54写道:
>
> Trying with inline PATCH since attached file was not showing up...
>
> ---
>
> From: Lukas Fellechner 
> Subject: [PATCH 1/1] lavf/dashdec: Multithreaded DASH initialization
>
> Initializing DASH streams is currently slow, because each individual stream 
> is opened and probed sequentially. With DASH streams often having somewhere 
> between 10-20 streams, this can easily take up to half a minute. This patch 
> adds an "init-threads" option, specifying the max number of threads to use. 
> Multiple worker threads are spun up to massively bring down init times.
> ---
>  libavformat/dashdec.c | 421 +-
>  1 file changed, 375 insertions(+), 46 deletions(-)
>
> diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c
> index 63bf7e96a5..69a6c2ba79 100644
> --- a/libavformat/dashdec.c
> +++ b/libavformat/dashdec.c
> @@ -24,6 +24,7 @@
>  #include "libavutil/opt.h"
>  #include "libavutil/time.h"
>  #include "libavutil/parseutils.h"
> +#include "libavutil/thread.h"
>  #include "internal.h"
>  #include "avio_internal.h"
>  #include "dash.h"
> @@ -152,6 +153,8 @@ typedef struct DASHContext {
>  int max_url_size;
>  char *cenc_decryption_key;
>
> +int init_threads;
> +
>  /* Flags for init section*/
>  int is_init_section_common_video;
>  int is_init_section_common_audio;
> @@ -1918,22 +1921,40 @@ fail:
>  return ret;
>  }
>
> -static int open_demux_for_component(AVFormatContext *s, struct 
> representation *pls)
> +static int open_demux_for_component(AVFormatContext* s, struct 
> representation* pls)
> +{
> +int ret = 0;
> +
> +ret = begin_open_demux_for_component(s, pls);
> +if (ret < 0)
> +return ret;
> +
> +ret = end_open_demux_for_component(s, pls);
> +
> +return ret;
> +}
> +
> +static int begin_open_demux_for_component(AVFormatContext* s, struct 
> representation* pls)
>  {
>  int ret = 0;
> -int i;
>
>  pls->parent = s;
> -pls->cur_seq_no  = calc_cur_seg_no(s, pls);
> +pls->cur_seq_no = calc_cur_seg_no(s, pls);
>
>  if (!pls->last_seq_no) {
>  pls->last_seq_no = calc_max_seg_no(pls, s->priv_data);
>  }
>
>  ret = reopen_demux_for_component(s, pls);
> -if (ret < 0) {
> -goto fail;
> -}
> +
> +return ret;
> +}
> +
> +static int end_open_demux_for_component(AVFormatContext* s, struct 
> representation* pls)
> +{
> +int ret = 0;
> +int i;
> +
>  for (i = 0; i < pls->ctx->nb_streams; i++) {
>  AVStream *st = avformat_new_stream(s, NULL);
>  AVStream *ist = pls->ctx->streams[i];
> @@ -2015,6 +2036,131 @@ static void move_metadata(AVStream *st, const char 
> *key, char **value)
>  }
>  }
>
> +struct work_pool_data
> +{
> +AVFormatContext* ctx;
> +struct representation* pls;
> +struct representation* common_pls;
> +pthread_mutex_t* common_mutex;
> +pthread_cond_t* common_condition;
Should add #if HAVE_THREADS to check if the pthread supported.
> +int is_common;
> +int is_started;
> +int result;
> +};
> +
> +struct thread_data
> +{
> +pthread_t thread;
> +pthread_mutex_t* mutex;
> +struct work_pool_data* work_pool;
> +int work_pool_size;
> +int is_started;
> +};
> +
> +static void *worker_thread(void *ptr)
> +{
> +int ret = 0;
> +int i;
> +struct thread_data* thread_data = (struct thread_data*)ptr;
> +struct work_pool_data* work_pool = NULL;
> +struct work_pool_data* data = NULL;
> +for (;;) {
> +
> +// get next work item
> +pthread_mutex_lock(thread_data->mutex);
> +data = NULL;
> +work_pool = thread_data->work_pool;
> +for (i = 0; i < thread_data->work_pool_size; i++) {
> +if (!work_pool->is_started) {
> +data = work_pool;
> +data->is_started = 1;
> +break;
> +}
> +work_pool++;
> +}
> +pthread_mutex_unlock(thread_data->mutex);
> +
> +if (!data) {
> +// no more work to do
> +return NULL;
> +}
> +
> +// if we are common section provider, init and signal
> +if (data->is_common) {
> +data->pls->parent = data->ctx;
> +ret = update_init_section(data->pls);
> +if (ret < 0) {
> +pthread_cond_signal(data->common_condition);
> +goto end;
> +}
> +else
> +ret = AVERROR(pthread_cond_signal(data->common_condition));
> +}
> +
> +// if we depend on common section provider, wait for signal and copy
> +if (data->common_pls) {
> +ret = AVERROR(pthread_cond_wait(data->common_condition, 
> data->common_mutex));
> +if (ret < 0)
> +goto end;
> +
> +if (!data->common_pls->init_sec_buf) {
> +goto end;
> +ret = AVERROR(EFAULT);
> +