Re: [FFmpeg-devel] [PATCH v5 00/25] Subtitle Filtering 2022

2022-08-30 Thread Soft Works



> -Original Message-
> From: ffmpeg-devel  On Behalf Of
> Anton Khirnov
> Sent: Wednesday, August 31, 2022 3:40 AM
> To: FFmpeg development discussions and patches  de...@ffmpeg.org>
> Subject: Re: [FFmpeg-devel] [PATCH v5 00/25] Subtitle Filtering 2022
> 
> Quoting Soft Works (2022-08-27 00:48:01)
> > 2. "There's no reason why this cannot be handled using the buffer
> > and data fields"
> >
> > I had explained the reasons and in conversation on IRC, Lynne was
> > no longer insisting on this AFAIR.
> 
> I did not see this explanation, can you restate it here?

Sure. Let's look at the AVSubtitleArea struct first:


  typedef struct AVSubtitleArea {

enum AVSubtitleType type;
int flags;

int x; ///< top left corner  of area.
int y; ///< top left corner  of area.
int w; ///< widthof area.
int h; ///< height   of area.
int nb_colors; ///< number of colors in bitmap palette (@ref pal).

/**
 * Buffers and line sizes for the bitmap of this subtitle.
 *
 * @{
 */
AVBufferRef *buf[AV_NUM_BUFFER_POINTERS];
int linesize[AV_NUM_BUFFER_POINTERS];
/**
 * @}
 */

uint32_t pal[256]; ///< RGBA palette for the bitmap.

char *text;///< 0-terminated plain UTF-8 text
char *ass; ///< 0-terminated ASS/SSA compatible event line.

  } AVSubtitleArea;



These structs are stored in AVFrame like this:


/**
 * Number of items in the @ref subtitle_areas array.
 */
unsigned num_subtitle_areas;

/**
 * Array of subtitle areas, may be empty.
 */
AVSubtitleArea **subtitle_areas;



The question was "why this cannot be handled using the buffer
and data fields?" - there are multiple reasons:

1. Area Count

In ASS subtitles it's not uncommon that animations are defined
through subtitle events (regular ass events). This can go as 
far as that dust particles are flying around on the screen and
each particle has its own subtitle event/line which defines 
how it flies from x to y and how fast, etc.
Not yet, but in a future update, the ass decoder should be 
improved in a way that it doesn't emit an individual AVFrame
for each event line but bundles subsequent events together 
when these would have the same start time and duration.
As a result, we can have AVFrames with dozens or even a hundred 
AVSubtitleArea items in extreme cases.

The buffer and data fields are an array of fixed size (currently
8). Increasing to 16 or 32 would not help: there will still be
cases where this does not suffice.

2. What exactly should be stored in frame->buf[]?

Should we store the AVSubtitleArea structs as AVBuffer there?

Or should we only store data in those buffers? If yes, which 
data? The subtitle bitmap probably. How about the subtitle 
text - maybe and area has even both. And should we also
store the palette in some frame->buf[n]?
If yes, how to keep track of which data is stored in which 
buffer? 
Further, there's a documented convention that requires that
non-zero buffers are contiguous, i.e. there must not be
an empty buffer pointer between two other a non-empty buffer
pointers. This would require to re-arrange the buffers to
close any gap when some subtitle area data is removed, zeroed
out or has been converted to another format.
Closing such gap also require to update any mapping information
("which buffer is related to which area?")

That's a lot of tedious work and every API user (or codec/filter
developer) would need to do it in the right way.



3. AVFrame Code Logic Mistmatch

A subtitle frame can have 0 to N areas, which means that a 
frame without any area is still valid. Opposed to that, existing
(code all over the place in ffmpeg) is treating an AVFrame
as invalid when the first data buffer is empty,
i.e. frame->buf[0] != NULL

To accommodate to this situation, subtitle frames are always 
creating a 1-byte buffer for buf[0].

When we would want subtitle data to be stored in those buffers,
every developer would need to be aware about the requirement
to have that dummy buffer in the first array element. When something
is to be stored, the dummy buffer would need to be freed first
before storing the actual data.
And when the last buffer gets deleted, API users would need to
know to create a new dummy buffer.


That fixed size array might be a good fit for image data, but 
it's not for subtitle data.


The approach in my patchset is simple, intuitive and everybody
can easily work with it without needing any special knowledge:


unsigned num_subtitle_areas;
AVSubtitleArea **subtitle_areas;

IMHO, this is the most suitable pattern for this situation.



> If you claim the other points were addressed I will look at the
> patches
> again.

Oh cool, that would be great!

Thanks,
softworkz
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To 

Re: [FFmpeg-devel] [PATCH 16/16] avutil/fifo: Properly deprecate av_tempfile()

2022-08-30 Thread Andreas Rheinhardt
Anton Khirnov:
> Quoting Andreas Rheinhardt (2022-08-29 01:34:48)
>> Subject: Re: [FFmpeg-devel] [PATCH 16/16] avutil/fifo: Properly deprecate 
>> av_tempfile()
>
> you mean file
> 

Thanks for noticing, will fix.
(It is btw not the only bug in this patchset: #15 got the header
inclusion guards wrong (there is space before the #define and I have no
clue where it comes from).)

- Andreas
___
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 16/16] avutil/fifo: Properly deprecate av_tempfile()

2022-08-30 Thread Anton Khirnov
Quoting Andreas Rheinhardt (2022-08-29 01:34:48)
> Subject: Re: [FFmpeg-devel] [PATCH 16/16] avutil/fifo: Properly deprecate 
> av_tempfile()
   
you mean file

-- 
Anton Khirnov
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH] lavu: header and documentation for AVWriter

2022-08-30 Thread Andreas Rheinhardt
Leo Izen:
> 
> On 8/30/22 15:37, Nicolas George wrote:
>> Leo Izen (12022-08-30):
>>> Is there a reason this is AVWriter wr = foo() and not AVWriter *wr =
>>> foo()?
>>> Most other APIs return pointers to structs, rather than structs
>>> themselves
>>> (see: av_packet_alloc). Using a pointer would prevent us from having
>>> sizeof(AVWriter) as part of the ABI, as was done with AVPacket.
>>
>> Yes: to return a pointer, you need somewhere to store the structure. One
>> of the point of AVWriter is that you can store it on the stack to avoid
>> dynamic allocations when the string is short enough.
>>
>> Note that AVWriter is exactly two pointers. It will always be two
>> pointers, and all the objects that I intend to introduce later will
>> always be two pointers: one const pointer for the methods, one pointer
>> for the object itself.
>>
>> This design is essential to the features I promised for AVWriter and for
>> later.
>>
> 
> I don't see how you are planning on avoiding dynamic allocations by
> stack-allocating AVWriter when AVWriter itself only contains two pointers.
> 
> I also don't see how this design is essential to the features you
> promised in a way that can't be done by just not making sizeof(AVWriter)
> part of the ABI and returning pointers to a struct.
> 

He is not only stack-allocating AVWriter, he also intends to
stack-allocate the actual writers like AVDynbufWriter, AVBufWriter
(AVWriter is just a wrapper around the underlying writers). This means
that no allocations need to be performed for AVBufWriter at all (and due
to the inherent small-string optimization of an AVBPrint, it can also be
avoided for AVDynbufWriter in lots of cases).
If you return pointers to an AVWriter struct, you need to allocate this
struct somewhere, which means that your init/av_dynbuf_writer_wrap has
an allocation that can fail and therefore needs to be checked; and the
struct needs to be freed lateron.

- Andreas
___
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] lavu: header and documentation for AVWriter

2022-08-30 Thread Leo Izen



On 8/30/22 15:37, Nicolas George wrote:

Leo Izen (12022-08-30):

Is there a reason this is AVWriter wr = foo() and not AVWriter *wr = foo()?
Most other APIs return pointers to structs, rather than structs themselves
(see: av_packet_alloc). Using a pointer would prevent us from having
sizeof(AVWriter) as part of the ABI, as was done with AVPacket.


Yes: to return a pointer, you need somewhere to store the structure. One
of the point of AVWriter is that you can store it on the stack to avoid
dynamic allocations when the string is short enough.

Note that AVWriter is exactly two pointers. It will always be two
pointers, and all the objects that I intend to introduce later will
always be two pointers: one const pointer for the methods, one pointer
for the object itself.

This design is essential to the features I promised for AVWriter and for
later.



I don't see how you are planning on avoiding dynamic allocations by 
stack-allocating AVWriter when AVWriter itself only contains two pointers.


I also don't see how this design is essential to the features you 
promised in a way that can't be done by just not making sizeof(AVWriter) 
part of the ABI and returning pointers to a struct.


- Leo Izen (thebombzen)
___
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 17/18] lavf/dv: do not update AVCodecParameters.sample_rate while demuxing

2022-08-30 Thread Anton Khirnov
Quoting Andreas Rheinhardt (2022-08-24 16:20:35)
> Anton Khirnov:
> > Demuxers are not allowed to do this and few callers, if any, will handle
> > this correctly. Send the AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE side data
> > instead.
> 
> 1. One of the callers which did not handle this correctly is the mov
> demuxer: A sample rate update would not propagate to the user, because
> it uses a separate AVFormatContext for it. This should be mentioned in
> the commit message. (Btw: I don't see anything that guarantees that the
> samplerate and timebase of the inner demuxer and the sample rate and
> time base reported to the user (presumably taken from mov structures)
> coincide. Given that dv_fctx and dv_demux are part of MOVContext, they
> would also leak if it would be attempted to allocate them multiple
> times. Do you see anything that guarantees that they will not be
> allocated multiple times?)
> 2. In case of ff_add_param_change() failure, users will just interpret
> that as "no more packets available", won't they?

yes, I think so

> This might be wrong, but it is not problematic.

I agree

> 3. Have you tested this with a sample with actual parameter changes?

Yes, I made a sample by concatenating two dv files. The side data is
exported correctly, but the PCM decoder fails because it is not marked
with AV_CODEC_CAP_PARAM_CHANGE. Patches welcome.

-- 
Anton Khirnov
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v3 2/3] lavf/dashdec: Multithreaded DASH initialization

2022-08-30 Thread Andreas Rheinhardt
Lukas Fellechner:
> 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 | 351 +-
>  1 file changed, 350 insertions(+), 1 deletion(-)
> 
> diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c
> index e82da45e43..20f2557ea3 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;
> @@ -2033,6 +2036,331 @@ static void move_metadata(AVStream *st, const char 
> *key, char **value)
>  }
>  }
> 
> +#if HAVE_THREADS
> +
> +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

This is against our naming conventions: CamelCase for struct tags and
typedefs, lowercase names with underscore for variable names.

