summaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
authorNirbheek Chauhan <nirbheek@centricular.com>2014-07-14 19:40:53 (GMT)
committerNirbheek Chauhan <nirbheek@centricular.com>2014-07-14 19:49:08 (GMT)
commit5e3b9fc170c77a55003d9d94a71fea6eda88f847 (patch)
tree252d78023594e031566db0aeb0d4c6511de88378 /src/main.c
parent4ebd3a09a6979bc568459aea842f09d12f4ad4f2 (diff)
downloadsoup-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.c30
1 files changed, 12 insertions, 18 deletions
diff --git a/src/main.c b/src/main.c
index 6e61c3e..fe9d44a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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",