summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
Diffstat (limited to 'main')
-rw-r--r--main/channel.c38
-rw-r--r--main/channel_internal_api.c13
2 files changed, 33 insertions, 18 deletions
diff --git a/main/channel.c b/main/channel.c
index e3e9561fe..12a30e048 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -3944,13 +3944,17 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio, int
default:
break;
}
- } else if (!(ast_channel_tech(chan)->properties & AST_CHAN_TP_MULTISTREAM) && (
- f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO)) {
- /* Since this channel driver does not support multistream determine the default stream this frame
- * originated from and update the frame to include it.
- */
- stream = default_stream = ast_channel_get_default_stream(chan, ast_format_get_type(f->subclass.format));
- f->stream_num = ast_stream_get_position(stream);
+ } else if (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO) {
+ if (ast_channel_tech(chan) && ast_channel_tech(chan)->read_stream) {
+ stream = ast_stream_topology_get_stream(ast_channel_get_stream_topology(chan), f->stream_num);
+ default_stream = ast_channel_get_default_stream(chan, ast_format_get_type(f->subclass.format));
+ } else {
+ /* Since this channel driver does not support multistream determine the default stream this frame
+ * originated from and update the frame to include it.
+ */
+ stream = default_stream = ast_channel_get_default_stream(chan, ast_format_get_type(f->subclass.format));
+ f->stream_num = ast_stream_get_position(stream);
+ }
}
} else {
ast_channel_blocker_set(chan, pthread_self());
@@ -3970,7 +3974,7 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio, int
* thing different is that we need to find the default stream so we know whether to invoke the
* default stream logic or not (such as transcoding).
*/
- if (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO) {
+ if (f && (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO)) {
stream = ast_stream_topology_get_stream(ast_channel_get_stream_topology(chan), f->stream_num);
default_stream = ast_channel_get_default_stream(chan, ast_format_get_type(f->subclass.format));
}
@@ -3980,7 +3984,7 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio, int
/* Since this channel driver does not support multistream determine the default stream this frame
* originated from and update the frame to include it.
*/
- if (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO) {
+ if (f && (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO)) {
stream = default_stream = ast_channel_get_default_stream(chan, ast_format_get_type(f->subclass.format));
f->stream_num = ast_stream_get_position(stream);
}
@@ -3989,13 +3993,7 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio, int
ast_log(LOG_WARNING, "No read routine on channel %s\n", ast_channel_name(chan));
}
- if (dropnondefault && stream != default_stream) {
- /* If the frame originates from a non-default stream and the caller can not handle other streams
- * absord the frame and replace it with a null one instead.
- */
- ast_frfree(f);
- f = &ast_null_frame;
- } else if (stream == default_stream) {
+ if (stream == default_stream) {
/* Perform the framehook read event here. After the frame enters the framehook list
* there is no telling what will happen, <insert mad scientist laugh here>!!! */
f = ast_framehook_list_read_event(ast_channel_framehooks(chan), f);
@@ -4022,6 +4020,14 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio, int
AST_LIST_NEXT(f, frame_list) = NULL;
}
+ if (dropnondefault && stream != default_stream) {
+ /* If the frame originates from a non-default stream and the caller can not handle other streams
+ * absorb the frame and replace it with a null one instead.
+ */
+ ast_frfree(f);
+ f = &ast_null_frame;
+ }
+
switch (f->frametype) {
case AST_FRAME_CONTROL:
if (f->subclass.integer == AST_CONTROL_ANSWER) {
diff --git a/main/channel_internal_api.c b/main/channel_internal_api.c
index 362bd1a3d..d7ae8f9c1 100644
--- a/main/channel_internal_api.c
+++ b/main/channel_internal_api.c
@@ -867,7 +867,7 @@ void ast_channel_nativeformats_set(struct ast_channel *chan,
return;
}
- if (!chan->tech || !(chan->tech->properties & AST_CHAN_TP_MULTISTREAM) || !value) {
+ if ((!ast_channel_is_multistream(chan)) || !value) {
struct ast_stream_topology *new_topology;
if (!value) {
@@ -949,6 +949,10 @@ const struct ast_channel_tech *ast_channel_tech(const struct ast_channel *chan)
}
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
{
+ if (value->read_stream || value->write_stream) {
+ ast_assert(value->read_stream && value->write_stream);
+ }
+
chan->tech = value;
}
enum ast_channel_adsicpe ast_channel_adsicpe(const struct ast_channel *chan)
@@ -1798,7 +1802,7 @@ struct ast_stream_topology *ast_channel_set_stream_topology(struct ast_channel *
ast_assert(chan != NULL);
/* A non-MULTISTREAM channel can't manipulate topology directly */
- ast_assert(chan->tech != NULL && (chan->tech->properties & AST_CHAN_TP_MULTISTREAM));
+ ast_assert(ast_channel_is_multistream(chan));
/* Unless the channel is being destroyed, we always want a topology on
* it even if its empty.
@@ -1839,3 +1843,8 @@ void ast_channel_internal_swap_stream_topology(struct ast_channel *chan1,
channel_set_default_streams(chan1);
channel_set_default_streams(chan2);
}
+
+int ast_channel_is_multistream(struct ast_channel *chan)
+{
+ return (chan->tech && chan->tech->read_stream && chan->tech->write_stream);
+}