> +{
> +pthread_t thread;
> +pthread_mutex_t *mutex;
> +struct work_pool_data *work_pool;
> +int work_pool_size;
> +int is_started;
> +int has_error;
> +};
> +
> +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 unless there was an error
> +pthread_mutex_lock(thread_data->mutex);
> +data = NULL;
> +if (!thread_data->has_error) {
> +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;
> +
> +// notify error to other threads and exit
> +if (ret < 0) {
> +pthread_mutex_lock(thread_data->mutex);
> +thread_data->has_error = 1;
> +pthread_mutex_unlock(thread_data->mutex);
> +return NULL;
> +}
> +}
> +
> +
> +return NULL;
> +}
> +
> +static void create_work_pool_data(AVFormatContext *ctx, int stream_index,
> +struct representation *pls, struct representation *common_pls,
> +struct work_pool_data *init_data, pthread_mutex_t *common_mutex,
> +pthread_cond_t *common_condition)
> +{
> +init_data->ctx = ctx;
> +init_data->pls = pls;
> +init_data->pls->stream_index = stream_index;
> +init_data->common_condition = common_condition;
> +init_data->common_mutex = common_mutex;
> +init_data->result = -1;
> +
> +if (pls == common_pls) {
> +init_data->is_common = 1;
> +}
> +else if (common_pls) {
> +init_data->common_pls = common_pls;
> +}
> +}
> +
> +static int start_thread(struct thread_data *thread_data,
> +struct work_pool_data *work_pool, int 

[FFmpeg-devel] [PATCH] lavf/dv: return a meaningful error code from avpriv_dv_produce_packet()

2022-08-30 Thread Anton Khirnov
---
 libavformat/dv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/dv.c b/libavformat/dv.c
index f88fe62349..c888111789 100644
--- a/libavformat/dv.c
+++ b/libavformat/dv.c
@@ -404,7 +404,7 @@ int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket 
*pkt,
 if (buf_size < DV_PROFILE_BYTES ||
 !(c->sys = av_dv_frame_profile(c->sys, buf, buf_size)) ||
 buf_size < c->sys->frame_size) {
-return -1;   /* Broken frame, or not enough data */
+return AVERROR_INVALIDDATA;
 }
 
 /* Queueing audio packet */
-- 
2.35.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] lavf/mov: avoid leaks with multiple dv-audio streams

2022-08-30 Thread Anton Khirnov
---
 libavformat/mov.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/libavformat/mov.c b/libavformat/mov.c
index a2b429e52f..f433746192 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -2430,6 +2430,11 @@ static int mov_finalize_stsd_codec(MOVContext *c, 
AVIOContext *pb,
 switch (st->codecpar->codec_id) {
 #if CONFIG_DV_DEMUXER
 case AV_CODEC_ID_DVAUDIO:
+if (c->dv_fctx) {
+avpriv_request_sample(c->fc, "multiple DV audio streams");
+return AVERROR(ENOSYS);
+}
+
 c->dv_fctx = avformat_alloc_context();
 if (!c->dv_fctx) {
 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
-- 
2.35.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 12/18] lavf/dv: make returning the video packet optional

2022-08-30 Thread Anton Khirnov
Quoting Andreas Rheinhardt (2022-08-24 18:03:05)
> Anton Khirnov:
> > The mov demuxer only returns DV audio, video packets are discarded.
> > 
> > It first reads the data to be parsed into a packet. Then both this
> > packet and the pointer to its data are passed together to
> > avpriv_dv_produce_packet(), which parses the data and partially
> > overwrites the packet. This is confusing and potentially dangerous, so
> > just pass NULL and avoid pointless packet modification.
> > ---
> >  libavformat/dv.c  | 19 +++
> >  libavformat/mov.c |  2 +-
> >  2 files changed, 12 insertions(+), 9 deletions(-)
> > 
> > diff --git a/libavformat/dv.c b/libavformat/dv.c
> > index 303cecf9bb..f88fe62349 100644
> > --- a/libavformat/dv.c
> > +++ b/libavformat/dv.c
> > @@ -430,14 +430,17 @@ int avpriv_dv_produce_packet(DVDemuxContext *c, 
> > AVPacket *pkt,
> >  }
> >  }
> >  
> > -/* Now it's time to return video packet */
> > -size = dv_extract_video_info(c, buf);
> > -pkt->data = buf;
> > -pkt->pos  = pos;
> > -pkt->size = size;
> > -pkt->flags   |= AV_PKT_FLAG_KEY;
> > -pkt->stream_index = c->vst->index;
> > -pkt->pts  = c->frames;
> > +/* return the video packet, if the caller wants it */
> > +if (pkt) {
> > +size = dv_extract_video_info(c, buf);
> > +
> > +pkt->data = buf;
> > +pkt->pos  = pos;
> > +pkt->size = size;
> > +pkt->flags   |= AV_PKT_FLAG_KEY;
> > +pkt->stream_index = c->vst->index;
> > +pkt->pts  = c->frames;
> > +}
> >  
> >  c->frames++;
> >  
> > diff --git a/libavformat/mov.c b/libavformat/mov.c
> > index 1d8c5b2904..a2b429e52f 100644
> > --- a/libavformat/mov.c
> > +++ b/libavformat/mov.c
> > @@ -8768,7 +8768,7 @@ static int mov_read_packet(AVFormatContext *s, 
> > AVPacket *pkt)
> >  }
> >  #if CONFIG_DV_DEMUXER
> >  if (mov->dv_demux && sc->dv_audio_container) {
> > -ret = avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, 
> > pkt->size, pkt->pos);
> > +ret = avpriv_dv_produce_packet(mov->dv_demux, NULL, pkt->data, 
> > pkt->size, pkt->pos);
> >  av_packet_unref(pkt);
> >  if (ret < 0)
> >  return ret;
> 
> 1. LGTM.
> 2. The way mov handles dv audio is very broken:
> a) I don't see anything that guarantees that the
> samplerate of the inner demuxer and the sample rate reported to the user
> (presumably taken from mov structures) coincide.
> b) dv_fctx and dv_demux are part of MOVContext, not MOVStreamContext. If
> there were multiple MOVStreams with dv-audio, the older dv_fctx and
> dv_demux would leak. Do you see anything that guarantees that they will
>  only be at most one MOVStream for dv-audio?

Not that I can see. I'd say the best thing to do here is fail when a
dvaudio stream already exists - trying to support it without having any
valid samples seems pointless. I'll send a patch.

> c) The former would be easily fixable by moving the fields to
> MOVStreamContext. But there is actually another bug: The underlying dv
> stream can contain multiple audio streams in this one MOVStream and only
> the first of these is forwarded.
> https://samples.ffmpeg.org/ffmpeg-bugs/trac/ticket4671/dir1.tar.bz2
> contains a sample where this actually occurs: The DV stream has two
> stereo tracks, only the first of which is forwarded (use -enable_drefs 1
> to be able to play it; the non-forwarded seems to be silent in this
> case). Are these actually independent audios or are these stereo pairs
> part of a single streams with more than two channels?

Cannot answer this. I would ignore this until and unless someone
actually comes complaining about this.

-- 
Anton Khirnov
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v3 1/3] lavf/dashdec: Prepare DASH decoder for multithreading

2022-08-30 Thread Steven Liu
Lukas Fellechner  于2022年8月24日周三 03:04写道:
>
> For adding multithreading to the DASH decoder initialization,
> the open_demux_for_component() method must be split up into two parts:
>
> begin_open_demux_for_component(): Opens the stream and does probing
> and format detection. This can be run in parallel.
>
> end_open_demux_for_component(): Creates the AVStreams and adds
> them to the common parent AVFormatContext. This method must always be
> run synchronously, after all threads are finished.
> ---
>  libavformat/dashdec.c | 42 ++
>  1 file changed, 30 insertions(+), 12 deletions(-)
>
> diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c
> index 63bf7e96a5..e82da45e43 100644
> --- a/libavformat/dashdec.c
> +++ b/libavformat/dashdec.c
> @@ -1918,10 +1918,9 @@ fail:
>  return ret;
>  }
>
> -static int open_demux_for_component(AVFormatContext *s, struct 
> representation *pls)
> +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);
> @@ -1931,9 +1930,15 @@ static int open_demux_for_component(AVFormatContext 
> *s, struct representation *p
>  }
>
>  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];
> @@ -1965,6 +1970,19 @@ fail:
>  return ret;
>  }
>
> +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 is_common_init_section_exist(struct representation **pls, int 
> n_pls)
>  {
>  struct fragment *first_init_section = pls[0]->init_section;
> @@ -2040,9 +2058,15 @@ static int dash_read_header(AVFormatContext *s)
>  av_dict_set(>avio_opts, "seekable", "0", 0);
>  }
>
> -if(c->n_videos)
> +if (c->n_videos)
>  c->is_init_section_common_video = 
> is_common_init_section_exist(c->videos, c->n_videos);
>
> +if (c->n_audios)
> +c->is_init_section_common_audio = 
> is_common_init_section_exist(c->audios, c->n_audios);
> +
> +if (c->n_subtitles)
> +c->is_init_section_common_subtitle = 
> is_common_init_section_exist(c->subtitles, c->n_subtitles);
> +
>  /* Open the demuxer for video and audio components if available */
>  for (i = 0; i < c->n_videos; i++) {
>  rep = c->videos[i];
> @@ -2059,9 +2083,6 @@ static int dash_read_header(AVFormatContext *s)
>  ++stream_index;
>  }
>
> -if(c->n_audios)
> -c->is_init_section_common_audio = 
> is_common_init_section_exist(c->audios, c->n_audios);
> -
>  for (i = 0; i < c->n_audios; i++) {
>  rep = c->audios[i];
>  if (i > 0 && c->is_init_section_common_audio) {
> @@ -2077,9 +2098,6 @@ static int dash_read_header(AVFormatContext *s)
>  ++stream_index;
>  }
>
> -if (c->n_subtitles)
> -c->is_init_section_common_subtitle = 
> is_common_init_section_exist(c->subtitles, c->n_subtitles);
> -
>  for (i = 0; i < c->n_subtitles; i++) {
>  rep = c->subtitles[i];
>  if (i > 0 && c->is_init_section_common_subtitle) {
> --
> 2.31.1.windows.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".

Patchset looks ok and test passed here. Any comments?


Thanks
Steven
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v5 00/25] Subtitle Filtering 2022

2022-08-30 Thread Anton Khirnov
Quoting Soft Works (2022-08-27 00:48:01)
> 2. "There's no reason why this cannot be handled using the buffer
> and data fields"
> 
> I had explained the reasons and in conversation on IRC, Lynne was
> no longer insisting on this AFAIR.

I did not see this explanation, can you restate it here?

If you claim the other points were addressed I will look at the patches
again.

-- 
Anton Khirnov
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v3 1/3] lavc/decode: Warp get_hw_config function

2022-08-30 Thread Wang, Fei W
On Tue, 2022-08-23 at 16:19 +0800, Fei Wang wrote:
> From: Linjie Fu 
> 
> Wrap the procedure of getting the hardware config from a pixel format
> into a function.
> 
> Signed-off-by: Linjie Fu 
> Signed-off-by: Fei Wang 
> ---
>  libavcodec/decode.c | 31 +++
>  1 file changed, 19 insertions(+), 12 deletions(-)
> 
> diff --git a/libavcodec/decode.c b/libavcodec/decode.c
> index 75373989c6..3b69426c09 100644
> --- a/libavcodec/decode.c
> +++ b/libavcodec/decode.c
> @@ -1156,6 +1156,24 @@ static void hwaccel_uninit(AVCodecContext
> *avctx)
>  av_buffer_unref(>hw_frames_ctx);
>  }
>  
> +static const AVCodecHWConfigInternal *get_hw_config(AVCodecContext
> *avctx, enum AVPixelFormat fmt)
> +{
> +const AVCodecHWConfigInternal *hw_config;
> +
> +if (!ffcodec(avctx->codec)->hw_configs)
> +return NULL;
> +
> +for (int i = 0;; i++) {
> +hw_config = ffcodec(avctx->codec)->hw_configs[i];
> +if (!hw_config)
> +return NULL;
> +if (hw_config->public.pix_fmt == fmt)
> +return hw_config;
> +}
> +
> +return NULL;
> +}
> +
>  int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat
> *fmt)
>  {
>  const AVPixFmtDescriptor *desc;
> @@ -1213,18 +1231,7 @@ int ff_get_format(AVCodecContext *avctx, const
> enum AVPixelFormat *fmt)
>  break;
>  }
>  
> -if (ffcodec(avctx->codec)->hw_configs) {
> -for (i = 0;; i++) {
> -hw_config = ffcodec(avctx->codec)->hw_configs[i];
> -if (!hw_config)
> -break;
> -if (hw_config->public.pix_fmt == user_choice)
> -break;
> -}
> -} else {
> -hw_config = NULL;
> -}
> -
> +hw_config = get_hw_config(avctx, user_choice);
>  if (!hw_config) {
>  // No config available, so no extra setup required.
>  ret = user_choice;

Ping, any more comments on V3?

Thanks
Fei

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 3/3 v2] avformat/avisynth: reindent

