21#include "config_components.h"
45#define MAX_EXTRADATA_SIZE ((INT_MAX - 10) / 2)
47struct sdp_session_level {
64static void sdp_write_address(
char *buff,
int size,
const char *dest_addr,
65 const char *dest_type,
int ttl)
70 if (ttl > 0 && !strcmp(dest_type,
"IP4")) {
73 av_strlcatf(buff,
size,
"c=IN %s %s/%d\r\n", dest_type, dest_addr, ttl);
80static void sdp_write_header(
char *buff,
int size,
struct sdp_session_level *
s)
83 "o=- %d %d IN %s %s\r\n"
86 s->id,
s->version,
s->src_type,
s->src_addr,
88 sdp_write_address(buff,
size,
s->dst_addr,
s->dst_type,
s->ttl);
91 s->start_time,
s->end_time);
95static int resolve_destination(
char *dest_addr,
int size,
char *
type,
113 if (ai->ai_family == AF_INET6)
121static int resolve_destination(
char *dest_addr,
int size,
char *
type,
128static int sdp_get_address(
char *dest_addr,
int size,
int *ttl,
const char *url)
138 if (strcmp(proto,
"rtp") && strcmp(proto,
"srtp")) {
145 p = strchr(url,
'?');
150 *ttl = strtol(buff,
NULL, 10);
173 av_strlcatf(psets, 64,
"profile=%u;level-idx=%u;tier=%u",
179#define MAX_PSET_SIZE 1024
185 static const char pset_string[] =
"; sprop-parameter-sets=";
186 static const char profile_string[] =
"; profile-level-id=";
189 uint8_t *tmpbuf =
NULL;
190 const uint8_t *
sps =
NULL, *sps_end;
213 memcpy(psets, pset_string, strlen(pset_string));
214 p = psets + strlen(pset_string);
216 while (
r < extradata + extradata_size) {
221 nal_type = *
r & 0x1f;
223 if (nal_type != 7 && nal_type != 8) {
227 if (p != (psets + strlen(pset_string))) {
228 if (p - psets >= MAX_PSET_SIZE)
239 MAX_PSET_SIZE - (p - psets), r1 -
r);
249 if (
sps && sps_end -
sps >= 4 && p - psets <= MAX_PSET_SIZE - strlen(profile_string) - 7) {
250 memcpy(p, profile_string, strlen(profile_string));
266 uint8_t *tmpbuf =
NULL;
267 int ps_pos[3] = { 0 };
268 static const char *
const ps_names[3] = {
"vps",
"sps",
"pps" };
269 int num_arrays, num_nalus;
270 int pos,
i, j, ret = 0;
294 if (extradata_size < 23)
297 num_arrays = extradata[22];
299 for (
i = 0;
i < num_arrays;
i++) {
300 int num_nalus, nalu_type;
301 if (
pos + 3 > extradata_size)
303 nalu_type = extradata[
pos] & 0x3f;
308 else if (nalu_type == 33)
310 else if (nalu_type == 34)
314 for (j = 0; j < num_nalus; j++) {
316 if (
pos + 2 > extradata_size)
320 if (
pos +
len > extradata_size)
325 if (!ps_pos[0] || !ps_pos[1] || !ps_pos[2])
336 for (
i = 0;
i < 3;
i++) {
341 av_strlcatf(psets, MAX_PSET_SIZE,
"sprop-%s=", ps_names[
i]);
347 for (j = 0; j < num_nalus; j++) {
353 strpos = strlen(psets);
389 memcpy(config,
"; config=", 9);
400 char *encoded_config;
401 const uint8_t *header_start[3];
402 int headers_len, header_len[3], config_len;
403 int first_header_size, ret;
409 first_header_size = 42;
412 first_header_size = 30;
420 first_header_size, header_start,
427 headers_len = header_len[0] + header_len[2];
440 if (!encoded_config) {
450 config[7] = (headers_len >> 8) & 0xff;
451 config[8] = headers_len & 0xff;
453 config[10] = header_len[0];
455 memcpy(config + 12, header_start[0], header_len[0]);
456 memcpy(config + 12 + header_len[0], header_start[2], header_len[2]);
462 *
out = encoded_config;
467 "Not enough memory for configuration string\n");
477 int profile_level = 0x2B;
484 profile_level = 0x28;
487 profile_level = 0x29;
489 profile_level = 0x2A;
493 profile_level = 0x2B;
497 return profile_level;
507 uint8_t config_byte[6];
513 for (rate_index = 0; rate_index < 16; rate_index++)
516 if (rate_index == 16) {
521 config_byte[0] = 0x40;
523 config_byte[2] = 0x20 | rate_index;
525 config_byte[4] = 0x3f;
526 config_byte[5] = 0xc0;
539static int sdp_write_media_attributes(
char *buff,
int size,
const AVStream *st,
546 switch (
p->codec_id) {
549 if (
p->extradata_size) {
550 ret = extradata2psets_av1(fmt, p, &config);
564 if (
p->extradata_size) {
565 ret = extradata2psets(fmt, p, &config);
570 "a=fmtp:%d packetization-mode=%d%s\r\n",
572 payload_type,
mode, config ? config :
"");
577 const char *pic_fmt =
NULL;
579 if (
p->width == 176 &&
p->height == 144)
581 else if (
p->width == 352 &&
p->height == 288)
599 "a=framesize:%d %d-%d\r\n",
601 payload_type,
p->width,
p->height);
604 if (
p->extradata_size) {
605 ret = extradata2psets_hevc(fmt, p, &config);
612 payload_type, config);
615 if (
p->extradata_size) {
616 ret = extradata2config(fmt, p, &config);
621 "a=fmtp:%d profile-level-id=1%s\r\n",
623 payload_type, config ? config :
"");
628 ret = latm_context2config(fmt, p, &config);
632 "a=fmtp:%d profile-level-id=%d;cpresent=0;config=%s\r\n",
633 payload_type,
p->sample_rate,
p->ch_layout.nb_channels,
634 payload_type, latm_context2profilelevel(p), config);
636 if (
p->extradata_size) {
637 ret = extradata2config(fmt, p, &config);
644 av_log(fmt,
AV_LOG_ERROR,
"AAC with no global headers is currently not supported.\n");
648 "a=fmtp:%d profile-level-id=1;"
649 "mode=AAC-hbr;sizelength=13;indexlength=3;"
650 "indexdeltalength=3%s\r\n",
651 payload_type,
p->sample_rate,
p->ch_layout.nb_channels,
652 payload_type, config);
659 p->sample_rate,
p->ch_layout.nb_channels);
665 p->sample_rate,
p->ch_layout.nb_channels);
671 p->sample_rate,
p->ch_layout.nb_channels);
677 p->sample_rate,
p->ch_layout.nb_channels);
681 "a=fmtp:%d octet-align=1\r\n",
682 payload_type,
p->sample_rate,
p->ch_layout.nb_channels,
687 "a=fmtp:%d octet-align=1\r\n",
688 payload_type,
p->sample_rate,
p->ch_layout.nb_channels,
692 if (
p->extradata_size)
693 ret = xiph_extradata2config(fmt, p, &config);
702 "a=fmtp:%d configuration=%s\r\n",
703 payload_type,
p->sample_rate,
p->ch_layout.nb_channels,
704 payload_type, config);
723 if (
p->extradata_size)
724 ret = xiph_extradata2config(fmt, p, &config);
733 "a=fmtp:%d delivery-method=inline; "
734 "width=%d; height=%d; sampling=%s; "
735 "configuration=%s\r\n",
736 payload_type, payload_type,
768 "a=fmtp:%d sampling=%s; "
769 "width=%d; height=%d; "
771 payload_type, payload_type,
796 8000,
p->ch_layout.nb_channels);
802 p->bits_per_coded_sample*8,
810 p->bits_per_coded_sample*8,
816 "a=fmtp:%d mode=%d\r\n",
817 payload_type,
p->sample_rate,
818 payload_type,
p->block_align == 38 ? 20 : 30);
822 payload_type,
p->sample_rate);
833 if (
p->ch_layout.nb_channels == 2) {
849 const char *dest_addr,
const char *dest_type,
858 switch (
p->codec_type) {
862 default :
type =
"application";
break;
866 sdp_write_address(buff,
size, dest_addr, dest_type, ttl);
870 if (
p->framerate.num > 0 &&
p->framerate.den > 0) {
874 return sdp_write_media_attributes(buff,
size, st, payload_type, fmt);
880 struct sdp_session_level
s = { 0 };
881 int i, j, port, ttl, is_multicast,
index = 0;
882 char dst[32], dst_type[5];
884 memset(buf, 0,
size);
886 s.src_addr =
"127.0.0.1";
888 s.name = title ? title->
value :
"No Name";
893 port = sdp_get_address(
dst,
sizeof(
dst), &ttl, ac[0]->url ? ac[0]->url :
"");
894 is_multicast = resolve_destination(
dst,
sizeof(
dst), dst_type,
900 s.dst_type = dst_type;
902 if (!strcmp(dst_type,
"IP6")) {
908 sdp_write_header(buf,
size, &
s);
911 for (
i = 0;
i < n_files;
i++) {
913 port = sdp_get_address(
dst,
sizeof(
dst), &ttl, ac[
i]->url ? ac[
i]->url :
"");
914 is_multicast = resolve_destination(
dst,
sizeof(
dst), dst_type,
922 (port > 0) ? port + j * 2 : 0,
929 "a=control:streamid=%d\r\n",
i + j);
932 uint8_t *crypto_suite =
NULL, *crypto_params =
NULL;
937 if (crypto_suite && crypto_suite[0])
939 "a=crypto:1 %s inline:%s\r\n",
940 crypto_suite, crypto_params);
956 const char *dest_addr,
const char *dest_type,
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
static void bit_depth(AudioStatsContext *s, const uint64_t *const mask, uint8_t *depth)
int ff_av1_parse_seq_header(AV1SequenceParameters *seq, const uint8_t *buf, int size)
Parses a Sequence Header from the the provided buffer.
int ff_avc_write_annexb_extradata(const uint8_t *in, uint8_t **buf, int *size)
int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
int avio_open_dyn_buf(AVIOContext **s)
Open a write only memory stream.
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
static int FUNC metadata(CodedBitstreamContext *ctx, RWContext *rw, APVRawMetadata *current)
#define i(width, name, range_min, range_max)
static int FUNC sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
static enum AVPixelFormat pix_fmt
static int64_t start_time
@ AV_CODEC_ID_ADPCM_G726LE
void av_url_split(char *proto, int proto_size, char *authorization, int authorization_size, char *hostname, int hostname_size, int *port_ptr, char *path, int path_size, const char *url)
Split a URL string into components.
int av_sdp_create(AVFormatContext *ac[], int n_files, char *buf, int size)
Generate an SDP for an RTP session.
char * av_base64_encode(char *out, int out_size, const uint8_t *in, int in_size)
Encode data to base64 and null-terminate.
#define AV_BASE64_SIZE(x)
Calculate the output size needed to base64-encode x bytes to a null-terminated string.
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static double av_q2d(AVRational a)
Convert an AVRational to a double.
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes,...
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
#define AV_OPT_SEARCH_CHILDREN
Search in possible children of the given object first.
int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name)
Check whether a particular flag is set in a flags field.
int ff_isom_write_hvcc(AVIOContext *pb, const uint8_t *data, int size, int ps_array_completeness, void *logctx)
Writes HEVC extradata (parameter sets and declarative SEI NAL units with nuh_layer_id == 0,...
#define MAX_EXTRADATA_SIZE
Memory handling functions.
const int ff_mpeg4audio_sample_rates[16]
const uint8_t * ff_nal_find_startcode(const uint8_t *p, const uint8_t *end)
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
int ff_is_multicast_address(struct sockaddr *addr)
int av_find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
Attempt to find a specific tag in a URL.
#define AV_PIX_FMT_YUV422P10
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
@ AV_PIX_FMT_UYVY422
packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
int ff_rtp_get_payload_type(const AVFormatContext *fmt, const AVCodecParameters *par, int idx)
Return the payload type for a given stream used in the given format context.
int ff_sdp_write_media(char *buff, int size, const AVStream *st, int idx, const char *dest_addr, const char *dest_type, int port, int ttl, AVFormatContext *fmt)
Append the media-specific SDP fragment for the media stream c to the buffer buff.
int nb_channels
Number of channels in this layout.
This struct describes the properties of an encoded stream.
int extradata_size
Size of the extradata content in bytes.
AVChannelLayout ch_layout
The channel layout and number of channels.
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
int sample_rate
The number of audio samples per second.
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
const struct AVOutputFormat * oformat
The output container format.
void * priv_data
Format private data.
const AVClass * av_class
A class for private options.
AVCodecParameters * codecpar
Codec parameters associated with this stream.
int avpriv_split_xiph_headers(const uint8_t *extradata, int extradata_size, int first_header_size, const uint8_t *header_start[3], int header_len[3])
Split a single extradata buffer into the three headers that most Xiph codecs use.