if (codec_id == AV_CODEC_ID_H264) {
c->ticks_per_frame = 2;
+
+ c->coder_type = 1; // coder = 1
+ c->flags|=CODEC_FLAG_LOOP_FILTER; // flags=+loop
+ c->me_cmp|= 1; // cmp=+chroma, where CHROMA = 1
+ c->me_method=ME_HEX; // me_method=hex
+ c->me_range = 16; // me_range=16
+ c->max_b_frames = 3; // bf=3
+
switch (mm->vprofile) {
case SWITCH_VIDEO_PROFILE_BASELINE:
av_opt_set(c->priv_data, "profile", "baseline", 0);
case SWITCH_VIDEO_PROFILE_MAIN:
av_opt_set(c->priv_data, "profile", "main", 0);
av_opt_set(c->priv_data, "level", "5", 0);
+ c->level = 5;
break;
case SWITCH_VIDEO_PROFILE_HIGH:
av_opt_set(c->priv_data, "profile", "high", 0);
av_opt_set(c->priv_data, "level", "52", 0);
+ c->level = 52;
break;
}
av_opt_set(c->priv_data, "preset", "medium", 0);
break;
case SWITCH_VIDEO_ENCODE_SPEED_FAST:
+ //av_opt_set(c->priv_data, "tune", "zerolatency", 0);
av_opt_set(c->priv_data, "preset", "veryfast", 0);
break;
default:
}
}
+ c->gop_size = 250; // g=250
+ c->keyint_min = 25; // keyint_min=25
+ c->scenechange_threshold = 40; // sc_threshold=40
+ c->i_quant_factor = 0.71; // i_qfactor=0.71
+ c->b_frame_strategy = 1; // b_strategy=1
+ c->qcompress = 0.6; // qcomp=0.6
+ c->qmin = 10; // qmin=10
+ c->qmax = 51; // qmax=51
+ c->max_qdiff = 4; // qdiff=4
+
+
if (codec_id == AV_CODEC_ID_VP8) {
av_set_options_string(c, "quality=realtime", "=", ":");
}
switch_image_t *img = NULL, *tmp_img = NULL;
int d_w = eh->video_st->width, d_h = eh->video_st->height;
int size = 0, skip = 0, skip_freq = 0, skip_count = 0, skip_total = 0, skip_total_count = 0;
- uint64_t delta = 0, last_ts = 0;
+ uint64_t hard_delta = 0, delta = 0, last_ts = 0;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "video thread start\n");
+
+ if (eh->mm->fps) {
+ hard_delta = 1000 / eh->mm->fps;
+ }
for(;;) {
AVPacket pkt = { 0 };
skip_total_count = skip_total;
skip_count = 0;
skip--;
+
goto top;
}
} else {
ret = av_frame_make_writable(eh->video_st->frame);
}
- if (ret < 0) continue;
+ if (ret < 0) {
+ continue;
+ }
fill_avframe(eh->video_st->frame, img);
- switch_core_timer_sync(eh->timer);
- if (eh->finalize && delta) {
+ if (hard_delta) {
+ delta = hard_delta;
+ }
+
+ if ((eh->finalize && delta) || hard_delta) {
eh->video_st->frame->pts += delta;
- } else if (eh->video_st->frame->pts == eh->timer->samplecount) {
- // never use the same pts, or the encoder coughs
- eh->video_st->frame->pts++;
} else {
- uint64_t delta_tmp = eh->timer->samplecount - last_ts;
-
- if (delta_tmp > 1) {
- delta = delta_tmp;
+ 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++;
+ } else {
+ uint64_t delta_tmp = eh->timer->samplecount - last_ts;
+
+ if (delta_tmp > 10) {
+ delta = delta_tmp;
+ }
+
+ eh->video_st->frame->pts = eh->timer->samplecount;
}
-
- eh->video_st->frame->pts = eh->timer->samplecount;
}
last_ts = eh->video_st->frame->pts;
handle->mm.ab = 128;
}
+ handle->mm.vb = switch_calc_bitrate(handle->mm.vw, handle->mm.vh, 1, handle->mm.fps);
+
if (fmt->video_codec != AV_CODEC_ID_NONE) {
const AVCodecDescriptor *desc;
- if ((handle->stream_name && (!strcasecmp(handle->stream_name, "rtmp") || !strcasecmp(handle->stream_name, "youtube"))) || !strcasecmp(ext, "mp4")) {
+ if ((handle->stream_name && (!strcasecmp(handle->stream_name, "rtmp") || !strcasecmp(handle->stream_name, "youtube")))) {
+
if (fmt->video_codec != AV_CODEC_ID_H264 ) {
fmt->video_codec = AV_CODEC_ID_H264; // force H264
}
-
+
fmt->audio_codec = AV_CODEC_ID_AAC;
handle->samplerate = 44100;
handle->mm.samplerate = 44100;
handle->mm.vb = 4500;
break;
default:
- handle->mm.vb = (handle->mm.vw * handle->mm.vh) / 175;
+ handle->mm.vb = switch_calc_bitrate(handle->mm.vw, handle->mm.vh, 1, handle->mm.fps);
break;
}
}
context->audio_st.sample_rate = handle->samplerate;
add_stream(&context->audio_st, context->fc, &context->audio_codec, fmt->audio_codec, &handle->mm);
+
if (open_audio(context->fc, context->audio_codec, &context->audio_st) != SWITCH_STATUS_SUCCESS) {
switch_goto_status(SWITCH_STATUS_GENERR, end);
}
unsigned char *buf = NULL;
switch_rgb_color_t bgcolor;
switch_rtp_engine_t *v_engine = NULL;
-
const char *var;
+ int buflen = SWITCH_RTP_MAX_BUF_LEN;
if (!(smh = session->media_handle)) {
return NULL;
switch_channel_get_name(session->channel), switch_channel_test_flag(channel, CF_VIDEO_ECHO) ? "on" : "off");
switch_core_session_request_video_refresh(session);
+ buf = switch_core_session_alloc(session, buflen);
+ fr.packet = buf;
+ fr.packetlen = buflen;
+ fr.data = buf + 12;
+ fr.buflen = buflen - 12;
+
+ switch_core_media_gen_key_frame(session);
+
while (switch_channel_up_nosig(channel)) {
int send_blank = 0;
}
}
- //if (!smh->video_write_fh || !switch_channel_test_flag(channel, CF_VIDEO_READY)) {
status = switch_core_session_read_video_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
if (!SWITCH_READ_ACCEPTABLE(status)) {
continue;
}
- //if (switch_test_flag(read_frame, SFF_CNG)) {
- // continue;
- //}
- //}
-
- //if (vloops < 300 && (vloops % 100) == 0) {
- // switch_core_media_gen_key_frame(session);
- //switch_core_session_request_video_refresh(session);
- //}
-
vloops++;
-
- if (!buf) {
- int buflen = SWITCH_RTP_MAX_BUF_LEN;
- buf = switch_core_session_alloc(session, buflen);
- fr.packet = buf;
- fr.packetlen = buflen;
- fr.data = buf + 12;
- fr.buflen = buflen - 12;
- switch_core_media_gen_key_frame(session);
- }
send_blank = 1;
- if (switch_channel_test_flag(channel, CF_VIDEO_READY)) {
+ if (switch_channel_test_flag(channel, CF_VIDEO_READY) && !switch_test_flag(read_frame, SFF_CNG)) {
switch_mutex_lock(mh->file_read_mutex);
if (smh->video_read_fh && switch_test_flag(smh->video_read_fh, SWITCH_FILE_OPEN) && read_frame->img) {
switch_core_file_write_video(smh->video_read_fh, read_frame);
- send_blank = 0;
}
switch_mutex_unlock(mh->file_read_mutex);
- //} else if (switch_channel_test_flag(channel, CF_VIDEO_DECODED_READ) || v_engine->smode == SWITCH_MEDIA_FLOW_SENDONLY) {
- //send_blank = 1;
}
-
+
if (switch_channel_test_flag(channel, CF_VIDEO_WRITING) || session->video_read_callback) {
send_blank = 0;
}
switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_FORCE, 0);
}
}
-#if 0
- if (blank_img && (send_blank || switch_channel_test_flag(channel, CF_VIDEO_BLANK)) && !session->video_read_callback) {
- fr.img = blank_img;
- switch_yield(10000);
- switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_FORCE, 0);
- } else if (read_frame && (switch_channel_test_flag(channel, CF_VIDEO_ECHO))) {
- switch_core_session_write_video_frame(session, read_frame, SWITCH_IO_FLAG_NONE, 0);
- }
-#endif
-
}
switch_img_free(&blank_img);
{
switch_media_handle_t *smh;
switch_codec_implementation_t read_impl = { 0 };
+ switch_rtp_engine_t *v_engine = NULL;
switch_assert(session != NULL);
return SWITCH_STATUS_GENERR;;
}
+ v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
+
+ if (v_engine->smode == SWITCH_MEDIA_FLOW_SENDONLY) {
+ return SWITCH_STATUS_NOTIMPL;
+ }
+
switch_core_session_get_read_impl(session, &read_impl);
while(switch_channel_ready(session->channel) && timeout_ms > 0) {