2022-08-30 Thread Stephen Hutchinson
Signed-off-by: Stephen Hutchinson 
---
 libavformat/avisynth.c | 348 -
 1 file changed, 174 insertions(+), 174 deletions(-)

diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c
index 7bb2977383..b426ac343e 100644
--- a/libavformat/avisynth.c
+++ b/libavformat/avisynth.c
@@ -533,235 +533,235 @@ static int avisynth_create_stream_video(AVFormatContext 
*s, AVStream *st)
 
 /* Field order */
 if(avs->flags & AVISYNTH_FRAMEPROP_FIELD_ORDER) {
-if(avs_library.avs_prop_get_type(avs->env, avsmap, "_FieldBased") == 
AVS_PROPTYPE_UNSET) {
-st->codecpar->field_order = AV_FIELD_UNKNOWN;
-} else {
-switch (avs_library.avs_prop_get_int(avs->env, avsmap, 
"_FieldBased", 0, )) {
-case 0:
-st->codecpar->field_order = AV_FIELD_PROGRESSIVE;
-break;
-case 1:
-st->codecpar->field_order = AV_FIELD_BB;
-break;
-case 2:
-st->codecpar->field_order = AV_FIELD_TT;
-break;
-default:
+if(avs_library.avs_prop_get_type(avs->env, avsmap, "_FieldBased") 
== AVS_PROPTYPE_UNSET) {
 st->codecpar->field_order = AV_FIELD_UNKNOWN;
+} else {
+switch (avs_library.avs_prop_get_int(avs->env, avsmap, 
"_FieldBased", 0, )) {
+case 0:
+st->codecpar->field_order = AV_FIELD_PROGRESSIVE;
+break;
+case 1:
+st->codecpar->field_order = AV_FIELD_BB;
+break;
+case 2:
+st->codecpar->field_order = AV_FIELD_TT;
+break;
+default:
+st->codecpar->field_order = AV_FIELD_UNKNOWN;
+}
 }
 }
-}
 
 /* Color Range */
 if(avs->flags & AVISYNTH_FRAMEPROP_RANGE) {
-if(avs_library.avs_prop_get_type(avs->env, avsmap, "_ColorRange") == 
AVS_PROPTYPE_UNSET) {
-st->codecpar->color_range = AVCOL_RANGE_UNSPECIFIED;
-} else {
-switch (avs_library.avs_prop_get_int(avs->env, avsmap, 
"_ColorRange", 0, )) {
-case 0:
-st->codecpar->color_range = AVCOL_RANGE_JPEG;
-break;
-case 1:
-st->codecpar->color_range = AVCOL_RANGE_MPEG;
-break;
-default:
+if(avs_library.avs_prop_get_type(avs->env, avsmap, "_ColorRange") 
== AVS_PROPTYPE_UNSET) {
 st->codecpar->color_range = AVCOL_RANGE_UNSPECIFIED;
+} else {
+switch (avs_library.avs_prop_get_int(avs->env, avsmap, 
"_ColorRange", 0, )) {
+case 0:
+st->codecpar->color_range = AVCOL_RANGE_JPEG;
+break;
+case 1:
+st->codecpar->color_range = AVCOL_RANGE_MPEG;
+break;
+default:
+st->codecpar->color_range = AVCOL_RANGE_UNSPECIFIED;
+}
 }
 }
-}
 
 /* Color Primaries */
 if(avs->flags & AVISYNTH_FRAMEPROP_PRIMARIES) {
-switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_Primaries", 
0, )) {
-case 1:
-st->codecpar->color_primaries = AVCOL_PRI_BT709;
-break;
-case 2:
-st->codecpar->color_primaries = AVCOL_PRI_UNSPECIFIED;
-break;
-case 4:
-st->codecpar->color_primaries = AVCOL_PRI_BT470M;
-break;
-case 5:
-st->codecpar->color_primaries = AVCOL_PRI_BT470BG;
-break;
-case 6:
-st->codecpar->color_primaries = AVCOL_PRI_SMPTE170M;
-break;
-case 7:
-st->codecpar->color_primaries = AVCOL_PRI_SMPTE240M;
-break;
-case 8:
-st->codecpar->color_primaries = AVCOL_PRI_FILM;
-break;
-case 9:
-st->codecpar->color_primaries = AVCOL_PRI_BT2020;
-break;
-case 10:
-st->codecpar->color_primaries = AVCOL_PRI_SMPTE428;
-break;
-case 11:
-st->codecpar->color_primaries = AVCOL_PRI_SMPTE431;
-break;
-case 12:
-st->codecpar->color_primaries = AVCOL_PRI_SMPTE432;
-break;
-case 22:
-st->codecpar->color_primaries = AVCOL_PRI_EBU3213;
-break;
-default:
-st->codecpar->color_primaries = AVCOL_PRI_UNSPECIFIED;
-}
+switch (avs_library.avs_prop_get_int(avs->env, avsmap, 
"_Primaries", 0, )) {
+case 1:
+st->codecpar->color_primaries = AVCOL_PRI_BT709;
+break;
+case 2:
+st->codecpar->color_primaries = AVCOL_PRI_UNSPECIFIED;
+

[FFmpeg-devel] [PATCH 2/3 v2] avformat/avisynth: implement avisynth_flags option

2022-08-30 Thread Stephen Hutchinson
Signed-off-by: Stephen Hutchinson 
---
 libavformat/avisynth.c | 52 ++
 1 file changed, 52 insertions(+)

diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c
index d978e6ec40..7bb2977383 100644
--- a/libavformat/avisynth.c
+++ b/libavformat/avisynth.c
@@ -21,6 +21,7 @@
 
 #include "libavutil/attributes.h"
 #include "libavutil/internal.h"
+#include "libavutil/opt.h"
 
 #include "libavcodec/internal.h"
 
@@ -85,7 +86,18 @@ typedef struct AviSynthLibrary {
 #undef AVSC_DECLARE_FUNC
 } AviSynthLibrary;
 
+typedef enum AviSynthFlags {
+AVISYNTH_FRAMEPROP_FIELD_ORDER = (1 << 0),
+AVISYNTH_FRAMEPROP_RANGE = (1 << 1),
+AVISYNTH_FRAMEPROP_PRIMARIES = (1 << 2),
+AVISYNTH_FRAMEPROP_TRANSFER = (1 << 3),
+AVISYNTH_FRAMEPROP_MATRIX = (1 << 4),
+AVISYNTH_FRAMEPROP_CHROMA_LOCATION = (1 << 5),
+AVISYNTH_FRAMEPROP_SAR = (1 << 6),
+} AviSynthFlags;
+
 typedef struct AviSynthContext {
+const AVClass *class;
 AVS_ScriptEnvironment *env;
 AVS_Clip *clip;
 const AVS_VideoInfo *vi;
@@ -100,6 +112,8 @@ typedef struct AviSynthContext {
 
 int error;
 
+uint32_t flags;
+
 /* Linked list pointers. */
 struct AviSynthContext *next;
 } AviSynthContext;
@@ -518,6 +532,7 @@ static int avisynth_create_stream_video(AVFormatContext *s, 
AVStream *st)
 avsmap = avs_library.avs_get_frame_props_ro(avs->env, frame);
 
 /* Field order */
+if(avs->flags & AVISYNTH_FRAMEPROP_FIELD_ORDER) {
 if(avs_library.avs_prop_get_type(avs->env, avsmap, "_FieldBased") == 
AVS_PROPTYPE_UNSET) {
 st->codecpar->field_order = AV_FIELD_UNKNOWN;
 } else {
@@ -535,8 +550,10 @@ static int avisynth_create_stream_video(AVFormatContext 
*s, AVStream *st)
 st->codecpar->field_order = AV_FIELD_UNKNOWN;
 }
 }
+}
 
 /* Color Range */
+if(avs->flags & AVISYNTH_FRAMEPROP_RANGE) {
 if(avs_library.avs_prop_get_type(avs->env, avsmap, "_ColorRange") == 
AVS_PROPTYPE_UNSET) {
 st->codecpar->color_range = AVCOL_RANGE_UNSPECIFIED;
 } else {
@@ -551,8 +568,10 @@ static int avisynth_create_stream_video(AVFormatContext 
*s, AVStream *st)
 st->codecpar->color_range = AVCOL_RANGE_UNSPECIFIED;
 }
 }
+}
 
 /* Color Primaries */
+if(avs->flags & AVISYNTH_FRAMEPROP_PRIMARIES) {
 switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_Primaries", 
0, )) {
 case 1:
 st->codecpar->color_primaries = AVCOL_PRI_BT709;
@@ -593,8 +612,10 @@ static int avisynth_create_stream_video(AVFormatContext 
*s, AVStream *st)
 default:
 st->codecpar->color_primaries = AVCOL_PRI_UNSPECIFIED;
 }
+}
 
 /* Color Transfer Characteristics */
