From c2dba3dbd209b10e9ede95983defed4e496bc5d3 Mon Sep 17 00:00:00 2001 From: Jeegar Patel Date: Wed, 25 Jan 2017 20:17:04 +0530 Subject: [PATCH 17/24] Add event for transcode usecase - Custom event handling is added in between decoder and encoder for sharing list of fds in pause->playing state - Now we do not need to drop frames in transcode Signed-off-by: Jeegar Patel Upstream Status: Pending --- omx/gstomx.c | 5 +- omx/gstomxvideodec.c | 24 +++++++--- omx/gstomxvideoenc.c | 130 +++++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 138 insertions(+), 21 deletions(-) diff --git a/omx/gstomx.c b/omx/gstomx.c index ccfeec8..9b7f1eb 100644 --- a/omx/gstomx.c +++ b/omx/gstomx.c @@ -1637,6 +1637,8 @@ gst_omx_port_allocate_buffers_unlocked (GstOMXPort * port, err = OMX_UseBuffer (comp->handle, &buf->omx_buf, port->index, buf, port->port_def.nBufferSize, l->data); + if (port->index == 0) + printf ("Encoder i/p OMX_Usebuffer %d\n", buf->omx_buf->pBuffer); buf->eglimage = FALSE; } else if (images) { err = @@ -1647,6 +1649,8 @@ gst_omx_port_allocate_buffers_unlocked (GstOMXPort * port, err = OMX_AllocateBuffer (comp->handle, &buf->omx_buf, port->index, buf, port->port_def.nBufferSize); + if (port->index == 1) + printf ("Decoder o/p OMX_AllocateBuffer %d\n", buf->omx_buf->pBuffer); buf->eglimage = FALSE; } @@ -1660,7 +1664,6 @@ gst_omx_port_allocate_buffers_unlocked (GstOMXPort * port, GST_DEBUG_OBJECT (comp->parent, "%s: allocated buffer %p (%p)", comp->name, buf, buf->omx_buf->pBuffer); - g_assert (buf->omx_buf->pAppPrivate == buf); /* In the beginning all buffers are not owned by the component */ diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c index 38bb196..7383ab6 100644 --- a/omx/gstomxvideodec.c +++ b/omx/gstomxvideodec.c @@ -25,7 +25,7 @@ #endif #include - +#include #if defined (USE_OMX_TARGET_RPI) && defined(__GNUC__) #ifndef __VCCOREVER__ #define __VCCOREVER__ 0x04000000 @@ -213,7 +213,7 @@ gst_omx_video_dec_open (GstVideoDecoder * decoder) (OMX_STRING) "OMX.allegro.linux.enableDMA", &DMAtype); memset (&enable_dmabuf, 0, sizeof (enable_dmabuf)); - enable_dmabuf.nSize = sizeof(enable_dmabuf); + enable_dmabuf.nSize = sizeof (enable_dmabuf); enable_dmabuf.nVersion.s.nVersionMajor = OMXIL_MAJOR_VERSION; enable_dmabuf.nVersion.s.nVersionMinor = OMXIL_MINOR_VERSION; enable_dmabuf.nVersion.s.nRevision = OMXIL_REVISION; @@ -944,8 +944,8 @@ gst_omx_video_dec_deallocate_output_buffers (GstOMXVideoDec * self) } #if defined (USE_OMX_TARGET_RPI) && defined (HAVE_GST_GL) err = - gst_omx_port_deallocate_buffers (self->eglimage ? self-> - egl_out_port : self->dec_out_port); + gst_omx_port_deallocate_buffers (self-> + eglimage ? self->egl_out_port : self->dec_out_port); #else err = gst_omx_port_deallocate_buffers (self->dec_out_port); #endif @@ -1191,6 +1191,18 @@ enable_port: if (err != OMX_ErrorNone) goto done; + GstStructure *dmaList = gst_structure_new ("dmaStruct", + "dmaPtrArray", G_TYPE_POINTER, port->buffers, NULL); + + GstEvent *dmaListEvent = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, + dmaList); + GstPad *newpad = gst_element_get_static_pad (GST_ELEMENT (self), "src"); + if (newpad == NULL) + printf ("src pad did not found\n"); + + gst_pad_push_event (newpad, dmaListEvent); + + err = gst_omx_port_populate (port); if (err != OMX_ErrorNone) goto done; @@ -1342,8 +1354,8 @@ gst_omx_video_dec_loop (GstOMXVideoDec * self) OMX_VIDEO_CodingUnused); format = - gst_omx_video_get_format_from_omx (port_def.format.video. - eColorFormat); + gst_omx_video_get_format_from_omx (port_def.format. + video.eColorFormat); if (format == GST_VIDEO_FORMAT_UNKNOWN) { GST_ERROR_OBJECT (self, "Unsupported color format: %d", diff --git a/omx/gstomxvideoenc.c b/omx/gstomxvideoenc.c index 77c3f86..c7fb0db 100644 --- a/omx/gstomxvideoenc.c +++ b/omx/gstomxvideoenc.c @@ -112,6 +112,9 @@ static GstFlowReturn gst_omx_video_enc_drain (GstOMXVideoEnc * self, static GstFlowReturn gst_omx_video_enc_handle_output_frame (GstOMXVideoEnc * self, GstOMXPort * port, GstOMXBuffer * buf, GstVideoCodecFrame * frame); +static gboolean *gst_omx_video_enc_sink_event (GstVideoEncoder * encoder, + GstEvent * event); + enum { PROP_0, @@ -141,6 +144,11 @@ enum G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstOMXVideoEnc, gst_omx_video_enc, GST_TYPE_VIDEO_ENCODER, DEBUG_INIT); +gboolean (*sink_event_backup) (GstVideoEncoder * encoder, GstEvent * event); +GList *buffer_list = NULL; +gint g_dmalist_count = 0; +gint bufpool_complete = 0; + static void gst_omx_video_enc_class_init (GstOMXVideoEncClass * klass) { @@ -219,6 +227,9 @@ gst_omx_video_enc_class_init (GstOMXVideoEncClass * klass) video_encoder_class->propose_allocation = GST_DEBUG_FUNCPTR (gst_omx_video_enc_propose_allocation); video_encoder_class->getcaps = GST_DEBUG_FUNCPTR (gst_omx_video_enc_getcaps); + sink_event_backup = video_encoder_class->sink_event; + video_encoder_class->sink_event = + GST_DEBUG_FUNCPTR (gst_omx_video_enc_sink_event); klass->cdata.type = GST_OMX_COMPONENT_TYPE_FILTER; klass->cdata.default_sink_template_caps = "video/x-raw, " @@ -1385,9 +1396,12 @@ gst_omx_video_enc_fill_buffer (GstOMXVideoEnc * self, GstBuffer * inbuf, } if (self->input_mode == OMX_Enc_InputMode_DMABufImport) { - outbuf->omx_buf->pBuffer = - gst_dmabuf_memory_get_fd (gst_buffer_peek_memory (inbuf, 0)); - printf ("Stride matches & Passed fd to OMX is %d\n", + //outbuf->omx_buf->pBuffer = + // gst_dmabuf_memory_get_fd (gst_buffer_peek_memory (inbuf, 0)); + //printf ("Stride matches & Passed fd to OMX is %d\n", + // outbuf->omx_buf->pBuffer); + printf ("Stride matches,Decoder o/p FD is %d, Encoder o/p FD is %d\n", + gst_dmabuf_memory_get_fd (gst_buffer_peek_memory (inbuf, 0)), outbuf->omx_buf->pBuffer); } @@ -1570,10 +1584,10 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder, GstOMXPort *port; GstOMXBuffer *buf; OMX_ERRORTYPE err; - GList *buffer_list = NULL; static gint count = 0; - static gint fd1 = 0, fd2 = 0; - + gint fd1 = 0, fd2 = 0; + static GList *garray = NULL; + gint i; self = GST_OMX_VIDEO_ENC (encoder); GST_DEBUG_OBJECT (self, "Handling frame"); @@ -1594,25 +1608,70 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder, if (self->input_mode == OMX_Enc_InputMode_DMABufImport) { count++; - if (count == 1) { + if ((count == 1) && (bufpool_complete == 0)) { fd1 = gst_dmabuf_memory_get_fd (gst_buffer_peek_memory (frame->input_buffer, 0)); + printf ("Got 1st fd %d\n", fd1); + garray = g_list_append (garray, fd1); frame->output_buffer = NULL; gst_video_encoder_finish_frame (self, frame); return self->downstream_flow_ret; } - - if (count == 2) { - fd2 = + if (bufpool_complete == 0) { + fd1 = gst_dmabuf_memory_get_fd (gst_buffer_peek_memory (frame->input_buffer, 0)); + printf ("Got next fd %d\n", fd1); + if (g_list_find (garray, fd1) != NULL) { + printf ("Bufferpool found completed \n"); + bufpool_complete = 1; + } else { + garray = g_list_append (garray, fd1); + frame->output_buffer = NULL; + gst_video_encoder_finish_frame (self, frame); + return self->downstream_flow_ret; + } + } + if (bufpool_complete == 1) { + + if (count == 1) { + printf ("Bufferpool found by event, It has %d buffers \n", + g_dmalist_count); + bufpool_complete = 2; + buffer_list = g_list_reverse (buffer_list); + + gst_omx_port_update_port_definition (self->enc_in_port, NULL); + printf ("OMX Encoder BuffercountActual is %d\n", + self->enc_in_port->port_def.nBufferCountActual); + self->enc_in_port->port_def.nBufferCountActual = g_dmalist_count; + gst_omx_port_update_port_definition (self->enc_in_port, + &self->enc_in_port->port_def); + printf ("Updated OMX Encoder BuffercountActual is %d\n", + self->enc_in_port->port_def.nBufferCountActual); + - gst_omx_port_update_port_definition (self->enc_in_port, NULL); + } else { + + printf ("Bufferpool found by fd tracing, It has %d buffers \n", + g_list_length (garray)); + bufpool_complete = 2; + + for (i = 0; i < g_list_length (garray); i++) + buffer_list = + g_list_append (buffer_list, + GPOINTER_TO_INT (g_list_nth_data (garray, i))); + + gst_omx_port_update_port_definition (self->enc_in_port, NULL); + printf ("OMX Encoder BuffercountActual is %d\n", + self->enc_in_port->port_def.nBufferCountActual); + self->enc_in_port->port_def.nBufferCountActual = g_list_length (garray); + gst_omx_port_update_port_definition (self->enc_in_port, + &self->enc_in_port->port_def); + printf ("Updated OMX Encoder BuffercountActual is %d\n", + self->enc_in_port->port_def.nBufferCountActual); - //TODO: Currently we know, V4l2src bufferpool has 2 fds, But we need to make it dynamic */ - buffer_list = g_list_append (buffer_list, fd2); - buffer_list = g_list_append (buffer_list, fd1); + } if (gst_omx_port_use_buffers (self->enc_in_port, buffer_list) != OMX_ErrorNone) @@ -1912,6 +1971,49 @@ gst_omx_video_enc_drain (GstOMXVideoEnc * self, gboolean at_eos) return GST_FLOW_OK; } +static void +test_data (GstOMXBuffer * buf) +{ + buffer_list = g_list_append (buffer_list, buf->omx_buf->pBuffer); + g_dmalist_count++; + return; +} + +static gboolean * +gst_omx_video_enc_sink_event (GstVideoEncoder * encoder, GstEvent * event) +{ + GstOMXVideoEnc *self; + + self = GST_OMX_VIDEO_ENC (encoder); + GstOMXVideoEncClass *klass = GST_OMX_VIDEO_ENC_GET_CLASS (self); + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + const GValue *p; + struct GPtrArray *buffers; + gint value; + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_CUSTOM_DOWNSTREAM:{ + const GstStructure *structure = gst_event_get_structure (event); + + if (gst_structure_has_name (structure, "dmaStruct")) { + p = gst_structure_get_value (structure, "dmaPtrArray"); + buffers = g_value_get_pointer (p); + g_ptr_array_foreach (buffers, test_data, NULL); + bufpool_complete = 1; + printf ("Custom event for DMA list is sucessful, got %d fd \n", + g_dmalist_count); + } + return sink_event_backup (encoder, event); + break; + } + default: + return sink_event_backup (encoder, event); + break; + } + + return 0; +} + static gboolean gst_omx_video_enc_propose_allocation (GstVideoEncoder * encoder, GstQuery * query) -- 2.7.4