diff mbox series

[FFmpeg-devel,v4] avformat/utils: add helper functions to retrieve index entries from an AVStream

Message ID 20210403231200.1165-1-jamrial@gmail.com
State Accepted
Headers show
Series [FFmpeg-devel,v4] avformat/utils: add helper functions to retrieve index entries from an AVStream | expand

Checks

Context Check Description
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished
andriy/PPC64_make success Make finished
andriy/PPC64_make_fate success Make fate finished

Commit Message

James Almer April 3, 2021, 11:12 p.m. UTC
Signed-off-by: James Almer <jamrial@gmail.com>
---
Now using the avformat_ prefix as Anton requested. I forgot about it when i
made v3.

 libavformat/avformat.h | 39 +++++++++++++++++++++++++++++++++++++++
 libavformat/utils.c    | 27 +++++++++++++++++++++++++++
 2 files changed, 66 insertions(+)

Comments

James Almer April 6, 2021, 6:34 p.m. UTC | #1
On 4/3/2021 8:12 PM, James Almer wrote:
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
> Now using the avformat_ prefix as Anton requested. I forgot about it when i
> made v3.

Will apply soon if there are no objections.

> 
>   libavformat/avformat.h | 39 +++++++++++++++++++++++++++++++++++++++
>   libavformat/utils.c    | 27 +++++++++++++++++++++++++++
>   2 files changed, 66 insertions(+)
> 
> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
> index 6a9b09160c..a1e87ef891 100644
> --- a/libavformat/avformat.h
> +++ b/libavformat/avformat.h
> @@ -2767,6 +2767,45 @@ int av_find_default_stream_index(AVFormatContext *s);
>    */
>   int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags);
>   
> +/**
> + * Get the index entry count for the given AVStream.
> + *
> + * @param st stream
> + * @return the number of index entries in the stream
> + */
> +int avformat_index_get_entries_count(AVStream *st);
> +
> +/**
> + * Get the AVIndexEntry corresponding to the given index.
> + *
> + * @param st          Stream containing the requested AVIndexEntry.
> + * @param idx         The desired index.
> + * @return A pointer to the requested AVIndexEntry if it exists, NULL otherwise.
> + *
> + * @note The pointer returned by this function is only guaranteed to be valid
> + *       until any function that could alter the stream or the AVFormatContext
> + *       that cointains it is called.
> + */
> +const AVIndexEntry *avformat_index_get_entry(AVStream *st, int idx);
> +
> +/**
> + * Get the AVIndexEntry corresponding to the given timestamp.
> + *
> + * @param st          Stream containing the requested AVIndexEntry.
> + * @param timestamp   Timestamp to retrieve the index entry for.
> + * @param flags       If AVSEEK_FLAG_BACKWARD then the returned entry will correspond
> + *                    to the timestamp which is <= the requested one, if backward
> + *                    is 0, then it will be >=
> + *                    if AVSEEK_FLAG_ANY seek to any frame, only keyframes otherwise.
> + * @return A pointer to the requested AVIndexEntry if it exists, NULL otherwise.
> + *
> + * @note The pointer returned by this function is only guaranteed to be valid
> + *       until any function that could alter the stream or the AVFormatContext
> + *       that cointains it is called.
> + */
> +const AVIndexEntry *avformat_index_get_entry_from_timestamp(AVStream *st,
> +                                                            int64_t wanted_timestamp,
> +                                                            int flags);
>   /**
>    * Add an index entry into a sorted list. Update the entry if the list
>    * already contains it.
> diff --git a/libavformat/utils.c b/libavformat/utils.c
> index e9bf31e38b..942d7c8390 100644
> --- a/libavformat/utils.c
> +++ b/libavformat/utils.c
> @@ -2176,6 +2176,33 @@ int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp, int flags)
>                                        wanted_timestamp, flags);
>   }
>   
> +int avformat_index_get_entries_count(AVStream *st)
> +{
> +    return st->internal->nb_index_entries;
> +}
> +
> +const AVIndexEntry *avformat_index_get_entry(AVStream *st, int idx)
> +{
> +    if (idx < 0 || idx >= st->internal->nb_index_entries)
> +        return NULL;
> +
> +    return &st->internal->index_entries[idx];
> +}
> +
> +const AVIndexEntry *avformat_index_get_entry_from_timestamp(AVStream *st,
> +                                                            int64_t wanted_timestamp,
> +                                                            int flags)
> +{
> +    int idx = ff_index_search_timestamp(st->internal->index_entries,
> +                                        st->internal->nb_index_entries,
> +                                        wanted_timestamp, flags);
> +
> +    if (idx < 0)
> +        return NULL;
> +
> +    return &st->internal->index_entries[idx];
> +}
> +
>   static int64_t ff_read_timestamp(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit,
>                                    int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ))
>   {
>
Andreas Rheinhardt April 6, 2021, 6:46 p.m. UTC | #2
James Almer:
> On 4/3/2021 8:12 PM, James Almer wrote:
>> Signed-off-by: James Almer <jamrial@gmail.com>
>> ---
>> Now using the avformat_ prefix as Anton requested. I forgot about it
>> when i
>> made v3.
> 
> Will apply soon if there are no objections.
> 

I wonder whether the AVStream *st should be const; together with a
guarantee that calling these functions does not invalidate entries that
have been returned earlier.

>>
>>   libavformat/avformat.h | 39 +++++++++++++++++++++++++++++++++++++++
>>   libavformat/utils.c    | 27 +++++++++++++++++++++++++++
>>   2 files changed, 66 insertions(+)
>>
>> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
>> index 6a9b09160c..a1e87ef891 100644
>> --- a/libavformat/avformat.h
>> +++ b/libavformat/avformat.h
>> @@ -2767,6 +2767,45 @@ int
>> av_find_default_stream_index(AVFormatContext *s);
>>    */
>>   int av_index_search_timestamp(AVStream *st, int64_t timestamp, int
>> flags);
>>   +/**
>> + * Get the index entry count for the given AVStream.
>> + *
>> + * @param st stream
>> + * @return the number of index entries in the stream
>> + */
>> +int avformat_index_get_entries_count(AVStream *st);

