diff options
author | Nirbheek Chauhan <nirbheek@centricular.com> | 2014-07-14 19:40:53 (GMT) |
---|---|---|
committer | Nirbheek Chauhan <nirbheek@centricular.com> | 2014-07-14 19:49:08 (GMT) |
commit | 5e3b9fc170c77a55003d9d94a71fea6eda88f847 (patch) | |
tree | 252d78023594e031566db0aeb0d4c6511de88378 /src/main.c | |
parent | 4ebd3a09a6979bc568459aea842f09d12f4ad4f2 (diff) | |
download | soup-transcoding-proxy-5e3b9fc170c77a55003d9d94a71fea6eda88f847.zip soup-transcoding-proxy-5e3b9fc170c77a55003d9d94a71fea6eda88f847.tar.gz |
Improve latency by waiting for the next keyframe
Instead of caching all the data from the previous keyframe till right now and
sending it to the client in a burst, since latency is important, we instead wait
for the next keyframe before sending buffers to the clients. This will lead to
a delay of upto 128 frames before the stream starts.
The keyframe distance and hence the delay can be tweaked by setting the
"keyframe-max-dist" property on vp8enc in src/encode.c:create_webm_profile()
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 30 |
1 files changed, 12 insertions, 18 deletions
@@ -134,6 +134,15 @@ invoke_write_client_chunk (TranscodeClientCtx *ctx) } buffer = gst_sample_get_buffer (sample); + + /* Skip all frames till the next keyframe */ + if (!ctx->keyframe_found && + GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT)) { + gst_sample_unref (sample); + return FALSE; + } + ctx->keyframe_found = TRUE; + gst_buffer_map (buffer, &info, GST_MAP_READ); soup_message_body_append (ctx->msg->response_body, SOUP_MEMORY_COPY, @@ -151,7 +160,7 @@ static GstFlowReturn write_client_chunk_cb (GstElement *appsink, TranscodeClientCtx *ctx) { - g_main_context_invoke_full (NULL, G_PRIORITY_HIGH, + g_main_context_invoke_full (NULL, G_PRIORITY_DEFAULT, (GSourceFunc)invoke_write_client_chunk, ctx, NULL); return GST_FLOW_OK; @@ -227,7 +236,6 @@ GET: /* A GET request was received. We connect from the pipeline to the * client requesting the stream and start writing the response. */ GstCaps *caps = NULL; - GstState state; GstBuffer *buffer; GstFlowReturn ret; GstStateChangeReturn state_change; @@ -311,7 +319,7 @@ GET: buffer = stp_get_streamheader_from_caps (caps); if (!buffer) { g_critical ("Unable to get streamheader from caps"); - goto push_keyframe; + goto nostreamheader; } ret = gst_pad_push (srcpad, buffer); @@ -321,21 +329,7 @@ GET: goto err; } -push_keyframe: - ret = gst_pad_push_list (srcpad, - gst_buffer_list_copy (server_ctx->keyframe)); - if (ret != GST_FLOW_OK) { - g_critical ("Unable to push keyframe data: %s", - gst_flow_get_name (ret)); - goto err; - } - - state_change = gst_element_get_state (server_ctx->pipeline, - &state, NULL, 1); - g_debug ("Pushed buffer. State was %s:%s.", - gst_element_state_change_return_get_name (state_change), - gst_element_state_get_name (state)); - +nostreamheader: client_ctx->appsink = appsink; g_signal_connect (appsink, "new-sample", |