"Fossies" - the Fresh Open Source Software Archive

Member "gstreamer-1.16.1/tests/examples/memory/my-vidmem.c" (19 Apr 2019, 4457 Bytes) of package /linux/misc/gstreamer-1.16.1.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /* GStreamer
    2  * Copyright (C) 2012 Wim Taymans <wim.taymans@gmail.be>
    3  *
    4  * This library is free software; you can redistribute it and/or
    5  * modify it under the terms of the GNU Library General Public
    6  * License as published by the Free Software Foundation; either
    7  * version 2 of the License, or (at your option) any later version.
    8  *
    9  * This library is distributed in the hope that it will be useful,
   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   12  * Library General Public License for more details.
   13  *
   14  * You should have received a copy of the GNU Library General Public
   15  * License along with this library; if not, write to the
   16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
   17  * Boston, MA 02110-1301, USA.
   18  */
   19 
   20 #include "my-vidmem.h"
   21 
   22 static GstAllocator *_my_allocator;
   23 
   24 typedef struct
   25 {
   26   GstMemory mem;
   27 
   28   guint format;
   29   guint width;
   30   guint height;
   31   gpointer data;
   32 
   33 } MyVidmem;
   34 
   35 
   36 static GstMemory *
   37 _my_alloc (GstAllocator * allocator, gsize size, GstAllocationParams * params)
   38 {
   39   g_warning ("Use my_vidmem_alloc() to allocate from this allocator");
   40 
   41   return NULL;
   42 }
   43 
   44 static void
   45 _my_free (GstAllocator * allocator, GstMemory * mem)
   46 {
   47   MyVidmem *vmem = (MyVidmem *) mem;
   48 
   49   g_free (vmem->data);
   50   g_slice_free (MyVidmem, vmem);
   51   GST_DEBUG ("%p: freed", vmem);
   52 }
   53 
   54 static gpointer
   55 _my_vidmem_map (MyVidmem * mem, gsize maxsize, GstMapFlags flags)
   56 {
   57   gpointer res;
   58 
   59   while (TRUE) {
   60     if ((res = g_atomic_pointer_get (&mem->data)) != NULL)
   61       break;
   62 
   63     res = g_malloc (maxsize);
   64 
   65     if (g_atomic_pointer_compare_and_exchange (&mem->data, NULL, res))
   66       break;
   67 
   68     g_free (res);
   69   }
   70 
   71   GST_DEBUG ("%p: mapped %p", mem, res);
   72 
   73   return res;
   74 }
   75 
   76 static gboolean
   77 _my_vidmem_unmap (MyVidmem * mem)
   78 {
   79   GST_DEBUG ("%p: unmapped", mem);
   80   return TRUE;
   81 }
   82 
   83 static MyVidmem *
   84 _my_vidmem_share (MyVidmem * mem, gssize offset, gsize size)
   85 {
   86   MyVidmem *sub;
   87   GstMemory *parent;
   88 
   89   GST_DEBUG ("%p: share %" G_GSSIZE_FORMAT " %" G_GSIZE_FORMAT, mem, offset,
   90       size);
   91 
   92   /* find the real parent */
   93   if ((parent = mem->mem.parent) == NULL)
   94     parent = (GstMemory *) mem;
   95 
   96   if (size == -1)
   97     size = mem->mem.size - offset;
   98 
   99   sub = g_slice_new (MyVidmem);
  100   /* the shared memory is always readonly */
  101   gst_memory_init (GST_MEMORY_CAST (sub), GST_MINI_OBJECT_FLAGS (parent) |
  102       GST_MINI_OBJECT_FLAG_LOCK_READONLY, mem->mem.allocator, parent,
  103       mem->mem.maxsize, mem->mem.align, mem->mem.offset + offset, size);
  104 
  105   /* install pointer */
  106   sub->data = _my_vidmem_map (mem, mem->mem.maxsize, GST_MAP_READ);
  107 
  108   return sub;
  109 }
  110 
  111 typedef struct
  112 {
  113   GstAllocator parent;
  114 } MyVidmemAllocator;
  115 
  116 typedef struct
  117 {
  118   GstAllocatorClass parent_class;
  119 } MyVidmemAllocatorClass;
  120 
  121 GType my_vidmem_allocator_get_type (void);
  122 G_DEFINE_TYPE (MyVidmemAllocator, my_vidmem_allocator, GST_TYPE_ALLOCATOR);
  123 
  124 static void
  125 my_vidmem_allocator_class_init (MyVidmemAllocatorClass * klass)
  126 {
  127   GstAllocatorClass *allocator_class;
  128 
  129   allocator_class = (GstAllocatorClass *) klass;
  130 
  131   allocator_class->alloc = _my_alloc;
  132   allocator_class->free = _my_free;
  133 }
  134 
  135 static void
  136 my_vidmem_allocator_init (MyVidmemAllocator * allocator)
  137 {
  138   GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);
  139 
  140   alloc->mem_type = "MyVidmem";
  141   alloc->mem_map = (GstMemoryMapFunction) _my_vidmem_map;
  142   alloc->mem_unmap = (GstMemoryUnmapFunction) _my_vidmem_unmap;
  143   alloc->mem_share = (GstMemoryShareFunction) _my_vidmem_share;
  144 }
  145 
  146 void
  147 my_vidmem_init (void)
  148 {
  149   _my_allocator = g_object_new (my_vidmem_allocator_get_type (), NULL);
  150 
  151   gst_allocator_register ("MyVidmem", gst_object_ref (_my_allocator));
  152 }
  153 
  154 GstMemory *
  155 my_vidmem_alloc (guint format, guint width, guint height)
  156 {
  157   MyVidmem *mem;
  158   gsize maxsize;
  159 
  160   GST_DEBUG ("alloc frame format %u %ux%u", format, width, height);
  161 
  162   maxsize = (GST_ROUND_UP_4 (width) * height);
  163 
  164   mem = g_slice_new (MyVidmem);
  165 
  166   gst_memory_init (GST_MEMORY_CAST (mem), 0, _my_allocator, NULL,
  167       maxsize, 31, 0, maxsize);
  168 
  169   mem->format = format;
  170   mem->width = width;
  171   mem->height = height;
  172   mem->data = NULL;
  173 
  174   return (GstMemory *) mem;
  175 }
  176 
  177 gboolean
  178 my_is_vidmem (GstMemory * mem)
  179 {
  180   return mem->allocator == _my_allocator;
  181 }
  182 
  183 void
  184 my_vidmem_get_format (GstMemory * mem, guint * format, guint * width,
  185     guint * height)
  186 {
  187   MyVidmem *vmem = (MyVidmem *) mem;
  188 
  189   *format = vmem->format;
  190   *width = vmem->width;
  191   *height = vmem->height;
  192 }