+if(avs->flags & AVISYNTH_FRAMEPROP_TRANSFER) {
 switch (avs_library.avs_prop_get_int(avs->env, avsmap, "_Transfer", 0, 
)) {
 case 1:
 st->codecpar->color_trc = AVCOL_TRC_BT709;
@@ -650,8 +671,10 @@ static int avisynth_create_stream_video(AVFormatContext 
*s, AVStream *st)
 default:
 st->codecpar->color_trc = AVCOL_TRC_UNSPECIFIED;
 }
+}
 
 /* Matrix coefficients */
+if(avs->flags & AVISYNTH_FRAMEPROP_MATRIX) {
 if(avs_library.avs_prop_get_type(avs->env, avsmap, "_Matrix") == 
AVS_PROPTYPE_UNSET) {
 st->codecpar->color_space = AVCOL_SPC_UNSPECIFIED;
 } else {
@@ -702,8 +725,10 @@ static int avisynth_create_stream_video(AVFormatContext 
*s, AVStream *st)
 st->codecpar->color_space = AVCOL_SPC_UNSPECIFIED;
 }
 }
+}
 
 /* Chroma Location */
+if(avs->flags & AVISYNTH_FRAMEPROP_CHROMA_LOCATION) {
 if(avs_library.avs_prop_get_type(avs->env, avsmap, "_ChromaLocation") 
== AVS_PROPTYPE_UNSET) {
 st->codecpar->chroma_location = AVCHROMA_LOC_UNSPECIFIED;
 } else {
@@ -730,11 +755,14 @@ static int avisynth_create_stream_video(AVFormatContext 
*s, AVStream *st)
 st->codecpar->chroma_location = AVCHROMA_LOC_UNSPECIFIED;
 }
 }
+}
 
 /* Sample aspect ratio */
+if(avs->flags & AVISYNTH_FRAMEPROP_SAR) {
 sar_num = avs_library.avs_prop_get_int(avs->env, avsmap, "_SARNum", 0, 
);
 sar_den = avs_library.avs_prop_get_int(avs->env, avsmap, "_SARDen", 0, 
);
 st->sample_aspect_ratio = (AVRational){ sar_num, sar_den };
+}
 
 avs_library.avs_release_video_frame(frame);
 } else {
@@ -1140,6 +1168,29 @@ static int avisynth_read_seek(AVFormatContext *s, int 
stream_index,
 return 0;
 }
 
+#define AVISYNTH_FRAMEPROP_DEFAULT AVISYNTH_FRAMEPROP_FIELD_ORDER | 
AVISYNTH_FRAMEPROP_RANGE | \
+   AVISYNTH_FRAMEPROP_PRIMARIES | 
AVISYNTH_FRAMEPROP_TRANSFER | \
+   

[FFmpeg-devel] [PATCH 1/3 v2] avformat/avisynth: read _SARNum/_SARDen from frame properties

2022-08-30 Thread Stephen Hutchinson
Initialized to 1:1, but if the script sets these properties, it
will be set to those instead (0:0 disables it, apparently).

Signed-off-by: Stephen Hutchinson 
---
 libavformat/avisynth.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c
index 3d9fa2be50..d978e6ec40 100644
--- a/libavformat/avisynth.c
+++ b/libavformat/avisynth.c
@@ -251,6 +251,8 @@ static int avisynth_create_stream_video(AVFormatContext *s, 
AVStream *st)
 AVS_VideoFrame *frame;
 int error;
 int planar = 0; // 0: packed, 1: YUV, 2: Y8, 3: Planar RGB, 4: YUVA, 5: 
Planar RGBA
+int sar_num = 1;
+int sar_den = 1;
 
 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
 st->codecpar->codec_id   = AV_CODEC_ID_RAWVIDEO;
@@ -728,6 +730,12 @@ static int avisynth_create_stream_video(AVFormatContext 
*s, AVStream *st)
 st->codecpar->chroma_location = AVCHROMA_LOC_UNSPECIFIED;
 }
 }
+
+/* Sample aspect ratio */
+sar_num = avs_library.avs_prop_get_int(avs->env, avsmap, "_SARNum", 0, 
);
+sar_den = avs_library.avs_prop_get_int(avs->env, avsmap, "_SARDen", 0, 
);
+st->sample_aspect_ratio = (AVRational){ sar_num, sar_den };
+
 avs_library.avs_release_video_frame(frame);
 } else {
 st->codecpar->field_order = AV_FIELD_UNKNOWN;
-- 
2.34.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 0/3 v2] avisynth: add user-selectable flags

2022-08-30 Thread Stephen Hutchinson
The reading of frame properties from the script can now be toggled
on and off per-property or as a whole, using the avisynth_flags
option.

The ability to read _SARNum/_SARDen properties has been added,
but is kept off by default because it poses more of a risk of a
user accidentally getting it wrong than the already existing properties
do, which is what prompted adding the ability to switch frame property
reading on and off.

Stephen Hutchinson (3):
  avformat/avisynth: read _SARNum/_SARDen from frame properties
  avformat/avisynth: implement avisynth_flags option
  avformat/avisynth: reindent

 libavformat/avisynth.c | 386 -
 1 file changed, 223 insertions(+), 163 deletions(-)

-- 
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 3/9] avformat/avisynth: add read_frameprops option

2022-08-30 Thread Stephen Hutchinson

On 8/30/22 7:17 PM, Andreas Rheinhardt wrote:

{ "avisynth_flags", "set flags related to reading frame properties from
script (AviSynth+ v3.7.1 or higher)", OFFSET(flags), AV_OPT_TYPE_FLAGS,
{.i64 = 1}, 0, 1, AV_OPT_FLAG_DECODING_PARAM, "flags" },

This is wrong. It should be
{ "avisynth_flags", "set flags related to reading frame properties from
script (AviSynth+ v3.7.1 or higher)", OFFSET(flags), AV_OPT_TYPE_FLAGS,
{.i64 = AVISYNTH_FRAMEPROP_FIELD_ORDER | AVISYNTH_FRAMEPROP_RANGE |
AVISYNTH_FRAMEPROP_PRIMARIES | AVISYNTH_FRAMEPROP_TRANSFER |
AVISYNTH_FRAMEPROP_MATRIX | AVISYNTH_FRAMEPROP_CHROMA_LOCATION}, 0,
INT_MAX, AV_OPT_FLAG_DECODING_PARAM, "flags" }
The default option should be removed. Users can then set the options via
avisynth_flags=+sar-range or via avisynth_flags=matrix or however they wish.
The AVISYNTH_FRAMEPROP_DEFAULT should also be removed (at least, it
should not be part of the bitfield, but you can of course add a define
(or an enum value) equivalent to the default value I used above and you
can use that for the default value above); to know whether field order
should be exported, you simply query via "if (avs->flags &
AVISYNTH_FRAMEPROP_FIELD_ORDER)". For this it is of course important
that the default value is a combination of other bits of the bitfield
and not a bit of its own.



I don't know why I didn't think to use it directly in the avisynth_flags
line.  Thanks.
___
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] avformat/asfdec_o: limit recursion depth in asf_read_unknown()

2022-08-30 Thread Michael Niedermayer
The threshold of 5 is arbitrary, both smaller and larger should work fine

Fixes: Stack overflow
Fixes: 
50603/clusterfuzz-testcase-minimized-ffmpeg_dem_ASF_O_fuzzer-6049302564175872

Found-by: continuous fuzzing process 
https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer 
---
 libavformat/asfdec_o.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/libavformat/asfdec_o.c b/libavformat/asfdec_o.c
index 907be6de04f..48b7d17322d 100644
--- a/libavformat/asfdec_o.c
+++ b/libavformat/asfdec_o.c
@@ -109,6 +109,7 @@ typedef struct ASFContext {
 int64_t data_offset;
 int64_t first_packet_offset; // packet offset
 int64_t unknown_offset;   // for top level header objects or subobjects 
without specified behavior
+int in_asf_read_unknown;
 
 // ASF file must not contain more than 128 streams according to the 
specification
 ASFStream *asf_st[ASF_MAX_STREAMS];
@@ -173,7 +174,7 @@ static int asf_read_unknown(AVFormatContext *s, const 
GUIDParseTable *g)
 uint64_t size   = avio_rl64(pb);
 int ret;
 
-if (size > INT64_MAX)
+if (size > INT64_MAX || asf->in_asf_read_unknown > 5)
 return AVERROR_INVALIDDATA;
 
 if (asf->is_header)
@@ -182,8 +183,11 @@ static int asf_read_unknown(AVFormatContext *s, const 
GUIDParseTable *g)
 if (!g->is_subobject) {
 if (!(ret = strcmp(g->name, "Header Extension")))
 avio_skip(pb, 22); // skip reserved fields and Data Size
-if ((ret = detect_unknown_subobject(s, asf->unknown_offset,
-asf->unknown_size)) < 0)
+asf->in_asf_read_unknown ++;
+ret = detect_unknown_subobject(s, asf->unknown_offset,
+asf->unknown_size);
+asf->in_asf_read_unknown --;
+if (ret < 0)
 return ret;
 } else {
 if (size < 24) {
-- 
2.17.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH 3/9] avformat/avisynth: add read_frameprops option

2022-08-30 Thread Andreas Rheinhardt
Stephen Hutchinson:
> On 8/28/22 8:41 PM, Andreas Rheinhardt wrote:
>> This will make frameprops a global on-off which overrides everything
>> else even if some of the "else" stuff has been enabled explicitly. Worse
>> yet, if you want to disable everything except exactly one field, you
>> have to leave frameprops enabled and disable everything else explicitly.
>>
>> Why not use a bitfield (with AV_OPT_TYPE_FLAGS and AV_OPT_TYPE_CONST)?
>> These properties certainly seem like a bitfield and the above would be
>> easily achievable with it.
>>
> 
> How are flags supposed to be set to on by default? With av_dict_set or
> a different mechanism?  Because the closest I was able to get¹,
> 
> if(avs->flags & AVISYNTH_FRAMEPROP_FIELD_ORDER |
> AVISYNTH_FRAMEPROP_DEFAULT) {
> 
> ends up correctly setting the flags that should be on by default,
> with the new sar flag able to be enabled or disabled, but the ones
> flagged as default refuse to be disabled now.
> 
> ¹https://github.com/qyot27/FFmpeg/commit/6d3d6108145f9c7ac2dfcdaf09852b7472f6ca7f
> 

{ "avisynth_flags", "set flags related to reading frame properties from
script (AviSynth+ v3.7.1 or higher)", OFFSET(flags), AV_OPT_TYPE_FLAGS,
{.i64 = 1}, 0, 1, AV_OPT_FLAG_DECODING_PARAM, "flags" },

This is wrong. It should be
{ "avisynth_flags", "set flags related to reading frame properties from
script (AviSynth+ v3.7.1 or higher)", OFFSET(flags), AV_OPT_TYPE_FLAGS,
{.i64 = AVISYNTH_FRAMEPROP_FIELD_ORDER | AVISYNTH_FRAMEPROP_RANGE |
AVISYNTH_FRAMEPROP_PRIMARIES | AVISYNTH_FRAMEPROP_TRANSFER |
AVISYNTH_FRAMEPROP_MATRIX | AVISYNTH_FRAMEPROP_CHROMA_LOCATION}, 0,
INT_MAX, AV_OPT_FLAG_DECODING_PARAM, "flags" }
The default option should be removed. Users can then set the options via
avisynth_flags=+sar-range or via avisynth_flags=matrix or however they wish.
The AVISYNTH_FRAMEPROP_DEFAULT should also be removed (at least, it
should not be part of the bitfield, but you can of course add a define
(or an enum value) equivalent to the default value I used above and you
can use that for the default value above); to know whether field order
should be exported, you simply query via "if (avs->flags &
AVISYNTH_FRAMEPROP_FIELD_ORDER)". For this it is of course important
that the default value is a combination of other bits of the bitfield
and not a bit of its own.

- Andreas
___
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 3/9] avformat/avisynth: add read_frameprops option

2022-08-30 Thread Stephen Hutchinson

On 8/28/22 8:41 PM, Andreas Rheinhardt wrote:

This will make frameprops a global on-off which overrides everything
else even if some of the "else" stuff has been enabled explicitly. Worse
yet, if you want to disable everything except exactly one field, you
have to leave frameprops enabled and disable everything else explicitly.

Why not use a bitfield (with AV_OPT_TYPE_FLAGS and AV_OPT_TYPE_CONST)?
These properties certainly seem like a bitfield and the above would be
easily achievable with it.



How are flags supposed to be set to on by default? With av_dict_set or
a different mechanism?  Because the closest I was able to get¹,

if(avs->flags & AVISYNTH_FRAMEPROP_FIELD_ORDER | 
AVISYNTH_FRAMEPROP_DEFAULT) {


ends up correctly setting the flags that should be on by default,
with the new sar flag able to be enabled or disabled, but the ones
flagged as default refuse to be disabled now.

¹https://github.com/qyot27/FFmpeg/commit/6d3d6108145f9c7ac2dfcdaf09852b7472f6ca7f
___
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] lavu: header and documentation for AVWriter

2022-08-30 Thread Nicolas George
Leo Izen (12022-08-30):
> Is there a reason this is AVWriter wr = foo() and not AVWriter *wr = foo()?
> Most other APIs return pointers to structs, rather than structs themselves
> (see: av_packet_alloc). Using a pointer would prevent us from having
> sizeof(AVWriter) as part of the ABI, as was done with AVPacket.

Yes: to return a pointer, you need somewhere to store the structure. One
of the point of AVWriter is that you can store it on the stack to avoid
dynamic allocations when the string is short enough.

Note that AVWriter is exactly two pointers. It will always be two
pointers, and all the objects that I intend to introduce later will
always be two pointers: one const pointer for the methods, one pointer
for the object itself.

This design is essential to the features I promised for AVWriter and for
later.

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] lavu: header and documentation for AVWriter

