From: Nicolas Dufresne Date: Mon, 14 Dec 2020 22:07:01 +0000 (-0500) Subject: v4l2codecs: Rework handling of queues and pending requests X-Git-Tag: 1.19.3~507^2~851 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3db6f45ca902a88ae1a235136accede243a6a6c3;p=platform%2Fupstream%2Fgstreamer.git v4l2codecs: Rework handling of queues and pending requests Starting from this patch, all queue and dequeue operation happening on V4L2 is now abstracted with the request. Buffers are dequeued automatically when pending requests are marked done and only 1 in-flight request is now used. Along with fixing issues with request not being reused with slice decoders, this change reduces the memory footprint by allocating only two bitstream buffers. Part-of: --- diff --git a/sys/v4l2codecs/gstv4l2codech264dec.c b/sys/v4l2codecs/gstv4l2codech264dec.c index a24739e..f554f99 100644 --- a/sys/v4l2codecs/gstv4l2codech264dec.c +++ b/sys/v4l2codecs/gstv4l2codech264dec.c @@ -337,7 +337,7 @@ gst_v4l2_codec_h264_dec_decide_allocation (GstVideoDecoder * decoder, min = MAX (2, min); self->sink_allocator = gst_v4l2_codec_allocator_new (self->decoder, - GST_PAD_SINK, self->min_pool_size + 2); + GST_PAD_SINK, 2); self->src_allocator = gst_v4l2_codec_allocator_new (self->decoder, GST_PAD_SRC, self->min_pool_size + min + 4); self->src_pool = gst_v4l2_codec_pool_new (self->src_allocator, &self->vinfo); @@ -825,24 +825,6 @@ fail: return FALSE; } -static gboolean -gst_v4l2_codec_h264_dec_wait (GstV4l2CodecH264Dec * self, - GstV4l2Request * request) -{ - gint ret = gst_v4l2_request_poll (request, GST_SECOND); - if (ret == 0) { - GST_ELEMENT_ERROR (self, STREAM, DECODE, - ("Decoding frame took too long"), (NULL)); - return FALSE; - } else if (ret < 0) { - GST_ELEMENT_ERROR (self, STREAM, DECODE, - ("Decoding request failed: %s", g_strerror (errno)), (NULL)); - return FALSE; - } - - return TRUE; -} - static GstFlowReturn gst_v4l2_codec_h264_dec_output_picture (GstH264Decoder * decoder, GstVideoCodecFrame * frame, GstH264Picture * picture) @@ -850,41 +832,35 @@ gst_v4l2_codec_h264_dec_output_picture (GstH264Decoder * decoder, GstV4l2CodecH264Dec *self = GST_V4L2_CODEC_H264_DEC (decoder); GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder); GstV4l2Request *request = gst_h264_picture_get_user_data (picture); + gint ret; GST_DEBUG_OBJECT (self, "Output picture %u", picture->system_frame_number); if (gst_v4l2_request_is_done (request)) goto finish_frame; - if (!gst_v4l2_codec_h264_dec_wait (self, request)) + ret = gst_v4l2_request_poll (request, GST_SECOND); + if (ret == 0) { + GST_ELEMENT_ERROR (self, STREAM, DECODE, + ("Decoding frame %u took too long", picture->system_frame_number), + (NULL)); + goto error; + } else if (ret < 0) { + GST_ELEMENT_ERROR (self, STREAM, DECODE, + ("Decoding request failed: %s", g_strerror (errno)), (NULL)); goto error; - - while (TRUE) { - guint32 frame_num; - GstH264Picture *other_pic; - GstV4l2Request *other_request; - - if (!gst_v4l2_decoder_dequeue_src (self->decoder, &frame_num)) { - GST_ELEMENT_ERROR (self, STREAM, DECODE, - ("Decoder did not produce a frame"), (NULL)); - goto error; - } - - if (frame_num == picture->system_frame_number) - break; - - other_pic = gst_h264_decoder_get_picture (decoder, frame_num); - if (other_pic) { - other_request = gst_h264_picture_get_user_data (other_pic); - gst_v4l2_request_set_done (other_request); - gst_h264_picture_unref (other_pic); - } } -finish_frame: gst_v4l2_request_set_done (request); g_return_val_if_fail (frame->output_buffer, GST_FLOW_ERROR); +finish_frame: + if (gst_v4l2_request_failed (request)) { + GST_ELEMENT_ERROR (self, STREAM, DECODE, + ("Failed to decode frame %u", picture->system_frame_number), (NULL)); + goto error; + } + /* Hold on reference buffers for the rest of the picture lifetime */ gst_h264_picture_set_user_data (picture, gst_buffer_ref (frame->output_buffer), (GDestroyNotify) gst_buffer_unref); @@ -937,14 +913,6 @@ gst_v4l2_codec_h264_dec_ensure_output_buffer (GstV4l2CodecH264Dec * self, return FALSE; } - if (!gst_v4l2_decoder_queue_src_buffer (self->decoder, buffer, - frame->system_frame_number)) { - GST_ELEMENT_ERROR (self, RESOURCE, WRITE, - ("Driver did not accept the picture buffer."), (NULL)); - gst_buffer_unref (buffer); - return FALSE; - } - frame->output_buffer = buffer; return TRUE; } @@ -953,8 +921,7 @@ static gboolean gst_v4l2_codec_h264_dec_submit_bitstream (GstV4l2CodecH264Dec * self, GstH264Picture * picture, guint flags) { - GstVideoCodecFrame *frame; - GstV4l2Request *prev_request, *request; + GstV4l2Request *prev_request, *request = NULL; gsize bytesused; gboolean ret = FALSE; @@ -989,23 +956,38 @@ gst_v4l2_codec_h264_dec_submit_bitstream (GstV4l2CodecH264Dec * self, }; /* *INDENT-ON* */ - request = gst_v4l2_decoder_alloc_request (self->decoder); + prev_request = gst_h264_picture_get_user_data (picture); + + bytesused = self->bitstream_map.size; + gst_memory_unmap (self->bitstream, &self->bitstream_map); + self->bitstream_map = (GstMapInfo) GST_MAP_INFO_INIT; + gst_memory_resize (self->bitstream, 0, bytesused); + + if (prev_request) { + request = gst_v4l2_decoder_alloc_sub_request (self->decoder, prev_request, + self->bitstream); + } else { + GstVideoCodecFrame *frame; + + frame = gst_video_decoder_get_frame (GST_VIDEO_DECODER (self), + picture->system_frame_number); + g_return_val_if_fail (frame, FALSE); + + if (!gst_v4l2_codec_h264_dec_ensure_output_buffer (self, frame)) + goto done; + + request = gst_v4l2_decoder_alloc_request (self->decoder, + picture->system_frame_number, self->bitstream, frame->output_buffer); + + gst_video_codec_frame_unref (frame); + } + if (!request) { GST_ELEMENT_ERROR (self, RESOURCE, NO_SPACE_LEFT, ("Failed to allocate a media request object."), (NULL)); goto done; } - - frame = gst_video_decoder_get_frame (GST_VIDEO_DECODER (self), - picture->system_frame_number); - g_return_val_if_fail (frame, FALSE); - - if (!gst_v4l2_codec_h264_dec_ensure_output_buffer (self, frame)) - goto done; - - gst_video_codec_frame_unref (frame); - if (!gst_v4l2_decoder_set_controls (self->decoder, request, control, G_N_ELEMENTS (control))) { GST_ELEMENT_ERROR (self, RESOURCE, WRITE, @@ -1013,30 +995,12 @@ gst_v4l2_codec_h264_dec_submit_bitstream (GstV4l2CodecH264Dec * self, goto done; } - bytesused = self->bitstream_map.size; - gst_memory_unmap (self->bitstream, &self->bitstream_map); - self->bitstream_map = (GstMapInfo) GST_MAP_INFO_INIT; - - if (!gst_v4l2_decoder_queue_sink_mem (self->decoder, request, self->bitstream, - picture->system_frame_number, bytesused, flags)) { - GST_ELEMENT_ERROR (self, RESOURCE, WRITE, - ("Driver did not accept the bitstream data."), (NULL)); - goto done; - } - - if (!gst_v4l2_request_queue (request)) { + if (!gst_v4l2_request_queue (request, flags)) { GST_ELEMENT_ERROR (self, RESOURCE, WRITE, ("Driver did not accept the decode request."), (NULL)); goto done; } - prev_request = gst_h264_picture_get_user_data (picture); - if (prev_request) { - if (!gst_v4l2_codec_h264_dec_wait (self, prev_request)) - goto done; - gst_v4l2_request_set_done (prev_request); - } - gst_h264_picture_set_user_data (picture, g_steal_pointer (&request), (GDestroyNotify) gst_v4l2_request_free); ret = TRUE; @@ -1044,6 +1008,7 @@ gst_v4l2_codec_h264_dec_submit_bitstream (GstV4l2CodecH264Dec * self, done: if (request) gst_v4l2_request_free (request); + gst_v4l2_codec_h264_dec_reset_picture (self); return ret; diff --git a/sys/v4l2codecs/gstv4l2codecvp8dec.c b/sys/v4l2codecs/gstv4l2codecvp8dec.c index 0e5024c..ca5267b 100644 --- a/sys/v4l2codecs/gstv4l2codecvp8dec.c +++ b/sys/v4l2codecs/gstv4l2codecvp8dec.c @@ -246,7 +246,7 @@ gst_v4l2_codec_vp8_dec_decide_allocation (GstVideoDecoder * decoder, min = MAX (2, min); self->sink_allocator = gst_v4l2_codec_allocator_new (self->decoder, - GST_PAD_SINK, self->min_pool_size + 2); + GST_PAD_SINK, 2); self->src_allocator = gst_v4l2_codec_allocator_new (self->decoder, GST_PAD_SRC, self->min_pool_size + min + 4); self->src_pool = gst_v4l2_codec_pool_new (self->src_allocator, &self->vinfo); @@ -539,15 +539,10 @@ gst_v4l2_codec_vp8_dec_end_picture (GstVp8Decoder * decoder, }; /* *INDENT-ON* */ - request = gst_v4l2_decoder_alloc_request (self->decoder); - if (!request) { - GST_ELEMENT_ERROR (decoder, RESOURCE, NO_SPACE_LEFT, - ("Failed to allocate a media request object."), (NULL)); - goto fail; - } - - gst_vp8_picture_set_user_data (picture, request, - (GDestroyNotify) gst_v4l2_request_free); + bytesused = self->bitstream_map.size; + gst_memory_unmap (self->bitstream, &self->bitstream_map); + self->bitstream_map = (GstMapInfo) GST_MAP_INFO_INIT; + gst_memory_resize (self->bitstream, 0, bytesused); flow_ret = gst_buffer_pool_acquire_buffer (GST_BUFFER_POOL (self->src_pool), &buffer, NULL); @@ -567,33 +562,25 @@ gst_v4l2_codec_vp8_dec_end_picture (GstVp8Decoder * decoder, frame->output_buffer = buffer; gst_video_codec_frame_unref (frame); - if (!gst_v4l2_decoder_set_controls (self->decoder, request, control, - G_N_ELEMENTS (control))) { - GST_ELEMENT_ERROR (decoder, RESOURCE, WRITE, - ("Driver did not accept the bitstream parameters."), (NULL)); - goto fail; - } - - bytesused = self->bitstream_map.size; - gst_memory_unmap (self->bitstream, &self->bitstream_map); - self->bitstream_map = (GstMapInfo) GST_MAP_INFO_INIT; - - if (!gst_v4l2_decoder_queue_sink_mem (self->decoder, request, self->bitstream, - picture->system_frame_number, bytesused, 0)) { - GST_ELEMENT_ERROR (decoder, RESOURCE, WRITE, - ("Driver did not accept the bitstream data."), (NULL)); + request = gst_v4l2_decoder_alloc_request (self->decoder, + picture->system_frame_number, self->bitstream, buffer); + if (!request) { + GST_ELEMENT_ERROR (decoder, RESOURCE, NO_SPACE_LEFT, + ("Failed to allocate a media request object."), (NULL)); goto fail; } + gst_vp8_picture_set_user_data (picture, request, + (GDestroyNotify) gst_v4l2_request_free); - if (!gst_v4l2_decoder_queue_src_buffer (self->decoder, buffer, - picture->system_frame_number)) { + if (!gst_v4l2_decoder_set_controls (self->decoder, request, control, + G_N_ELEMENTS (control))) { GST_ELEMENT_ERROR (decoder, RESOURCE, WRITE, - ("Driver did not accept the picture buffer."), (NULL)); + ("Driver did not accept the bitstream parameters."), (NULL)); goto fail; } - if (!gst_v4l2_request_queue (request)) { + if (!gst_v4l2_request_queue (request, 0)) { GST_ELEMENT_ERROR (decoder, RESOURCE, WRITE, ("Driver did not accept the decode request."), (NULL)); goto fail; @@ -663,7 +650,6 @@ gst_v4l2_codec_vp8_dec_output_picture (GstVp8Decoder * decoder, GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder); GstV4l2Request *request = gst_vp8_picture_get_user_data (picture); gint ret; - guint32 frame_num; GST_DEBUG_OBJECT (self, "Output picture %u", picture->system_frame_number); @@ -682,18 +668,16 @@ gst_v4l2_codec_vp8_dec_output_picture (GstVp8Decoder * decoder, goto error; } - do { - if (!gst_v4l2_decoder_dequeue_src (self->decoder, &frame_num)) { - GST_ELEMENT_ERROR (self, STREAM, DECODE, - ("Decoder did not produce a frame"), (NULL)); - goto error; - } - } while (frame_num != picture->system_frame_number); - -finish_frame: gst_v4l2_request_set_done (request); g_return_val_if_fail (frame->output_buffer, GST_FLOW_ERROR); +finish_frame: + if (gst_v4l2_request_failed (request)) { + GST_ELEMENT_ERROR (self, STREAM, DECODE, + ("Failed to decode frame %u", picture->system_frame_number), (NULL)); + goto error; + } + /* Hold on reference buffers for the rest of the picture lifetime */ gst_vp8_picture_set_user_data (picture, gst_buffer_ref (frame->output_buffer), (GDestroyNotify) gst_buffer_unref); diff --git a/sys/v4l2codecs/gstv4l2decoder.c b/sys/v4l2codecs/gstv4l2decoder.c index abe81f94..533ce3d 100644 --- a/sys/v4l2codecs/gstv4l2decoder.c +++ b/sys/v4l2codecs/gstv4l2decoder.c @@ -49,10 +49,17 @@ struct _GstV4l2Request { GstV4l2Decoder *decoder; gint fd; + guint32 frame_num; GstMemory *bitstream; + GstBuffer *pic_buf; GstPoll *poll; GstPollFD pollfd; + + /* request state */ gboolean pending; + gboolean failed; + gboolean hold_pic_buf; + gboolean sub_request; }; struct _GstV4l2Decoder @@ -225,11 +232,12 @@ gst_v4l2_decoder_streamon (GstV4l2Decoder * self, GstPadDirection direction) gboolean gst_v4l2_decoder_streamoff (GstV4l2Decoder * self, GstPadDirection direction) { - GstV4l2Request *pending_req; guint32 type = direction_to_buffer_type (self, direction); gint ret; if (direction == GST_PAD_SRC) { + GstV4l2Request *pending_req; + /* STREAMOFF have the effect of cancelling all requests and unqueuing all * buffers, so clear the pending request list */ while ((pending_req = gst_queue_array_pop_head (self->pending_requests))) { @@ -530,12 +538,13 @@ gst_v4l2_decoder_export_buffer (GstV4l2Decoder * self, return TRUE; } -gboolean +static gboolean gst_v4l2_decoder_queue_sink_mem (GstV4l2Decoder * self, GstV4l2Request * request, GstMemory * mem, guint32 frame_num, - gsize bytesused, guint flags) + guint flags) { gint ret; + gsize bytesused = gst_memory_get_sizes (mem, NULL, NULL); struct v4l2_plane plane = { .bytesused = bytesused, }; @@ -563,14 +572,11 @@ gst_v4l2_decoder_queue_sink_mem (GstV4l2Decoder * self, return FALSE; } - request->bitstream = gst_memory_ref (mem); - return TRUE; } -gboolean -gst_v4l2_decoder_queue_src_buffer (GstV4l2Decoder * self, GstBuffer * buffer, - guint32 frame_num) +static gboolean +gst_v4l2_decoder_queue_src_buffer (GstV4l2Decoder * self, GstBuffer * buffer) { gint i, ret; struct v4l2_plane planes[GST_VIDEO_MAX_PLANES]; @@ -606,7 +612,7 @@ gst_v4l2_decoder_queue_src_buffer (GstV4l2Decoder * self, GstBuffer * buffer, return TRUE; } -gboolean +static gboolean gst_v4l2_decoder_dequeue_sink (GstV4l2Decoder * self) { gint ret; @@ -632,7 +638,7 @@ gst_v4l2_decoder_dequeue_sink (GstV4l2Decoder * self) return TRUE; } -gboolean +static gboolean gst_v4l2_decoder_dequeue_src (GstV4l2Decoder * self, guint32 * out_frame_num) { gint ret; @@ -806,8 +812,23 @@ gst_v4l2_decoder_register (GstPlugin * plugin, g_free (type_name); } +/* + * gst_v4l2_decoder_alloc_request: + * @self a #GstV4l2Decoder pointer + * @frame_num: Used as a timestamp to identify references + * @bitstream the #GstMemory that holds the bitstream data + * @pic_buf the #GstBuffer holding the decoded picture + * + * Allocate a Linux media request file descriptor. This request wrapper will + * hold a reference to the requested bitstream memory to decoded and the + * picture buffer this request will decode to. This will be used for + * transparent management of the V4L2 queues. + * + * Returns: a new #GstV4l2Request + */ GstV4l2Request * -gst_v4l2_decoder_alloc_request (GstV4l2Decoder * self) +gst_v4l2_decoder_alloc_request (GstV4l2Decoder * self, guint32 frame_num, + GstMemory * bitstream, GstBuffer * pic_buf) { GstV4l2Request *request = gst_queue_array_pop_head (self->request_pool); gint ret; @@ -830,9 +851,60 @@ gst_v4l2_decoder_alloc_request (GstV4l2Decoder * self) } request->decoder = g_object_ref (self); + request->bitstream = gst_memory_ref (bitstream); + request->pic_buf = gst_buffer_ref (pic_buf); + request->frame_num = frame_num; + return request; } +/* + * gst_v4l2_decoder_alloc_sub_request: + * @self a #GstV4l2Decoder pointer + * @prev_request the #GstV4l2Request this request continue + * @bitstream the #GstMemory that holds the bitstream data + * + * Allocate a Linux media request file descriptor. Similar to + * gst_v4l2_decoder_alloc_request(), but used when a request is the + * continuation of the decoding of the same picture. This is notably the case + * for subsequent slices or for second field of a frame. + * + * Returns: a new #GstV4l2Request + */ +GstV4l2Request * +gst_v4l2_decoder_alloc_sub_request (GstV4l2Decoder * self, + GstV4l2Request * prev_request, GstMemory * bitstream) +{ + GstV4l2Request *request = gst_queue_array_pop_head (self->request_pool); + gint ret; + + if (!request) { + request = g_new0 (GstV4l2Request, 1); + + ret = ioctl (self->media_fd, MEDIA_IOC_REQUEST_ALLOC, &request->fd); + if (ret < 0) { + GST_ERROR_OBJECT (self, "MEDIA_IOC_REQUEST_ALLOC failed: %s", + g_strerror (errno)); + return NULL; + } + + request->poll = gst_poll_new (FALSE); + gst_poll_fd_init (&request->pollfd); + request->pollfd.fd = request->fd; + gst_poll_add_fd (request->poll, &request->pollfd); + gst_poll_fd_ctl_pri (request->poll, &request->pollfd, TRUE); + } + + request->decoder = g_object_ref (self); + request->bitstream = gst_memory_ref (bitstream); + request->pic_buf = gst_buffer_ref (prev_request->pic_buf); + request->frame_num = prev_request->frame_num; + request->sub_request = TRUE; + + return request; +} + + void gst_v4l2_request_free (GstV4l2Request * request) { @@ -847,6 +919,11 @@ gst_v4l2_request_free (GstV4l2Request * request) } g_clear_pointer (&request->bitstream, gst_memory_unref); + g_clear_pointer (&request->pic_buf, gst_buffer_unref); + request->frame_num = G_MAXUINT32; + request->failed = FALSE; + request->hold_pic_buf = FALSE; + request->sub_request = FALSE; request->decoder = NULL; if (request->pending) { @@ -879,21 +956,48 @@ gst_v4l2_request_free (GstV4l2Request * request) } gboolean -gst_v4l2_request_queue (GstV4l2Request * request) +gst_v4l2_request_queue (GstV4l2Request * request, guint flags) { + GstV4l2Decoder *decoder = request->decoder; gint ret; - GST_TRACE_OBJECT (request->decoder, "Queuing request %p.", request); + GST_TRACE_OBJECT (decoder, "Queuing request %p.", request); + + if (!gst_v4l2_decoder_queue_sink_mem (decoder, request, + request->bitstream, request->frame_num, flags)) { + GST_ERROR_OBJECT (decoder, "Driver did not accept the bitstream data."); + return FALSE; + } + + if (!request->sub_request && + !gst_v4l2_decoder_queue_src_buffer (decoder, request->pic_buf)) { + GST_ERROR_OBJECT (decoder, "Driver did not accept the picture buffer."); + return FALSE; + } ret = ioctl (request->fd, MEDIA_REQUEST_IOC_QUEUE, NULL); if (ret < 0) { - GST_ERROR_OBJECT (request->decoder, "MEDIA_REQUEST_IOC_QUEUE, failed: %s", + GST_ERROR_OBJECT (decoder, "MEDIA_REQUEST_IOC_QUEUE, failed: %s", g_strerror (errno)); return FALSE; } + if (flags & V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF) + request->hold_pic_buf = TRUE; + request->pending = TRUE; - gst_queue_array_push_tail (request->decoder->pending_requests, request); + gst_queue_array_push_tail (decoder->pending_requests, request); + + /* FIXME to support more then one pending requests, we need the request to + * be refcounted */ + if (gst_queue_array_get_length (decoder->pending_requests) > 1) { + GstV4l2Request *pending_req; + + pending_req = gst_queue_array_peek_head (decoder->pending_requests); + ret = gst_v4l2_request_poll (pending_req, GST_SECOND); + if (ret > 0) + gst_v4l2_request_set_done (pending_req); + } return TRUE; } @@ -907,28 +1011,38 @@ gst_v4l2_request_poll (GstV4l2Request * request, GstClockTime timeout) void gst_v4l2_request_set_done (GstV4l2Request * request) { - if (request->bitstream) { - GstV4l2Decoder *dec = request->decoder; - GstV4l2Request *pending_req; + GstV4l2Decoder *decoder = request->decoder; + GstV4l2Request *pending_req = NULL; - while ((pending_req = gst_queue_array_pop_head (dec->pending_requests))) { - gst_v4l2_decoder_dequeue_sink (request->decoder); - g_clear_pointer (&pending_req->bitstream, gst_memory_unref); - pending_req->pending = FALSE; + if (!request->pending) + return; - if (pending_req == request) - break; - } + while ((pending_req = gst_queue_array_pop_head (decoder->pending_requests))) { + gst_v4l2_decoder_dequeue_sink (decoder); + g_clear_pointer (&pending_req->bitstream, gst_memory_unref); - /* Pending request should always be found in the fifo */ - if (pending_req != request) { - g_warning ("Pending request not found in the pending list."); - gst_v4l2_decoder_dequeue_sink (request->decoder); - g_clear_pointer (&pending_req->bitstream, gst_memory_unref); + if (!pending_req->hold_pic_buf) { + guint32 frame_num = G_MAXUINT32; + + if (!gst_v4l2_decoder_dequeue_src (decoder, &frame_num)) { + pending_req->failed = TRUE; + } else if (frame_num != pending_req->frame_num) { + GST_WARNING_OBJECT (decoder, + "Requested frame %u, but driver returned frame %u.", + pending_req->frame_num, frame_num); + pending_req->failed = TRUE; + } } + + g_clear_pointer (&pending_req->pic_buf, gst_buffer_unref); + pending_req->pending = FALSE; + + if (pending_req == request) + break; } - request->pending = FALSE; + /* Pending request must be in the pending request list */ + g_assert (pending_req == request); } gboolean @@ -936,3 +1050,9 @@ gst_v4l2_request_is_done (GstV4l2Request * request) { return !request->pending; } + +gboolean +gst_v4l2_request_failed (GstV4l2Request * request) +{ + return request->failed; +} diff --git a/sys/v4l2codecs/gstv4l2decoder.h b/sys/v4l2codecs/gstv4l2decoder.h index 0d32e31..e0f9cf8 100644 --- a/sys/v4l2codecs/gstv4l2decoder.h +++ b/sys/v4l2codecs/gstv4l2decoder.h @@ -72,22 +72,6 @@ gboolean gst_v4l2_decoder_export_buffer (GstV4l2Decoder * self, gsize * offsets, guint *num_fds); -gboolean gst_v4l2_decoder_queue_sink_mem (GstV4l2Decoder * self, - GstV4l2Request * request, - GstMemory * mem, - guint32 frame_num, - gsize bytesused, - guint flags); - -gboolean gst_v4l2_decoder_dequeue_sink (GstV4l2Decoder * self); - -gboolean gst_v4l2_decoder_queue_src_buffer (GstV4l2Decoder * self, - GstBuffer * buffer, - guint32 frame_num); - -gboolean gst_v4l2_decoder_dequeue_src (GstV4l2Decoder * self, - guint32 *out_frame_num); - gboolean gst_v4l2_decoder_set_controls (GstV4l2Decoder * self, GstV4l2Request * request, struct v4l2_ext_control *control, @@ -115,18 +99,29 @@ void gst_v4l2_decoder_register (GstPlugin * plugin, GstV4l2CodecDevice * device, guint rank); -GstV4l2Request *gst_v4l2_decoder_alloc_request (GstV4l2Decoder * self); +GstV4l2Request *gst_v4l2_decoder_alloc_request (GstV4l2Decoder * self, + guint32 frame_num, + GstMemory *bitstream, + GstBuffer * pic_buf); + +GstV4l2Request *gst_v4l2_decoder_alloc_sub_request (GstV4l2Decoder * self, + GstV4l2Request * prev_request, + GstMemory *bitstream); void gst_v4l2_request_free (GstV4l2Request * request); -gboolean gst_v4l2_request_queue (GstV4l2Request * request); +gboolean gst_v4l2_request_queue (GstV4l2Request * request, + guint flags); -gint gst_v4l2_request_poll (GstV4l2Request * request, GstClockTime timeout); +gint gst_v4l2_request_poll (GstV4l2Request * request, + GstClockTime timeout); void gst_v4l2_request_set_done (GstV4l2Request * request); gboolean gst_v4l2_request_is_done (GstV4l2Request * request); +gboolean gst_v4l2_request_failed (GstV4l2Request * request); + G_END_DECLS #endif /* __GST_V4L2_DECODER_H__ */