mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-08-14 01:49:05 +00:00
FS-7500: Work in progress. Added codec config params that can be set from session and made vpx codec re-init on size change. Also add periodic key frame timer
This commit is contained in:
committed by
Michael Jerris
parent
365a5dd820
commit
659c1e474e
@@ -36,174 +36,6 @@
|
||||
#include <switch.h>
|
||||
#include "private/switch_core_pvt.h"
|
||||
|
||||
SWITCH_DECLARE(void) switch_core_session_set_image_write_callback(switch_core_session_t *session, switch_image_write_callback_t callback, void *user_data)
|
||||
{
|
||||
session->image_write_callback = callback;
|
||||
session->image_write_callback_user_data = user_data;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_image(switch_core_session_t *session, switch_frame_t *frame,
|
||||
switch_image_t *img, switch_size_t size, uint32_t *flag)
|
||||
{
|
||||
uint32_t encoded_data_len = size, lflag = 0, *flagp = flag;
|
||||
switch_codec_t *codec = switch_core_session_get_video_write_codec(session);
|
||||
switch_timer_t *timer;
|
||||
|
||||
switch_assert(session);
|
||||
|
||||
if (!flag) {
|
||||
flagp = &lflag;
|
||||
}
|
||||
|
||||
timer = switch_core_media_get_timer(session, SWITCH_MEDIA_TYPE_VIDEO);
|
||||
switch_assert(timer);
|
||||
|
||||
switch_core_codec_encode_video(codec, img, frame->data, &encoded_data_len, flagp);
|
||||
|
||||
while(encoded_data_len) {
|
||||
|
||||
frame->datalen = encoded_data_len;
|
||||
frame->packetlen = frame->datalen + 12;
|
||||
frame->m = (*flagp & SFF_MARKER) ? 1 : 0;
|
||||
frame->timestamp = timer->samplecount;
|
||||
|
||||
switch_set_flag(frame, SFF_RAW_RTP_PARSE_FRAME);
|
||||
|
||||
switch_core_session_write_video_frame(session, frame, SWITCH_IO_FLAG_NONE, 0);
|
||||
|
||||
if (session->image_write_callback) {
|
||||
session->image_write_callback(session, frame, img, session->image_write_callback_user_data);
|
||||
}
|
||||
|
||||
encoded_data_len = size;
|
||||
switch_core_codec_encode_video(codec, NULL, frame->data, &encoded_data_len, flagp);
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags,
|
||||
int stream_id)
|
||||
{
|
||||
switch_io_event_hook_video_write_frame_t *ptr;
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
|
||||
if (switch_channel_down(session->channel)) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if (switch_channel_test_flag(session->channel, CF_VIDEO_PAUSE)) {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (session->endpoint_interface->io_routines->write_video_frame) {
|
||||
if ((status = session->endpoint_interface->io_routines->write_video_frame(session, frame, flags, stream_id)) == SWITCH_STATUS_SUCCESS) {
|
||||
for (ptr = session->event_hooks.video_write_frame; ptr; ptr = ptr->next) {
|
||||
if ((status = ptr->video_write_frame(session, frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_session_read_video_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags,
|
||||
int stream_id)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
switch_io_event_hook_video_read_frame_t *ptr;
|
||||
|
||||
switch_assert(session != NULL);
|
||||
|
||||
if (switch_channel_down(session->channel)) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if (switch_channel_test_flag(session->channel, CF_VIDEO_PAUSE)) {
|
||||
*frame = &runtime.dummy_cng_frame;
|
||||
switch_yield(20000);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (session->endpoint_interface->io_routines->read_video_frame) {
|
||||
if ((status = session->endpoint_interface->io_routines->read_video_frame(session, frame, flags, stream_id)) == SWITCH_STATUS_SUCCESS) {
|
||||
for (ptr = session->event_hooks.video_read_frame; ptr; ptr = ptr->next) {
|
||||
if ((status = ptr->video_read_frame(session, frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (status == SWITCH_STATUS_INUSE) {
|
||||
*frame = &runtime.dummy_cng_frame;
|
||||
switch_yield(20000);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (status != SWITCH_STATUS_SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!(*frame)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (switch_test_flag(*frame, SFF_CNG)) {
|
||||
status = SWITCH_STATUS_SUCCESS;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (session->bugs) {
|
||||
switch_media_bug_t *bp;
|
||||
switch_bool_t ok = SWITCH_TRUE;
|
||||
int prune = 0;
|
||||
switch_thread_rwlock_rdlock(session->bug_rwlock);
|
||||
for (bp = session->bugs; bp; bp = bp->next) {
|
||||
if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (switch_test_flag(bp, SMBF_PRUNE)) {
|
||||
prune++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bp->ready && switch_test_flag(bp, SMBF_READ_PING)) {
|
||||
switch_mutex_lock(bp->read_mutex);
|
||||
bp->ping_frame = *frame;
|
||||
if (bp->callback) {
|
||||
if (bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ_VIDEO_PING) == SWITCH_FALSE
|
||||
|| (bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL))) {
|
||||
ok = SWITCH_FALSE;
|
||||
}
|
||||
}
|
||||
bp->ping_frame = NULL;;
|
||||
switch_mutex_unlock(bp->read_mutex);
|
||||
}
|
||||
|
||||
if (ok == SWITCH_FALSE) {
|
||||
switch_set_flag(bp, SMBF_PRUNE);
|
||||
prune++;
|
||||
}
|
||||
}
|
||||
switch_thread_rwlock_unlock(session->bug_rwlock);
|
||||
if (prune) {
|
||||
switch_core_media_bug_prune(session);
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(void) switch_core_gen_encoded_silence(unsigned char *data, const switch_codec_implementation_t *read_impl, switch_size_t len)
|
||||
{
|
||||
unsigned char g729_filler[] = {
|
||||
|
Reference in New Issue
Block a user