Skip to content

Instantly share code, notes, and snippets.

@yashi
Created October 2, 2015 10:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yashi/512940efcc2d4c1d3264 to your computer and use it in GitHub Desktop.
Save yashi/512940efcc2d4c1d3264 to your computer and use it in GitHub Desktop.
diff --git a/ceu2rtp.c b/ceu2rtp.c
index 17c43d5..18efc86 100644
--- a/ceu2rtp.c
+++ b/ceu2rtp.c
@@ -50,7 +50,7 @@ enum {
#define DEFAULT_FRAME_RATE_RESOLUTION (30)
#define DEFAULT_FRAME_RATE_TICK (1)
#define DEFAULT_MAX_GOP_LENGTH (30)
-#define DEFAULT_B_PIC_MODE (3)
+#define DEFAULT_B_PIC_MODE GST_ACMH264ENC_B_PIC_MODE_0_B_PIC
#define DEFAULT_X_OFFSET (0)
#define DEFAULT_Y_OFFSET (0)
#define DEFAULT_FPS_N (30)
@@ -97,6 +97,8 @@ typedef struct _C2rEncoder {
GstMemory *spspps_buf;
C2rV4l2Buf *src_buf;
C2rV4l2Buf *dst_buf;
+ gint b_pic_mode;
+ gint max_gop_len;
gint pre_encode_num; /* b_pic_mode + 1 */
gint buffer_in_out_count;
GMutex count_lock; /* lock buffer_in_out_count */
@@ -132,9 +134,12 @@ typedef struct _C2rOptions {
gchar *encoder_name;
gchar *ip_addr;
int port;
+ int b_pic_mode;
+ int max_gop_len;
} C2rOptions;
static gboolean c2r_caught_intr = FALSE;
+gint framerate = 30;
static int c2r_xioctl (int fd, int request, void *arg)
{
@@ -543,11 +548,11 @@ static int c2r_encoder_setup (C2rEncoder *enc,
if (ret) return -1;
/* max_GOP_length */
ret = c2r_device_set_control (enc->dev,
- V4L2_CID_MAX_GOP_LENGTH, DEFAULT_MAX_GOP_LENGTH);
+ V4L2_CID_MAX_GOP_LENGTH, enc->max_gop_len);
if (ret) return -1;
/* B_pic_modeの指定 */
ret = c2r_device_set_control (enc->dev,
- V4L2_CID_B_PIC_MODE, DEFAULT_B_PIC_MODE);
+ V4L2_CID_B_PIC_MODE, enc->b_pic_mode);
if (ret) return -1;
/* reqbuf */
@@ -615,6 +620,11 @@ static int c2r_encoder_stream_off (C2rEncoder *enc)
static void c2r_appsrc_camera_loop (gpointer appsrc)
{
int i;
+ static int track = 30;
+ static float potential_per_frame = 1.0;
+ static float current_potential = 0.0;
+ int target_rate = g_atomic_int_get(&framerate);
+
C2rAppsrc *c2r_appsrc = (C2rAppsrc *)appsrc;
struct v4l2_buffer cam_buf;
struct v4l2_buffer enc_buf;
@@ -628,35 +638,50 @@ static void c2r_appsrc_camera_loop (gpointer appsrc)
c2r_xioctl (c2r_appsrc->cam.dev.fd, VIDIOC_DQBUF, &cam_buf);
- /* look for the index based on fd */
- for (i = 0; i < C2R_ENC_OUTPUT_MMAP_COUNT; i++) {
- if (cam_buf.m.fd == c2r_appsrc->enc.src_buf->eb[i].fd) {
- enc_index = i;
- break;
- }
+ track--;
+
+ if (track <= 0) {
+ track = 30;
+ potential_per_frame = target_rate / 30.0;
}
- if (enc_index != G_MAXUINT32) {
- enc_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- enc_buf.memory = V4L2_MEMORY_MMAP;
- enc_buf.index = enc_index;
- enc_buf.bytesused = cam_buf.bytesused;
- enc_buf.length = cam_buf.bytesused;
+ if (current_potential >= 1.0) {
+ /* look for the index based on fd */
+ for (i = 0; i < C2R_ENC_OUTPUT_MMAP_COUNT; i++) {
+ if (cam_buf.m.fd == c2r_appsrc->enc.src_buf->eb[i].fd) {
+ enc_index = i;
+ break;
+ }
+ }
- c2r_xioctl (c2r_appsrc->enc.dev.fd, VIDIOC_QBUF, &enc_buf);
- g_mutex_lock (&c2r_appsrc->enc.count_lock);
- c2r_appsrc->enc.buffer_in_out_count++;
- g_mutex_unlock (&c2r_appsrc->enc.count_lock);
- c2r_index_queue_push (
- c2r_appsrc->cam.buf->idx_queue, cam_buf.index);
+ if (enc_index != G_MAXUINT32) {
+ enc_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ enc_buf.memory = V4L2_MEMORY_MMAP;
+ enc_buf.index = enc_index;
+ enc_buf.bytesused = cam_buf.bytesused;
+ enc_buf.length = cam_buf.bytesused;
+
+ c2r_xioctl (c2r_appsrc->enc.dev.fd, VIDIOC_QBUF, &enc_buf);
+ g_mutex_lock (&c2r_appsrc->enc.count_lock);
+ c2r_appsrc->enc.buffer_in_out_count++;
+ g_mutex_unlock (&c2r_appsrc->enc.count_lock);
+
+ c2r_index_queue_push (
+ c2r_appsrc->cam.buf->idx_queue, cam_buf.index);
+ } else {
+ g_print ("cam pop fail\n");
+ gst_task_stop (c2r_appsrc->cam_task.task);
+ }
+
+ if (c2r_caught_intr)
+ gst_task_stop (c2r_appsrc->cam_task.task);
+ current_potential -= 1.0;
} else {
- g_print ("cam pop fail\n");
- gst_task_stop (c2r_appsrc->cam_task.task);
+ c2r_xioctl (c2r_appsrc->cam.dev.fd, VIDIOC_QBUF, &cam_buf);
}
- if (c2r_caught_intr)
- gst_task_stop (c2r_appsrc->cam_task.task);
+ current_potential += potential_per_frame;
}
static void c2r_appsrc_encoder_capture_loop (gpointer appsrc)
@@ -828,6 +853,8 @@ static C2rAppsrc *c2r_appsrc_new (GstElement *pipeline, C2rOptions *opt)
}
result->cam.dev.name = opt->camera_name;
result->enc.dev.name = opt->encoder_name;
+ result->enc.b_pic_mode = opt->b_pic_mode;
+ result->enc.max_gop_len = opt->max_gop_len;
result->size.input_width = opt->size.input_width;
result->size.input_height = opt->size.input_height;
result->size.output_width = opt->size.output_width;
@@ -979,10 +1006,18 @@ static int c2r_pipeline_play (C2rPipeline *c2r_pipeline)
(GSourceFunc) c2r_appsrc_check_intr, c2r_pipeline->c2r_appsrc);
bus = gst_element_get_bus (c2r_pipeline->pipeline);
- msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, GST_CLOCK_TIME_NONE);
+ while (1) {
+ //msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, 1000);
+ //if (!msg)
+ // goto exit;
+ int r;
+ scanf("%d", &r);
+ if (r < 0) r = 0;
+ if (r > 30) r = 30;
+ g_atomic_int_set(&framerate, r);
+
+ }
- if (!msg)
- goto exit;
if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR)
c2r_print_error_message (msg);
@@ -1005,6 +1040,9 @@ static int c2r_options_check (C2rOptions opt)
They must be equal or less than input width and height.");
return -1;
+ } else if ((opt.max_gop_len != 0 || opt.b_pic_mode != 0) && opt.max_gop_len <= opt.b_pic_mode) {
+ g_print ("Max GOP length must be greater than B picture mode.\n");
+ return -1;
}
return 0;
@@ -1026,6 +1064,8 @@ int main(int argc, char *argv[])
{ "output-height", 0, 0, G_OPTION_ARG_INT, &options.size.output_height, "output height", NULL },
{ "ip", 'i', 0, G_OPTION_ARG_STRING, &options.ip_addr, "ip addr", NULL },
{ "port", 'p', 0, G_OPTION_ARG_INT, &options.port, "port", NULL },
+ { "b-pic-mode", 'b', 0, G_OPTION_ARG_INT, &options.b_pic_mode, "B picture mode", NULL },
+ { "max-gop-len", 'g', 0, G_OPTION_ARG_INT, &options.max_gop_len, "max GOP length", NULL },
{ NULL }
};
@@ -1039,6 +1079,8 @@ int main(int argc, char *argv[])
options.size.output_height = C2R_ENC_HEIGHT;
options.ip_addr = DEFAULT_IP_ADDR;
options.port = DEFAULT_PORT;
+ options.b_pic_mode = DEFAULT_B_PIC_MODE;
+ options.max_gop_len = DEFAULT_MAX_GOP_LENGTH;
context = g_option_context_new ("- v4l2src-acmh264enc");
g_option_context_add_main_entries (context, cmd_option_entries, NULL);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment