From beb1521e882a4c982094e3e1c05de79a6ef3ede2 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 30 Sep 2015 22:02:50 -0500 Subject: [PATCH] revert --- src/mod/applications/mod_av/avformat.c | 445 +++++++++--------- .../mod_conference/conference_video.c | 4 +- .../mod_local_stream/mod_local_stream.c | 128 ++--- src/switch_core_media.c | 4 +- src/switch_ivr_async.c | 3 - 5 files changed, 281 insertions(+), 303 deletions(-) diff --git a/src/mod/applications/mod_av/avformat.c b/src/mod/applications/mod_av/avformat.c index d33c462666..ab3fc2b9ce 100644 --- a/src/mod/applications/mod_av/avformat.c +++ b/src/mod/applications/mod_av/avformat.c @@ -139,6 +139,7 @@ typedef struct record_helper_s { AVFormatContext *fc; MediaStream *video_st; switch_timer_t *timer; + switch_timer_t *other_timer; int in_callback; switch_queue_t *video_queue; switch_thread_t *video_thread; @@ -258,6 +259,11 @@ static switch_status_t add_stream(MediaStream *mst, AVFormatContext *fc, AVCodec c->channels = mst->channels; c->channel_layout = av_get_default_channel_layout(c->channels); + mst->st->time_base.den = 1000; + mst->st->time_base.num = 1; + c->time_base.den = 1000; + c->time_base.num = 1; + if (mm) { if (mm->ab) { c->bit_rate = mm->ab * 1024; @@ -494,37 +500,59 @@ static switch_status_t open_audio(AVFormatContext *fc, AVCodec *codec, MediaStre static void *SWITCH_THREAD_FUNC video_thread_run(switch_thread_t *thread, void *obj) { record_helper_t *eh = (record_helper_t *) obj; - void *pop = NULL; - switch_image_t *img = NULL, *tmp_img = NULL; - int d_w = 0, d_h = 0; + void *pop; + switch_image_t *img, *last_img = NULL, *tmp_img = NULL; + switch_size_t size; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "video thread start\n"); for(;;) { AVPacket pkt = { 0 }; int got_packet; - int ret = -1; + int ret = -1, popped = 0; - if (switch_queue_pop(eh->video_queue, &pop) == SWITCH_STATUS_SUCCESS) { - if (!pop) { - goto endfor; + do { + switch_status_t status; + img = NULL; + + if (!popped) { + status = switch_queue_pop(eh->video_queue, &pop); + popped++; + } else { + status = switch_queue_trypop(eh->video_queue, &pop); } - img = (switch_image_t *) pop; - - if (!d_w) d_w = img->d_w; - if (!d_h) d_h = img->d_h; - - if (d_w && d_h && (d_w != img->d_w || d_h != img->d_h)) { - /* scale to match established stream */ - switch_img_scale(img, &tmp_img, d_w, d_h); + + if (status == SWITCH_STATUS_SUCCESS) { switch_img_free(&img); - img = tmp_img; - tmp_img = NULL; + + if (!pop) { + goto endfor; + } + img = (switch_image_t *)pop; + } else { + if (img) { + break; + } else { + popped = 0; + continue; + } } - } else { - continue; + + size = switch_queue_size(eh->video_queue); + } while(img && size > 1); + + + if (last_img && (last_img->d_w != img->d_w || last_img->d_h != img->d_h)) { + /* scale to match established stream */ + switch_img_scale(img, &tmp_img, last_img->d_w, last_img->d_h); + switch_img_free(&img); + img = tmp_img; + tmp_img = NULL; } + switch_img_free(&last_img); + last_img = img; + //switch_mutex_lock(eh->mutex); eh->in_callback = 1; @@ -540,6 +568,14 @@ static void *SWITCH_THREAD_FUNC video_thread_run(switch_thread_t *thread, void * fill_avframe(eh->video_st->frame, img); switch_core_timer_sync(eh->timer); + if (eh->other_timer) { + if (eh->timer->samplecount > eh->other_timer->samplecount) { + int sleepfor = (eh->timer->samplecount - eh->other_timer->samplecount) * 1000; + switch_yield(sleepfor); + switch_core_timer_sync(eh->timer); + } + } + if (eh->video_st->frame->pts == eh->timer->samplecount) { // never use the same pts, or the encoder coughs eh->video_st->frame->pts++; @@ -570,6 +606,8 @@ static void *SWITCH_THREAD_FUNC video_thread_run(switch_thread_t *thread, void * endfor: + switch_img_free(&last_img); + while(switch_queue_trypop(eh->video_queue, &pop) == SWITCH_STATUS_SUCCESS) { if (!pop) break; img = (switch_image_t *) pop; @@ -592,7 +630,7 @@ static switch_status_t video_read_callback(switch_core_session_t *session, switc switch_queue_push(eh->video_queue, img); } - return SWITCH_STATUS_SUCCESS; + return SWITCH_STATUS_SUCCESS;; } static void close_stream(AVFormatContext *fc, MediaStream *mst) @@ -1055,6 +1093,7 @@ struct av_file_context { switch_buffer_t *buf; switch_buffer_t *audio_buffer; switch_timer_t video_timer; + switch_timer_t audio_timer; int offset; int audio_start; int vid_ready; @@ -1211,18 +1250,17 @@ static void *SWITCH_THREAD_FUNC file_read_thread_run(switch_thread_t *thread, vo AVPacket pkt = { 0 }; int got_data = 0; int error; - int sync = 0; context->file_read_thread_running = 1; -#define AUDIO_BUF_SEC 5 +#define AUDIO_BUF_SEC 1 while (context->file_read_thread_running) { if (switch_buffer_inuse(context->audio_buffer) > AUDIO_BUF_SEC * context->audio_st.sample_rate * context->audio_st.channels * 2) { - switch_yield(10000); + switch_yield(100000); continue; } - + av_init_packet(&pkt); pkt.data = NULL; pkt.size = 0; @@ -1238,10 +1276,7 @@ static void *SWITCH_THREAD_FUNC file_read_thread_run(switch_thread_t *thread, vo if (context->has_video && pkt.stream_index == context->video_st.st->index) { AVFrame *vframe = av_frame_alloc(); switch_image_t *img; - if (!sync) { - switch_buffer_zero(context->audio_buffer); - sync = 1; - } + switch_assert(vframe); if ((error = avcodec_decode_video2(context->video_st.st->codec, vframe, &got_data, &pkt)) < 0) { @@ -1254,11 +1289,11 @@ static void *SWITCH_THREAD_FUNC file_read_thread_run(switch_thread_t *thread, vo // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "pkt: %d, pts: %lld dts: %lld\n", pkt.size, pkt.pts, pkt.dts); av_free_packet(&pkt); - //if (switch_queue_size(context->eh.video_queue) > 300) { - // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Dropping frames\n"); - // av_frame_free(&vframe); - // continue; - //} + if (switch_queue_size(context->eh.video_queue) > 300) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Dropping frames\n"); + av_frame_free(&vframe); + continue; + } if (got_data && error > 0) { // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "got picture %dx%d fmt: %d pktpts:%lld pktdts:%lld\n", vframe->width, vframe->height, vframe->format, vframe->pkt_pts, vframe->pkt_dts); @@ -1549,6 +1584,9 @@ static switch_status_t av_file_open(switch_file_handle_t *handle, const char *pa handle->pos = 0; + switch_core_timer_init(&context->audio_timer, "soft", 1, 1, /*handle->samplerate / 1000,*/ context->pool); + switch_core_timer_init(&context->video_timer, "soft", 1, 1, context->pool); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Opening File [%s] %dhz %s\n", file, handle->samplerate, switch_test_flag(handle, SWITCH_FILE_FLAG_VIDEO) ? " with VIDEO" : ""); @@ -1564,6 +1602,10 @@ static switch_status_t av_file_open(switch_file_handle_t *handle, const char *pa switch_core_timer_destroy(&context->video_timer); } + if (context->audio_timer.interval) { + switch_core_timer_destroy(&context->audio_timer); + } + if (context->audio_buffer) { switch_buffer_destroy(&context->audio_buffer); } @@ -1576,123 +1618,21 @@ static switch_status_t av_file_truncate(switch_file_handle_t *handle, int64_t of return SWITCH_STATUS_FALSE; } -static void flush_video_queue(switch_queue_t *q, int min) +static void flush_video_queue(switch_queue_t *q) { void *pop; - if (switch_queue_size(q) <= min) { + if (switch_queue_size(q) == 0) { return; } while (switch_queue_trypop(q, &pop) == SWITCH_STATUS_SUCCESS) { switch_image_t *img = (switch_image_t *) pop; switch_img_free(&img); - if (min && switch_queue_size(q) <= min) { - break; - } } } -static switch_status_t av_file_write(switch_file_handle_t *handle, void *data, size_t *len) -{ - - uint32_t datalen = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - // uint8_t buf[SWITCH_RECOMMENDED_BUFFER_SIZE] = { 0 }, *bp = buf; - // uint32_t encoded_rate; - av_file_context_t *context = (av_file_context_t *)handle->private_info; - // uint32_t size = 0; - uint32_t bytes; - int inuse; - - if (!context->vid_ready) { - return status; - } - - if (data && len) { - datalen = *len * 2 * handle->channels; - - if (context->offset) { - char buf[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0}; - switch_size_t samples = *len; - int fps = handle->samplerate / samples; - int lead_frames = (context->offset * fps) / 1000; - - for (int x = 0; x < lead_frames; x++) { - switch_buffer_write(context->audio_buffer, buf, datalen); - } - context->offset = 0; - } - - switch_buffer_write(context->audio_buffer, data, datalen); - } - - bytes = context->audio_st.frame->nb_samples * 2 * context->audio_st.st->codec->channels; - - - //inuse = switch_buffer_inuse(context->audio_buffer); - //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "inuse: %d samples: %d bytes: %d\n", inuse, context->audio_st.frame->nb_samples, bytes); - - - while ((inuse = switch_buffer_inuse(context->audio_buffer)) >= bytes) { - AVPacket pkt = { 0 }; - int got_packet = 0; - int ret; - - av_init_packet(&pkt); - - if (context->audio_st.resample_ctx) { // need resample - int out_samples = avresample_get_out_samples(context->audio_st.resample_ctx, context->audio_st.frame->nb_samples); - - av_frame_make_writable(context->audio_st.frame); - av_frame_make_writable(context->audio_st.tmp_frame); - switch_buffer_read(context->audio_buffer, context->audio_st.frame->data[0], bytes); - /* convert to destination format */ - ret = avresample_convert(context->audio_st.resample_ctx, - (uint8_t **)context->audio_st.frame->data, 0, out_samples, - context->audio_st.tmp_frame->data, 0, context->audio_st.frame->nb_samples); - - if (ret < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error while converting %d samples, error text: %s\n", - context->audio_st.frame->nb_samples, get_error_text(ret)); - continue; - } - - context->audio_st.tmp_frame->pts = context->audio_st.next_pts; - context->audio_st.next_pts += context->audio_st.frame->nb_samples; - ret = avcodec_encode_audio2(context->audio_st.st->codec, &pkt, context->audio_st.tmp_frame, &got_packet); - } else { - av_frame_make_writable(context->audio_st.frame); - switch_buffer_read(context->audio_buffer, context->audio_st.frame->data[0], bytes); - context->audio_st.frame->pts = context->audio_st.next_pts; - context->audio_st.next_pts += context->audio_st.frame->nb_samples; - - ret = avcodec_encode_audio2(context->audio_st.st->codec, &pkt, context->audio_st.frame, &got_packet); - } - - if (ret < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Error encoding audio frame: %d\n", ret); - continue; - } - - if (got_packet) { - if (context->mutex) switch_mutex_lock(context->mutex); - ret = write_frame(context->fc, &context->audio_st.st->codec->time_base, context->audio_st.st, &pkt); - if (context->mutex) switch_mutex_unlock(context->mutex); - if (ret < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error while writing audio frame: %s\n", get_error_text(ret)); - //switch_goto_status(SWITCH_STATUS_FALSE, end); - } - } - if (data) { - break; - } - } - - return status; -} - static switch_status_t av_file_close(switch_file_handle_t *handle) { av_file_context_t *context = (av_file_context_t *)handle->private_info; @@ -1705,8 +1645,6 @@ static switch_status_t av_file_close(switch_file_handle_t *handle) if (context->eh.video_thread) { switch_thread_join(&status, context->eh.video_thread); } - - av_file_write(handle, NULL, NULL); if (context->file_read_thread_running && context->file_read_thread) { context->file_read_thread_running = 0; @@ -1714,7 +1652,7 @@ static switch_status_t av_file_close(switch_file_handle_t *handle) } if (context->eh.video_queue) { - flush_video_queue(context->eh.video_queue, 0); + flush_video_queue(context->eh.video_queue); } if (context->fc) { @@ -1727,6 +1665,10 @@ static switch_status_t av_file_close(switch_file_handle_t *handle) switch_core_timer_destroy(&context->video_timer); } + if (context->audio_timer.interval) { + switch_core_timer_destroy(&context->audio_timer); + } + switch_img_free(&context->last_img); switch_buffer_destroy(&context->audio_buffer); @@ -1780,122 +1722,159 @@ static switch_status_t av_file_read(switch_file_handle_t *handle, void *data, si return *len == 0 ? SWITCH_STATUS_FALSE : SWITCH_STATUS_SUCCESS; } +static switch_status_t av_file_write(switch_file_handle_t *handle, void *data, size_t *len) +{ + + uint32_t datalen = *len * 2 * handle->channels; + switch_status_t status = SWITCH_STATUS_SUCCESS; + // uint8_t buf[SWITCH_RECOMMENDED_BUFFER_SIZE] = { 0 }, *bp = buf; + // uint32_t encoded_rate; + av_file_context_t *context = (av_file_context_t *)handle->private_info; + // uint32_t size = 0; + uint32_t bytes; + int inuse; + + if (!context->vid_ready) { + return status; + } + + if (context->offset) { + char buf[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0}; + switch_size_t samples = *len; + int fps = handle->samplerate / samples; + int lead_frames = (context->offset * fps) / 1000; + + for (int x = 0; x < lead_frames; x++) { + switch_buffer_write(context->audio_buffer, buf, datalen); + } + context->offset = 0; + } + + switch_buffer_write(context->audio_buffer, data, datalen); + bytes = context->audio_st.frame->nb_samples * 2 * context->audio_st.st->codec->channels; + + //inuse = switch_buffer_inuse(context->audio_buffer); + //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "inuse: %d samples: %d bytes: %d\n", inuse, context->audio_st.frame->nb_samples, bytes); + + while ((inuse = switch_buffer_inuse(context->audio_buffer)) >= bytes) { + AVPacket pkt = { 0 }; + int got_packet = 0; + int ret; + + av_init_packet(&pkt); + + if (context->audio_st.resample_ctx) { // need resample + int out_samples = avresample_get_out_samples(context->audio_st.resample_ctx, context->audio_st.frame->nb_samples); + + av_frame_make_writable(context->audio_st.frame); + av_frame_make_writable(context->audio_st.tmp_frame); + switch_buffer_read(context->audio_buffer, context->audio_st.frame->data[0], bytes); + /* convert to destination format */ + ret = avresample_convert(context->audio_st.resample_ctx, + (uint8_t **)context->audio_st.frame->data, 0, out_samples, + context->audio_st.tmp_frame->data, 0, context->audio_st.frame->nb_samples); + + if (ret < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error while converting %d samples, error text: %s\n", + context->audio_st.frame->nb_samples, get_error_text(ret)); + continue; + } + + context->audio_st.tmp_frame->pts = context->audio_st.next_pts; + context->audio_st.next_pts += context->audio_st.frame->nb_samples; + ret = avcodec_encode_audio2(context->audio_st.st->codec, &pkt, context->audio_st.tmp_frame, &got_packet); + } else { + av_frame_make_writable(context->audio_st.frame); + switch_buffer_read(context->audio_buffer, context->audio_st.frame->data[0], bytes); + + switch_core_timer_sync(&context->audio_timer); + context->audio_st.frame->pts = context->audio_timer.samplecount; + //context->audio_st.frame->pts = context->audio_st.next_pts; + //context->audio_st.next_pts += context->audio_st.frame->nb_samples; + + ret = avcodec_encode_audio2(context->audio_st.st->codec, &pkt, context->audio_st.frame, &got_packet); + } + + if (ret < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Error encoding audio frame: %d\n", ret); + continue; + } + + if (got_packet) { + if (context->mutex) switch_mutex_lock(context->mutex); + ret = write_frame(context->fc, &context->audio_st.st->codec->time_base, context->audio_st.st, &pkt); + if (context->mutex) switch_mutex_unlock(context->mutex); + if (ret < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error while writing audio frame: %s\n", get_error_text(ret)); + switch_goto_status(SWITCH_STATUS_FALSE, end); + } + } + + break; + } + + + +end: + return status; +} + + static switch_status_t av_file_read_video(switch_file_handle_t *handle, switch_frame_t *frame, switch_video_read_flag_t flags) { - av_file_context_t *context = (av_file_context_t *)handle->private_info; void *pop; - MediaStream *mst = &context->video_st; - AVStream *st = mst->st; - int ticks = 0; - int max_delta = 1 * AV_TIME_BASE; // 1 second - switch_status_t status = SWITCH_STATUS_SUCCESS; - double fl_to = 0.02; - int do_fl = 0; + av_file_context_t *context = (av_file_context_t *)handle->private_info; + switch_status_t status; + int fps = (int)ceil(handle->mm.fps); + int min_qsize = context->read_fps; - if (!context->has_video) return SWITCH_STATUS_FALSE; + if (fps && fps < min_qsize) { + min_qsize = fps; + } + + if (!min_qsize) { + min_qsize = 1; + } + + if (!context->file_read_thread_running) { + return SWITCH_STATUS_FALSE; + } if ((flags & SVR_CHECK)) { return SWITCH_STATUS_BREAK; } - fl_to = (1000 / context->read_fps) * 1000; - //printf("WTF %d (%f)\n",switch_queue_size(context->eh.video_queue), fl_to); - if (flags & SVR_FLUSH) { - max_delta = fl_to * AV_TIME_BASE; - do_fl = 1; + if (switch_queue_size(context->eh.video_queue) < min_qsize / 2) { + return SWITCH_STATUS_BREAK; } - - if (context->last_img) { - if (mst->next_pts && (switch_time_now() - mst->next_pts > max_delta)) { - switch_img_free(&context->last_img); // too late - } else if (mst->next_pts && (switch_time_now() - mst->next_pts > -10000)) { - frame->img = context->last_img; - context->last_img = NULL; - return SWITCH_STATUS_SUCCESS; + + while((flags & SVR_FLUSH) && switch_queue_size(context->eh.video_queue) > min_qsize) { + if (switch_queue_trypop(context->eh.video_queue, &pop) == SWITCH_STATUS_SUCCESS) { + switch_image_t *img = (switch_image_t *) pop; + switch_img_free(&img); } - - if (!(flags & SVR_BLOCK) && !do_fl) return SWITCH_STATUS_BREAK; } - if (!context->file_read_thread_running && switch_queue_size(context->eh.video_queue) == 0) { + if (!context->file_read_thread_running) { return SWITCH_STATUS_FALSE; } - if (st->codec->time_base.num) { - ticks = st->parser ? st->parser->repeat_pict + 1 : st->codec->ticks_per_frame; - // mst->next_pts += ((int64_t)AV_TIME_BASE * st->codec->time_base.num * ticks) / st->codec->time_base.den; - } - - if (!context->video_start_time) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "start: %" SWITCH_INT64_T_FMT " ticks: %d ticks_per_frame: %d st num:%d st den:%d codec num:%d codec den:%d start: %" SWITCH_TIME_T_FMT ", duration:%" SWITCH_INT64_T_FMT " nb_frames:%" SWITCH_INT64_T_FMT " q2d:%f\n", - context->video_start_time, ticks, st->codec->ticks_per_frame, st->time_base.num, st->time_base.den, st->codec->time_base.num, st->codec->time_base.den, - st->start_time, st->duration, st->nb_frames, av_q2d(st->time_base)); - } - - again: - if ((flags & SVR_BLOCK)) { status = switch_queue_pop(context->eh.video_queue, &pop); } else { status = switch_queue_trypop(context->eh.video_queue, &pop); } - if (pop && status == SWITCH_STATUS_SUCCESS) { - switch_image_t *img = (switch_image_t *)pop; - uint64_t pts; - uint64_t now = switch_time_now(); - - pts = av_rescale_q(*((uint64_t *)img->user_priv), st->time_base, AV_TIME_BASE_Q); - - if (!context->video_start_time) { - context->video_start_time = now - pts; + if (status == SWITCH_STATUS_SUCCESS) { + if (!pop) { + return SWITCH_STATUS_FALSE; } - if (st->time_base.num == 0) { - mst->next_pts = 0; - } else { - //uint64_t last_pts = mst->next_pts; - mst->next_pts = context->video_start_time + pts; - //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "pts: %" SWITCH_INT64_T_FMT " last_pts: %" SWITCH_INT64_T_FMT " delta: %" SWITCH_INT64_T_FMT " frame_pts: %" SWITCH_INT64_T_FMT " nextpts: %" SWITCH_INT64_T_FMT ", num: %d, den:%d num:%d den:%d sleep: %" SWITCH_INT64_T_FMT "\n", - //pts, last_pts, mst->next_pts - last_pts, *((uint64_t *)img->user_priv), mst->next_pts, st->time_base.num, st->time_base.den, st->codec->time_base.num, st->codec->time_base.den, mst->next_pts - now); - } - - if (pts == 0) mst->next_pts = 0; - - if ((mst->next_pts && switch_time_now() - mst->next_pts > max_delta)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG3, "picture is too late, off: %" SWITCH_INT64_T_FMT " queue size:%u\n", (int64_t)(switch_time_now() - mst->next_pts), switch_queue_size(context->eh.video_queue)); - switch_img_free(&img); - max_delta = AV_TIME_BASE; - - if (switch_queue_size(context->eh.video_queue) > 0) { - goto again; - } else if (!(flags & SVR_BLOCK) && !do_fl) { - mst->next_pts = 0; - return SWITCH_STATUS_BREAK; - } - } - - if ((flags & SVR_BLOCK) || do_fl) { - while (switch_micro_time_now() - mst->next_pts < -10000 / 2) { - // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "yield\n"); - switch_yield(10000); - } - frame->img = img; - do_fl = 0; - } else { - if (switch_micro_time_now() - mst->next_pts > -10000 / 2) { - frame->img = img; - } else { - context->last_img = img; - return SWITCH_STATUS_BREAK; - } - } - - } else { - return SWITCH_STATUS_BREAK; + frame->img = (switch_image_t *) pop; + return SWITCH_STATUS_SUCCESS; } - return frame->img ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; + return (flags & SVR_FLUSH) ? SWITCH_STATUS_BREAK : status; } static switch_status_t av_file_write_video(switch_file_handle_t *handle, switch_frame_t *frame) @@ -1944,16 +1923,13 @@ static switch_status_t av_file_write_video(switch_file_handle_t *handle, switch_ context->eh.fc = context->fc; context->eh.mm = &handle->mm; context->eh.timer = &context->video_timer; + context->eh.other_timer = &context->audio_timer; switch_queue_create(&context->eh.video_queue, SWITCH_CORE_QUEUE_LEN, handle->memory_pool); switch_threadattr_create(&thd_attr, handle->memory_pool); //switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_thread_create(&context->eh.video_thread, thd_attr, video_thread_run, &context->eh, handle->memory_pool); - switch_core_timer_init(&context->video_timer, "soft", 1, 1, context->pool); - switch_buffer_zero(context->audio_buffer); - context->audio_st.frame->pts = 0; - context->audio_st.next_pts = 0; } if (context->has_video) { @@ -1969,7 +1945,6 @@ end: return status; } - static switch_status_t av_file_set_string(switch_file_handle_t *handle, switch_audio_col_t col, const char *string) { av_file_context_t *context = (av_file_context_t *)handle->private_info; diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index 6935e61cd8..07c9a1021d 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -1493,7 +1493,9 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_write_thread_run(switch_thread_ if (last) { int delta = now - last; if (delta > member->conference->video_fps.ms * 5000) { - switch_core_session_request_video_refresh(member->session); + printf("WTF %d %d\n", delta, member->conference->video_fps.ms * 5000); + switch_core_session_request_video_refresh(member->session); + } } diff --git a/src/mod/formats/mod_local_stream/mod_local_stream.c b/src/mod/formats/mod_local_stream/mod_local_stream.c index 69986b27cb..27542a08e8 100644 --- a/src/mod/formats/mod_local_stream/mod_local_stream.c +++ b/src/mod/formats/mod_local_stream/mod_local_stream.c @@ -70,6 +70,7 @@ struct local_stream_context { int last_h; int serno; int pop_count; + int video_sync; switch_image_t *banner_img; switch_time_t banner_timeout; struct local_stream_context *next; @@ -89,7 +90,6 @@ struct local_stream_source { char *timer_name; local_stream_context_t *context_list; int total; - int first; switch_dir_t *dir_handle; switch_mutex_t *mutex; switch_memory_pool_t *pool; @@ -161,6 +161,7 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void switch_memory_pool_t *temp_pool = NULL; uint32_t dir_count = 0, do_shuffle = 0; char *p; + int old_total = 0; switch_mutex_lock(globals.mutex); THREADS++; @@ -363,6 +364,16 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void is_open = switch_test_flag(use_fh, SWITCH_FILE_OPEN); + if (is_open && source->total != old_total && source->total == 1) { + if (switch_core_file_has_video(&fh)) { + flush_video_queue(source->video_q); + } + + switch_buffer_zero(audio_buffer); + } + + old_total = source->total; + if (source->hup) { source->hup = 0; if (is_open) { @@ -380,22 +391,21 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void } if (is_open) { - int svr = 0; - if (switch_core_has_video() && switch_core_file_has_video(use_fh)) { switch_frame_t vid_frame = { 0 }; if (use_fh == &source->chime_fh && switch_core_file_has_video(&fh)) { - if (switch_core_file_read_video(&fh, &vid_frame, svr) == SWITCH_STATUS_SUCCESS) { + if (switch_core_file_read_video(&fh, &vid_frame, SVR_FLUSH) == SWITCH_STATUS_SUCCESS) { switch_img_free(&vid_frame.img); } } - while (switch_core_file_read_video(use_fh, &vid_frame, svr) == SWITCH_STATUS_SUCCESS) { + if (switch_core_file_read_video(use_fh, &vid_frame, SVR_FLUSH) == SWITCH_STATUS_SUCCESS) { if (vid_frame.img) { int flush = 1; source->has_video = 1; + if (source->total) { if (switch_queue_trypush(source->video_q, vid_frame.img) == SWITCH_STATUS_SUCCESS) { flush = 0; @@ -455,70 +465,69 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void break; } - source->prebuf = source->samples * 2 * source->channels; - - if (!source->total) { - flush_video_queue(source->video_q); - switch_buffer_zero(audio_buffer); - } else if (used > source->samples * 2 * source->channels) { - //if (!is_open || used >= source->prebuf || (source->total && used > source->samples * 2 * source->channels)) { + source->prebuf = source->samples * 2 * source->channels * 10; + + if (!is_open || used >= source->prebuf || (source->total && used > source->samples * 2 * source->channels)) { void *pop; - uint32_t bused; - + used = switch_buffer_read(audio_buffer, dist_buf, source->samples * 2 * source->channels); - bused = 0; + if (!source->total) { + flush_video_queue(source->video_q); + } else { + uint32_t bused = 0; - switch_mutex_lock(source->mutex); - for (cp = source->context_list; cp && RUNNING; cp = cp->next) { + switch_mutex_lock(source->mutex); + for (cp = source->context_list; cp && RUNNING; cp = cp->next) { - if (source->has_video) { - switch_set_flag(cp->handle, SWITCH_FILE_FLAG_VIDEO); - } else { - switch_clear_flag(cp->handle, SWITCH_FILE_FLAG_VIDEO); - } + if (source->has_video) { + switch_set_flag(cp->handle, SWITCH_FILE_FLAG_VIDEO); + } else { + switch_clear_flag(cp->handle, SWITCH_FILE_FLAG_VIDEO); + } - if (switch_test_flag(cp->handle, SWITCH_FILE_CALLBACK)) { - continue; - } + if (switch_test_flag(cp->handle, SWITCH_FILE_CALLBACK)) { + continue; + } - switch_mutex_lock(cp->audio_mutex); - bused = (uint32_t)switch_buffer_inuse(cp->audio_buffer); - if (bused > source->samples * 768) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Flushing Stream Handle Buffer [%s() %s:%d] size: %u samples: %ld\n", - cp->func, cp->file, cp->line, bused, (long)source->samples); - switch_buffer_zero(cp->audio_buffer); - } else { - switch_buffer_write(cp->audio_buffer, dist_buf, used); + switch_mutex_lock(cp->audio_mutex); + bused = (uint32_t)switch_buffer_inuse(cp->audio_buffer); + if (bused > source->samples * 768) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Flushing Stream Handle Buffer [%s() %s:%d] size: %u samples: %ld\n", + cp->func, cp->file, cp->line, bused, (long)source->samples); + switch_buffer_zero(cp->audio_buffer); + } else { + switch_buffer_write(cp->audio_buffer, dist_buf, used); + } + switch_mutex_unlock(cp->audio_mutex); } - switch_mutex_unlock(cp->audio_mutex); - } - switch_mutex_unlock(source->mutex); + switch_mutex_unlock(source->mutex); - while (switch_queue_trypop(source->video_q, &pop) == SWITCH_STATUS_SUCCESS) { - switch_image_t *img = (switch_image_t *) pop; - switch_image_t *imgcp = NULL; + while (switch_queue_trypop(source->video_q, &pop) == SWITCH_STATUS_SUCCESS) { + switch_image_t *img = (switch_image_t *) pop; + switch_image_t *imgcp = NULL; - if (source->total == 1) { - switch_queue_push(source->context_list->video_q, img); - } else { - if (source->context_list) { - switch_mutex_lock(source->mutex); - for (cp = source->context_list; cp && RUNNING; cp = cp->next) { - if (cp->video_q) { - imgcp = NULL; - switch_img_copy(img, &imgcp); - if (imgcp) { - if (switch_queue_trypush(cp->video_q, imgcp) != SWITCH_STATUS_SUCCESS) { - flush_video_queue(cp->video_q); + if (source->total == 1) { + switch_queue_push(source->context_list->video_q, img); + } else { + if (source->context_list) { + switch_mutex_lock(source->mutex); + for (cp = source->context_list; cp && RUNNING; cp = cp->next) { + if (cp->video_q) { + imgcp = NULL; + switch_img_copy(img, &imgcp); + if (imgcp) { + if (switch_queue_trypush(cp->video_q, imgcp) != SWITCH_STATUS_SUCCESS) { + flush_video_queue(cp->video_q); + } } } } + switch_mutex_unlock(source->mutex); } - switch_mutex_unlock(source->mutex); + switch_img_free(&img); } - switch_img_free(&img); } } } @@ -716,9 +725,6 @@ static switch_status_t local_stream_file_open(switch_file_handle_t *handle, cons context->next = source->context_list; source->context_list = context; source->total++; - if (source->total == 1) { - source->first = 1; - } switch_mutex_unlock(source->mutex); end: @@ -808,7 +814,9 @@ static switch_status_t local_stream_file_read_video(switch_file_handle_t *handle return SWITCH_STATUS_BREAK; } - while(context->ready && context->source->ready && (flags & SVR_FLUSH) && switch_queue_size(context->video_q) > min_qsize / 2) { + context->video_sync = 1; + + while(context->ready && context->source->ready && (flags & SVR_FLUSH) && switch_queue_size(context->video_q) > min_qsize) { if (switch_queue_trypop(context->video_q, &pop) == SWITCH_STATUS_SUCCESS) { switch_image_t *img = (switch_image_t *) pop; switch_img_free(&img); @@ -819,10 +827,6 @@ static switch_status_t local_stream_file_read_video(switch_file_handle_t *handle return SWITCH_STATUS_FALSE; } - while (switch_queue_size(context->video_q) < 5) { - return SWITCH_STATUS_BREAK; - } - if ((flags & SVR_BLOCK)) { status = switch_queue_pop(context->video_q, &pop); } else { @@ -885,7 +889,7 @@ static switch_status_t local_stream_file_read_video(switch_file_handle_t *handle //switch_img_overlay(frame->img, context->banner_img, 0, frame->img->d_h - context->banner_img->d_h, 100); switch_img_patch(frame->img, context->banner_img, 0, frame->img->d_h - context->banner_img->d_h); } - + return SWITCH_STATUS_SUCCESS; } diff --git a/src/switch_core_media.c b/src/switch_core_media.c index edcd43a9b2..6ba192e186 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -5120,9 +5120,9 @@ static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, voi if (switch_channel_test_flag(channel, CF_VIDEO_READY)) { switch_mutex_lock(mh->file_mutex); if (smh->video_write_fh && switch_channel_ready(session->channel) && switch_test_flag(smh->video_write_fh, SWITCH_FILE_OPEN)) { - switch_status_t wstatus = switch_core_file_read_video(smh->video_write_fh, &fr, 0); + switch_status_t wstatus = switch_core_file_read_video(smh->video_write_fh, &fr, SVR_FLUSH); if (wstatus == SWITCH_STATUS_SUCCESS) { - switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_NONE, SVR_FLUSH); + switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_NONE, 0); switch_img_free(&fr.img); } else if (wstatus != SWITCH_STATUS_BREAK && wstatus != SWITCH_STATUS_IGNORE) { smh->video_write_fh = NULL; diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index d55b8ac29b..9f5b472b19 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -1113,14 +1113,11 @@ static void *SWITCH_THREAD_FUNC recording_thread(switch_thread_t *thread, void * switch_size_t bsize = SWITCH_RECOMMENDED_BUFFER_SIZE, samples = 0, inuse = 0; unsigned char *data; int channels = 1; - switch_codec_implementation_t read_impl = { 0 }; if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) { return NULL; } - switch_core_session_get_read_impl(session, &read_impl); - bsize = read_impl.decoded_bytes_per_packet; rh = switch_core_media_bug_get_user_data(bug); switch_buffer_create_dynamic(&rh->thread_buffer, 1024 * 512, 1024 * 64, 0); rh->thread_ready = 1;