diff options
Diffstat (limited to 'main')
-rw-r--r-- | main/channel.c | 38 | ||||
-rw-r--r-- | main/channel_internal_api.c | 13 |
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); +} |