2022-08-30 Thread Leo Izen



On 8/24/22 11:18, Nicolas George wrote:

+```
+AVWriter wr = av_dynbuf_writer();
+av_something_write(wr, something, 0);
+if (av_writer_get_error(wr, 0) < 0)
+die("Failed");
+use_string(av_dynbuf_writer_get_data(wr, NULL));
+av_dynbuf_writer_finalize(wr, NULL, NULL);
+```


Is there a reason this is AVWriter wr = foo() and not AVWriter *wr = 
foo()? Most other APIs return pointers to structs, rather than structs 
themselves (see: av_packet_alloc). Using a pointer would prevent us from 
having sizeof(AVWriter) as part of the ABI, as was done with AVPacket.


- Leo Izen (thebombzen)
___
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 1/3] fftools/cmdutils: Add function to report error before exit

2022-08-30 Thread Andreas Rheinhardt
Andreas Rheinhardt:
> This is designed to improve and unify error handling for
> allocation failures for the many (often small) allocations that we have
> in the fftools. These typically either don't return an error message
> or an error message that is not really helpful to the user
> and can be replaced by a generic error message without loss of
> information.
> 
> Reviewed-by: James Almer 
> Signed-off-by: Andreas Rheinhardt 
> ---
>  fftools/cmdutils.c |  6 ++
>  fftools/cmdutils.h | 11 +++
>  2 files changed, 17 insertions(+)
> 
> diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c
> index 18e768b386..da3d391694 100644
> --- a/fftools/cmdutils.c
> +++ b/fftools/cmdutils.c
> @@ -90,6 +90,12 @@ void register_exit(void (*cb)(int ret))
>  program_exit = cb;
>  }
>  
> +void report_and_exit(int ret)
> +{
> +av_log(NULL, AV_LOG_FATAL, "%s\n", av_err2str(ret));
> +exit_program(AVUNERROR(ret));
> +}
> +
>  void exit_program(int ret)
>  {
>  if (program_exit)
> diff --git a/fftools/cmdutils.h b/fftools/cmdutils.h
> index d87e162ccd..4496221983 100644
> --- a/fftools/cmdutils.h
> +++ b/fftools/cmdutils.h
> @@ -54,6 +54,17 @@ extern int hide_banner;
>   */
>  void register_exit(void (*cb)(int ret));
>  
> +/**
> + * Reports an error corresponding to the provided
> + * AVERROR code and calls exit_program() with the
> + * corresponding POSIX error code.
> + * @note ret must be an AVERROR-value of a POSIX error code
> + *   (i.e. AVERROR(EFOO) and not AVERROR_FOO).
> + *   library functions can return both, so call this only
> + *   with AVERROR(EFOO) of your own.
> + */
> +void report_and_exit(int ret) av_noreturn;
> +
>  /**
>   * Wraps exit with a program-specific cleanup routine.
>   */

Will apply tonight unless there are objections.

- Andreas
___
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] lavu: header and documentation for AVWriter

2022-08-30 Thread Nicolas George
Nicolas George (12022-08-24):
> The actual implementation, tests and uses in the rest of
> FFmpeg code will be committed separately once the API is
> settled.
> 
> Signed-off-by: Nicolas George 
> ---
>  doc/avwriter_intro.md | 109 ++
>  libavutil/writer.h| 484 ++
>  2 files changed, 593 insertions(+)
>  create mode 100644 doc/avwriter_intro.md
>  create mode 100644 libavutil/writer.h
> 
> 
> As suggested by JB, here is the header and documentation for AVWriter,
> to discuss the principle before investing time in polishing the
> implementation. I expect to discuss the API and if no blockign
> objections are raised push it then spend time on the implementation.
> 
> This API is a nicer and much more powerful version of BPrint. It can be
> used to simplify existing code where BPrint could help, plus places
> where BPrint could not help.
> 
> It also is the prerequisite for more ambitious projects, expecially
> universal serialization of FFmpeg objects (side data and such) into
> standardized formats.
> 
> The implementation is in most part done, and I am sure I can deliver.
> What remains is the boring part of integrating the tests in FATE,
> polishing various parts, updating the parts where I changed my mind
> midway, etc.
> 
> Note: FF_NEW_SZ is a macro defined elsewhere; it is really part of the
> implementation more than the API.
> 
> 

Ping.

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] avcodec: add a bsf to reorder DTS into PTS

2022-08-30 Thread Andreas Rheinhardt
James Almer:
> On 8/30/2022 11:30 AM, Andreas Rheinhardt wrote:
>> James Almer:
>>> Starting with an h264 implementation. Can be extended to support
>>> other codecs.
>>>
>>> Addresses ticket #502.
>>>
>>> Signed-off-by: James Almer 
>>> ---
>>>   configure  |   1 +
>>>   libavcodec/Makefile    |   1 +
>>>   libavcodec/bitstream_filters.c |   1 +
>>>   libavcodec/dts2pts_bsf.c   | 477 +
>>>   4 files changed, 480 insertions(+)
>>>   create mode 100644 libavcodec/dts2pts_bsf.c
>>>
>>> diff --git a/configure b/configure
>>> index 932ea5b553..91ee5eb303 100755
>>> --- a/configure
>>> +++ b/configure
>>> @@ -3275,6 +3275,7 @@ aac_adtstoasc_bsf_select="adts_header mpeg4audio"
>>>   av1_frame_merge_bsf_select="cbs_av1"
>>>   av1_frame_split_bsf_select="cbs_av1"
>>>   av1_metadata_bsf_select="cbs_av1"
>>> +dts2pts_bsf_select="cbs_h264 h264parse"
>>>   eac3_core_bsf_select="ac3_parser"
>>>   filter_units_bsf_select="cbs"
>>>   h264_metadata_bsf_deps="const_nan"
>>> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
>>> index cb80f73d99..858e110b79 100644
>>> --- a/libavcodec/Makefile
>>> +++ b/libavcodec/Makefile
>>> @@ -1176,6 +1176,7 @@ OBJS-$(CONFIG_AV1_FRAME_SPLIT_BSF)    +=
>>> av1_frame_split_bsf.o
>>>   OBJS-$(CONFIG_CHOMP_BSF)  += chomp_bsf.o
>>>   OBJS-$(CONFIG_DUMP_EXTRADATA_BSF) += dump_extradata_bsf.o
>>>   OBJS-$(CONFIG_DCA_CORE_BSF)   += dca_core_bsf.o
>>> +OBJS-$(CONFIG_DTS2PTS_BSF)    += dts2pts_bsf.o
>>>   OBJS-$(CONFIG_DV_ERROR_MARKER_BSF)    += dv_error_marker_bsf.o
>>>   OBJS-$(CONFIG_EAC3_CORE_BSF)  += eac3_core_bsf.o
>>>   OBJS-$(CONFIG_EXTRACT_EXTRADATA_BSF)  +=
>>> extract_extradata_bsf.o    \
>>> diff --git a/libavcodec/bitstream_filters.c
>>> b/libavcodec/bitstream_filters.c
>>> index 23ae93..a3bebefe5f 100644
>>> --- a/libavcodec/bitstream_filters.c
>>> +++ b/libavcodec/bitstream_filters.c
>>> @@ -31,6 +31,7 @@ extern const FFBitStreamFilter ff_av1_metadata_bsf;
>>>   extern const FFBitStreamFilter ff_chomp_bsf;
>>>   extern const FFBitStreamFilter ff_dump_extradata_bsf;
>>>   extern const FFBitStreamFilter ff_dca_core_bsf;
>>> +extern const FFBitStreamFilter ff_dts2pts_bsf;
>>>   extern const FFBitStreamFilter ff_dv_error_marker_bsf;
>>>   extern const FFBitStreamFilter ff_eac3_core_bsf;
>>>   extern const FFBitStreamFilter ff_extract_extradata_bsf;
>>> diff --git a/libavcodec/dts2pts_bsf.c b/libavcodec/dts2pts_bsf.c
>>> new file mode 100644
>>> index 00..f600150a6b
>>> --- /dev/null
>>> +++ b/libavcodec/dts2pts_bsf.c
>>> @@ -0,0 +1,477 @@
>>> +/*
>>> + * Copyright (c) 2022 James Almer
>>> + *
>>> + * 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
>>> + * Derive PTS by reordering DTS from supported streams
>>> + */
>>> +
>>> +#include "libavutil/avassert.h"
>>> +#include "libavutil/eval.h"

