diff options
Diffstat (limited to 'main/channel.c')
-rw-r--r-- | main/channel.c | 60 |
1 files changed, 53 insertions, 7 deletions
diff --git a/main/channel.c b/main/channel.c index 183f8936f..e3e9561fe 100644 --- a/main/channel.c +++ b/main/channel.c @@ -3782,11 +3782,12 @@ static inline int calc_monitor_jump(int samples, int sample_rate, int seek_rate) return samples; } -static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio) +static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio, int dropnondefault) { struct ast_frame *f = NULL; /* the return value */ int prestate; int cause = 0; + struct ast_stream *stream = NULL, *default_stream = NULL; /* this function is very long so make sure there is only one return * point at the end (there are only two exceptions to this). @@ -3943,6 +3944,13 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio) 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 { ast_channel_blocker_set(chan, pthread_self()); @@ -3955,15 +3963,43 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio) } /* Clear the exception flag */ ast_clear_flag(ast_channel_flags(chan), AST_FLAG_EXCEPTION); - } else if (ast_channel_tech(chan) && ast_channel_tech(chan)->read) + } else if (ast_channel_tech(chan) && ast_channel_tech(chan)->read_stream) { + f = ast_channel_tech(chan)->read_stream(chan); + + /* This channel driver supports multistream so the stream_num on the frame is valid, the only + * 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) { + 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 if (ast_channel_tech(chan) && ast_channel_tech(chan)->read) { f = ast_channel_tech(chan)->read(chan); + + /* 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) { + 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_log(LOG_WARNING, "No read routine on channel %s\n", ast_channel_name(chan)); } - /* 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); + 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) { + /* 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); + } /* * Reset the recorded file descriptor that triggered this read so that we can @@ -4162,6 +4198,11 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio) } break; case AST_FRAME_VOICE: + /* If media was received from a non-default stream don't perform any actions, let it just go through */ + if (stream != default_stream) { + break; + } + /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration * is reached , because we want to make sure we pass at least one * voice frame through before starting the next digit, to ensure a gap @@ -4396,12 +4437,17 @@ done: struct ast_frame *ast_read(struct ast_channel *chan) { - return __ast_read(chan, 0); + return __ast_read(chan, 0, 1); +} + +struct ast_frame *ast_read_stream(struct ast_channel *chan) +{ + return __ast_read(chan, 0, 0); } struct ast_frame *ast_read_noaudio(struct ast_channel *chan) { - return __ast_read(chan, 1); + return __ast_read(chan, 1, 1); } int ast_indicate(struct ast_channel *chan, int condition) |