* [FFmpeg-devel] [PATCH] avcodec/avformat: Store SDP attributes from RTSP stream into AVStream side data.
@ 2024-07-09 8:44 Bernardo Pilarz via ffmpeg-devel
0 siblings, 0 replies; 5+ messages in thread
From: Bernardo Pilarz via ffmpeg-devel @ 2024-07-09 8:44 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Bernardo Pilarz
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 <bernardo.pilarz@aitek.it>
---
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: <codec_name>/<clock_rate>[/<other 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 */
+ if (rt->nb_rtsp_streams > 0) {
+ rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
+ if (rtsp_st->stream_index >= 0) {
+ st = s->streams[rtsp_st->stream_index];
+ if (sdp_add_attribute_to_stream_side_data(s, st, p)) {
+ av_log(s, AV_LOG_WARNING,
+ "Failed to add SDP attribute to stream");
+ }
+ }
+ }
+ /* now parse the SDP attribute line */
if (av_strstart(p, "control:", &p)) {
if (rt->nb_rtsp_streams == 0) {
if (!strncmp(p, "rtsp://", 7))
--
2.43.5
--
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-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [FFmpeg-devel] [PATCH] avcodec/avformat: Store SDP attributes from RTSP stream into AVStream side data.
2024-07-09 10:02 Bernardo Pilarz via ffmpeg-devel
@ 2024-07-10 9:09 ` Bernardo Pilarz via ffmpeg-devel
0 siblings, 0 replies; 5+ messages in thread
From: Bernardo Pilarz via ffmpeg-devel @ 2024-07-10 9:09 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Bernardo Pilarz
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 <bernardo.pilarz@aitek.it>
> ---
> 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: <codec_name>/<clock_rate>[/<other 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 */
> + if (rt->nb_rtsp_streams > 0) {
> + rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
> + if (rtsp_st->stream_index >= 0) {
> + st = s->streams[rtsp_st->stream_index];
> + if (sdp_add_attribute_to_stream_side_data(s, st, p)) {
> + av_log(s, AV_LOG_WARNING,
> + "Failed to add SDP attribute to stream");
> + }
> + }
> + }
> + /* now parse the SDP attribute line */
> if (av_strstart(p, "control:", &p)) {
> if (rt->nb_rtsp_streams == 0) {
> if (!strncmp(p, "rtsp://", 7))
--
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-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 5+ messages in thread
* [FFmpeg-devel] [PATCH] avcodec/avformat: Store SDP attributes from RTSP stream into AVStream side data.
@ 2024-07-09 10:02 Bernardo Pilarz via ffmpeg-devel
2024-07-10 9:09 ` Bernardo Pilarz via ffmpeg-devel
0 siblings, 1 reply; 5+ messages in thread
From: Bernardo Pilarz via ffmpeg-devel @ 2024-07-09 10:02 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Bernardo Pilarz
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 <bernardo.pilarz@aitek.it>
---
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: <codec_name>/<clock_rate>[/<other 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 */
+ if (rt->nb_rtsp_streams > 0) {
+ rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
+ if (rtsp_st->stream_index >= 0) {
+ st = s->streams[rtsp_st->stream_index];
+ if (sdp_add_attribute_to_stream_side_data(s, st, p)) {
+ av_log(s, AV_LOG_WARNING,
+ "Failed to add SDP attribute to stream");
+ }
+ }
+ }
+ /* now parse the SDP attribute line */
if (av_strstart(p, "control:", &p)) {
if (rt->nb_rtsp_streams == 0) {
if (!strncmp(p, "rtsp://", 7))
--
2.43.0
--
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-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 5+ messages in thread
* [FFmpeg-devel] [PATCH] avcodec/avformat: Store SDP attributes from RTSP stream into AVStream side data.
@ 2024-07-09 7:46 Bernardo Pilarz via ffmpeg-devel
0 siblings, 0 replies; 5+ messages in thread
From: Bernardo Pilarz via ffmpeg-devel @ 2024-07-09 7:46 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Bernardo Pilarz
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 <bernardo.pilarz@aitek.it>
---
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: <codec_name>/<clock_rate>[/<other
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_streams > 0) {
+ rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
+ if (rtsp_st->stream_index >= 0) {
+ st = s->streams[rtsp_st->stream_index];
+ if (sdp_add_attribute_to_stream_side_data(s, st, p)) {
+ av_log(s, AV_LOG_WARNING,
+ "Failed to add SDP attribute to stream");
+ }
+ }
+ }
+ /* now parse the SDP attribute line */
if (av_strstart(p, "control:", &p)) {
if (rt->nb_rtsp_streams == 0) {
if (!strncmp(p, "rtsp://", 7))
--
2.43.0
--
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-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 5+ messages in thread
* [FFmpeg-devel] [PATCH] avcodec/avformat: Store SDP attributes from RTSP stream into AVStream side data.
@ 2024-07-08 14:27 Bernardo Pilarz via ffmpeg-devel
0 siblings, 0 replies; 5+ messages in thread
From: Bernardo Pilarz via ffmpeg-devel @ 2024-07-08 14:27 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Bernardo Pilarz
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 <bernardo.pilarz@aitek.it>
---
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: <codec_name>/<clock_rate>[/<other
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 */
+ if (rt->nb_rtsp_streams > 0) {
+ rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
+ if (rtsp_st->stream_index >= 0) {
+ st = s->streams[rtsp_st->stream_index];
+ if (sdp_add_attribute_to_stream_side_data(s, st, p)) {
+ av_log(s, AV_LOG_WARNING,
+ "Failed to add SDP attribute to stream");
+ }
+ }
+ }
+ /* now parse the SDP attribute line */
if (av_strstart(p, "control:", &p)) {
if (rt->nb_rtsp_streams == 0) {
if (!strncmp(p, "rtsp://", 7))
--
2.43.5
--
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-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2024-07-10 9:10 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-07-09 8:44 [FFmpeg-devel] [PATCH] avcodec/avformat: Store SDP attributes from RTSP stream into AVStream side data Bernardo Pilarz via ffmpeg-devel
-- strict thread matches above, loose matches on Subject: below --
2024-07-09 10:02 Bernardo Pilarz via ffmpeg-devel
2024-07-10 9:09 ` Bernardo Pilarz via ffmpeg-devel
2024-07-09 7:46 Bernardo Pilarz via ffmpeg-devel
2024-07-08 14:27 Bernardo Pilarz via ffmpeg-devel
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git