Unused.

>>> +#include "libavutil/fifo.h"
>>> +#include "libavutil/opt.h"
>>> +#include "libavutil/tree.h"
>>> +
>>> +#include "bsf.h"
>>> +#include "bsf_internal.h"
>>> +#include "cbs.h"
>>> +#include "cbs_h264.h"
>>> +#include "h264_parse.h"
>>> +#include "h264_ps.h"
>>> +
>>> +typedef struct DTS2PTSNode {
>>> +    int64_t  dts;
>>> +    int64_t duration;
>>> +    int  poc;
>>> +} DTS2PTSNode;
>>> +
>>> +typedef struct DTS2PTSFrame {
>>> +    AVPacket    *pkt;
>>> +    int  poc;
>>> +    int poc_diff;
>>> +} DTS2PTSFrame;
>>> +
>>> +typedef struct DTS2PTSH264Context {
>>> +    H264POCContext poc;
>>> +    SPS sps;
>>> +    int last_poc;
>>> +    int highest_poc;
>>> +    int picture_structure;
>>> +} DTS2PTSH264Context;
>>> +
>>> +typedef struct DTS2PTSContext {
>>> +    struct AVTreeNode *root;
>>> +    AVFifo *fifo;
>>> +
>>> +    // Codec specific function pointers
>>> +    int (*init)(AVBSFContext *ctx);
>>> +    int (*filter)(AVBSFContext *ctx);
>>> +    void (*flush)(AVBSFContext *ctx);
>>> +
>>> +    CodedBitstreamContext *cbc;
>>> +    CodedBitstreamFragment au;
>>> +
>>> +    union {
>>> +    DTS2PTSH264Context h264;
>>> +    } u;
>>> +
>>> +    int nb_frame;
>>> +    int eof;
>>> +} DTS2PTSContext;
>>> +
>>> 

Re: [FFmpeg-devel] [PATCH] avcodec: add a bsf to reorder DTS into PTS

2022-08-30 Thread James Almer

On 8/30/2022 11:30 AM, Andreas Rheinhardt wrote:

James Almer:

Starting with an h264 implementation. Can be extended to support other codecs.

Addresses ticket #502.

Signed-off-by: James Almer 
---
  configure  |   1 +
  libavcodec/Makefile|   1 +
  libavcodec/bitstream_filters.c |   1 +
  libavcodec/dts2pts_bsf.c   | 477 +
  4 files changed, 480 insertions(+)
  create mode 100644 libavcodec/dts2pts_bsf.c

diff --git a/configure b/configure
index 932ea5b553..91ee5eb303 100755
--- a/configure
+++ b/configure
@@ -3275,6 +3275,7 @@ aac_adtstoasc_bsf_select="adts_header mpeg4audio"
  av1_frame_merge_bsf_select="cbs_av1"
  av1_frame_split_bsf_select="cbs_av1"
  av1_metadata_bsf_select="cbs_av1"
+dts2pts_bsf_select="cbs_h264 h264parse"
  eac3_core_bsf_select="ac3_parser"
  filter_units_bsf_select="cbs"
  h264_metadata_bsf_deps="const_nan"
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index cb80f73d99..858e110b79 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -1176,6 +1176,7 @@ OBJS-$(CONFIG_AV1_FRAME_SPLIT_BSF)+= 
av1_frame_split_bsf.o
  OBJS-$(CONFIG_CHOMP_BSF)  += chomp_bsf.o
  OBJS-$(CONFIG_DUMP_EXTRADATA_BSF) += dump_extradata_bsf.o
  OBJS-$(CONFIG_DCA_CORE_BSF)   += dca_core_bsf.o
+OBJS-$(CONFIG_DTS2PTS_BSF)+= dts2pts_bsf.o
  OBJS-$(CONFIG_DV_ERROR_MARKER_BSF)+= dv_error_marker_bsf.o
  OBJS-$(CONFIG_EAC3_CORE_BSF)  += eac3_core_bsf.o
  OBJS-$(CONFIG_EXTRACT_EXTRADATA_BSF)  += extract_extradata_bsf.o\
diff --git a/libavcodec/bitstream_filters.c b/libavcodec/bitstream_filters.c
index 23ae93..a3bebefe5f 100644
--- a/libavcodec/bitstream_filters.c
+++ b/libavcodec/bitstream_filters.c
@@ -31,6 +31,7 @@ extern const FFBitStreamFilter ff_av1_metadata_bsf;
  extern const FFBitStreamFilter ff_chomp_bsf;
  extern const FFBitStreamFilter ff_dump_extradata_bsf;
  extern const FFBitStreamFilter ff_dca_core_bsf;
+extern const FFBitStreamFilter ff_dts2pts_bsf;
  extern const FFBitStreamFilter ff_dv_error_marker_bsf;
  extern const FFBitStreamFilter ff_eac3_core_bsf;
  extern const FFBitStreamFilter ff_extract_extradata_bsf;
