content/media/gstreamer/GStreamerAllocator.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 #ifdef HAVE_CONFIG_H
     2 #include "config.h"
     3 #endif
     5 #include "GStreamerAllocator.h"
     7 #include <gst/video/video.h>
     8 #include <gst/video/gstvideometa.h>
    10 #include "GStreamerLoader.h"
    12 using namespace mozilla::layers;
    14 namespace mozilla {
    16 typedef struct
    17 {
    18   GstAllocator parent;
    19   GStreamerReader *reader;
    20 } MozGfxMemoryAllocator;
    22 typedef struct
    23 {
    24   GstAllocatorClass parent;
    25 } MozGfxMemoryAllocatorClass;
    27 typedef struct
    28 {
    29   GstMemory memory;
    30   PlanarYCbCrImage* image;
    31   guint8* data;
    32 } MozGfxMemory;
    34 typedef struct
    35 {
    36   GstMeta meta;
    37 } MozGfxMeta;
    39 typedef struct
    40 {
    41   GstVideoBufferPoolClass parent_class;
    42 } MozGfxBufferPoolClass;
    44 typedef struct
    45 {
    46   GstVideoBufferPool pool;
    47 } MozGfxBufferPool;
    49 // working around GTK+ bug https://bugzilla.gnome.org/show_bug.cgi?id=723899
    50 #pragma GCC diagnostic push
    51 #pragma GCC diagnostic ignored "-Wunused-function"
    52 G_DEFINE_TYPE(MozGfxMemoryAllocator, moz_gfx_memory_allocator, GST_TYPE_ALLOCATOR);
    53 G_DEFINE_TYPE(MozGfxBufferPool, moz_gfx_buffer_pool, GST_TYPE_VIDEO_BUFFER_POOL);
    54 #pragma GCC diagnostic pop
    56 void
    57 moz_gfx_memory_reset(MozGfxMemory *mem)
    58 {
    59   if (mem->image)
    60     mem->image->Release();
    62   ImageContainer* container = ((MozGfxMemoryAllocator*) mem->memory.allocator)->reader->GetImageContainer();
    63   mem->image = reinterpret_cast<PlanarYCbCrImage*>(container->CreateImage(ImageFormat::PLANAR_YCBCR).take());
    64   mem->data = mem->image->AllocateAndGetNewBuffer(mem->memory.size);
    65 }
    67 static GstMemory*
    68 moz_gfx_memory_allocator_alloc(GstAllocator* aAllocator, gsize aSize,
    69     GstAllocationParams* aParams)
    70 {
    71   MozGfxMemory* mem = g_slice_new (MozGfxMemory);
    72   gsize maxsize = aSize + aParams->prefix + aParams->padding;
    73   gst_memory_init(GST_MEMORY_CAST (mem),
    74                   (GstMemoryFlags)aParams->flags,
    75                   aAllocator, NULL, maxsize, aParams->align,
    76                   aParams->prefix, aSize);
    77   mem->image = NULL;
    78   moz_gfx_memory_reset(mem);
    80   return (GstMemory *) mem;
    81 }
    83 static void
    84 moz_gfx_memory_allocator_free (GstAllocator * allocator, GstMemory * gmem)
    85 {
    86   MozGfxMemory *mem = (MozGfxMemory *) gmem;
    88   if (mem->memory.parent)
    89     goto sub_mem;
    91   if (mem->image)
    92     mem->image->Release();
    94 sub_mem:
    95   g_slice_free (MozGfxMemory, mem);
    96 }
    98 static gpointer
    99 moz_gfx_memory_map (MozGfxMemory * mem, gsize maxsize, GstMapFlags flags)
   100 {
   101   // check that the allocation didn't fail
   102   if (mem->data == nullptr)
   103     return nullptr;
   105   return mem->data + mem->memory.offset;
   106 }
   108 static gboolean
   109 moz_gfx_memory_unmap (MozGfxMemory * mem)
   110 {
   111   return TRUE;
   112 }
   114 static MozGfxMemory *
   115 moz_gfx_memory_share (MozGfxMemory * mem, gssize offset, gsize size)
   116 {
   117   MozGfxMemory *sub;
   118   GstMemory *parent;
   120   /* find the real parent */
   121   if ((parent = mem->memory.parent) == NULL)
   122     parent = (GstMemory *) mem;
   124   if (size == (gsize) -1)
   125     size = mem->memory.size - offset;
   127   /* the shared memory is always readonly */
   128   sub = g_slice_new (MozGfxMemory);
   130   gst_memory_init (GST_MEMORY_CAST (sub),
   131       (GstMemoryFlags) (GST_MINI_OBJECT_FLAGS (parent) | GST_MINI_OBJECT_FLAG_LOCK_READONLY),
   132       mem->memory.allocator, &mem->memory, mem->memory.maxsize, mem->memory.align,
   133       mem->memory.offset + offset, size);
   135   sub->image = mem->image;
   136   sub->data = mem->data;
   138   return sub;
   139 }
   141 static void
   142 moz_gfx_memory_allocator_class_init (MozGfxMemoryAllocatorClass * klass)
   143 {
   144   GstAllocatorClass *allocator_class;
   146   allocator_class = (GstAllocatorClass *) klass;
   148   allocator_class->alloc = moz_gfx_memory_allocator_alloc;
   149   allocator_class->free = moz_gfx_memory_allocator_free;
   150 }
   152 static void
   153 moz_gfx_memory_allocator_init (MozGfxMemoryAllocator * allocator)
   154 {
   155   GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);
   157   alloc->mem_type = "moz-gfx-image";
   158   alloc->mem_map = (GstMemoryMapFunction) moz_gfx_memory_map;
   159   alloc->mem_unmap = (GstMemoryUnmapFunction) moz_gfx_memory_unmap;
   160   alloc->mem_share = (GstMemoryShareFunction) moz_gfx_memory_share;
   161   /* fallback copy and is_span */
   162 }
   164 void
   165 moz_gfx_memory_allocator_set_reader(GstAllocator* aAllocator, GStreamerReader* aReader)
   166 {
   167   MozGfxMemoryAllocator *allocator = (MozGfxMemoryAllocator *) aAllocator;
   168   allocator->reader = aReader;
   169 }
   171 nsRefPtr<PlanarYCbCrImage>
   172 moz_gfx_memory_get_image(GstMemory *aMemory)
   173 {
   174   NS_ASSERTION(GST_IS_MOZ_GFX_MEMORY_ALLOCATOR(aMemory->allocator), "Should be a gfx image");
   176   return ((MozGfxMemory *) aMemory)->image;
   177 }
   179 void
   180 moz_gfx_buffer_pool_reset_buffer (GstBufferPool* aPool, GstBuffer* aBuffer)
   181 {
   182   GstMemory* mem = gst_buffer_peek_memory(aBuffer, 0);
   184   NS_ASSERTION(GST_IS_MOZ_GFX_MEMORY_ALLOCATOR(mem->allocator), "Should be a gfx image");
   185   moz_gfx_memory_reset((MozGfxMemory *) mem);
   186   GST_BUFFER_POOL_CLASS(moz_gfx_buffer_pool_parent_class)->reset_buffer(aPool, aBuffer);
   187 }
   189 static void
   190 moz_gfx_buffer_pool_class_init (MozGfxBufferPoolClass * klass)
   191 {
   192   GstBufferPoolClass *pool_class = (GstBufferPoolClass *) klass;
   193   pool_class->reset_buffer = moz_gfx_buffer_pool_reset_buffer;
   194 }
   196 static void
   197 moz_gfx_buffer_pool_init (MozGfxBufferPool * pool)
   198 {
   199 }
   201 } // namespace mozilla

mercurial