An int? Not something unsigned?

>> +
>> +/**
>> + * Get the AVIndexEntry corresponding to the given index.
>> + *
>> + * @param st          Stream containing the requested AVIndexEntry.
>> + * @param idx         The desired index.
>> + * @return A pointer to the requested AVIndexEntry if it exists, NULL
>> otherwise.
>> + *
>> + * @note The pointer returned by this function is only guaranteed to
>> be valid
>> + *       until any function that could alter the stream or the
>> AVFormatContext
>> + *       that cointains it is called.
                    ^
                    typo
>> + */
>> +const AVIndexEntry *avformat_index_get_entry(AVStream *st, int idx);
>> +
>> +/**
>> + * Get the AVIndexEntry corresponding to the given timestamp.
>> + *
>> + * @param st          Stream containing the requested AVIndexEntry.
>> + * @param timestamp   Timestamp to retrieve the index entry for.
>> + * @param flags       If AVSEEK_FLAG_BACKWARD then the returned entry
>> will correspond
>> + *                    to the timestamp which is <= the requested one,
>> if backward
>> + *                    is 0, then it will be >=
>> + *                    if AVSEEK_FLAG_ANY seek to any frame, only
>> keyframes otherwise.
>> + * @return A pointer to the requested AVIndexEntry if it exists, NULL
>> otherwise.
>> + *
>> + * @note The pointer returned by this function is only guaranteed to
>> be valid
>> + *       until any function that could alter the stream or the
>> AVFormatContext
>> + *       that cointains it is called.
                    ^
                    same typo
>> + */
>> +const AVIndexEntry *avformat_index_get_entry_from_timestamp(AVStream
>> *st,
>> +                                                            int64_t
>> wanted_timestamp,
>> +                                                            int flags);
>>   /**
>>    * Add an index entry into a sorted list. Update the entry if the list
>>    * already contains it.
>> diff --git a/libavformat/utils.c b/libavformat/utils.c
>> index e9bf31e38b..942d7c8390 100644
>> --- a/libavformat/utils.c
>> +++ b/libavformat/utils.c
>> @@ -2176,6 +2176,33 @@ int av_index_search_timestamp(AVStream *st,
>> int64_t wanted_timestamp, int flags)
>>                                        wanted_timestamp, flags);
>>   }
>>   +int avformat_index_get_entries_count(AVStream *st)
>> +{
>> +    return st->internal->nb_index_entries;
>> +}
>> +
>> +const AVIndexEntry *avformat_index_get_entry(AVStream *st, int idx)
>> +{
>> +    if (idx < 0 || idx >= st->internal->nb_index_entries)
>> +        return NULL;
>> +
>> +    return &st->internal->index_entries[idx];
>> +}
>> +
>> +const AVIndexEntry *avformat_index_get_entry_from_timestamp(AVStream
>> *st,
>> +                                                            int64_t
>> wanted_timestamp,
>> +                                                            int flags)
>> +{
>> +    int idx = ff_index_search_timestamp(st->internal->index_entries,
>> +                                        st->internal->nb_index_entries,
>> +                                        wanted_timestamp, flags);
>> +
>> +    if (idx < 0)
>> +        return NULL;
>> +
>> +    return &st->internal->index_entries[idx];
>> +}
>> +
>>   static int64_t ff_read_timestamp(AVFormatContext *s, int
>> stream_index, int64_t *ppos, int64_t pos_limit,
>>                                    int64_t (*read_timestamp)(struct
>> AVFormatContext *, int , int64_t *, int64_t ))
>>   {
>>
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
James Almer April 6, 2021, 7:09 p.m. UTC | #3
On 4/6/2021 3:46 PM, Andreas Rheinhardt wrote:
> James Almer:
>> On 4/3/2021 8:12 PM, James Almer wrote:
>>> Signed-off-by: James Almer <jamrial@gmail.com>
>>> ---
>>> Now using the avformat_ prefix as Anton requested. I forgot about it
>>> when i
>>> made v3.
>>
>> Will apply soon if there are no objections.
>>
> 
> I wonder whether the AVStream *st should be const; together with a
> guarantee that calling these functions does not invalidate entries that
> have been returned earlier.

Sure, will make it const.

> 
>>>
>>>    libavformat/avformat.h | 39 +++++++++++++++++++++++++++++++++++++++
>>>    libavformat/utils.c    | 27 +++++++++++++++++++++++++++
>>>    2 files changed, 66 insertions(+)
>>>
>>> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
>>> index 6a9b09160c..a1e87ef891 100644
>>> --- a/libavformat/avformat.h
>>> +++ b/libavformat/avformat.h
>>> @@ -2767,6 +2767,45 @@ int
>>> av_find_default_stream_index(AVFormatContext *s);
>>>     */
>>>    int av_index_search_timestamp(AVStream *st, int64_t timestamp, int
>>> flags);
>>>    +/**
>>> + * Get the index entry count for the given AVStream.
>>> + *
>>> + * @param st stream
>>> + * @return the number of index entries in the stream
>>> + */
>>> +int avformat_index_get_entries_count(AVStream *st);
> 
> An int? Not something unsigned?

