FS-7503 FS-7514 FS-7513: fix some buffering bugs in vlc and set mod_conference to match the rate and channels when calling vlc files

This commit is contained in:
Anthony Minessale 2015-02-28 15:45:06 -06:00 committed by Michael Jerris
parent 36e754eed2
commit baa3d9cd7c
4 changed files with 57 additions and 31 deletions

View File

@ -407,7 +407,7 @@ typedef struct mcu_canvas_s {
int layers_used;
int layout_floor_id;
int refresh;
int reset_video;
int send_keyframe;
int play_file;
switch_rgb_color_t bgcolor;
switch_mutex_t *mutex;
@ -1414,6 +1414,7 @@ static void init_canvas_layers(conference_obj_t *conference, video_layout_t *vla
conference->canvas->layers_used = 0;
conference->canvas->total_layers = vlayout->layers;
conference->canvas->send_keyframe = 1;
switch_mutex_unlock(conference->canvas->mutex);
}
@ -1619,7 +1620,7 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread
}
switch_core_timer_init(&conference->canvas->timer, "soft", conference->video_fps.ms, conference->video_fps.samples, NULL);
conference->canvas->reset_video = 1;
conference->canvas->send_keyframe = 1;
}
if (!conference->playing_video_file) {
@ -1817,11 +1818,9 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread
conference->canvas->refresh = 0;
}
if (conference->canvas->reset_video) {
//need_refresh = SWITCH_TRUE;
//need_reset = SWITCH_TRUE;
if (conference->canvas->send_keyframe) {
need_keyframe = SWITCH_TRUE;
conference->canvas->reset_video = 0;
conference->canvas->send_keyframe = 0;
}
if (video_key_freq && (now - last_key_time) > video_key_freq) {
@ -1837,7 +1836,7 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread
switch_img_free(&file_img);
if (conference->canvas->play_file) {
conference->canvas->reset_video = 1;
conference->canvas->send_keyframe = 1;
conference->canvas->play_file = 0;
conference->canvas->timer.interval = 1;
@ -4142,7 +4141,7 @@ static switch_status_t conference_file_close(conference_obj_t *conference, confe
conference->canvas->timer.interval = conference->video_fps.ms;
conference->canvas->timer.samples = conference->video_fps.samples;
switch_core_timer_sync(&conference->canvas->timer);
conference->canvas->reset_video = 1;
conference->canvas->send_keyframe = 1;
conference->playing_video_file = 0;
}
return switch_core_file_close(&node->fh);
@ -6589,6 +6588,10 @@ static void *SWITCH_THREAD_FUNC conference_record_thread_run(switch_thread_t *th
goto end;
}
if (conference->canvas) {
conference->canvas->send_keyframe = 1;
}
fh.pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN;
flags = SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT;
@ -6723,6 +6726,10 @@ static void *SWITCH_THREAD_FUNC conference_record_thread_run(switch_thread_t *th
switch_core_timer_destroy(&timer);
conference_del_member(conference, member);
if (conference->canvas) {
conference->canvas->send_keyframe = 1;
}
switch_buffer_destroy(&member->audio_buffer);
switch_buffer_destroy(&member->mux_buffer);
switch_clear_flag_locked(member, MFLAG_RUNNING);
@ -6966,7 +6973,6 @@ static switch_status_t conference_play_file(conference_obj_t *conference, char *
flags = SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT;
if (conference->members_with_video && switch_test_flag(conference, CFLAG_TRANSCODE_VIDEO)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Vido FLAG\n");
flags |= SWITCH_FILE_FLAG_VIDEO;
}
@ -9620,6 +9626,7 @@ static switch_status_t conf_api_sub_enter_sound(conference_obj_t *conference, sw
static switch_status_t conf_api_sub_dial(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv)
{
switch_call_cause_t cause;
char *tmp;
switch_assert(stream != NULL);
@ -9628,6 +9635,12 @@ static switch_status_t conf_api_sub_dial(conference_obj_t *conference, switch_st
return SWITCH_STATUS_GENERR;
}
if (conference && argv[2] && strstr(argv[2], "vlc/")) {
tmp = switch_core_sprintf(conference->pool, "{vlc_rate=%d,vlc_channels=%d,vlc_interval=%d}%s",
conference->rate, conference->channels, conference->interval, argv[2]);
argv[2] = tmp;
}
if (conference) {
conference_outcall(conference, NULL, NULL, argv[2], 60, NULL, argv[4], argv[3], NULL, &cause, NULL, NULL);
} else {

View File

@ -1906,8 +1906,8 @@ typedef struct {
switch_codec_t video_codec;
switch_frame_t read_frame;
switch_frame_t read_video_frame;
void *audio_data[SWITCH_RECOMMENDED_BUFFER_SIZE];
void *video_data[SWITCH_RECOMMENDED_BUFFER_SIZE * 20];
unsigned char *audio_data;
switch_size_t audio_datalen;
const char *destination_number;
vlc_video_context_t *context;
switch_timer_t timer;
@ -1960,21 +1960,34 @@ static switch_status_t setup_tech_pvt(switch_core_session_t *osession, switch_co
memset(tech_pvt, 0, sizeof(*tech_pvt));
tech_pvt->audio_datalen = SWITCH_RECOMMENDED_BUFFER_SIZE;
tech_pvt->audio_data = switch_core_session_alloc(session, tech_pvt->audio_datalen);
if (osession) {
switch_core_session_get_read_impl(osession, &tech_pvt->read_impl);
} else {
const char *val;
int tmp = 0;
int packets;
tech_pvt->read_impl.microseconds_per_packet = 20000;
val = switch_event_get_header(var_event, "vlc_interval");
if (val) tmp = atoi(val);
if (tmp == 0) tmp = 20;
tech_pvt->read_impl.microseconds_per_packet = tmp * 1000;
tech_pvt->read_impl.iananame = "L16";
tmp = 0;
val = switch_event_get_header(var_event, "vlc_rate");
if (val) tmp = atoi(val);
if (tmp == 0) tmp = 8000;
packets = 1000 / (tech_pvt->read_impl.microseconds_per_packet / 1000);
tech_pvt->read_impl.samples_per_second = tmp;
tech_pvt->read_impl.actual_samples_per_second = tmp;
tech_pvt->read_impl.samples_per_packet = tech_pvt->read_impl.samples_per_second / (tech_pvt->read_impl.microseconds_per_packet / 1000);
tech_pvt->read_impl.samples_per_packet = tech_pvt->read_impl.samples_per_second / packets;
tmp = 0;
val = switch_event_get_header(var_event, "vlc_channels");
@ -1986,6 +1999,8 @@ static switch_status_t setup_tech_pvt(switch_core_session_t *osession, switch_co
}
tech_pvt->read_impl.number_of_channels = tmp;
tech_pvt->read_impl.decoded_bytes_per_packet = tech_pvt->read_impl.samples_per_packet * 2 * tech_pvt->read_impl.number_of_channels;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No BLAH %d %d\n", tech_pvt->read_impl.samples_per_second, tech_pvt->read_impl.number_of_channels);
}
tech_pvt->session = session;
@ -2329,26 +2344,19 @@ static switch_status_t vlc_read_frame(switch_core_session_t *session, switch_fra
return SWITCH_STATUS_SUCCESS;
}
switch_mutex_lock(context->audio_mutex);
if (switch_buffer_inuse(context->audio_buffer) >= audio_datalen) {
tech_pvt->read_frame.data = tech_pvt->audio_data;
switch_buffer_read(context->audio_buffer, tech_pvt->read_frame.data, audio_datalen);
tech_pvt->read_frame.datalen = audio_datalen;
tech_pvt->read_frame.buflen = audio_datalen;
tech_pvt->read_frame.flags &= ~SFF_CNG;
tech_pvt->read_frame.codec = &tech_pvt->read_codec;
*frame = &tech_pvt->read_frame;
switch_mutex_unlock(context->audio_mutex);
return SWITCH_STATUS_SUCCESS;
}
switch_mutex_unlock(context->audio_mutex);
*frame = &tech_pvt->read_frame;
tech_pvt->read_frame.codec = &tech_pvt->read_codec;
tech_pvt->read_frame.flags |= SFF_CNG;
tech_pvt->read_frame.datalen = 0;
tech_pvt->read_frame.data = tech_pvt->audio_data;
tech_pvt->read_frame.datalen = audio_datalen;
tech_pvt->read_frame.buflen = tech_pvt->audio_datalen;
switch_mutex_lock(context->audio_mutex);
if (switch_buffer_inuse(context->audio_buffer) >= audio_datalen) {
switch_buffer_read(context->audio_buffer, tech_pvt->audio_data, audio_datalen);
} else {
memset(tech_pvt->audio_data, 0, audio_datalen);
}
switch_mutex_unlock(context->audio_mutex);
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "read cng frame\n");
return SWITCH_STATUS_SUCCESS;

View File

@ -868,6 +868,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_codec_control(switch_codec_t *codec,
if (!codec->implementation || !switch_core_codec_ready(codec)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec is not initialized!\n");
abort();
return SWITCH_STATUS_NOT_INITALIZED;
}

View File

@ -9910,6 +9910,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_codec_control(switch_core_sess
codec = &engine->write_codec;
}
if (!switch_core_codec_ready(codec)) {
return SWITCH_STATUS_FALSE;
}
if (mtype == SWITCH_MEDIA_TYPE_VIDEO) {
if (!switch_channel_test_flag(session->channel, CF_VIDEO)) {
return SWITCH_STATUS_FALSE;