diff --git a/libavcodec/dts2pts_bsf.c b/libavcodec/dts2pts_bsf.c
new file mode 100644
index 00..f600150a6b
--- /dev/null
+++ b/libavcodec/dts2pts_bsf.c
@@ -0,0 +1,477 @@
+/*
+ * Copyright (c) 2022 James Almer
+ *
+ * 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
+ * Derive PTS by reordering DTS from supported streams
+ */
+
+#include "libavutil/avassert.h"
+#include "libavutil/eval.h"
+#include "libavutil/fifo.h"
+#include "libavutil/opt.h"
+#include "libavutil/tree.h"
+
+#include "bsf.h"
+#include "bsf_internal.h"
+#include "cbs.h"
+#include "cbs_h264.h"
+#include "h264_parse.h"
+#include "h264_ps.h"
+
+typedef struct DTS2PTSNode {
+int64_t  dts;
+int64_t duration;
+int  poc;
+} DTS2PTSNode;
+
+typedef struct DTS2PTSFrame {
+AVPacket*pkt;
+int  poc;
+int poc_diff;
+} DTS2PTSFrame;
+
+typedef struct DTS2PTSH264Context {
+H264POCContext poc;
+SPS sps;
+int last_poc;
+int highest_poc;
+int picture_structure;
+} DTS2PTSH264Context;
+
+typedef struct DTS2PTSContext {
+struct AVTreeNode *root;
+AVFifo *fifo;
+
+// Codec specific function pointers
+int (*init)(AVBSFContext *ctx);
+int (*filter)(AVBSFContext *ctx);
+void (*flush)(AVBSFContext *ctx);
+
+CodedBitstreamContext *cbc;
+CodedBitstreamFragment au;
+
+union {
+DTS2PTSH264Context h264;
+} u;
+
+int nb_frame;
+int eof;
+} DTS2PTSContext;
+
+// AVTreeNode callbacks
+static int cmp_insert(const void *key, const void *node)
+{
+return ((const DTS2PTSNode *) key)->poc - ((const DTS2PTSNode *) 
node)->poc;
+}
+
+static int cmp_find(const void *key, const void *node)
+{
+return *(const int *)key - ((const DTS2PTSNode *) node)->poc;
+}
+
+static int dec_poc(void *opaque, void *elem)
+{
+DTS2PTSNode *node = elem;
+int dec = *(int *)opaque;
+node->poc -= dec;
+return 0;
+}
+
+static int free_node(void *opaque, void *elem)
+{
+DTS2PTSNode *node = elem;
+av_free(node);
+return 0;

Re: [FFmpeg-devel] [PATCH] avcodec: add a bsf to reorder DTS into PTS

2022-08-30 Thread Andreas Rheinhardt
James Almer:
> Starting with an h264 implementation. Can be extended to support other codecs.
> 
> Addresses ticket #502.
> 
> Signed-off-by: James Almer 
> ---
>  configure  |   1 +
>  libavcodec/Makefile|   1 +
>  libavcodec/bitstream_filters.c |   1 +
>  libavcodec/dts2pts_bsf.c   | 477 +
>  4 files changed, 480 insertions(+)
>  create mode 100644 libavcodec/dts2pts_bsf.c
> 
> diff --git a/configure b/configure
> index 932ea5b553..91ee5eb303 100755
> --- a/configure
> +++ b/configure
> @@ -3275,6 +3275,7 @@ aac_adtstoasc_bsf_select="adts_header mpeg4audio"
>  av1_frame_merge_bsf_select="cbs_av1"
>  av1_frame_split_bsf_select="cbs_av1"
>  av1_metadata_bsf_select="cbs_av1"
> +dts2pts_bsf_select="cbs_h264 h264parse"
>  eac3_core_bsf_select="ac3_parser"
>  filter_units_bsf_select="cbs"
>  h264_metadata_bsf_deps="const_nan"
> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> index cb80f73d99..858e110b79 100644
> --- a/libavcodec/Makefile
> +++ b/libavcodec/Makefile
> @@ -1176,6 +1176,7 @@ OBJS-$(CONFIG_AV1_FRAME_SPLIT_BSF)+= 
> av1_frame_split_bsf.o
>  OBJS-$(CONFIG_CHOMP_BSF)  += chomp_bsf.o
>  OBJS-$(CONFIG_DUMP_EXTRADATA_BSF) += dump_extradata_bsf.o
>  OBJS-$(CONFIG_DCA_CORE_BSF)   += dca_core_bsf.o
> +OBJS-$(CONFIG_DTS2PTS_BSF)+= dts2pts_bsf.o
>  OBJS-$(CONFIG_DV_ERROR_MARKER_BSF)+= dv_error_marker_bsf.o
>  OBJS-$(CONFIG_EAC3_CORE_BSF)  += eac3_core_bsf.o
>  OBJS-$(CONFIG_EXTRACT_EXTRADATA_BSF)  += extract_extradata_bsf.o\
> diff --git a/libavcodec/bitstream_filters.c b/libavcodec/bitstream_filters.c
> index 23ae93..a3bebefe5f 100644
> --- a/libavcodec/bitstream_filters.c
> +++ b/libavcodec/bitstream_filters.c
> @@ -31,6 +31,7 @@ extern const FFBitStreamFilter ff_av1_metadata_bsf;
>  extern const FFBitStreamFilter ff_chomp_bsf;
>  extern const FFBitStreamFilter ff_dump_extradata_bsf;
>  extern const FFBitStreamFilter ff_dca_core_bsf;
> +extern const FFBitStreamFilter ff_dts2pts_bsf;
>  extern const FFBitStreamFilter ff_dv_error_marker_bsf;
>  extern const FFBitStreamFilter ff_eac3_core_bsf;
>  extern const FFBitStreamFilter ff_extract_extradata_bsf;
> diff --git a/libavcodec/dts2pts_bsf.c b/libavcodec/dts2pts_bsf.c
> new file mode 100644
> index 00..f600150a6b
> --- /dev/null
> +++ b/libavcodec/dts2pts_bsf.c
> @@ -0,0 +1,477 @@
> +/*
> + * Copyright (c) 2022 James Almer
> + *
> + * 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
> + * Derive PTS by reordering DTS from supported streams
> + */
> +
> +#include "libavutil/avassert.h"
> +#include "libavutil/eval.h"
> +#include "libavutil/fifo.h"
> +#include "libavutil/opt.h"
> +#include "libavutil/tree.h"
> +
> +#include "bsf.h"
> +#include "bsf_internal.h"
> +#include "cbs.h"
> +#include "cbs_h264.h"
> +#include "h264_parse.h"
> +#include "h264_ps.h"
> +
> +typedef struct DTS2PTSNode {
> +int64_t  dts;
> +int64_t duration;
> +int  poc;
> +} DTS2PTSNode;
> +
> +typedef struct DTS2PTSFrame {
> +AVPacket*pkt;
> +int  poc;
> +int poc_diff;
> +} DTS2PTSFrame;
> +
> +typedef struct DTS2PTSH264Context {
> +H264POCContext poc;
> +SPS sps;
> +int last_poc;
> +int highest_poc;
> +int picture_structure;
> +} DTS2PTSH264Context;
> +
> +typedef struct DTS2PTSContext {
> +struct AVTreeNode *root;
> +AVFifo *fifo;
> +
> +// Codec specific function pointers
> +int (*init)(AVBSFContext *ctx);
> +int (*filter)(AVBSFContext *ctx);
> +void (*flush)(AVBSFContext *ctx);
> +
> +CodedBitstreamContext *cbc;
> +CodedBitstreamFragment au;
> +
> +union {
> +DTS2PTSH264Context h264;
> +} u;
> +
> +int nb_frame;
> +int eof;
> +} DTS2PTSContext;
> +
> +// AVTreeNode callbacks
> +static int cmp_insert(const void *key, const void *node)
> +{
> +return ((const DTS2PTSNode *) key)->poc - ((const DTS2PTSNode *) 
> node)->poc;
> +}
> +
> +static int cmp_find(const void *key, const void *node)
> +{
> +return *(const int *)key - ((const DTS2PTSNode *) node)->poc;
> +}
> +
> +static int dec_poc(void *opaque, void *elem)
> +{

Re: [FFmpeg-devel] [PATCH 2/3] lavu/fifo: clarify interaction of AV_FIFO_FLAG_AUTO_GROW with av_fifo_can_write()

2022-08-30 Thread Anton Khirnov
Quoting James Almer (2022-08-30 14:56:45)
> > 
> > I disagree that this is a break.
> > 
> > The issue in my view is that 'can be written' is ambiguous here, so we
> > are interpreting it differently. Your interpretation is apparently
> > 'maximum number of elements for which a write can possibly succeeed',
> > whereas my intended interpretation was 'maximum number of elements for
> > which a write is always guaranteed to succeed'.
> 
> IMO it's not really ambiguous. If you don't state that's the intention, 
> which you're doing in this patch, then "can be written" has one literal 
> meaning.

I would disagree here. Consider an autogrowing fifo in an out-of-memory
situation. What "can be written" into it?

> > One of these interpretations is correct, because it matches the actual
> > behaviour. So the right solution IMO is to clarify the documentation so
> > it is no longer ambiguous, but I do not consider this an API break.
> 
> av_fifo_write() says "In case nb_elems > av_fifo_can_write(f), nothing 
> is written and an error is returned.", which is definitely not 
> ambiguous, and you're changing it in patch 3/3 to include the case where 
> having enabled autogrow could result in the function succeeding when 
> nb_elems > av_fifo_can_write(f).

That is quite clearly a bug in the documentation IMO. That line was not
present in the original patches I sent, but added at some time later in
the development (don't remember whether by myself or Andreas); then
whichever of us added it forgot to update it in the patch adding
AV_FIFO_FLAG_AUTO_GROW.

> The behavior of the function remains intact, but a library user reading 
> the documentation in ffmpeg 5.1 and the documentation in what will be 
> 5.2 after this patch could rightly assume the function was changed and 
> will behave differently between versions (Which is not the case, but to 
> find out you'll have to read the implementation, or the git history, or 
> test code with both versions). So this is technically an API break.

Technically yes, but the unfortunate fact of the matter is that our
API documentation simply is not, and never was, sufficiently complete
and precise to be the sole source of truth. Plenty of things are
missing, obsolete, inconsistent, and sometimes just wrong. I wish it
were otherwise, and I believe the situation is slowly improving, but we
just don't have the resources to make our docs anywhere close to
perfect any time soon. So unfortunately people have to test their code,
and testing in this case would immediately reveal how it actually works.

As a consequence we have to be pragmatic when choosing whether to change
code to match the docs or vice versa.

> 
> > 
> > More generally:
> > - a FIFO conceptually has a well-defined size at any given moment
> > - that size is can_read() + can_write()
> 
> But this could (should?) have been av_fifo_size2(). That way can_write() 
> could effectively become a generic "can write", instead of begin stuck 
> as "can write without the chance of failure".

Maybe, but it's a bit late for that. Actually I remember considering an
av_fifo_size2(), but then decided against it, probably because it could
confuse people into thinking it's like av_fifo_size(), which it most
definitely is not.

-- 
Anton Khirnov
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH 2/3] lavu/fifo: clarify interaction of AV_FIFO_FLAG_AUTO_GROW with av_fifo_can_write()

2022-08-30 Thread James Almer

On 8/30/2022 3:35 AM, Anton Khirnov wrote:

Quoting James Almer (2022-08-29 17:00:54)

On 8/29/2022 11:07 AM, Anton Khirnov wrote:

---
   libavutil/fifo.h | 8 +++-
   1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/libavutil/fifo.h b/libavutil/fifo.h
index 6c6bd78842..89872d0972 100644
--- a/libavutil/fifo.h
+++ b/libavutil/fifo.h
@@ -97,7 +97,13 @@ void av_fifo_auto_grow_limit(AVFifo *f, size_t max_elems);
   size_t av_fifo_can_read(const AVFifo *f);
   
   /**

- * @return number of elements that can be written into the given FIFO.
+ * @return Number of elements that can be written into the given FIFO without
+ * growing it.
+ *
+ * In other words, this number of elements or less is guaranteed to fit
+ * into the FIFO. More data may be written when the
+ * AV_FIFO_FLAG_AUTO_GROW flag was specified at FIFO creation, but this
+ * may involve memory allocation, which can fail.


This patch is an API break, because before it i was told
av_fifo_can_write() would tell me the amount of elements i could write
into the FIFO, regardless of how it was created, but now it legitimates
the one scenario where it was not reliable. An scenario i stumbled upon
in my code by following the documentation, which is in at least one
release, the LTS one.

Instead of changing the documentation to fit the behavior, the behavior
should match the documentation. This means that if a call to
av_fifo_write() can succeed, then av_fifo_can_write() should reflect that.

That said, it would be great if making av_fifo_can_write() tell the real
amount of elements one can write into the FIFO was possible without
breaking anything, but the doxy for av_fifo_grow2() says "On success,
the FIFO will be large enough to hold exactly inc + av_fifo_can_read() +
av_fifo_can_write()", a line that was obviously aware of the fact
av_fifo_can_write() ignored the autogrow feature, and would no longer be
true if said function is fixed.


I disagree that this is a break.

The issue in my view is that 'can be written' is ambiguous here, so we
are interpreting it differently. Your interpretation is apparently
'maximum number of elements for which a write can possibly succeeed',
whereas my intended interpretation was 'maximum number of elements for
which a write is always guaranteed to succeed'.


IMO it's not really ambiguous. If you don't state that's the intention, 
which you're doing in this patch, then "can be written" has one literal 
meaning.



One of these interpretations is correct, because it matches the actual
behaviour. So the right solution IMO is to clarify the documentation so
it is no longer ambiguous, but I do not consider this an API break.


av_fifo_write() says "In case nb_elems > av_fifo_can_write(f), nothing 
is written and an error is returned.", which is definitely not 
ambiguous, and you're changing it in patch 3/3 to include the case where 
having enabled autogrow could result in the function succeeding when 
nb_elems > av_fifo_can_write(f).
The behavior of the function remains intact, but a library user reading 
the documentation in ffmpeg 5.1 and the documentation in what will be 
5.2 after this patch could rightly assume the function was changed and 
will behave differently between versions (Which is not the case, but to 
find out you'll have to read the implementation, or the git history, or 
test code with both versions). So this is technically an API break.




More generally:
- a FIFO conceptually has a well-defined size at any given moment
- that size is can_read() + can_write()


But this could (should?) have been av_fifo_size2(). That way can_write() 
could effectively become a generic "can write", instead of begin stuck 
as "can write without the chance of failure".



- you can change the size by growing the FIFO
- AV_FIFO_FLAG_AUTO_GROW does not fundamentally change the above
   concepts, it merely calls av_fifo_grow2() when a write would
   otherwise fail

Now we can introduce a function for 'maximum number that can possibly
succeed' if you think it's useful - something like av_fifo_max_write().


Maybe, but only if we find a usecase for it.

Hendrik had an opinion about what av_fifo_can_write() should report, but 
it was on IRC. But otherwise, knowing that anything we do will be 
breaking, if the current behavior was your intention all along as the 
author of the API, then i guess this set can go in unless someone else 
chimes.

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 2/2] avformat/tests: Add a test for avio_check with the pipe protocol

2022-08-30 Thread Neil Roberts
Creates a UNIX pipe and then verifies that avio_check returns the right
access flags for the two ends of the pipe.

v2: Add support for the Windows version of _pipe

Signed-off-by: Neil Roberts 
---
 libavformat/Makefile |   1 +
 libavformat/tests/.gitignore |   1 +
 libavformat/tests/pipe.c | 108 +++
 tests/fate/libavformat.mak   |   5 ++
 4 files changed, 115 insertions(+)
 create mode 100644 libavformat/tests/pipe.c

diff --git a/libavformat/Makefile b/libavformat/Makefile
index f67a99f839..9c681c58c5 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -732,6 +732,7 @@ TESTPROGS-$(CONFIG_MOV_MUXER)+= movenc
 TESTPROGS-$(CONFIG_NETWORK)  += noproxy
 TESTPROGS-$(CONFIG_SRTP) += srtp
 TESTPROGS-$(CONFIG_IMF_DEMUXER)  += imf
+TESTPROGS-$(CONFIG_PIPE_PROTOCOL)+= pipe
 
 TOOLS = aviocat \
 ismindex\
diff --git a/libavformat/tests/.gitignore b/libavformat/tests/.gitignore
index cdd0cce061..567d6f9e40 100644
--- a/libavformat/tests/.gitignore
+++ b/libavformat/tests/.gitignore
@@ -7,3 +7,4 @@
 /srtp
 /url
 /seek_utils
+/pipe
diff --git a/libavformat/tests/pipe.c b/libavformat/tests/pipe.c
new file mode 100644
index 00..18a8551fd5
--- /dev/null
+++ b/libavformat/tests/pipe.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2022 Neil Roberts
+ *
+ * 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
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "libavformat/avio.h"
+#include "libavutil/error.h"
+
+static int check_pipe(const char *url, int mask, int expected)
+{
+int flags = avio_check(url, mask);
+
+if (flags < 0) {
+fprintf(stderr,
+"avio_check for %s with mask 0x%x failed: %s\n",
+url,
+mask,
+av_err2str(flags));
+return 0;
+}
+
+if (flags != expected) {
+fprintf(stderr,
+"Wrong result returned from avio_check for %s with mask 0x%x. "
+"Expected 0x%x but received 0x%x\n",
+url,
+mask,
+expected,
+flags);
+return 0;
+}
+
+return 1;
+}
+
+int main(int argc, char **argv)
+{
+int ret = 0;
+int pipe_fds[2];
+char read_url[20], write_url[20];
+int check_invalid_ret;
+int pipe_ret;
+
+#ifdef _WIN32
+pipe_ret = _pipe(pipe_fds, 1024 /* psize */, 0 /* textmode */);
+#else
+pipe_ret = pipe(pipe_fds);
+#endif
+
+if (pipe_ret == -1) {
+fprintf(stderr, "error creating pipe: %s\n", strerror(errno));
+return 1;
+}
+
+snprintf(read_url, sizeof(read_url), "pipe:%d", pipe_fds[0]);
+snprintf(write_url, sizeof(write_url), "pipe:%d", pipe_fds[1]);
+
+if (!check_pipe(read_url,
+AVIO_FLAG_READ | AVIO_FLAG_WRITE,
+AVIO_FLAG_READ))
+ret = 1;
+
+if (!check_pipe(write_url,
+AVIO_FLAG_READ | AVIO_FLAG_WRITE,
+AVIO_FLAG_WRITE))
+ret = 1;
+
+/* Ensure that we don't get flags that we didn't ask for */
+if (!check_pipe(read_url, AVIO_FLAG_WRITE, 0))
+ret = 1;
+
+close(pipe_fds[0]);
+close(pipe_fds[1]);
+
+/* An invalid fd should return EBADF */
+check_invalid_ret = avio_check(read_url, AVIO_FLAG_READ);
+
+if (check_invalid_ret != AVERROR(EBADF)) {
+fprintf(stderr,
+"avio_check on invalid FD expected to return %i "
+"but %i was received\n",
+AVERROR(EBADF),
+check_invalid_ret);
+ret = 1;
+}
+
+return ret;
+}
diff --git a/tests/fate/libavformat.mak b/tests/fate/libavformat.mak
index d2acb4c9e0..7a22f54c04 100644
--- a/tests/fate/libavformat.mak
+++ b/tests/fate/libavformat.mak
@@ -26,6 +26,11 @@ FATE_LIBAVFORMAT-$(CONFIG_IMF_DEMUXER) += fate-imf
 fate-imf: libavformat/tests/imf$(EXESUF)
 fate-imf: CMD = run libavformat/tests/imf$(EXESUF)
 
