summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--addons/chan_ooh323.c19
-rw-r--r--addons/ooh323c/src/context.c1
-rw-r--r--addons/ooh323c/src/memheap.c11
-rw-r--r--addons/ooh323c/src/ooCalls.c3
-rw-r--r--addons/ooh323c/src/ooCapability.c8
-rw-r--r--addons/ooh323c/src/ooGkClient.c3
-rw-r--r--addons/ooh323c/src/ooh245.c2
-rw-r--r--addons/ooh323c/src/ooq931.c6
-rw-r--r--bridges/bridge_softmix.c34
-rw-r--r--formats/format_pcm.c41
-rw-r--r--include/asterisk/stream.h78
-rw-r--r--main/Makefile3
-rw-r--r--main/cli.c12
-rw-r--r--main/sdp.c3
-rw-r--r--main/sdp_state.c4
-rw-r--r--main/stream.c135
-rw-r--r--menuselect/Makefile8
-rw-r--r--menuselect/autoconfig.h.in4
-rwxr-xr-xmenuselect/configure33
-rw-r--r--menuselect/configure.ac40
-rw-r--r--res/Makefile3
-rw-r--r--tests/test_stream.c120
22 files changed, 390 insertions, 181 deletions
diff --git a/addons/chan_ooh323.c b/addons/chan_ooh323.c
index ffdbf6721..b456796d7 100644
--- a/addons/chan_ooh323.c
+++ b/addons/chan_ooh323.c
@@ -1281,7 +1281,7 @@ static int ooh323_indicate(struct ast_channel *ast, int condition, const void *d
struct ooh323_pvt *p = (struct ooh323_pvt *) ast_channel_tech_pvt(ast);
char *callToken = (char *)NULL;
- int res = -1;
+ int res = -1, rres;
if (!p) return -1;
@@ -1328,11 +1328,9 @@ static int ooh323_indicate(struct ast_channel *ast, int condition, const void *d
case AST_CONTROL_PROGRESS:
if (ast_channel_state(ast) != AST_STATE_UP) {
if (!p->progsent) {
+ rres = ooManualProgress(callToken);
if (gH323Debug) {
- ast_debug(1, "Sending manual progress for %s, res = %u\n", callToken,
- ooManualProgress(callToken));
- } else {
- ooManualProgress(callToken);
+ ast_debug(1, "Sending manual progress for %s, res = %u\n", callToken, rres);
}
p->progsent = 1;
}
@@ -1341,12 +1339,9 @@ static int ooh323_indicate(struct ast_channel *ast, int condition, const void *d
case AST_CONTROL_RINGING:
if (ast_channel_state(ast) == AST_STATE_RING || ast_channel_state(ast) == AST_STATE_RINGING) {
if (!p->alertsent) {
+ rres = ooManualRingback(callToken);
if (gH323Debug) {
- ast_debug(1, "Sending manual ringback for %s, res = %u\n",
- callToken,
- ooManualRingback(callToken));
- } else {
- ooManualRingback(callToken);
+ ast_debug(1, "Sending manual ringback for %s, res = %u\n", callToken, rres);
}
p->alertsent = 1;
}
@@ -5053,9 +5048,7 @@ struct ast_frame *ooh323_rtp_read(struct ast_channel *ast, struct ooh323_pvt *p)
ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(p->owner),target_context);
}
p->faxdetected = 1;
- if (dfr) {
- ast_frfree(dfr);
- }
+ ast_frfree(dfr);
return &ast_null_frame;
}
}
diff --git a/addons/ooh323c/src/context.c b/addons/ooh323c/src/context.c
index bc3db4387..c1e2003a2 100644
--- a/addons/ooh323c/src/context.c
+++ b/addons/ooh323c/src/context.c
@@ -164,6 +164,7 @@ OOCTXT* newContext ()
/* ASN1CRTFREE0 (pctxt); */
ast_free(pctxt);
pctxt = 0;
+ return (pctxt);
}
pctxt->flags |= ASN1DYNCTXT;
}
diff --git a/addons/ooh323c/src/memheap.c b/addons/ooh323c/src/memheap.c
index 4bcbd7a3d..4020261bb 100644
--- a/addons/ooh323c/src/memheap.c
+++ b/addons/ooh323c/src/memheap.c
@@ -623,7 +623,7 @@ void memHeapFreePtr (void** ppvMemHeap, void* mem_p)
}
}
}
- if (!ISLAST (pElem) && ISFREE (GETNEXT (pElem))) {
+ if (pElem && !ISLAST (pElem) && ISFREE (GETNEXT (pElem))) {
OSMemElemDescr* nextelem_p = GETNEXT (pElem);
/* +1 because the OSMemElemDescr has size ONE unit (8 bytes) */
@@ -638,7 +638,7 @@ void memHeapFreePtr (void** ppvMemHeap, void* mem_p)
}
/* correct the prevOff field of next element */
- if (!ISLAST (pElem)) {
+ if (pElem && !ISLAST (pElem)) {
OSMemElemDescr* nextelem_p = GETNEXT (pElem);
pElem_prevOff (nextelem_p) = QOFFSETOF (nextelem_p, pElem);
}
@@ -686,7 +686,7 @@ static void initNewFreeElement (OSMemBlk* pMemBlk,
}
pNextElem = GETNEXT (pNewElem);
- if (ISFREE (pNextElem)) {
+ if (pNextElem && ISFREE (pNextElem)) {
/* if the next elem is free, then unite them together */
@@ -820,7 +820,7 @@ void* memHeapRealloc (void** ppvMemHeap, void* mem_p, int nbytes_)
/* look for free element after pElem */
pNextElem = GETNEXT (pElem);
- if (ISFREE (pNextElem)) {
+ if (pNextElem && ISFREE (pNextElem)) {
/* +1 'cos sizeof (OSMemElemDescr) == 1 unit */
sumSize += pElem_nunits (pNextElem) + 1;
freeMem++;
@@ -1062,7 +1062,7 @@ void memHeapAddRef (void** ppvMemHeap)
void memHeapRelease (void** ppvMemHeap)
{
OSMemHeap** ppMemHeap = (OSMemHeap**)ppvMemHeap;
- OSMemHeap* pMemHeap = *ppMemHeap;
+ OSMemHeap* pMemHeap;
if (ppMemHeap != 0 && *ppMemHeap != 0 && --(*ppMemHeap)->refCnt == 0) {
OSMemLink* pMemLink, *pMemLink2;
@@ -1080,6 +1080,7 @@ void memHeapRelease (void** ppvMemHeap)
}
if ((*ppMemHeap)->flags & RT_MH_FREEHEAPDESC) {
+ pMemHeap = *ppMemHeap;
ast_mutex_destroy(&pMemHeap->pLock);
ast_free(*ppMemHeap);
}
diff --git a/addons/ooh323c/src/ooCalls.c b/addons/ooh323c/src/ooCalls.c
index 3097c6d28..15ab3258f 100644
--- a/addons/ooh323c/src/ooCalls.c
+++ b/addons/ooh323c/src/ooCalls.c
@@ -805,8 +805,7 @@ int ooAddMediaInfo(OOH323CallData *call, OOMediaInfo mediaInfo)
if(!call)
{
- OOTRACEERR3("Error:Invalid 'call' param for ooAddMediaInfo.(%s, %s)\n",
- call->callType, call->callToken);
+ OOTRACEERR1("Error:Invalid 'call' param for ooAddMediaInfo.\n");
return OO_FAILED;
}
newMediaInfo = (OOMediaInfo*) memAlloc(call->pctxt, sizeof(OOMediaInfo));
diff --git a/addons/ooh323c/src/ooCapability.c b/addons/ooh323c/src/ooCapability.c
index 731478346..0796c46bf 100644
--- a/addons/ooh323c/src/ooCapability.c
+++ b/addons/ooh323c/src/ooCapability.c
@@ -62,8 +62,6 @@ int ooCapabilityEnableDTMFCISCO
/*Dynamic RTP payload type range is from 96 - 127 */
if(dynamicRTPPayloadType >= 96 && dynamicRTPPayloadType <= 127)
gcDynamicRTPPayloadType = dynamicRTPPayloadType;
- else
- call->dtmfcodec = dynamicRTPPayloadType;
}
else{
call->dtmfmode |= OO_CAP_DTMF_CISCO;
@@ -623,8 +621,7 @@ int ooCapabilityAddT38Capability
else pctxt = call->pctxt;
epCap = (ooH323EpCapability*)memAllocZ(pctxt, sizeof(ooH323EpCapability));
- params = (OOCapParams*) memAlloc(pctxt, sizeof(OOCapParams));
- memset(params, 0 , sizeof(OOCapParams));
+ params = (OOCapParams*) memAllocZ(pctxt, sizeof(OOCapParams));
if(!epCap || !params)
{
OOTRACEERR1("ERROR: Memory - ooCapabilityAddT38Capability - "
@@ -808,8 +805,7 @@ void* ooCapabilityCreateDTMFCapability(int cap, int dtmfcodec, OOCTXT *pctxt)
}
memset(pATECap, 0, sizeof(H245AudioTelephonyEventCapability));
pATECap->dynamicRTPPayloadType = dtmfcodec;
- events = (char*)memAlloc(pctxt, strlen("0-16")+1);
- memset(events, 0, strlen("0-16")+1);
+ events = (char*)memAllocZ(pctxt, strlen("0-16")+1);
if(!events)
{
OOTRACEERR1("Error:Memory - ooCapabilityCreateDTMFCapability - events\n");
diff --git a/addons/ooh323c/src/ooGkClient.c b/addons/ooh323c/src/ooGkClient.c
index a307f4eef..0168ee7de 100644
--- a/addons/ooh323c/src/ooGkClient.c
+++ b/addons/ooh323c/src/ooGkClient.c
@@ -2332,9 +2332,8 @@ int ooGkClientSendIRR
pIRR->m.perCallInfoPresent = TRUE;
perCallInfo =
- (H225InfoRequestResponse_perCallInfo_element *)memAlloc(pctxt,
+ (H225InfoRequestResponse_perCallInfo_element *)memAllocZ(pctxt,
sizeof(H225InfoRequestResponse_perCallInfo_element));
- memset(perCallInfo, 0, sizeof(H225InfoRequestResponse_perCallInfo_element));
if(!perCallInfo)
{
diff --git a/addons/ooh323c/src/ooh245.c b/addons/ooh323c/src/ooh245.c
index adff91790..fe8ff28e0 100644
--- a/addons/ooh323c/src/ooh245.c
+++ b/addons/ooh323c/src/ooh245.c
@@ -356,7 +356,6 @@ int ooSendTermCapMsg(OOH323CallData *call)
/* pctxt = &gH323ep.msgctxt; */
pctxt = call->msgctxt;
ph245msg->msgType = OOTerminalCapabilitySet;
- memset(request, 0, sizeof(H245RequestMessage));
if(request == NULL)
{
OOTRACEERR3("ERROR: No memory allocated for request message (%s, %s)\n",
@@ -364,6 +363,7 @@ int ooSendTermCapMsg(OOH323CallData *call)
return OO_FAILED;
}
+ memset(request, 0, sizeof(H245RequestMessage));
request->t = T_H245RequestMessage_terminalCapabilitySet;
request->u.terminalCapabilitySet = (H245TerminalCapabilitySet*)
memAlloc(pctxt, sizeof(H245TerminalCapabilitySet));
diff --git a/addons/ooh323c/src/ooq931.c b/addons/ooh323c/src/ooq931.c
index 1ca361c2c..01a8e4aaf 100644
--- a/addons/ooh323c/src/ooq931.c
+++ b/addons/ooh323c/src/ooq931.c
@@ -2439,8 +2439,10 @@ int ooH323HandleCallFwdRequest(OOH323CallData *call)
alias = call->pCallFwdData->aliases;
while(alias)
{
- pNewAlias = (ooAliases*) memAlloc(pctxt, sizeof(ooAliases));
- pNewAlias->value = (char*) memAlloc(pctxt, strlen(alias->value)+1);
+ pNewAlias = (ooAliases*) memAllocZ(pctxt, sizeof(ooAliases));
+ if (pNewAlias) {
+ pNewAlias->value = (char*) memAllocZ(pctxt, strlen(alias->value)+1);
+ }
if(!pNewAlias || !pNewAlias->value)
{
OOTRACEERR3("Error:Memory - ooH323HandleCallFwdRequest - "
diff --git a/bridges/bridge_softmix.c b/bridges/bridge_softmix.c
index f0a3fb42d..ed88b7cd5 100644
--- a/bridges/bridge_softmix.c
+++ b/bridges/bridge_softmix.c
@@ -1318,6 +1318,12 @@ static void remb_collect_report(struct ast_bridge *bridge, struct ast_bridge_cha
break;
}
}
+
+ /* After the report is integrated we reset this to 0 in case they stop producing
+ * REMB reports.
+ */
+ sc->remb.br_mantissa = 0;
+ sc->remb.br_exp = 0;
}
static void remb_send_report(struct ast_bridge_channel *bridge_channel, struct softmix_channel *sc)
@@ -1328,20 +1334,18 @@ static void remb_send_report(struct ast_bridge_channel *bridge_channel, struct s
return;
}
- /* If we have a new bitrate then use it for the REMB, if not we use the previous
- * one until we know otherwise. This way the bitrate doesn't drop to 0 all of a sudden.
+ /* We always do this calculation as even when the bitrate is zero the browser
+ * still prefers it to be accurate instead of lying.
*/
- if (sc->remb_collector->bitrate) {
- sc->remb_collector->feedback.remb.br_mantissa = sc->remb_collector->bitrate;
- sc->remb_collector->feedback.remb.br_exp = 0;
+ sc->remb_collector->feedback.remb.br_mantissa = sc->remb_collector->bitrate;
+ sc->remb_collector->feedback.remb.br_exp = 0;
- /* The mantissa only has 18 bits available, so while it exceeds them we bump
- * up the exp.
- */
- while (sc->remb_collector->feedback.remb.br_mantissa > 0x3ffff) {
- sc->remb_collector->feedback.remb.br_mantissa = sc->remb_collector->feedback.remb.br_mantissa >> 1;
- sc->remb_collector->feedback.remb.br_exp++;
- }
+ /* The mantissa only has 18 bits available, so while it exceeds them we bump
+ * up the exp.
+ */
+ while (sc->remb_collector->feedback.remb.br_mantissa > 0x3ffff) {
+ sc->remb_collector->feedback.remb.br_mantissa = sc->remb_collector->feedback.remb.br_mantissa >> 1;
+ sc->remb_collector->feedback.remb.br_exp++;
}
for (i = 0; i < AST_VECTOR_SIZE(&bridge_channel->stream_map.to_bridge); ++i) {
@@ -2062,6 +2066,7 @@ static void softmix_bridge_stream_topology_changed(struct ast_bridge *bridge, st
struct ast_bridge_channel *participant;
struct ast_vector_int media_types;
int nths[AST_MEDIA_TYPE_END] = {0};
+ int idx;
switch (bridge->softmix.video_mode.mode) {
case AST_BRIDGE_VIDEO_MODE_NONE:
@@ -2080,7 +2085,10 @@ static void softmix_bridge_stream_topology_changed(struct ast_bridge *bridge, st
* When channels end up getting added back in they'll reuse their existing
* collector and won't need to allocate a new one (unless they were just added).
*/
- AST_VECTOR_RESET(&softmix_data->remb_collectors, ao2_cleanup);
+ for (idx = 0; idx < AST_VECTOR_SIZE(&softmix_data->remb_collectors); ++idx) {
+ ao2_cleanup(AST_VECTOR_GET(&softmix_data->remb_collectors, idx));
+ AST_VECTOR_REPLACE(&softmix_data->remb_collectors, idx, NULL);
+ }
/* First traversal: re-initialize all of the participants' stream maps */
AST_LIST_TRAVERSE(&bridge->channels, participant, entry) {
diff --git a/formats/format_pcm.c b/formats/format_pcm.c
index 35612c964..4e846d7cf 100644
--- a/formats/format_pcm.c
+++ b/formats/format_pcm.c
@@ -91,10 +91,7 @@ static struct ast_frame *pcm_read(struct ast_filestream *s, int *whennext)
return NULL;
}
s->fr.datalen = res;
- if (ast_format_cmp(s->fmt->format, ast_format_g722) == AST_FORMAT_CMP_EQUAL)
- *whennext = s->fr.samples = res * 2;
- else
- *whennext = s->fr.samples = res;
+ *whennext = s->fr.samples = res;
return &s->fr;
}
@@ -410,16 +407,11 @@ static int au_rewrite(struct ast_filestream *s, const char *comment)
static int au_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
{
off_t min, max, cur;
- long offset = 0, bytes;
+ long offset = 0;
struct au_desc *desc = fs->_private;
min = desc->hdr_size;
- if (ast_format_cmp(fs->fmt->format, ast_format_g722) == AST_FORMAT_CMP_EQUAL)
- bytes = sample_offset / 2;
- else
- bytes = sample_offset;
-
if ((cur = ftello(fs->f)) < 0) {
ast_log(AST_LOG_WARNING, "Unable to determine current position in au filestream %p: %s\n", fs, strerror(errno));
return -1;
@@ -436,11 +428,11 @@ static int au_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
}
if (whence == SEEK_SET)
- offset = bytes + min;
+ offset = sample_offset + min;
else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
- offset = bytes + cur;
+ offset = sample_offset + cur;
else if (whence == SEEK_END)
- offset = max - bytes;
+ offset = max - sample_offset;
if (whence != SEEK_FORCECUR) {
offset = (offset > max) ? max : offset;
@@ -479,6 +471,23 @@ static off_t au_tell(struct ast_filestream *fs)
return offset - desc->hdr_size;
}
+static struct ast_frame *g722_read(struct ast_filestream *s, int *whennext)
+{
+ struct ast_frame *f = pcm_read(s, whennext);
+ *whennext = s->fr.samples = (*whennext * 2);
+ return f;
+}
+
+static int g722_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
+{
+ return pcm_seek(fs, sample_offset / 2, whence);
+}
+
+static off_t g722_tell(struct ast_filestream *fs)
+{
+ return pcm_tell(fs) * 2;
+}
+
static struct ast_format_def alaw_f = {
.name = "alaw",
.exts = "alaw|al|alw",
@@ -510,10 +519,10 @@ static struct ast_format_def g722_f = {
.name = "g722",
.exts = "g722",
.write = pcm_write,
- .seek = pcm_seek,
+ .seek = g722_seek,
.trunc = pcm_trunc,
- .tell = pcm_tell,
- .read = pcm_read,
+ .tell = g722_tell,
+ .read = g722_read,
.buf_size = (BUF_SIZE * 2) + AST_FRIENDLY_OFFSET,
};
diff --git a/include/asterisk/stream.h b/include/asterisk/stream.h
index c2d5a8877..0a5550b5e 100644
--- a/include/asterisk/stream.h
+++ b/include/asterisk/stream.h
@@ -78,20 +78,6 @@ enum ast_stream_state {
};
/*!
- * \brief Stream data slots
- */
-enum ast_stream_data_slot {
- /*!
- * \brief Data slot for RTP instance
- */
- AST_STREAM_DATA_RTP_CODECS = 0,
- /*!
- * \brief Controls the size of the data pointer array
- */
- AST_STREAM_DATA_SLOT_MAX
-};
-
-/*!
* \brief Create a new media stream representation
*
* \param name A name for the stream
@@ -239,32 +225,47 @@ const char *ast_stream_state2str(enum ast_stream_state state);
enum ast_stream_state ast_stream_str2state(const char *str);
/*!
- * \brief Get the opaque stream data
+ * \brief Get a stream metadata value
*
* \param stream The media stream
- * \param slot The data slot to retrieve
+ * \param m_key An arbitrary metadata key
*
- * \retval non-NULL success
- * \retval NULL failure
+ * \retval non-NULL metadata value
+ * \retval NULL failure or not found
*
- * \since 15
+ * \since 15.5
*/
-void *ast_stream_get_data(struct ast_stream *stream, enum ast_stream_data_slot slot);
+const char *ast_stream_get_metadata(const struct ast_stream *stream,
+ const char *m_key);
/*!
- * \brief Set the opaque stream data
+ * \brief Get all stream metadata keys
*
* \param stream The media stream
- * \param slot The data slot to set
- * \param data Opaque data
- * \param data_free_fn Callback to free data when stream is freed. May be NULL for no action.
*
- * \return data
+ * \retval An ast_variable list of the metadata key/value pairs.
+ * \retval NULL if error or no variables are set.
*
- * \since 15
+ * When you're finished with the list, you must call
+ * ast_variables_destroy(list);
+ *
+ * \since 15.5
+ */
+struct ast_variable *ast_stream_get_metadata_list(const struct ast_stream *stream);
+
+/*!
+ * \brief Set a stream metadata value
+ *
+ * \param stream The media stream
+ * \param m_key An arbitrary metadata key
+ * \param value String metadata value or NULL to remove existing value
+ *
+ * \retval -1 failure
+ * \retval 0 success
+ *
+ * \since 15.5
*/
-void *ast_stream_set_data(struct ast_stream *stream, enum ast_stream_data_slot slot,
- void *data, ast_stream_data_free_fn data_free_fn);
+int ast_stream_set_metadata(struct ast_stream *stream, const char *m_key, const char *value);
/*!
* \brief Get the position of the stream in the topology
@@ -278,6 +279,27 @@ void *ast_stream_set_data(struct ast_stream *stream, enum ast_stream_data_slot s
int ast_stream_get_position(const struct ast_stream *stream);
/*!
+ * \brief Get rtp_codecs associated with the stream
+ *
+ * \param stream The media stream
+ *
+ * \return The rtp_codecs
+ *
+ * \since 15.5
+ */
+struct ast_rtp_codecs *ast_stream_get_rtp_codecs(const struct ast_stream *stream);
+
+/*!
+ * \brief Set rtp_codecs associated with the stream
+ *
+ * \param stream The media stream
+ * \param rtp_codecs The rtp_codecs
+ *
+ * \since 15.5
+ */
+void ast_stream_set_rtp_codecs(struct ast_stream *stream, struct ast_rtp_codecs *rtp_codecs);
+
+/*!
* \brief Create a stream topology
*
* \retval non-NULL success
diff --git a/main/Makefile b/main/Makefile
index bef70e966..393ad1aa4 100644
--- a/main/Makefile
+++ b/main/Makefile
@@ -135,7 +135,8 @@ endif
$(ECHO_PREFIX) echo " [FLEX] $< -> $@"
$(CMD_PREFIX) $(FLEX) -o $@ ast_expr2.fl
$(CMD_PREFIX) sed 's@#if __STDC_VERSION__ >= 199901L@#if !defined __STDC_VERSION__ || __STDC_VERSION__ >= 199901L@' $@ > $@.fix
- $(CMD_PREFIX) echo "#include \"asterisk.h\"" > $@
+ $(CMD_PREFIX) echo "#define ASTMM_LIBC ASTMM_REDIRECT" > $@
+ $(CMD_PREFIX) echo "#include \"asterisk.h\"" >> $@
$(CMD_PREFIX) echo >> $@
$(CMD_PREFIX) cat $@.fix >> $@
$(CMD_PREFIX) rm $@.fix
diff --git a/main/cli.c b/main/cli.c
index 5730be17b..cf51d0d95 100644
--- a/main/cli.c
+++ b/main/cli.c
@@ -1614,19 +1614,29 @@ static char *handle_showchan(struct ast_cli_entry *e, int cmd, struct ast_cli_ar
ast_str_append(&output, 0, " -- Streams --\n");
for (stream_num = 0; stream_num < ast_stream_topology_get_count(ast_channel_get_stream_topology(chan)); stream_num++) {
struct ast_stream *stream = ast_stream_topology_get_stream(ast_channel_get_stream_topology(chan), stream_num);
+ struct ast_variable *metadata = ast_stream_get_metadata_list(stream);
ast_str_append(&output, 0,
"Name: %s\n"
" Type: %s\n"
" State: %s\n"
" Group: %d\n"
- " Formats: %s\n",
+ " Formats: %s\n"
+ " Metadata:\n",
ast_stream_get_name(stream),
ast_codec_media_type2str(ast_stream_get_type(stream)),
ast_stream_state2str(ast_stream_get_state(stream)),
ast_stream_get_group(stream),
ast_format_cap_get_names(ast_stream_get_formats(stream), &codec_buf)
);
+
+ if (metadata) {
+ struct ast_variable *v;
+ for(v = metadata; v; v = v->next) {
+ ast_str_append(&output, 0, " %s: %s\n", v->name, v->value);
+ }
+ ast_variables_destroy(metadata);
+ }
}
ast_channel_unlock(chan);
diff --git a/main/sdp.c b/main/sdp.c
index 7e283ebf8..e5c8803d5 100644
--- a/main/sdp.c
+++ b/main/sdp.c
@@ -848,8 +848,7 @@ static struct ast_stream *get_stream_from_m(const struct ast_sdp_a_lines *a_line
ast_free(codecs);
return NULL;
}
- ast_stream_set_data(stream, AST_STREAM_DATA_RTP_CODECS, codecs,
- (ast_stream_data_free_fn) rtp_codecs_free);
+ ast_stream_set_rtp_codecs(stream, codecs);
if (!m_line->port) {
/* Stream is declined. There may not be any attributes. */
diff --git a/main/sdp_state.c b/main/sdp_state.c
index 5f9ad5eb9..e02227755 100644
--- a/main/sdp_state.c
+++ b/main/sdp_state.c
@@ -1732,7 +1732,7 @@ static void merge_remote_stream_capabilities(
case AST_MEDIA_TYPE_AUDIO:
case AST_MEDIA_TYPE_VIDEO:
ao2_bump(joint_state_stream->rtp);
- codecs = ast_stream_get_data(remote_stream, AST_STREAM_DATA_RTP_CODECS);
+ codecs = ast_stream_get_rtp_codecs(remote_stream);
ast_assert(codecs != NULL);
if (sdp_state->role == SDP_ROLE_ANSWERER) {
/*
@@ -1789,7 +1789,7 @@ static int create_remote_stream_capabilities(
* Setup rx payload type mapping to prefer the mapping
* from the peer that the RFC says we SHOULD use.
*/
- codecs = ast_stream_get_data(remote_stream, AST_STREAM_DATA_RTP_CODECS);
+ codecs = ast_stream_get_rtp_codecs(remote_stream);
ast_assert(codecs != NULL);
ast_rtp_codecs_payloads_xover(codecs, codecs, NULL);
ast_rtp_codecs_payloads_copy(codecs,
diff --git a/main/stream.c b/main/stream.c
index 61eef2504..dd3e765f6 100644
--- a/main/stream.c
+++ b/main/stream.c
@@ -34,6 +34,15 @@
#include "asterisk/strings.h"
#include "asterisk/format.h"
#include "asterisk/format_cap.h"
+#include "asterisk/vector.h"
+#include "asterisk/config.h"
+#include "asterisk/rtp_engine.h"
+
+struct ast_stream_metadata_entry {
+ size_t length;
+ int value_start;
+ char name_value[0];
+};
struct ast_stream {
/*!
@@ -57,19 +66,19 @@ struct ast_stream {
enum ast_stream_state state;
/*!
- * \brief Opaque stream data
+ * \brief Stream metadata vector
*/
- void *data[AST_STREAM_DATA_SLOT_MAX];
+ struct ast_variable *metadata;
/*!
- * \brief What to do with data when the stream is freed
+ * \brief The group that the stream is part of
*/
- ast_stream_data_free_fn data_free_fn[AST_STREAM_DATA_SLOT_MAX];
+ int group;
/*!
- * \brief The group that the stream is part of
+ * \brief The rtp_codecs used by the stream
*/
- int group;
+ struct ast_rtp_codecs *rtp_codecs;
/*!
* \brief Name for the stream within the context of the channel it is on
@@ -105,7 +114,6 @@ struct ast_stream *ast_stream_clone(const struct ast_stream *stream, const char
{
struct ast_stream *new_stream;
size_t stream_size;
- int idx;
const char *stream_name;
if (!stream) {
@@ -126,27 +134,23 @@ struct ast_stream *ast_stream_clone(const struct ast_stream *stream, const char
ao2_ref(new_stream->formats, +1);
}
- /* We cannot clone the opaque data because we don't know how. */
- for (idx = 0; idx < AST_STREAM_DATA_SLOT_MAX; ++idx) {
- new_stream->data[idx] = NULL;
- new_stream->data_free_fn[idx] = NULL;
- }
+ new_stream->metadata = ast_stream_get_metadata_list(stream);
+
+ /* rtp_codecs aren't cloned */
return new_stream;
}
void ast_stream_free(struct ast_stream *stream)
{
- int i;
-
if (!stream) {
return;
}
- for (i = 0; i < AST_STREAM_DATA_SLOT_MAX; i++) {
- if (stream->data_free_fn[i]) {
- stream->data_free_fn[i](stream->data[i]);
- }
+ ast_variables_destroy(stream->metadata);
+
+ if (stream->rtp_codecs) {
+ ast_rtp_codecs_payloads_destroy(stream->rtp_codecs);
}
ao2_cleanup(stream->formats);
@@ -238,22 +242,81 @@ enum ast_stream_state ast_stream_str2state(const char *str)
return AST_STREAM_STATE_REMOVED;
}
-void *ast_stream_get_data(struct ast_stream *stream, enum ast_stream_data_slot slot)
+const char *ast_stream_get_metadata(const struct ast_stream *stream, const char *m_key)
{
- ast_assert(stream != NULL);
+ struct ast_variable *v;
+
+ ast_assert_return(stream != NULL, NULL);
+ ast_assert_return(m_key != NULL, NULL);
- return stream->data[slot];
+ for (v = stream->metadata; v; v = v->next) {
+ if (strcmp(v->name, m_key) == 0) {
+ return v->value;
+ }
+ }
+
+ return NULL;
}
-void *ast_stream_set_data(struct ast_stream *stream, enum ast_stream_data_slot slot,
- void *data, ast_stream_data_free_fn data_free_fn)
+struct ast_variable *ast_stream_get_metadata_list(const struct ast_stream *stream)
{
- ast_assert(stream != NULL);
+ struct ast_variable *v;
+ struct ast_variable *vout = NULL;
+
+ ast_assert_return(stream != NULL, NULL);
+
+ for (v = stream->metadata; v; v = v->next) {
+ struct ast_variable *vt = ast_variable_new(v->name, v->value, "");
+
+ if (!vt) {
+ ast_variables_destroy(vout);
+ return NULL;
+ }
+
+ ast_variable_list_append(&vout, vt);
+ }
- stream->data[slot] = data;
- stream->data_free_fn[slot] = data_free_fn;
+ return vout;
+}
- return data;
+int ast_stream_set_metadata(struct ast_stream *stream, const char *m_key, const char *value)
+{
+ struct ast_variable *v;
+ struct ast_variable *prev;
+
+ ast_assert_return(stream != NULL, -1);
+ ast_assert_return(m_key != NULL, -1);
+
+ prev = NULL;
+ v = stream->metadata;
+ while(v) {
+ struct ast_variable *next = v->next;
+ if (strcmp(v->name, m_key) == 0) {
+ if (prev) {
+ prev->next = next;
+ } else {
+ stream->metadata = next;
+ }
+ ast_free(v);
+ break;
+ } else {
+ prev = v;
+ }
+ v = next;
+ }
+
+ if (!value) {
+ return 0;
+ }
+
+ v = ast_variable_new(m_key, value, "");
+ if (!v) {
+ return -1;
+ }
+
+ ast_variable_list_append(&stream->metadata, v);
+
+ return 0;
}
int ast_stream_get_position(const struct ast_stream *stream)
@@ -263,6 +326,24 @@ int ast_stream_get_position(const struct ast_stream *stream)
return stream->position;
}
+struct ast_rtp_codecs *ast_stream_get_rtp_codecs(const struct ast_stream *stream)
+{
+ ast_assert(stream != NULL);
+
+ return stream->rtp_codecs;
+}
+
+void ast_stream_set_rtp_codecs(struct ast_stream *stream, struct ast_rtp_codecs *rtp_codecs)
+{
+ ast_assert(stream != NULL);
+
+ if (stream->rtp_codecs) {
+ ast_rtp_codecs_payloads_destroy(rtp_codecs);
+ }
+
+ stream->rtp_codecs = rtp_codecs;
+}
+
#define TOPOLOGY_INITIAL_STREAM_COUNT 2
struct ast_stream_topology *ast_stream_topology_alloc(void)
{
diff --git a/menuselect/Makefile b/menuselect/Makefile
index c2c9373f4..d949efd55 100644
--- a/menuselect/Makefile
+++ b/menuselect/Makefile
@@ -24,6 +24,14 @@ endif
OBJS:=menuselect.o strcompat.o
CFLAGS+=-g -D_GNU_SOURCE -Wall
+ifneq ($(findstring dragonfly,$(OSARCH)),)
+ CFLAGS += -isystem /usr/local/include
+else ifneq ($(findstring netbsd,$(OSARCH)),)
+ CFLAGS += -isystem /usr/pkg/include
+else ifneq ($(findstring bsd,$(OSARCH)),)
+ CFLAGS += -isystem /usr/local/include
+endif
+
ifeq ($(MENUSELECT_DEBUG),yes)
CFLAGS += -DMENUSELECT_DEBUG
endif
diff --git a/menuselect/autoconfig.h.in b/menuselect/autoconfig.h.in
index 3e1e18990..f1745516b 100644
--- a/menuselect/autoconfig.h.in
+++ b/menuselect/autoconfig.h.in
@@ -3,10 +3,6 @@
#ifndef MENUSELECT_AUTOCONFIG_H
#define MENUSELECT_AUTOCONFIG_H
-#ifndef _REENTRANT
-#define _REENTRANT
-#endif
-
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
systems. This function is required for `alloca.c' support on those systems.
diff --git a/menuselect/configure b/menuselect/configure
index a0aa10928..7cbe47756 100755
--- a/menuselect/configure
+++ b/menuselect/configure
@@ -2320,33 +2320,18 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
HOST_OS=${host_os}
-PBX_WINARCH=0
case "${host_os}" in
- freebsd*)
- OSARCH=FreeBSD
+ *dragonfly*)
+ CPPFLAGS="${CPPFLAGS} -I/usr/local/include"
+ LDFLAGS="${LDFLAGS} -L/usr/local/lib"
;;
- netbsd*)
- OSARCH=NetBSD
+ *netbsd*)
+ CPPFLAGS="${CPPFLAGS} -I/usr/pkg/include"
+ LDFLAGS="${LDFLAGS} -L/usr/pkg/lib"
;;
- openbsd*)
- OSARCH=OpenBSD
- ;;
- solaris*)
- OSARCH=SunOS
- ;;
- mingw32)
- OSARCH=mingw32
- PBX_WINARCH=1
- ;;
- cygwin)
- OSARCH=cygwin
- PBX_WINARCH=1
- ;;
- linux-gnueabi)
- OSARCH=linux-gnu
- ;;
- *)
- OSARCH=${host_os}
+ *bsd*)
+ CPPFLAGS="${CPPFLAGS} -I/usr/local/include"
+ LDFLAGS="${LDFLAGS} -L/usr/local/lib"
;;
esac
diff --git a/menuselect/configure.ac b/menuselect/configure.ac
index 2dd4ed652..4a2d0acc2 100644
--- a/menuselect/configure.ac
+++ b/menuselect/configure.ac
@@ -1,5 +1,3 @@
-# Process this file with autoconf to produce a configure script.
-
AC_PREREQ(2.59)
m4_define([MENUSELECT_VERSION],
@@ -16,49 +14,29 @@ AC_CONFIG_HEADER(autoconfig.h)
AC_COPYRIGHT("Menuselect")
-AC_CANONICAL_BUILD
AC_CANONICAL_HOST
HOST_OS=${host_os}
AC_SUBST(HOST_OS)
-PBX_WINARCH=0
case "${host_os}" in
- freebsd*)
- OSARCH=FreeBSD
- ;;
- netbsd*)
- OSARCH=NetBSD
- ;;
- openbsd*)
- OSARCH=OpenBSD
- ;;
- solaris*)
- OSARCH=SunOS
+ *dragonfly*)
+ CPPFLAGS="${CPPFLAGS} -I/usr/local/include"
+ LDFLAGS="${LDFLAGS} -L/usr/local/lib"
;;
- mingw32)
- OSARCH=mingw32
- PBX_WINARCH=1
+ *netbsd*)
+ CPPFLAGS="${CPPFLAGS} -I/usr/pkg/include"
+ LDFLAGS="${LDFLAGS} -L/usr/pkg/lib"
;;
- cygwin)
- OSARCH=cygwin
- PBX_WINARCH=1
- ;;
- linux-gnueabi)
- OSARCH=linux-gnu
- ;;
- *)
- OSARCH=${host_os}
+ *bsd*)
+ CPPFLAGS="${CPPFLAGS} -I/usr/local/include"
+ LDFLAGS="${LDFLAGS} -L/usr/local/lib"
;;
esac
AH_TOP(
#ifndef MENUSELECT_AUTOCONFIG_H
#define MENUSELECT_AUTOCONFIG_H
-
-#ifndef _REENTRANT
-#define _REENTRANT
-#endif
)
AH_BOTTOM([#endif])
diff --git a/res/Makefile b/res/Makefile
index ecaa03d3c..ec3417b35 100644
--- a/res/Makefile
+++ b/res/Makefile
@@ -45,7 +45,8 @@ endif
$(ECHO_PREFIX) echo " [FLEX] $< -> $@"
$(CMD_PREFIX) (cd ael; $(FLEX) ael.flex)
$(CMD_PREFIX) sed 's@#if __STDC_VERSION__ >= 199901L@#if !defined __STDC_VERSION__ || __STDC_VERSION__ >= 199901L@' $@ > $@.fix
- $(CMD_PREFIX) echo "#include \"asterisk.h\"" > $@
+ $(CMD_PREFIX) echo "#define ASTMM_LIBC ASTMM_REDIRECT" > $@
+ $(CMD_PREFIX) echo "#include \"asterisk.h\"" >> $@
$(CMD_PREFIX) echo >> $@
$(CMD_PREFIX) cat $@.fix >> $@
$(CMD_PREFIX) rm $@.fix
diff --git a/tests/test_stream.c b/tests/test_stream.c
index 8c887048c..50f0ccbfd 100644
--- a/tests/test_stream.c
+++ b/tests/test_stream.c
@@ -38,6 +38,7 @@
#include "asterisk/format_cap.h"
#include "asterisk/format_cache.h"
#include "asterisk/channel.h"
+#include "asterisk/uuid.h"
AST_TEST_DEFINE(stream_create)
{
@@ -224,6 +225,70 @@ AST_TEST_DEFINE(stream_set_state)
return AST_TEST_PASS;
}
+AST_TEST_DEFINE(stream_metadata)
+{
+ RAII_VAR(struct ast_stream *, stream, NULL, ast_stream_free);
+ char track_label[AST_UUID_STR_LEN + 1];
+ const char *stream_track_label;
+ int rc;
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "stream_metadata";
+ info->category = "/main/stream/";
+ info->summary = "stream metadata unit test";
+ info->description =
+ "Test that metadata operations on a stream works";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ stream = ast_stream_alloc("test", AST_MEDIA_TYPE_AUDIO);
+ if (!stream) {
+ ast_test_status_update(test, "Failed to create media stream given proper arguments\n");
+ return AST_TEST_FAIL;
+ }
+
+ stream_track_label = ast_stream_get_metadata(stream, "AST_STREAM_METADATA_TRACK_LABEL");
+ if (stream_track_label) {
+ ast_test_status_update(test, "New stream HAD a track label\n");
+ return AST_TEST_FAIL;
+ }
+
+ ast_uuid_generate_str(track_label, sizeof(track_label));
+ rc = ast_stream_set_metadata(stream, "AST_STREAM_METADATA_TRACK_LABEL", track_label);
+ if (rc != 0) {
+ ast_test_status_update(test, "Failed to add track label\n");
+ return AST_TEST_FAIL;
+ }
+
+ stream_track_label = ast_stream_get_metadata(stream, "AST_STREAM_METADATA_TRACK_LABEL");
+ if (!stream_track_label) {
+ ast_test_status_update(test, "Changed stream does not have a track label\n");
+ return AST_TEST_FAIL;
+ }
+
+ if (strcmp(stream_track_label, track_label) != 0) {
+ ast_test_status_update(test, "Changed stream did not return same track label\n");
+ return AST_TEST_FAIL;
+ }
+
+ rc = ast_stream_set_metadata(stream, "AST_STREAM_METADATA_TRACK_LABEL", NULL);
+ if (rc != 0) {
+ ast_test_status_update(test, "Failed to remove track label\n");
+ return AST_TEST_FAIL;
+ }
+
+ stream_track_label = ast_stream_get_metadata(stream, "AST_STREAM_METADATA_TRACK_LABEL");
+ if (stream_track_label) {
+ ast_test_status_update(test, "Changed stream still had a track label after we removed it\n");
+ return AST_TEST_FAIL;
+ }
+
+ return AST_TEST_PASS;
+}
+
AST_TEST_DEFINE(stream_topology_create)
{
RAII_VAR(struct ast_stream_topology *, topology, NULL, ast_stream_topology_free);
@@ -254,6 +319,11 @@ AST_TEST_DEFINE(stream_topology_clone)
RAII_VAR(struct ast_stream_topology *, topology, NULL, ast_stream_topology_free);
RAII_VAR(struct ast_stream_topology *, cloned, NULL, ast_stream_topology_free);
struct ast_stream *audio_stream, *video_stream;
+ char audio_track_label[AST_UUID_STR_LEN + 1];
+ char video_track_label[AST_UUID_STR_LEN + 1];
+ const char *original_track_label;
+ const char *cloned_track_label;
+ int rc;
switch (cmd) {
case TEST_INIT:
@@ -279,6 +349,13 @@ AST_TEST_DEFINE(stream_topology_clone)
return AST_TEST_FAIL;
}
+ ast_uuid_generate_str(audio_track_label, sizeof(audio_track_label));
+ rc = ast_stream_set_metadata(audio_stream, "AST_STREAM_METADATA_TRACK_LABEL", audio_track_label);
+ if (rc != 0) {
+ ast_test_status_update(test, "Failed to add track label\n");
+ return AST_TEST_FAIL;
+ }
+
if (ast_stream_topology_append_stream(topology, audio_stream) == -1) {
ast_test_status_update(test, "Failed to append valid audio stream to stream topology\n");
ast_stream_free(audio_stream);
@@ -291,6 +368,13 @@ AST_TEST_DEFINE(stream_topology_clone)
return AST_TEST_FAIL;
}
+ ast_uuid_generate_str(video_track_label, sizeof(video_track_label));
+ rc = ast_stream_set_metadata(video_stream, "AST_STREAM_METADATA_TRACK_LABEL", video_track_label);
+ if (rc != 0) {
+ ast_test_status_update(test, "Failed to add track label\n");
+ return AST_TEST_FAIL;
+ }
+
if (ast_stream_topology_append_stream(topology, video_stream) == -1) {
ast_test_status_update(test, "Failed to append valid video stream to stream topology\n");
ast_stream_free(video_stream);
@@ -313,11 +397,45 @@ AST_TEST_DEFINE(stream_topology_clone)
return AST_TEST_FAIL;
}
+ original_track_label = ast_stream_get_metadata(ast_stream_topology_get_stream(topology, 0),
+ "AST_STREAM_METADATA_TRACK_LABEL");
+ if (!original_track_label) {
+ ast_test_status_update(test, "Original topology stream 0 does not contain metadata\n");
+ return AST_TEST_FAIL;
+ }
+ cloned_track_label = ast_stream_get_metadata(ast_stream_topology_get_stream(cloned, 0),
+ "AST_STREAM_METADATA_TRACK_LABEL");
+ if (!cloned_track_label) {
+ ast_test_status_update(test, "Cloned topology stream 0 does not contain metadata\n");
+ return AST_TEST_FAIL;
+ }
+ if (strcmp(original_track_label, cloned_track_label) != 0) {
+ ast_test_status_update(test, "Cloned topology stream 0 track label was not the same as the original\n");
+ return AST_TEST_FAIL;
+ }
+
if (ast_stream_get_type(ast_stream_topology_get_stream(cloned, 1)) != ast_stream_get_type(ast_stream_topology_get_stream(topology, 1))) {
ast_test_status_update(test, "Cloned video stream does not contain same type as original\n");
return AST_TEST_FAIL;
}
+ original_track_label = ast_stream_get_metadata(ast_stream_topology_get_stream(topology, 1),
+ "AST_STREAM_METADATA_TRACK_LABEL");
+ if (!original_track_label) {
+ ast_test_status_update(test, "Original topology stream 1 does not contain metadata\n");
+ return AST_TEST_FAIL;
+ }
+ cloned_track_label = ast_stream_get_metadata(ast_stream_topology_get_stream(cloned, 1),
+ "AST_STREAM_METADATA_TRACK_LABEL");
+ if (!cloned_track_label) {
+ ast_test_status_update(test, "Cloned topology stream 1 does not contain metadata\n");
+ return AST_TEST_FAIL;
+ }
+ if (strcmp(original_track_label, cloned_track_label) != 0) {
+ ast_test_status_update(test, "Cloned topology stream 1 track label was not the same as the original\n");
+ return AST_TEST_FAIL;
+ }
+
return AST_TEST_PASS;
}
@@ -2139,6 +2257,7 @@ static int unload_module(void)
AST_TEST_UNREGISTER(stream_set_type);
AST_TEST_UNREGISTER(stream_set_formats);
AST_TEST_UNREGISTER(stream_set_state);
+ AST_TEST_UNREGISTER(stream_metadata);
AST_TEST_UNREGISTER(stream_topology_create);
AST_TEST_UNREGISTER(stream_topology_clone);
AST_TEST_UNREGISTER(stream_topology_clone);
@@ -2169,6 +2288,7 @@ static int load_module(void)
AST_TEST_REGISTER(stream_set_type);
AST_TEST_REGISTER(stream_set_formats);
AST_TEST_REGISTER(stream_set_state);
+ AST_TEST_REGISTER(stream_metadata);
AST_TEST_REGISTER(stream_topology_create);
AST_TEST_REGISTER(stream_topology_clone);
AST_TEST_REGISTER(stream_topology_append_stream);