st->internal->nb_index_entries is an int, and 
av_index_search_timestamp() returns an int, too, so I'm inclined to 
leave it as is.

> 
>>> +
>>> +/**
>>> + * Get the AVIndexEntry corresponding to the given index.
>>> + *
>>> + * @param st          Stream containing the requested AVIndexEntry.
>>> + * @param idx         The desired index.
>>> + * @return A pointer to the requested AVIndexEntry if it exists, NULL
>>> otherwise.
>>> + *
>>> + * @note The pointer returned by this function is only guaranteed to
>>> be valid
>>> + *       until any function that could alter the stream or the
>>> AVFormatContext
>>> + *       that cointains it is called.
>                      ^
>                      typo
>>> + */
>>> +const AVIndexEntry *avformat_index_get_entry(AVStream *st, int idx);
>>> +
>>> +/**
>>> + * Get the AVIndexEntry corresponding to the given timestamp.
>>> + *
>>> + * @param st          Stream containing the requested AVIndexEntry.
>>> + * @param timestamp   Timestamp to retrieve the index entry for.
>>> + * @param flags       If AVSEEK_FLAG_BACKWARD then the returned entry
>>> will correspond
>>> + *                    to the timestamp which is <= the requested one,
>>> if backward
>>> + *                    is 0, then it will be >=
>>> + *                    if AVSEEK_FLAG_ANY seek to any frame, only
>>> keyframes otherwise.
>>> + * @return A pointer to the requested AVIndexEntry if it exists, NULL
>>> otherwise.
>>> + *
>>> + * @note The pointer returned by this function is only guaranteed to
>>> be valid
>>> + *       until any function that could alter the stream or the
>>> AVFormatContext
>>> + *       that cointains it is called.
>                      ^
>                      same typo

Both fixed locally.

>>> + */
>>> +const AVIndexEntry *avformat_index_get_entry_from_timestamp(AVStream
>>> *st,
>>> +                                                            int64_t
>>> wanted_timestamp,
>>> +                                                            int flags);
>>>    /**
>>>     * Add an index entry into a sorted list. Update the entry if the list
>>>     * already contains it.
>>> diff --git a/libavformat/utils.c b/libavformat/utils.c
>>> index e9bf31e38b..942d7c8390 100644
>>> --- a/libavformat/utils.c
>>> +++ b/libavformat/utils.c
>>> @@ -2176,6 +2176,33 @@ int av_index_search_timestamp(AVStream *st,
>>> int64_t wanted_timestamp, int flags)
>>>                                         wanted_timestamp, flags);
>>>    }
>>>    +int avformat_index_get_entries_count(AVStream *st)
>>> +{
>>> +    return st->internal->nb_index_entries;
>>> +}
>>> +
>>> +const AVIndexEntry *avformat_index_get_entry(AVStream *st, int idx)
>>> +{
>>> +    if (idx < 0 || idx >= st->internal->nb_index_entries)
>>> +        return NULL;
>>> +
>>> +    return &st->internal->index_entries[idx];
>>> +}
>>> +
>>> +const AVIndexEntry *avformat_index_get_entry_from_timestamp(AVStream
>>> *st,
>>> +                                                            int64_t
>>> wanted_timestamp,
>>> +                                                            int flags)
>>> +{
>>> +    int idx = ff_index_search_timestamp(st->internal->index_entries,
>>> +                                        st->internal->nb_index_entries,
>>> +                                        wanted_timestamp, flags);
>>> +
>>> +    if (idx < 0)
>>> +        return NULL;
>>> +
>>> +    return &st->internal->index_entries[idx];
>>> +}
>>> +
>>>    static int64_t ff_read_timestamp(AVFormatContext *s, int
>>> stream_index, int64_t *ppos, int64_t pos_limit,
>>>                                     int64_t (*read_timestamp)(struct
>>> AVFormatContext *, int , int64_t *, int64_t ))
>>>    {
>>>
>>
>> _______________________________________________
>> ffmpeg-devel mailing list
>> ffmpeg-devel@ffmpeg.org
>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>
>> To unsubscribe, visit link above, or email
>> ffmpeg-devel-request@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-request@ffmpeg.org with subject "unsubscribe".
>
Anton Khirnov April 8, 2021, 1:09 p.m. UTC | #4
Quoting James Almer (2021-04-04 01:12:00)
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
> Now using the avformat_ prefix as Anton requested. I forgot about it when i
> made v3.
> 
>  libavformat/avformat.h | 39 +++++++++++++++++++++++++++++++++++++++
>  libavformat/utils.c    | 27 +++++++++++++++++++++++++++
>  2 files changed, 66 insertions(+)
> 
> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
> index 6a9b09160c..a1e87ef891 100644
> --- a/libavformat/avformat.h
> +++ b/libavformat/avformat.h
> @@ -2767,6 +2767,45 @@ int av_find_default_stream_index(AVFormatContext *s);
>   */
>  int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags);
>  
> +/**
> + * Get the index entry count for the given AVStream.
> + *
> + * @param st stream
> + * @return the number of index entries in the stream
> + */
> +int avformat_index_get_entries_count(AVStream *st);
> +
> +/**
> + * Get the AVIndexEntry corresponding to the given index.
> + *
> + * @param st          Stream containing the requested AVIndexEntry.
> + * @param idx         The desired index.
> + * @return A pointer to the requested AVIndexEntry if it exists, NULL otherwise.
> + *
> + * @note The pointer returned by this function is only guaranteed to be valid
> + *       until any function that could alter the stream or the AVFormatContext
> + *       that cointains it is called.
> + */
> +const AVIndexEntry *avformat_index_get_entry(AVStream *st, int idx);
> +
> +/**
> + * Get the AVIndexEntry corresponding to the given timestamp.
> + *
> + * @param st          Stream containing the requested AVIndexEntry.
> + * @param timestamp   Timestamp to retrieve the index entry for.
> + * @param flags       If AVSEEK_FLAG_BACKWARD then the returned entry will correspond
> + *                    to the timestamp which is <= the requested one, if backward
> + *                    is 0, then it will be >=
> + *                    if AVSEEK_FLAG_ANY seek to any frame, only keyframes otherwise.
> + * @return A pointer to the requested AVIndexEntry if it exists, NULL otherwise.
> + *
> + * @note The pointer returned by this function is only guaranteed to be valid
> + *       until any function that could alter the stream or the AVFormatContext
> + *       that cointains it is called.

How can the user know which functions can "alter the stream or the
AVFormatContext"?

I would prefer invalidating the pointer on ANY lavf call on that
AVFormatContext or its children, including calls to
avformat_index_get_entry*. That would allow us more freedom to change
the implementation later.
James Almer April 8, 2021, 1:19 p.m. UTC | #5
On 4/8/2021 10:09 AM, Anton Khirnov wrote:
> Quoting James Almer (2021-04-04 01:12:00)
>> Signed-off-by: James Almer <jamrial@gmail.com>
>> ---
>> Now using the avformat_ prefix as Anton requested. I forgot about it when i
>> made v3.
>>
>>   libavformat/avformat.h | 39 +++++++++++++++++++++++++++++++++++++++
>>   libavformat/utils.c    | 27 +++++++++++++++++++++++++++
>>   2 files changed, 66 insertions(+)
>>
>> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
>> index 6a9b09160c..a1e87ef891 100644
>> --- a/libavformat/avformat.h
>> +++ b/libavformat/avformat.h
>> @@ -2767,6 +2767,45 @@ int av_find_default_stream_index(AVFormatContext *s);
>>    */
>>   int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags);
>>   
>> +/**
>> + * Get the index entry count for the given AVStream.
>> + *
>> + * @param st stream
>> + * @return the number of index entries in the stream
>> + */
>> +int avformat_index_get_entries_count(AVStream *st);
>> +
>> +/**
>> + * Get the AVIndexEntry corresponding to the given index.
>> + *
>> + * @param st          Stream containing the requested AVIndexEntry.
>> + * @param idx         The desired index.
>> + * @return A pointer to the requested AVIndexEntry if it exists, NULL otherwise.
>> + *
>> + * @note The pointer returned by this function is only guaranteed to be valid
>> + *       until any function that could alter the stream or the AVFormatContext
>> + *       that cointains it is called.
>> + */
>> +const AVIndexEntry *avformat_index_get_entry(AVStream *st, int idx);
>> +
>> +/**
>> + * Get the AVIndexEntry corresponding to the given timestamp.
>> + *
>> + * @param st          Stream containing the requested AVIndexEntry.
>> + * @param timestamp   Timestamp to retrieve the index entry for.
>> + * @param flags       If AVSEEK_FLAG_BACKWARD then the returned entry will correspond
>> + *                    to the timestamp which is <= the requested one, if backward
>> + *                    is 0, then it will be >=
>> + *                    if AVSEEK_FLAG_ANY seek to any frame, only keyframes otherwise.
>> + * @return A pointer to the requested AVIndexEntry if it exists, NULL otherwise.
>> + *
>> + * @note The pointer returned by this function is only guaranteed to be valid
>> + *       until any function that could alter the stream or the AVFormatContext
>> + *       that cointains it is called.
> 
> How can the user know which functions can "alter the stream or the
> AVFormatContext"?

Any function that takes a non const AVStream or AVFormatContext should 
be considered one that can potentially alter the stream.

> 
> I would prefer invalidating the pointer on ANY lavf call on that
> AVFormatContext or its children, including calls to
> avformat_index_get_entry*. That would allow us more freedom to change
> the implementation later.

avformat_index_get_entry() takes a const AVStream after i included 
Andreas suggestion when i pushed this patch the other day, so in theory 
it should not change the index array stored within the AVStream. I'd 
have to remove the const qualifier.
If that's preferred, I can send a patch to make this change to the doxy 
and signature.
Anton Khirnov April 8, 2021, 2:08 p.m. UTC | #6
Quoting James Almer (2021-04-08 15:19:02)
> On 4/8/2021 10:09 AM, Anton Khirnov wrote:
> > Quoting James Almer (2021-04-04 01:12:00)
> >> Signed-off-by: James Almer <jamrial@gmail.com>
> >> ---
> >> Now using the avformat_ prefix as Anton requested. I forgot about it when i
> >> made v3.
> >>
> >>   libavformat/avformat.h | 39 +++++++++++++++++++++++++++++++++++++++
> >>   libavformat/utils.c    | 27 +++++++++++++++++++++++++++
> >>   2 files changed, 66 insertions(+)
> >>
> >> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
> >> index 6a9b09160c..a1e87ef891 100644
> >> --- a/libavformat/avformat.h
> >> +++ b/libavformat/avformat.h
> >> @@ -2767,6 +2767,45 @@ int av_find_default_stream_index(AVFormatContext *s);
> >>    */
> >>   int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags);
> >>   
> >> +/**
> >> + * Get the index entry count for the given AVStream.
> >> + *
> >> + * @param st stream
> >> + * @return the number of index entries in the stream
> >> + */
> >> +int avformat_index_get_entries_count(AVStream *st);
> >> +
> >> +/**
> >> + * Get the AVIndexEntry corresponding to the given index.
> >> + *
> >> + * @param st          Stream containing the requested AVIndexEntry.
> >> + * @param idx         The desired index.
> >> + * @return A pointer to the requested AVIndexEntry if it exists, NULL otherwise.
> >> + *
> >> + * @note The pointer returned by this function is only guaranteed to be valid
> >> + *       until any function that could alter the stream or the AVFormatContext
> >> + *       that cointains it is called.
> >> + */
> >> +const AVIndexEntry *avformat_index_get_entry(AVStream *st, int idx);
> >> +
> >> +/**
> >> + * Get the AVIndexEntry corresponding to the given timestamp.
> >> + *
> >> + * @param st          Stream containing the requested AVIndexEntry.
> >> + * @param timestamp   Timestamp to retrieve the index entry for.
> >> + * @param flags       If AVSEEK_FLAG_BACKWARD then the returned entry will correspond
> >> + *                    to the timestamp which is <= the requested one, if backward
> >> + *                    is 0, then it will be >=
> >> + *                    if AVSEEK_FLAG_ANY seek to any frame, only keyframes otherwise.
> >> + * @return A pointer to the requested AVIndexEntry if it exists, NULL otherwise.
> >> + *
> >> + * @note The pointer returned by this function is only guaranteed to be valid
> >> + *       until any function that could alter the stream or the AVFormatContext
> >> + *       that cointains it is called.
> > 
> > How can the user know which functions can "alter the stream or the
> > AVFormatContext"?
> 
> Any function that takes a non const AVStream or AVFormatContext should 
> be considered one that can potentially alter the stream.
> 
> > 
> > I would prefer invalidating the pointer on ANY lavf call on that
> > AVFormatContext or its children, including calls to
> > avformat_index_get_entry*. That would allow us more freedom to change
> > the implementation later.
> 
> avformat_index_get_entry() takes a const AVStream after i included 
> Andreas suggestion when i pushed this patch the other day, so in theory 
> it should not change the index array stored within the AVStream. I'd 
> have to remove the const qualifier.
> If that's preferred, I can send a patch to make this change to the doxy 
> and signature.

It seems preferable to me, but YMMV.
diff mbox series

Patch

diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 6a9b09160c..a1e87ef891 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -2767,6 +2767,45 @@  int av_find_default_stream_index(AVFormatContext *s);
  */
 int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags);
 
