X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=subprojects%2Fgst-plugins-good%2Fsys%2Fv4l2%2Fgstv4l2videoenc.c;h=5c99a97563b04b29db6c5ae4d64e859e539fe114;hb=c8416a3b5ce7d4b3ad91be58c71283af40997731;hp=19496b73f064fdc2c8fafcc2a6e4f21cf48a25ea;hpb=a7f54159b724d4966686c84a1f93688ef157e3f2;p=platform%2Fupstream%2Fgstreamer.git diff --git a/subprojects/gst-plugins-good/sys/v4l2/gstv4l2videoenc.c b/subprojects/gst-plugins-good/sys/v4l2/gstv4l2videoenc.c index 19496b7..5c99a97 100644 --- a/subprojects/gst-plugins-good/sys/v4l2/gstv4l2videoenc.c +++ b/subprojects/gst-plugins-good/sys/v4l2/gstv4l2videoenc.c @@ -35,7 +35,7 @@ #include "gstv4l2videoenc.h" #include -#include +#include GST_DEBUG_CATEGORY_STATIC (gst_v4l2_video_enc_debug); #define GST_CAT_DEFAULT gst_v4l2_video_enc_debug @@ -342,6 +342,9 @@ gst_v4l2_video_enc_set_format (GstVideoEncoder * encoder, return FALSE; } + /* best effort */ + gst_v4l2_object_setup_padding (self->v4l2output); + self->input_state = gst_video_codec_state_ref (state); GST_DEBUG_OBJECT (self, "output caps: %" GST_PTR_FORMAT, state->caps); @@ -649,10 +652,14 @@ gst_v4l2_video_enc_loop (GstVideoEncoder * encoder) /* FIXME Check if buffer isn't the last one here */ GST_LOG_OBJECT (encoder, "Process output buffer"); - ret = - gst_v4l2_buffer_pool_process (GST_V4L2_BUFFER_POOL - (self->v4l2capture->pool), &buffer, NULL); - + { + GstV4l2BufferPool *cpool = + GST_V4L2_BUFFER_POOL (gst_v4l2_object_get_buffer_pool + (self->v4l2capture)); + ret = gst_v4l2_buffer_pool_process (cpool, &buffer, NULL); + if (cpool) + gst_object_unref (cpool); + } if (ret != GST_FLOW_OK) goto beach; @@ -738,6 +745,7 @@ gst_v4l2_video_enc_handle_frame (GstVideoEncoder * encoder, GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (encoder); GstFlowReturn ret = GST_FLOW_OK; GstTaskState task_state; + gboolean active; GST_DEBUG_OBJECT (self, "Handling frame %d", frame->system_frame_number); @@ -746,7 +754,7 @@ gst_v4l2_video_enc_handle_frame (GstVideoEncoder * encoder, task_state = gst_pad_get_task_state (GST_VIDEO_ENCODER_SRC_PAD (self)); if (task_state == GST_TASK_STOPPED || task_state == GST_TASK_PAUSED) { - GstBufferPool *pool = GST_BUFFER_POOL (self->v4l2output->pool); + GstBufferPool *pool = gst_v4l2_object_get_buffer_pool (self->v4l2output); /* It is possible that the processing thread stopped due to an error or * when the last buffer has been met during the draining process. */ @@ -756,6 +764,8 @@ gst_v4l2_video_enc_handle_frame (GstVideoEncoder * encoder, GST_DEBUG_OBJECT (self, "Processing loop stopped with error: %s, leaving", gst_flow_get_name (self->output_flow)); ret = self->output_flow; + if (pool) + gst_object_unref (pool); goto drop; } @@ -769,15 +779,29 @@ gst_v4l2_video_enc_handle_frame (GstVideoEncoder * encoder, self->v4l2output->info.size, min, min); /* There is no reason to refuse this config */ - if (!gst_buffer_pool_set_config (pool, config)) + if (!gst_buffer_pool_set_config (pool, config)) { + if (pool) + gst_object_unref (pool); goto activate_failed; + } - if (!gst_buffer_pool_set_active (pool, TRUE)) + if (!gst_buffer_pool_set_active (pool, TRUE)) { + if (pool) + gst_object_unref (pool); goto activate_failed; + } + if (pool) + gst_object_unref (pool); } - if (!gst_buffer_pool_set_active - (GST_BUFFER_POOL (self->v4l2capture->pool), TRUE)) { + { + GstBufferPool *cpool = + gst_v4l2_object_get_buffer_pool (self->v4l2capture); + active = gst_buffer_pool_set_active (cpool, TRUE); + if (cpool) + gst_object_unref (cpool); + } + if (!active) { GST_WARNING_OBJECT (self, "Could not activate capture buffer pool."); goto activate_failed; } @@ -793,13 +817,29 @@ gst_v4l2_video_enc_handle_frame (GstVideoEncoder * encoder, } if (frame->input_buffer) { + /* Process force keyframe event if it was passed */ + if (GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame)) { + struct v4l2_control ctrl = { V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME, 1 }; + if (self->v4l2output->ioctl (self->v4l2output->video_fd, VIDIOC_S_CTRL, + &ctrl) < 0) + GST_ELEMENT_WARNING (self, RESOURCE, FAILED, + (_("Failed to force keyframe.")), + ("VIDIOC_S_CTRL (V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME) failed: %s (%d)", + g_strerror (errno), errno)); + } + GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder); GST_LOG_OBJECT (encoder, "Passing buffer with frame number %u", frame->system_frame_number); - ret = - gst_v4l2_buffer_pool_process (GST_V4L2_BUFFER_POOL (self-> - v4l2output->pool), &frame->input_buffer, - &frame->system_frame_number); + + { + GstBufferPool *opool = gst_v4l2_object_get_buffer_pool (self->v4l2output); + ret = gst_v4l2_buffer_pool_process (GST_V4L2_BUFFER_POOL (opool), + &frame->input_buffer, &frame->system_frame_number); + if (opool) + gst_object_unref (opool); + } + GST_VIDEO_ENCODER_STREAM_LOCK (encoder); if (ret == GST_FLOW_FLUSHING) { @@ -876,6 +916,9 @@ gst_v4l2_video_enc_decide_allocation (GstVideoEncoder * } gst_caps_unref (caps); + /* best effort */ + gst_v4l2_object_setup_padding (self->v4l2capture); + if (gst_v4l2_object_decide_allocation (self->v4l2capture, query)) { GstVideoEncoderClass *enc_class = GST_VIDEO_ENCODER_CLASS (parent_class); ret = enc_class->decide_allocation (encoder, query);