+FATE_LIBAVFORMAT-$(CONFIG_PIPE_PROTOCOL) += fate-pipe
+fate-pipe: libavformat/tests/pipe$(EXESUF)
+fate-pipe: CMD = run libavformat/tests/pipe$(EXESUF)

[FFmpeg-devel] [PATCH v2 1/2] avformat/file: Add a specialized url_check callback for pipe protocol

2022-08-30 Thread Neil Roberts
Using file_check for the pipe protocol doesn't make sense. For example,
for a URL like “pipe:0” it would end up checking whether the “pipe:0”
file exists. This patch instead makes it check the access modes on the
corresponding file descriptor using fcntl on *nix and DuplicateHandle on
Windows.

v2: Use DuplicateHandle on Windows to check whether the duplicated
handle can have the corresponding access flags.

Signed-off-by: Neil Roberts 
---
 libavformat/file.c | 74 --
 1 file changed, 71 insertions(+), 3 deletions(-)

diff --git a/libavformat/file.c b/libavformat/file.c
index 98c9e81bcb..b3f7bc9282 100644
--- a/libavformat/file.c
+++ b/libavformat/file.c
@@ -375,9 +375,8 @@ const URLProtocol ff_file_protocol = {
 
 #if CONFIG_PIPE_PROTOCOL
 
-static int pipe_open(URLContext *h, const char *filename, int flags)
+static int pipe_get_fd(const char *filename, int flags)
 {
-FileContext *c = h->priv_data;
 int fd;
 char *final;
 av_strstart(filename, "pipe:", );
@@ -390,6 +389,14 @@ static int pipe_open(URLContext *h, const char *filename, 
int flags)
 fd = 0;
 }
 }
+
+return fd;
+}
+
+static int pipe_open(URLContext *h, const char *filename, int flags)
+{
+FileContext *c = h->priv_data;
+int fd = pipe_get_fd(filename, flags);
 #if HAVE_SETMODE
 setmode(fd, O_BINARY);
 #endif
@@ -398,13 +405,74 @@ static int pipe_open(URLContext *h, const char *filename, 
int flags)
 return 0;
 }
 
+static int pipe_check(URLContext *h, int mask)
+{
+int fd = pipe_get_fd(h->filename, mask);
+int access = 0;
+
+#ifdef _WIN32
+
+HANDLE pipe_handle = (HANDLE) _get_osfhandle(fd);
+HANDLE tmp_handle;
+
+if (pipe_handle == INVALID_HANDLE_VALUE)
+return AVERROR(errno);
+
+if (mask & AVIO_FLAG_READ &&
+DuplicateHandle(GetCurrentProcess(), /* hSourceProcessHandle */
+pipe_handle,
+GetCurrentProcess(), /* hTargetProcessHandle */
+_handle,
+FILE_READ_DATA,
+FALSE, /* bInheritHandle */
+0 /* options */)) {
+access |= AVIO_FLAG_READ;
+CloseHandle(tmp_handle);
+}
+
+if (mask & AVIO_FLAG_WRITE &&
+DuplicateHandle(GetCurrentProcess(), /* hSourceProcessHandle */
+pipe_handle,
+GetCurrentProcess(), /* hTargetProcessHandle */
+_handle,
+FILE_WRITE_DATA,
+FALSE, /* bInheritHandle */
+0 /* options */)) {
+access |= AVIO_FLAG_WRITE;
+CloseHandle(tmp_handle);
+}
+
+#else /* _WIN32 */
+
+int status_flags = fcntl(fd, F_GETFL);
+
+if (status_flags == -1)
+return AVERROR(errno);
+
+switch (status_flags & O_ACCMODE) {
+case O_RDONLY:
+access = AVIO_FLAG_READ;
+break;
+case O_WRONLY:
+access = AVIO_FLAG_WRITE;
+break;
+case O_RDWR:
+access = AVIO_FLAG_READ | AVIO_FLAG_WRITE;
+break;
+}
+
+#endif /* _WIN32 */
+
+return access & mask;
+}
+
 const URLProtocol ff_pipe_protocol = {
 .name= "pipe",
 .url_open= pipe_open,
 .url_read= file_read,
 .url_write   = file_write,
 .url_get_file_handle = file_get_handle,
-.url_check   = file_check,
+.url_check   = pipe_check,
 .priv_data_size  = sizeof(FileContext),
 .priv_data_class = _class,
 .default_whitelist   = "crypto,data"
-- 
2.37.2

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH 2/3] lavu/fifo: clarify interaction of AV_FIFO_FLAG_AUTO_GROW with av_fifo_can_write()

2022-08-30 Thread Anton Khirnov
Quoting James Almer (2022-08-29 17:00:54)
> On 8/29/2022 11:07 AM, Anton Khirnov wrote:
> > ---
> >   libavutil/fifo.h | 8 +++-
> >   1 file changed, 7 insertions(+), 1 deletion(-)
> > 
> > diff --git a/libavutil/fifo.h b/libavutil/fifo.h
> > index 6c6bd78842..89872d0972 100644
> > --- a/libavutil/fifo.h
> > +++ b/libavutil/fifo.h
> > @@ -97,7 +97,13 @@ void av_fifo_auto_grow_limit(AVFifo *f, size_t 
> > max_elems);
> >   size_t av_fifo_can_read(const AVFifo *f);
> >   
> >   /**
> > - * @return number of elements that can be written into the given FIFO.
> > + * @return Number of elements that can be written into the given FIFO 
> > without
> > + * growing it.
> > + *
> > + * In other words, this number of elements or less is guaranteed 
> > to fit
> > + * into the FIFO. More data may be written when the
> > + * AV_FIFO_FLAG_AUTO_GROW flag was specified at FIFO creation, but 
> > this
> > + * may involve memory allocation, which can fail.
> 
> This patch is an API break, because before it i was told 
> av_fifo_can_write() would tell me the amount of elements i could write 
> into the FIFO, regardless of how it was created, but now it legitimates 
> the one scenario where it was not reliable. An scenario i stumbled upon 
> in my code by following the documentation, which is in at least one 
> release, the LTS one.
> 
> Instead of changing the documentation to fit the behavior, the behavior 
> should match the documentation. This means that if a call to 
> av_fifo_write() can succeed, then av_fifo_can_write() should reflect that.
> 
> That said, it would be great if making av_fifo_can_write() tell the real 
> amount of elements one can write into the FIFO was possible without 
> breaking anything, but the doxy for av_fifo_grow2() says "On success, 
> the FIFO will be large enough to hold exactly inc + av_fifo_can_read() + 
> av_fifo_can_write()", a line that was obviously aware of the fact 
> av_fifo_can_write() ignored the autogrow feature, and would no longer be 
> true if said function is fixed.

I disagree that this is a break.

The issue in my view is that 'can be written' is ambiguous here, so we
are interpreting it differently. Your interpretation is apparently
'maximum number of elements for which a write can possibly succeeed',
whereas my intended interpretation was 'maximum number of elements for
which a write is always guaranteed to succeed'.
One of these interpretations is correct, because it matches the actual
behaviour. So the right solution IMO is to clarify the documentation so
it is no longer ambiguous, but I do not consider this an API break.

More generally:
- a FIFO conceptually has a well-defined size at any given moment
- that size is can_read() + can_write()
- you can change the size by growing the FIFO
- AV_FIFO_FLAG_AUTO_GROW does not fundamentally change the above
  concepts, it merely calls av_fifo_grow2() when a write would
  otherwise fail

Now we can introduce a function for 'maximum number that can possibly
succeed' if you think it's useful - something like av_fifo_max_write().

-- 
Anton Khirnov
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".