[FFmpeg-devel] [PATCH] avcodec/avformat: Added codec_name to AVCodecContext and AVCodecParameters

2024-07-02 Thread Bernardo Pilarz via ffmpeg-devel

Added the codec_name field, in which the unprocessed, not-interpreted codec
name is stored.
This is useful when codecs that are not handled by the libav
(i.e. AV_CODEC_ID_NONE) are encountered, since the application might still
want to handle them.
Having this field allows the application to determine the codec type.

As of this commit, the codec_name field is only filled when opening an RTSP
stream, during the parsing of the SDP.

Signed-off-by: bpilarz 
---
 libavcodec/avcodec.h   | 10 ++
 libavcodec/codec_par.c | 19 +++
 libavcodec/codec_par.h | 10 ++
 libavcodec/options.c   |  1 +
 libavformat/rtsp.c |  5 +
 5 files changed, 45 insertions(+)

diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 2da63c87ea..464b4078fc 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -451,6 +451,16 @@ typedef struct AVCodecContext {
 int log_level_offset;
  enum AVMediaType codec_type; /* see AVMEDIA_TYPE_xxx */
+/**
+ * Generic codec name of the encoded data.
+ * + * Null-terminated string, can be NULL.
+ * Contents may vary depending on the source of the data stream.
+ * This is typically the string that's interpreted to determine 
'codec_id'.
+ * Must be allocated with av_malloc() or av_strdup() and will be 
freed by + * avcodec_free_context().

+ */
+char *codec_name;
 const struct AVCodec  *codec;
 enum AVCodecID codec_id; /* see AV_CODEC_ID_xxx */
 diff --git a/libavcodec/codec_par.c b/libavcodec/codec_par.c
index 790ea01d10..27d9880b53 100644
--- a/libavcodec/codec_par.c
+++ b/libavcodec/codec_par.c
@@ -31,6 +31,7 @@
  static void codec_parameters_reset(AVCodecParameters *par)
 {
+av_freep(&par->codec_name);
 av_freep(&par->extradata);
 av_channel_layout_uninit(&par->ch_layout);
 av_packet_side_data_free(&par->coded_side_data, 
&par->nb_coded_side_data);
@@ -110,6 +111,13 @@ int avcodec_parameters_copy(AVCodecParameters *dst, 
const AVCodecParameters *src

 codec_parameters_reset(dst);
 memcpy(dst, src, sizeof(*dst));
 +dst->codec_name = NULL;
+if (src->codec_name) {
+dst->codec_name = av_strdup(src->codec_name);
+if (!dst->codec_name)
+return AVERROR(ENOMEM);
+}
+ dst->ch_layout  = (AVChannelLayout){0};
 dst->extradata  = NULL;
 dst->extradata_size = 0;
@@ -142,6 +150,11 @@ int 
avcodec_parameters_from_context(AVCodecParameters *par,

 codec_parameters_reset(par);
  par->codec_type = codec->codec_type;
+if (codec->codec_name) {
+par->codec_name = av_strdup(codec->codec_name);
+if (!par->codec_name)
+return AVERROR(ENOMEM);
+}
 par->codec_id   = codec->codec_id;
 par->codec_tag  = codec->codec_tag;
 @@ -206,6 +219,12 @@ int avcodec_parameters_to_context(AVCodecContext 
*codec,

 int ret;
  codec->codec_type = par->codec_type;
+av_freep(&codec->codec_name);
+if (par->codec_name) {
+codec->codec_name = av_strdup(par->codec_name);
+if (!codec->codec_name)
+return AVERROR(ENOMEM);
+}
 codec->codec_id   = par->codec_id;
 codec->codec_tag  = par->codec_tag;
 diff --git a/libavcodec/codec_par.h b/libavcodec/codec_par.h
index f4b9bb5c06..196ef1fc66 100644
--- a/libavcodec/codec_par.h
+++ b/libavcodec/codec_par.h
@@ -49,6 +49,16 @@ typedef struct AVCodecParameters {
  * General type of the encoded data.
  */
 enum AVMediaType codec_type;
+/**
+ * Generic codec name of the encoded data.
+ * + * Null-terminated string, can be NULL.
+ * Contents may vary depending on the source of the data stream.
+ * This is typically the string that's interpreted to determine 
'codec_id'.
+ * Must be allocated with av_malloc() or av_strdup() and will be 
freed by + * avcodec_parameters_free().

+ */
+char *codec_name;
 /**
  * Specific type of the encoded data (the codec used).
  */
diff --git a/libavcodec/options.c b/libavcodec/options.c
index f60c41bdc3..c107f4efbd 100644
--- a/libavcodec/options.c
+++ b/libavcodec/options.c
@@ -170,6 +170,7 @@ void avcodec_free_context(AVCodecContext **pavctx)
  ff_codec_close(avctx);
 +av_freep(&avctx->codec_name);
 av_freep(&avctx->extradata);
 av_freep(&avctx->subtitle_header);
 av_freep(&avctx->intra_matrix);
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index db78735c7a..56363caeda 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -317,6 +317,11 @@ static int sdp_parse_rtpmap(AVFormatContext *s,
 par->codec_id = ff_rtp_codec_id(buf, par->codec_type);
 }
 +/* Copy the codec name, regardless of whether we can handle it.
+ * Applications might handle unknown codecs on their own. */
+av_freep(&par->codec_name);
+par->codec_name = av_strdup(buf);
+
 desc = avcodec_descriptor_get(par->codec_id);
 if (desc && desc->name)
 c_name = desc->name;
-

[FFmpeg-devel] [PATCH] avcodec/avformat: Added codec_name to AVCodecContext and AVCodecParameters

2024-07-03 Thread Bernardo Pilarz via ffmpeg-devel

Added the codec_name field, in which the unprocessed, not-interpreted codec
name is stored.
This is useful when codecs that are not handled by the libav
(i.e. AV_CODEC_ID_NONE) are encountered, since the application might still
want to handle them.
Having this field allows the application to determine the codec type.

As of this commit, the codec_name field is only filled when opening an RTSP
stream, during the parsing of the SDP.

Signed-off-by: bpilarz 
---
 libavcodec/avcodec.h   | 10 ++
 libavcodec/codec_par.c | 19 +++
 libavcodec/codec_par.h | 10 ++
 libavcodec/options.c   |  1 +
 libavformat/rtsp.c |  5 +
 5 files changed, 45 insertions(+)

diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 2da63c87ea..464b4078fc 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -451,6 +451,16 @@ typedef struct AVCodecContext {
 int log_level_offset;

 enum AVMediaType codec_type; /* see AVMEDIA_TYPE_xxx */
+/**
+ * Generic codec name of the encoded data.
+ *
+ * Null-terminated string, can be NULL.
+ * Contents may vary depending on the source of the data stream.
+ * This is typically the string that's interpreted to determine 
'codec_id'.
+ * Must be allocated with av_malloc() or av_strdup() and will be 
freed by

+ * avcodec_free_context().
+ */
+char *codec_name;
 const struct AVCodec  *codec;
 enum AVCodecID codec_id; /* see AV_CODEC_ID_xxx */

diff --git a/libavcodec/codec_par.c b/libavcodec/codec_par.c
index 790ea01d10..27d9880b53 100644
--- a/libavcodec/codec_par.c
+++ b/libavcodec/codec_par.c
@@ -31,6 +31,7 @@

 static void codec_parameters_reset(AVCodecParameters *par)
 {
+av_freep(&par->codec_name);
 av_freep(&par->extradata);
 av_channel_layout_uninit(&par->ch_layout);
 av_packet_side_data_free(&par->coded_side_data, 
&par->nb_coded_side_data);
@@ -110,6 +111,13 @@ int avcodec_parameters_copy(AVCodecParameters *dst, 
const AVCodecParameters *src

 codec_parameters_reset(dst);
 memcpy(dst, src, sizeof(*dst));

+dst->codec_name = NULL;
+if (src->codec_name) {
+dst->codec_name = av_strdup(src->codec_name);
+if (!dst->codec_name)
+return AVERROR(ENOMEM);
+}
+
 dst->ch_layout  = (AVChannelLayout){0};
 dst->extradata  = NULL;
 dst->extradata_size = 0;
@@ -142,6 +150,11 @@ int 
avcodec_parameters_from_context(AVCodecParameters *par,

 codec_parameters_reset(par);

 par->codec_type = codec->codec_type;
+if (codec->codec_name) {
+par->codec_name = av_strdup(codec->codec_name);
+if (!par->codec_name)
+return AVERROR(ENOMEM);
+}
 par->codec_id   = codec->codec_id;
 par->codec_tag  = codec->codec_tag;

@@ -206,6 +219,12 @@ int avcodec_parameters_to_context(AVCodecContext 
*codec,

 int ret;

 codec->codec_type = par->codec_type;
+av_freep(&codec->codec_name);
+if (par->codec_name) {
+codec->codec_name = av_strdup(par->codec_name);
+if (!codec->codec_name)
+return AVERROR(ENOMEM);
+}
 codec->codec_id   = par->codec_id;
 codec->codec_tag  = par->codec_tag;

diff --git a/libavcodec/codec_par.h b/libavcodec/codec_par.h
index f4b9bb5c06..196ef1fc66 100644
--- a/libavcodec/codec_par.h
+++ b/libavcodec/codec_par.h
@@ -49,6 +49,16 @@ typedef struct AVCodecParameters {
  * General type of the encoded data.
  */
 enum AVMediaType codec_type;
+/**
+ * Generic codec name of the encoded data.
+ *
+ * Null-terminated string, can be NULL.
+ * Contents may vary depending on the source of the data stream.
+ * This is typically the string that's interpreted to determine 
'codec_id'.
+ * Must be allocated with av_malloc() or av_strdup() and will be 
freed by

+ * avcodec_parameters_free().
+ */
+char *codec_name;
 /**
  * Specific type of the encoded data (the codec used).
  */
diff --git a/libavcodec/options.c b/libavcodec/options.c
index f60c41bdc3..c107f4efbd 100644
--- a/libavcodec/options.c
+++ b/libavcodec/options.c
@@ -170,6 +170,7 @@ void avcodec_free_context(AVCodecContext **pavctx)

 ff_codec_close(avctx);

+av_freep(&avctx->codec_name);
 av_freep(&avctx->extradata);
 av_freep(&avctx->subtitle_header);
 av_freep(&avctx->intra_matrix);
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index db78735c7a..56363caeda 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -317,6 +317,11 @@ static int sdp_parse_rtpmap(AVFormatContext *s,
 par->codec_id = ff_rtp_codec_id(buf, par->codec_type);
 }

+/* Copy the codec name, regardless of whether we can handle it.
+ * Applications might handle unknown codecs on their own. */
+av_freep(&par->codec_name);
+par->codec_name = av_strdup(buf);
+
 desc = avcodec_descriptor_get(par->codec_id);
 if (desc && desc->name)
 c_name = desc->name;
--
2

Re: [FFmpeg-devel] [PATCH] avcodec/avformat: Added codec_name to AVCodecContext and AVCodecParameters

2024-07-03 Thread Bernardo Pilarz via ffmpeg-devel

On 03/07/2024 10:02, Hendrik Leppkes wrote:

On Wed, Jul 3, 2024 at 9:48 AM Bernardo Pilarz via ffmpeg-devel
 wrote:

Added the codec_name field, in which the unprocessed, not-interpreted codec
name is stored.
This is useful when codecs that are not handled by the libav
(i.e. AV_CODEC_ID_NONE) are encountered, since the application might still
want to handle them.
Having this field allows the application to determine the codec type.

As of this commit, the codec_name field is only filled when opening an RTSP
stream, during the parsing of the SDP.

Signed-off-by: bpilarz 
---
   libavcodec/avcodec.h   | 10 ++
   libavcodec/codec_par.c | 19 +++
   libavcodec/codec_par.h | 10 ++
   libavcodec/options.c   |  1 +
   libavformat/rtsp.c |  5 +
   5 files changed, 45 insertions(+)

diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 2da63c87ea..464b4078fc 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -451,6 +451,16 @@ typedef struct AVCodecContext {
   int log_level_offset;

   enum AVMediaType codec_type; /* see AVMEDIA_TYPE_xxx */
+/**
+ * Generic codec name of the encoded data.
+ *
+ * Null-terminated string, can be NULL.
+ * Contents may vary depending on the source of the data stream.
+ * This is typically the string that's interpreted to determine
'codec_id'.
+ * Must be allocated with av_malloc() or av_strdup() and will be
freed by
+ * avcodec_free_context().
+ */
+char *codec_name;
   const struct AVCodec  *codec;
   enum AVCodecID codec_id; /* see AV_CODEC_ID_xxx */


Adding a new field here is an ABI break, it would need to go at the
end of the struct.

In general, I feel like this might be better served to go into
metadata though, especially as very few containers have a string codec
identifier to begin with.

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

I would be very glad to do it the right way, but I need some guidance 
since this is the first time I try to contribute to FFmpeg.


The problem that I am trying to solve is receiving metadata from an RTSP 
stream (in example, ONVIF metadata identified by the codec name 
'vcd.onvif.metadata').
This is data that the application will want to handle on its own (and 
not through FFmpeg).


Can you guide me on how to do this properly?

Thanks,
Bernardo


--
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.

___
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/avformat: Added codec_name to AVCodecContext and AVCodecParameters

2024-07-03 Thread Bernardo Pilarz via ffmpeg-devel

On 03/07/2024 11:10, Anton Khirnov wrote:

Quoting Bernardo Pilarz via ffmpeg-devel (2024-07-03 10:10:15)

+char *codec_name;
const struct AVCodec  *codec;
enum AVCodecID codec_id; /* see AV_CODEC_ID_xxx */


Adding a new field here is an ABI break, it would need to go at the
end of the struct.

In general, I feel like this might be better served to go into
metadata though, especially as very few containers have a string codec
identifier to begin with.

I would be very glad to do it the right way, but I need some guidance
since this is the first time I try to contribute to FFmpeg.

The problem that I am trying to solve is receiving metadata from an RTSP
stream (in example, ONVIF metadata identified by the codec name
'vcd.onvif.metadata').
This is data that the application will want to handle on its own (and
not through FFmpeg).

Can you guide me on how to do this properly?

First of all, this should definitely NOT go into AVCodecContext, since
the entire premise is that we have no codec ID and hence no decoders or
encoders, so a codec context makes no sense.

Next, the idea that you can define a generic container-independent
"codec name" sounds dubious to me, as they are not universally
standardized. You'd either have to define precisely what can the API
caller expect in there, or make this a private AV_OPT_FLAG_EXPORT option
of your demuxer. I'd suggest the second, as it's much simpler, though
IIRC we do not yet support per-stream private options.

I ended up adding it to the AVCodecContext because 
'avformat_find_stream_info()' invokes 'avcodec_parameters_to_context()' 
followed by 'avcodec_parameters_from_context()', thereby overwriting the 
entire 'codecpar' field of each stream in my format context.
This also means that an AVCodecContext is in fact created even for 
streams with no codec ID.


It's not clear to me how I can use AV_OPT_FLAG_EXPORT (it's my fault 
because I don't know the library so well).
It might very well be the solution I am looking for, but I need some 
help in understanding how to implement it.


The basic problem is I need to get the "codec name" information that is 
available in 'sdp_parse_rtpmap()' and is completely lost when the codec 
is not supported by FFmpeg.
By the way, we are talking of AVMEDIA_TYPE_DATA streams, and codecs that 
are potentially custom/not widespread and therefore should probably be 
handled by the application rather than by ffmpeg itself.


P.S.: I am currently only using FFmpeg to grab an RTSP stream. The audio 
and video streams might very well get decoded using FFmpeg later on, but 
so far I am only concerned with getting the compressed packets and being 
able to read their declared codec names.



--
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.

___
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/avformat: Added codec_name to AVCodecContext and AVCodecParameters

2024-07-03 Thread Bernardo Pilarz via ffmpeg-devel

On 03/07/2024 11:56, Bernardo Pilarz via ffmpeg-devel wrote:

On 03/07/2024 11:10, Anton Khirnov wrote:

Quoting Bernardo Pilarz via ffmpeg-devel (2024-07-03 10:10:15)

+    char *codec_name;
    const struct AVCodec  *codec;
    enum AVCodecID codec_id; /* see AV_CODEC_ID_xxx */


Adding a new field here is an ABI break, it would need to go at the
end of the struct.

In general, I feel like this might be better served to go into
metadata though, especially as very few containers have a string codec
identifier to begin with.

I would be very glad to do it the right way, but I need some guidance
since this is the first time I try to contribute to FFmpeg.

The problem that I am trying to solve is receiving metadata from an 
RTSP

stream (in example, ONVIF metadata identified by the codec name
'vcd.onvif.metadata').
This is data that the application will want to handle on its own (and
not through FFmpeg).

Can you guide me on how to do this properly?

First of all, this should definitely NOT go into AVCodecContext, since
the entire premise is that we have no codec ID and hence no decoders or
encoders, so a codec context makes no sense.

Next, the idea that you can define a generic container-independent
"codec name" sounds dubious to me, as they are not universally
standardized. You'd either have to define precisely what can the API
caller expect in there, or make this a private AV_OPT_FLAG_EXPORT option
of your demuxer. I'd suggest the second, as it's much simpler, though
IIRC we do not yet support per-stream private options.

I ended up adding it to the AVCodecContext because 
'avformat_find_stream_info()' invokes 
'avcodec_parameters_to_context()' followed by 
'avcodec_parameters_from_context()', thereby overwriting the entire 
'codecpar' field of each stream in my format context.
This also means that an AVCodecContext is in fact created even for 
streams with no codec ID.


It's not clear to me how I can use AV_OPT_FLAG_EXPORT (it's my fault 
because I don't know the library so well).
It might very well be the solution I am looking for, but I need some 
help in understanding how to implement it.


The basic problem is I need to get the "codec name" information that 
is available in 'sdp_parse_rtpmap()' and is completely lost when the 
codec is not supported by FFmpeg.
By the way, we are talking of AVMEDIA_TYPE_DATA streams, and codecs 
that are potentially custom/not widespread and therefore should 
probably be handled by the application rather than by ffmpeg itself.


P.S.: I am currently only using FFmpeg to grab an RTSP stream. The 
audio and video streams might very well get decoded using FFmpeg later 
on, but so far I am only concerned with getting the compressed packets 
and being able to read their declared codec names.



How about putting this information in the stream's 
'codecpar.coded_side_data'?


--
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.

___
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] avcodec/avformat: Store SDP attributes from RTSP stream into AVStream side data.

2024-07-08 Thread Bernardo Pilarz via ffmpeg-devel

Connecting to an RTSP stream will now cause the SDP attributes of each media
stream to be stored in the codecpar of the relative AVStream.
The SDP attributes are stored in the coded_side_data using the (new) type
AV_PKT_DATA_SDP_ATTRIBUTES (AVPacketSideDataType enum).

Signed-off-by: Bernardo Pilarz 
---
 libavcodec/packet.h |  7 
 libavformat/rtsp.c  | 97 +
 2 files changed, 104 insertions(+)

diff --git a/libavcodec/packet.h b/libavcodec/packet.h
index f05deb7950..54bfc96c38 100644
--- a/libavcodec/packet.h
+++ b/libavcodec/packet.h
@@ -326,6 +326,13 @@ enum AVPacketSideDataType {
 */
 AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT,

+/**
+ * Attributes found in the SDP, associated with the stream. This is 
a list

+ * of zero terminated key/value strings. There is no end marker for the
+ * list, so it is required to rely on the side data size to stop.
+ */
+AV_PKT_DATA_SDP_ATTRIBUTES,
+
 /**
  * The number of side data types.
  * This is not part of the public API/ABI in the sense that it may
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index db78735c7a..dfc1e1c9bb 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -283,6 +283,91 @@ static int init_satip_stream(AVFormatContext *s)
 }
 #endif

+
+static int sdp_add_attribute_to_stream_side_data(AVFormatContext *s, 
AVStream *st,
+ const char 
*attribute_line)

+{
+AVPacketSideData *side_data = NULL;
+AVDictionary* attributes_dict = NULL;
+char *key = NULL, *value = NULL;
+int ret = 0;
+
+/* Get the stream's attributes dictionary.
+ * If the stream has no attributes dictionary, it will be automatically
+ * created by av_dict_set. */
+side_data = av_packet_side_data_get(st->codecpar->coded_side_data,
+st->codecpar->nb_coded_side_data,
+AV_PKT_DATA_SDP_ATTRIBUTES);
+if (side_data) {
+ret = av_packet_unpack_dictionary(side_data->data, side_data->size,
+  &attributes_dict);
+if (ret) {
+av_log(s, AV_LOG_WARNING,
+   "Unable to unpack SDP attributes dictionary.\n");
+return -1;
+}
+}
+
+/* The attribute can either be a value attribute (key:value) or 
property

+ * attribute (just the key).
+ * Look for the ':' separator, and create the 'key' and 'value'
+ * appropriately. */
+const char *separator = strchr(attribute_line, ':');
+if (separator) {
+/* Make a copy of the key and value. */
+key = av_strndup(attribute_line, separator - attribute_line);
+value = av_strdup(separator + 1);
+} else {
+/* Copy the key and create an empty value. */
+key = av_strdup(attribute_line);
+value = av_mallocz(1);
+}
+if (!key || !value) {
+av_dict_free(&attributes_dict);
+av_free(value);
+av_free(key);
+return -1;
+}
+
+/* Add the attribute, then pack the dictionary again. */
+ret = av_dict_set(&attributes_dict, key, value,
+  AV_DICT_DONT_STRDUP_KEY |
+  AV_DICT_DONT_STRDUP_VAL |
+  AV_DICT_MULTIKEY);
+if (ret) {
+av_log(s, AV_LOG_WARNING,
+   "Unable to add SDL attribute to dictionary.\n");
+av_dict_free(&attributes_dict);
+return -1;
+}
+size_t packed_dict_size = 0u;
+uint8_t *packed_dict = av_packet_pack_dictionary(attributes_dict,
+ &packed_dict_size);
+
+/* Free the dictionary, which is not needed any longer. */
+av_dict_free(&attributes_dict);
+
+/* Make sure the dictionary was packet successfully, then add it 
back to

+ * the stream's side data. */
+if (!packed_dict) {
+av_log(s, AV_LOG_WARNING,
+   "Unable to pack SDP attributes dictionary.\n");
+return -1;
+}
+side_data = av_packet_side_data_add(&st->codecpar->coded_side_data,
+&st->codecpar->nb_coded_side_data,
+AV_PKT_DATA_SDP_ATTRIBUTES,
+packed_dict, packed_dict_size,
+0);
+if (!side_data) {
+av_log(s, AV_LOG_WARNING,
+   "Unable to add SDP attributes side data to stream.\n");
+return -1;
+}
+
+return 0;
+}
+
 /* parse the rtpmap description: /[/params>] */

 static int sdp_parse_rtpmap(AVFormatContext *s,
 AVStream *st, RTSPStream *rtsp_st,
@@ -570,6 +655,18 @@ static void sdp_parse_line(AVFormatContext *s, 
SDPParseState *s1,

sizeof(rtsp_st->control_url));
 break;
 case 'a':
+/* add all SDP attributes to the stream's side data */
+

[FFmpeg-devel] [PATCH] avcodec/avformat: Store SDP attributes from RTSP stream into AVStream side data.

2024-07-09 Thread Bernardo Pilarz via ffmpeg-devel

Connecting to an RTSP stream will now cause the SDP attributes of each media
stream to be stored in the codecpar of the relative AVStream.
The SDP attributes are stored in the coded_side_data using the (new) type
AV_PKT_DATA_SDP_ATTRIBUTES (AVPacketSideDataType enum).

Signed-off-by: bpilarz 
---
 libavcodec/packet.h |  7 
 libavformat/rtsp.c  | 96 +
 2 files changed, 103 insertions(+)

diff --git a/libavcodec/packet.h b/libavcodec/packet.h
index 13667ffa36..dabe970dbb 100644
--- a/libavcodec/packet.h
+++ b/libavcodec/packet.h
@@ -339,6 +339,13 @@ enum AVPacketSideDataType {
  */
 AV_PKT_DATA_FRAME_CROPPING,

+/**
+ * Attributes found in the SDP, associated with the stream. This is 
a list

+ * of zero terminated key/value strings. There is no end marker for the
+ * list, so it is required to rely on the side data size to stop.
+ */
+AV_PKT_DATA_SDP_ATTRIBUTES,
+
 /**
  * The number of side data types.
  * This is not part of the public API/ABI in the sense that it may
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index 19b93df839..efe01141c3 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -283,6 +283,90 @@ static int init_satip_stream(AVFormatContext *s)
 }
 #endif

+static int sdp_add_attribute_to_stream_side_data(AVFormatContext *s, 
AVStream *st,
+ const char 
*attribute_line)

+{
+AVPacketSideData *side_data = NULL;
+AVDictionary* attributes_dict = NULL;
+char *key = NULL, *value = NULL;
+int ret = 0;
+
+/* Get the stream's attributes dictionary.
+ * If the stream has no attributes dictionary, it will be automatically
+ * created by av_dict_set. */
+side_data = av_packet_side_data_get(st->codecpar->coded_side_data,
+st->codecpar->nb_coded_side_data,
+AV_PKT_DATA_SDP_ATTRIBUTES);
+if (side_data) {
+ret = av_packet_unpack_dictionary(side_data->data, side_data->size,
+  &attributes_dict);
+if (ret) {
+av_log(s, AV_LOG_WARNING,
+   "Unable to unpack SDP attributes dictionary.\n");
+return -1;
+}
+}
+
+/* The attribute can either be a value attribute (key:value) or 
property

+ * attribute (just the key).
+ * Look for the ':' separator, and create the 'key' and 'value'
+ * appropriately. */
+const char *separator = strchr(attribute_line, ':');
+if (separator) {
+/* Make a copy of the key and value. */
+key = av_strndup(attribute_line, separator - attribute_line);
+value = av_strdup(separator + 1);
+} else {
+/* Copy the key and create an empty value. */
+key = av_strdup(attribute_line);
+value = av_mallocz(1);
+}
+if (!key || !value) {
+av_dict_free(&attributes_dict);
+av_free(value);
+av_free(key);
+return -1;
+}
+
+/* Add the attribute, then pack the dictionary again. */
+ret = av_dict_set(&attributes_dict, key, value,
+  AV_DICT_DONT_STRDUP_KEY |
+  AV_DICT_DONT_STRDUP_VAL |
+  AV_DICT_MULTIKEY);
+if (ret) {
+av_log(s, AV_LOG_WARNING,
+   "Unable to add SDL attribute to dictionary.\n");
+av_dict_free(&attributes_dict);
+return -1;
+}
+size_t packed_dict_size = 0u;
+uint8_t *packed_dict = av_packet_pack_dictionary(attributes_dict,
+ &packed_dict_size);
+
+/* Free the dictionary, which is not needed any longer. */
+av_dict_free(&attributes_dict);
+
+/* Make sure the dictionary was packet successfully, then add it 
back to

+ * the stream's side data. */
+if (!packed_dict) {
+av_log(s, AV_LOG_WARNING,
+   "Unable to pack SDP attributes dictionary.\n");
+return -1;
+}
+side_data = av_packet_side_data_add(&st->codecpar->coded_side_data,
+&st->codecpar->nb_coded_side_data,
+AV_PKT_DATA_SDP_ATTRIBUTES,
+packed_dict, packed_dict_size,
+0);
+if (!side_data) {
+av_log(s, AV_LOG_WARNING,
+   "Unable to add SDP attributes side data to stream.\n");
+return -1;
+}
+
+return 0;
+}
+
 /* parse the rtpmap description: /[/params>] */

 static int sdp_parse_rtpmap(AVFormatContext *s,
 AVStream *st, RTSPStream *rtsp_st,
@@ -570,6 +654,18 @@ static void sdp_parse_line(AVFormatContext *s, 
SDPParseState *s1,

sizeof(rtsp_st->control_url));
 break;
 case 'a':
+/* add all SDP attributes to the stream's side data */
+if (rt->nb_rtsp_stream

[FFmpeg-devel] [PATCH] avcodec/avformat: Store SDP attributes from RTSP stream into AVStream side data.

2024-07-09 Thread Bernardo Pilarz via ffmpeg-devel

Connecting to an RTSP stream will now cause the SDP attributes of each media
stream to be stored in the codecpar of the relative AVStream.
The SDP attributes are stored in the coded_side_data using the (new) type
AV_PKT_DATA_SDP_ATTRIBUTES (AVPacketSideDataType enum).

Signed-off-by: Bernardo Pilarz 
---
 libavcodec/packet.h |  7 
 libavformat/rtsp.c  | 97 +
 2 files changed, 104 insertions(+)
 mode change 100644 => 100755 libavcodec/packet.h
 mode change 100644 => 100755 libavformat/rtsp.c

diff --git a/libavcodec/packet.h b/libavcodec/packet.h
old mode 100644
new mode 100755
index 13667ffa36..8cbb1c2a75
--- a/libavcodec/packet.h
+++ b/libavcodec/packet.h
@@ -339,6 +339,13 @@ enum AVPacketSideDataType {
  */
 AV_PKT_DATA_FRAME_CROPPING,
 
+/**

+ * Attributes found in the SDP, associated with the stream. This is a
+ * list of zero terminated key/value strings. There is no end marker for
+ * the list, so it is required to rely on the side data size to stop.
+ */
+AV_PKT_DATA_SDP_ATTRIBUTES,
+
 /**
  * The number of side data types.
  * This is not part of the public API/ABI in the sense that it may
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
old mode 100644
new mode 100755
index 19b93df839..10594e501a
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -283,6 +283,91 @@ static int init_satip_stream(AVFormatContext *s)
 }
 #endif
 
+static int sdp_add_attribute_to_stream_side_data(AVFormatContext *s,

+ AVStream *st,
+ const char *p)
+{
+AVPacketSideData *side_data = NULL;
+AVDictionary* attributes_dict = NULL;
+char *key = NULL, *value = NULL;
+int ret = 0;
+
+/* Get the stream's attributes dictionary.
+ * If the stream has no attributes dictionary, it will be automatically
+ * created by av_dict_set. */
+side_data = av_packet_side_data_get(st->codecpar->coded_side_data,
+st->codecpar->nb_coded_side_data,
+AV_PKT_DATA_SDP_ATTRIBUTES);
+if (side_data) {
+ret = av_packet_unpack_dictionary(side_data->data, side_data->size,
+  &attributes_dict);
+if (ret) {
+av_log(s, AV_LOG_WARNING,
+   "Unable to unpack SDP attributes dictionary.\n");
+return -1;
+}
+}
+
+/* The attribute can either be a value attribute (key:value) or
+ * property attribute (just the key).
+ * Look for the ':' separator, and create the 'key' and 'value'
+ * appropriately. */
+const char *separator = strchr(p, ':');
+if (separator) {
+/* Make a copy of the key and value. */
+key = av_strndup(p, separator - p);
+value = av_strdup(separator + 1);
+} else {
+/* Copy the key and create an empty value. */
+key = av_strdup(p);
+value = av_mallocz(1);
+}
+if (!key || !value) {
+av_dict_free(&attributes_dict);
+av_free(value);
+av_free(key);
+return -1;
+}
+
+/* Add the attribute, then pack the dictionary again. */
+ret = av_dict_set(&attributes_dict, key, value,
+  AV_DICT_DONT_STRDUP_KEY |
+  AV_DICT_DONT_STRDUP_VAL |
+  AV_DICT_MULTIKEY);
+if (ret) {
+av_log(s, AV_LOG_WARNING,
+   "Unable to add SDL attribute to dictionary.\n");
+av_dict_free(&attributes_dict);
+return -1;
+}
+size_t packed_dict_size = 0u;
+uint8_t *packed_dict = av_packet_pack_dictionary(attributes_dict,
+ &packed_dict_size);
+
+/* Free the dictionary, which is not needed any longer. */
+av_dict_free(&attributes_dict);
+
+/* Make sure the dictionary was packet successfully, then add it
+ * back to the stream's side data. */
+if (!packed_dict) {
+av_log(s, AV_LOG_WARNING,
+   "Unable to pack SDP attributes dictionary.\n");
+return -1;
+}
+side_data = av_packet_side_data_add(&st->codecpar->coded_side_data,
+&st->codecpar->nb_coded_side_data,
+AV_PKT_DATA_SDP_ATTRIBUTES,
+packed_dict, packed_dict_size,
+0);
+if (!side_data) {
+av_log(s, AV_LOG_WARNING,
+   "Unable to add SDP attributes side data to stream.\n");
+return -1;
+}
+
+return 0;
+}
+
 /* parse the rtpmap description: /[/] */
 static int sdp_parse_rtpmap(AVFormatContext *s,
 AVStream *st, RTSPStream *rtsp_st,
@@ -570,6 +655,18 @@ static void sdp_parse_line(AVFormatContext *s, 
SDPParseState *s1,
sizeof(rtsp_st->control_url))

[FFmpeg-devel] [PATCH] avcodec/avformat: Store SDP attributes from RTSP stream into AVStream side data.

2024-07-09 Thread Bernardo Pilarz via ffmpeg-devel

Connecting to an RTSP stream will now cause the SDP attributes of each media
stream to be stored in the codecpar of the relative AVStream.
The SDP attributes are stored in the coded_side_data using the (new) type
AV_PKT_DATA_SDP_ATTRIBUTES (AVPacketSideDataType enum).

Signed-off-by: bpilarz 
---
 libavcodec/packet.h |  7 
 libavformat/rtsp.c  | 97 +
 2 files changed, 104 insertions(+)

diff --git a/libavcodec/packet.h b/libavcodec/packet.h
index 13667ffa36..3091c3ce56
--- a/libavcodec/packet.h
+++ b/libavcodec/packet.h
@@ -339,6 +339,13 @@ enum AVPacketSideDataType {
  */
 AV_PKT_DATA_FRAME_CROPPING,
 
+/**

+ * Attributes found in the SDP, associated with the stream. This is a
+ * list of zero terminated key/value strings. There is no end marker for
+ * the list, so it is required to rely on the side data size to stop.
+ */
+AV_PKT_DATA_SDP_ATTRIBUTES,
+
 /**
  * The number of side data types.
  * This is not part of the public API/ABI in the sense that it may
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index 19b93df839..10594e501a
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -283,6 +283,91 @@ static int init_satip_stream(AVFormatContext *s)
 }
 #endif
 
+static int sdp_add_attribute_to_stream_side_data(AVFormatContext *s,

+ AVStream *st,
+ const char *p)
+{
+AVPacketSideData *side_data = NULL;
+AVDictionary* attributes_dict = NULL;
+char *key = NULL, *value = NULL;
+int ret = 0;
+
+/* Get the stream's attributes dictionary.
+ * If the stream has no attributes dictionary, it will be automatically
+ * created by av_dict_set. */
+side_data = av_packet_side_data_get(st->codecpar->coded_side_data,
+st->codecpar->nb_coded_side_data,
+AV_PKT_DATA_SDP_ATTRIBUTES);
+if (side_data) {
+ret = av_packet_unpack_dictionary(side_data->data, side_data->size,
+  &attributes_dict);
+if (ret) {
+av_log(s, AV_LOG_WARNING,
+   "Unable to unpack SDP attributes dictionary.\n");
+return -1;
+}
+}
+
+/* The attribute can either be a value attribute (key:value) or
+ * property attribute (just the key).
+ * Look for the ':' separator, and create the 'key' and 'value'
+ * appropriately. */
+const char *separator = strchr(p, ':');
+if (separator) {
+/* Make a copy of the key and value. */
+key = av_strndup(p, separator - p);
+value = av_strdup(separator + 1);
+} else {
+/* Copy the key and create an empty value. */
+key = av_strdup(p);
+value = av_mallocz(1);
+}
+if (!key || !value) {
+av_dict_free(&attributes_dict);
+av_free(value);
+av_free(key);
+return -1;
+}
+
+/* Add the attribute, then pack the dictionary again. */
+ret = av_dict_set(&attributes_dict, key, value,
+  AV_DICT_DONT_STRDUP_KEY |
+  AV_DICT_DONT_STRDUP_VAL |
+  AV_DICT_MULTIKEY);
+if (ret) {
+av_log(s, AV_LOG_WARNING,
+   "Unable to add SDL attribute to dictionary.\n");
+av_dict_free(&attributes_dict);
+return -1;
+}
+size_t packed_dict_size = 0u;
+uint8_t *packed_dict = av_packet_pack_dictionary(attributes_dict,
+ &packed_dict_size);
+
+/* Free the dictionary, which is not needed any longer. */
+av_dict_free(&attributes_dict);
+
+/* Make sure the dictionary was packet successfully, then add it
+ * back to the stream's side data. */
+if (!packed_dict) {
+av_log(s, AV_LOG_WARNING,
+   "Unable to pack SDP attributes dictionary.\n");
+return -1;
+}
+side_data = av_packet_side_data_add(&st->codecpar->coded_side_data,
+&st->codecpar->nb_coded_side_data,
+AV_PKT_DATA_SDP_ATTRIBUTES,
+packed_dict, packed_dict_size,
+0);
+if (!side_data) {
+av_log(s, AV_LOG_WARNING,
+   "Unable to add SDP attributes side data to stream.\n");
+return -1;
+}
+
+return 0;
+}
+
 /* parse the rtpmap description: /[/] */
 static int sdp_parse_rtpmap(AVFormatContext *s,
 AVStream *st, RTSPStream *rtsp_st,
@@ -570,6 +655,18 @@ static void sdp_parse_line(AVFormatContext *s, 
SDPParseState *s1,
sizeof(rtsp_st->control_url));
 break;
 case 'a':
+/* add all SDP attributes to the stream's side data */
+if (rt->nb_rtsp_streams > 0) {
+rtsp_st = rt->rtsp_st

Re: [FFmpeg-devel] [PATCH] avcodec/avformat: Store SDP attributes from RTSP stream into AVStream side data.

2024-07-10 Thread Bernardo Pilarz via ffmpeg-devel

Hi,

I've tried to push this patch several times, but it looks like my email client 
is messing up the diff, and patchwork isn't able to apply it.

On 09/07/2024 12:02, Bernardo Pilarz via ffmpeg-devel wrote:

Connecting to an RTSP stream will now cause the SDP attributes of each media
stream to be stored in the codecpar of the relative AVStream.
The SDP attributes are stored in the coded_side_data using the (new) type
AV_PKT_DATA_SDP_ATTRIBUTES (AVPacketSideDataType enum).

Signed-off-by: bpilarz 
---
 libavcodec/packet.h |  7 
 libavformat/rtsp.c  | 97 +
 2 files changed, 104 insertions(+)

diff --git a/libavcodec/packet.h b/libavcodec/packet.h
index 13667ffa36..3091c3ce56
--- a/libavcodec/packet.h
+++ b/libavcodec/packet.h
@@ -339,6 +339,13 @@ enum AVPacketSideDataType {
  */
 AV_PKT_DATA_FRAME_CROPPING,

+    /**
+ * Attributes found in the SDP, associated with the stream. This is a
+ * list of zero terminated key/value strings. There is no end marker for
+ * the list, so it is required to rely on the side data size to stop.
+ */
+    AV_PKT_DATA_SDP_ATTRIBUTES,
+
 /**
  * The number of side data types.
  * This is not part of the public API/ABI in the sense that it may
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index 19b93df839..10594e501a
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -283,6 +283,91 @@ static int init_satip_stream(AVFormatContext *s)
 }
 #endif

+static int sdp_add_attribute_to_stream_side_data(AVFormatContext *s,
+ AVStream *st,
+ const char *p)
+{
+    AVPacketSideData *side_data = NULL;
+    AVDictionary* attributes_dict = NULL;
+    char *key = NULL, *value = NULL;
+    int ret = 0;
+
+    /* Get the stream's attributes dictionary.
+ * If the stream has no attributes dictionary, it will be automatically
+ * created by av_dict_set. */
+    side_data = av_packet_side_data_get(st->codecpar->coded_side_data,
+ st->codecpar->nb_coded_side_data,
+ AV_PKT_DATA_SDP_ATTRIBUTES);
+    if (side_data) {
+    ret = av_packet_unpack_dictionary(side_data->data, side_data->size,
+  &attributes_dict);
+    if (ret) {
+    av_log(s, AV_LOG_WARNING,
+   "Unable to unpack SDP attributes dictionary.\n");
+    return -1;
+    }
+    }
+
+    /* The attribute can either be a value attribute (key:value) or
+ * property attribute (just the key).
+ * Look for the ':' separator, and create the 'key' and 'value'
+ * appropriately. */
+    const char *separator = strchr(p, ':');
+    if (separator) {
+    /* Make a copy of the key and value. */
+    key = av_strndup(p, separator - p);
+    value = av_strdup(separator + 1);
+    } else {
+    /* Copy the key and create an empty value. */
+    key = av_strdup(p);
+    value = av_mallocz(1);
+    }
+    if (!key || !value) {
+    av_dict_free(&attributes_dict);
+    av_free(value);
+    av_free(key);
+    return -1;
+    }
+
+    /* Add the attribute, then pack the dictionary again. */
+    ret = av_dict_set(&attributes_dict, key, value,
+  AV_DICT_DONT_STRDUP_KEY |
+  AV_DICT_DONT_STRDUP_VAL |
+  AV_DICT_MULTIKEY);
+    if (ret) {
+    av_log(s, AV_LOG_WARNING,
+   "Unable to add SDL attribute to dictionary.\n");
+    av_dict_free(&attributes_dict);
+    return -1;
+    }
+    size_t packed_dict_size = 0u;
+    uint8_t *packed_dict = av_packet_pack_dictionary(attributes_dict,
+ &packed_dict_size);
+
+    /* Free the dictionary, which is not needed any longer. */
+    av_dict_free(&attributes_dict);
+
+    /* Make sure the dictionary was packet successfully, then add it
+ * back to the stream's side data. */
+    if (!packed_dict) {
+    av_log(s, AV_LOG_WARNING,
+   "Unable to pack SDP attributes dictionary.\n");
+    return -1;
+    }
+    side_data = av_packet_side_data_add(&st->codecpar->coded_side_data,
+ &st->codecpar->nb_coded_side_data,
+ AV_PKT_DATA_SDP_ATTRIBUTES,
+    packed_dict, packed_dict_size,
+    0);
+    if (!side_data) {
+    av_log(s, AV_LOG_WARNING,
+   "Unable to add SDP attributes side data to stream.\n");
+    return -1;
+    }
+
+    return 0;
+}
+
 /* parse the rtpmap description: /[/] */
 static int sdp_parse_rtpmap(AVFormatContext *s,
 AVStream *st, RTSPStream *rtsp_st,
@@ -570,6 +655,18 @@ static void sdp_parse_line(AVFormatContext *s, 
SDPParseState *s1,
    sizeof(rtsp_st->control_ur