Created
October 2, 2015 10:56
-
-
Save yashi/512940efcc2d4c1d3264 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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