+/**
+ * Get the index entry count for the given AVStream.
+ *
+ * @param st stream
+ * @return the number of index entries in the stream
+ */
+int avformat_index_get_entries_count(AVStream *st);
+
+/**
+ * Get the AVIndexEntry corresponding to the given index.
+ *
+ * @param st          Stream containing the requested AVIndexEntry.
+ * @param idx         The desired index.
+ * @return A pointer to the requested AVIndexEntry if it exists, NULL otherwise.
+ *
+ * @note The pointer returned by this function is only guaranteed to be valid
+ *       until any function that could alter the stream or the AVFormatContext
+ *       that cointains it is called.
+ */
+const AVIndexEntry *avformat_index_get_entry(AVStream *st, int idx);
+
+/**
+ * Get the AVIndexEntry corresponding to the given timestamp.
+ *
+ * @param st          Stream containing the requested AVIndexEntry.
+ * @param timestamp   Timestamp to retrieve the index entry for.
+ * @param flags       If AVSEEK_FLAG_BACKWARD then the returned entry will correspond
+ *                    to the timestamp which is <= the requested one, if backward
+ *                    is 0, then it will be >=
+ *                    if AVSEEK_FLAG_ANY seek to any frame, only keyframes otherwise.
+ * @return A pointer to the requested AVIndexEntry if it exists, NULL otherwise.
+ *
+ * @note The pointer returned by this function is only guaranteed to be valid
+ *       until any function that could alter the stream or the AVFormatContext
+ *       that cointains it is called.
+ */
+const AVIndexEntry *avformat_index_get_entry_from_timestamp(AVStream *st,
+                                                            int64_t wanted_timestamp,
+                                                            int flags);
 /**
  * Add an index entry into a sorted list. Update the entry if the list
  * already contains it.
diff --git a/libavformat/utils.c b/libavformat/utils.c
index e9bf31e38b..942d7c8390 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -2176,6 +2176,33 @@  int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp, int flags)
                                      wanted_timestamp, flags);
 }
 
+int avformat_index_get_entries_count(AVStream *st)
+{
+    return st->internal->nb_index_entries;
+}
+
+const AVIndexEntry *avformat_index_get_entry(AVStream *st, int idx)
+{
+    if (idx < 0 || idx >= st->internal->nb_index_entries)
+        return NULL;
+
+    return &st->internal->index_entries[idx];
+}
+
+const AVIndexEntry *avformat_index_get_entry_from_timestamp(AVStream *st,
+                                                            int64_t wanted_timestamp,
+                                                            int flags)
+{
+    int idx = ff_index_search_timestamp(st->internal->index_entries,
+                                        st->internal->nb_index_entries,
+                                        wanted_timestamp, flags);
+
+    if (idx < 0)
+        return NULL;
+
+    return &st->internal->index_entries[idx];
+}
+
 static int64_t ff_read_timestamp(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit,
                                  int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ))
 {