From: SeokYeon Hwang Date: Tue, 12 Nov 2013 08:08:05 +0000 (+0900) Subject: Enhancement logic about using direct buffer. X-Git-Tag: submit/tizen/20150529.014846~37 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a87ecbfbe20c202d52ebbdd72ebeaf82d7bc26a8;p=platform%2Fadaptation%2Femulator%2Fgst-plugins-emulator.git Enhancement logic about using direct buffer. Fix some bugs related with device_fd. Use a device buffer wisely. Change-Id: Ie8c858348303fa917b856a3212f0407eaca5677d Signed-off-by: SeokYeon Hwang --- diff --git a/src/gstmarudec.c b/src/gstmarudec.c index f88f2ee..218bf62 100644 --- a/src/gstmarudec.c +++ b/src/gstmarudec.c @@ -37,75 +37,10 @@ #define GST_MARUDEC_PARAMS_QDATA g_quark_from_static_string("marudec-params") /* indicate dts, pts, offset in the stream */ -typedef struct -{ - gint idx; - GstClockTime timestamp; - GstClockTime duration; - gint64 offset; -} GstTSInfo; #define GST_TS_INFO_NONE &ts_info_none static const GstTSInfo ts_info_none = { -1, -1, -1, -1 }; -#define MAX_TS_MASK 0xff - -typedef struct _GstMaruDec -{ - GstElement element; - - GstPad *srcpad; - GstPad *sinkpad; - - CodecContext *context; - CodecDevice *dev; - - union { - struct { - gint width, height; - gint clip_width, clip_height; - gint par_n, par_d; - gint fps_n, fps_d; - gint old_fps_n, old_fps_d; - gboolean interlaced; - - enum PixelFormat pix_fmt; - } video; - struct { - gint channels; - gint samplerate; - gint depth; - } audio; - } format; - - gboolean opened; - gboolean discont; - gboolean clear_ts; - - /* tracking DTS/PTS */ - GstClockTime next_out; - - /* Qos stuff */ - gdouble proportion; - GstClockTime earliest_time; - gint64 processed; - gint64 dropped; - - - /* GstSegment can be used for two purposes: - * 1. performing seeks (handling seek events) - * 2. tracking playback regions (handling newsegment events) - */ - GstSegment segment; - - GstTSInfo ts_info[MAX_TS_MASK + 1]; - gint ts_idx; - - /* reverse playback queue */ - GList *queued; - -} GstMaruDec; - typedef struct _GstMaruDecClass { GstElementClass parent_class; @@ -940,14 +875,14 @@ get_output_buffer (GstMaruDec *marudec, GstBuffer **outbuf) CODEC_LOG (DEBUG, "outbuf size of decoded video: %d\n", pict_size); -#ifndef USE_HEAP_BUFFER + gst_pad_set_element_private(GST_PAD_PEER(marudec->srcpad), (gpointer)marudec); + /* GstPadBufferAllocFunction is mostly overridden by elements that can * provide a hardware buffer in order to avoid additional memcpy operations. */ gst_pad_set_bufferalloc_function( GST_PAD_PEER(marudec->srcpad), (GstPadBufferAllocFunction) codec_buffer_alloc); -#endif ret = gst_pad_alloc_buffer_and_set_caps (marudec->srcpad, GST_BUFFER_OFFSET_NONE, pict_size, @@ -958,16 +893,6 @@ get_output_buffer (GstMaruDec *marudec, GstBuffer **outbuf) return ret; } - if ((uintptr_t) GST_BUFFER_DATA (*outbuf) % 16) { - GST_DEBUG_OBJECT (marudec, - "Downstream can't allocate aligned buffers."); - gst_buffer_unref (*outbuf); - *outbuf = new_aligned_buffer (pict_size, GST_PAD_CAPS (marudec->srcpad)); - } - - codec_picture_copy (marudec->context, GST_BUFFER_DATA (*outbuf), - GST_BUFFER_SIZE (*outbuf), marudec->dev); - return ret; } diff --git a/src/gstmaruinterface.c b/src/gstmaruinterface.c index 3fa9503..2858a05 100644 --- a/src/gstmaruinterface.c +++ b/src/gstmaruinterface.c @@ -85,8 +85,8 @@ _codec_write_to_qemu (int32_t ctx_index, int32_t api_index, CODEC_LOG (DEBUG, "leave: %s\n", __func__); } -static struct mem_info -secure_device_mem (guint buf_size) +static int +secure_device_mem (guint buf_size, gpointer offset) { int ret = 0; uint32_t opaque = 0; @@ -95,23 +95,14 @@ secure_device_mem (guint buf_size) CODEC_LOG (DEBUG, "enter: %s\n", __func__); opaque = buf_size; - ret = ioctl (device_fd, CODEC_CMD_TRY_SECURE_BUFFER, &opaque); - if (ret == -1) { - CODEC_LOG (DEBUG, "failed to get available buffer\n"); - info.start = NULL; - info.offset = 0; - } else { - info.start = (gpointer)((uint32_t)device_mem + opaque); - info.offset = opaque; - CODEC_LOG (DEBUG, "acquire device_memory: 0x%x\n", opaque); - } + ret = ioctl (device_fd, CODEC_CMD_SECURE_BUFFER, &opaque); + offset = opaque; CODEC_LOG (DEBUG, "leave: %s\n", __func__); - return info; + return ret; } -#ifndef USE_HEAP_BUFFER static void release_device_mem (gpointer start) { @@ -144,20 +135,44 @@ codec_buffer_alloc (GstPad *pad, guint64 offset, guint size, GstCaps *caps, GstBuffer **buf) { struct mem_info info; + uint32_t opaque; + int ret = 0; + GstMaruDec *marudec; CODEC_LOG (DEBUG, "enter: %s\n", __func__); + opaque = size; + *buf = gst_buffer_new (); - info = secure_device_mem (size); + marudec = (GstMaruDec *)gst_pad_get_element_private(pad); + + _codec_write_to_qemu (marudec->context->index, CODEC_PICTURE_COPY, + 0, marudec->dev->fd); - if (info.start == NULL) { - CODEC_LOG (DEBUG, "can not secure memory now, so we will use heap buffer"); + ret = ioctl (marudec->dev->fd, CODEC_CMD_GET_DATA_INTO_DEVICE_MEM, &opaque); + + if (ret < 0) { + CODEC_LOG (DEBUG, "failed to get available buffer\n"); + } else if (ret == 1) { + // FIXME: we must aligned buffer offset. info.start = g_malloc (size); + info.offset = 0; + GST_BUFFER_FREE_FUNC (*buf) = g_free; + + memcpy (info.start, (uint32_t)device_mem + opaque, size); + release_device_mem((uint32_t)device_mem + opaque); + + CODEC_LOG (DEBUG, "we secured last buffer, so we will use heap buffer"); } else { - CODEC_LOG (DEBUG, "device memory start: 0x%p, offset 0x%x\n", info.start, info.offset); + // address of "device_mem" and "opaque" is aleady aligned. + info.start = (gpointer)((uint32_t)device_mem + opaque); + info.offset = opaque; + GST_BUFFER_FREE_FUNC (*buf) = codec_buffer_free; + + CODEC_LOG (DEBUG, "device memory start: 0x%p, offset 0x%x\n", info.start, info.offset); } GST_BUFFER_DATA (*buf) = GST_BUFFER_MALLOCDATA (*buf) = info.start; @@ -172,7 +187,6 @@ codec_buffer_alloc (GstPad *pad, guint64 offset, guint size, return GST_FLOW_OK; } -#endif int codec_init (CodecContext *ctx, CodecElement *codec, CodecDevice *dev) @@ -332,80 +346,6 @@ codec_decode_video (CodecContext *ctx, uint8_t *in_buf, int in_size, return len; } -void -codec_picture_copy (CodecContext *ctx, uint8_t *pict, - uint32_t pict_size, CodecDevice *dev) -{ - int fd, ret = 0; - uint32_t opaque = 0; - int is_direct_buffer = 0; - - CODEC_LOG (DEBUG, "enter: %s\n", __func__); - - fd = dev->fd; - if (fd < 0) { - GST_ERROR ("failed to get %s fd\n", CODEC_DEV); - return; - } - - if (!dev->buf) { - GST_ERROR ("failed to get mmaped memory address\n"); - return; - } - - // determine buffer located in device memory or not. - if ((uint32_t)pict >= (uint32_t)(dev->buf) && - (uint32_t)pict < (uint32_t)(dev->buf) + (dev->buf_size)) { - is_direct_buffer = 1; - } - - CODEC_LOG (DEBUG, "pict_size: %d\n", pict_size); - - _codec_write_to_qemu (ctx->index, CODEC_PICTURE_COPY, - 0, fd); - - if (is_direct_buffer) { - // if we can use device memory as a output buffer... -#ifdef USE_HEAP_BUFFER - GST_ERROR ("failed to get mmaped memory address\n"); -#else - dev->mem_info.offset = (uint32_t)pict - (uint32_t)(dev->buf); - CODEC_LOG (DEBUG, "%d of pict: %p , device_mem: %p\n", - ctx->index, pict, dev->buf); - CODEC_LOG (DEBUG, "%d of picture_copy, mem_offset = 0x%x\n", - ctx->index, dev->mem_info.offset); - - ret = ioctl (fd, CODEC_CMD_USE_DEVICE_MEM, &(dev->mem_info.offset)); - if (ret < 0) { - CODEC_LOG (ERR, "failed to use device memory\n"); - return; - } -#endif - } else { - // if we can not use device memory as a output buffer, - // we must copy data from device memory to heap buffer. - CODEC_LOG (DEBUG, "need a memory\n"); - opaque = pict_size; - ret = ioctl (fd, CODEC_CMD_GET_DATA_INTO_DEVICE_MEM, &opaque); - if (ret < 0) { - CODEC_LOG (ERR, "failed to secure device memory\n"); - return; - } - - CODEC_LOG (DEBUG, "picture_copy, mem_offset = 0x%x\n", opaque); - - memcpy (pict, (dev->buf) + opaque, pict_size); - - ret = ioctl(fd, CODEC_CMD_RELEASE_BUFFER, &opaque); - - if (ret < 0) { - CODEC_LOG (ERR, "failed to release used memory\n"); - } - } - - CODEC_LOG (DEBUG, "leave: %s\n", __func__); -} - int codec_decode_audio (CodecContext *ctx, int16_t *samples, int *have_data, uint8_t *in_buf, diff --git a/src/gstmaruinterface.h b/src/gstmaruinterface.h index c0f49f8..d9fa633 100644 --- a/src/gstmaruinterface.h +++ b/src/gstmaruinterface.h @@ -33,6 +33,72 @@ #include "gstmaru.h" +#define MAX_TS_MASK 0xff + +typedef struct +{ + gint idx; + GstClockTime timestamp; + GstClockTime duration; + gint64 offset; +} GstTSInfo; + +typedef struct _GstMaruDec +{ + GstElement element; + + GstPad *srcpad; + GstPad *sinkpad; + + CodecContext *context; + CodecDevice *dev; + + union { + struct { + gint width, height; + gint clip_width, clip_height; + gint par_n, par_d; + gint fps_n, fps_d; + gint old_fps_n, old_fps_d; + gboolean interlaced; + + enum PixelFormat pix_fmt; + } video; + struct { + gint channels; + gint samplerate; + gint depth; + } audio; + } format; + + gboolean opened; + gboolean discont; + gboolean clear_ts; + + /* tracking DTS/PTS */ + GstClockTime next_out; + + /* Qos stuff */ + gdouble proportion; + GstClockTime earliest_time; + gint64 processed; + gint64 dropped; + + + /* GstSegment can be used for two purposes: + * 1. performing seeks (handling seek events) + * 2. tracking playback regions (handling newsegment events) + */ + GstSegment segment; + + GstTSInfo ts_info[MAX_TS_MASK + 1]; + gint ts_idx; + + /* reverse playback queue */ + GList *queued; + +} GstMaruDec; + int codec_init (CodecContext *ctx, CodecElement *codec, CodecDevice *dev);