1 /* GStreamer
2 * Copyright (C) 2020 Ognyan Tonchev <ognyan at axis dot com>
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 "gstbuffermemory.h"
21
22 gboolean
gst_buffer_memory_map(GstBuffer * buffer,GstBufferMemoryMap * map)23 gst_buffer_memory_map (GstBuffer * buffer, GstBufferMemoryMap * map)
24 {
25 GstMemory *mem;
26
27 g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
28 g_return_val_if_fail (map != NULL, FALSE);
29
30 if (gst_buffer_n_memory (buffer) == 0) {
31 GST_DEBUG ("no memory blocks in buffer");
32 return FALSE;
33 }
34
35 mem = gst_buffer_get_memory (buffer, 0);
36
37 if (!gst_memory_map (mem, &map->map, GST_MAP_READ)) {
38 GST_ERROR ("failed to map memory");
39 gst_memory_unref (mem);
40 return FALSE;
41 }
42
43 map->buf = buffer;
44 map->mem = mem;
45 map->data = map->map.data;
46 map->size = map->map.size;
47 map->index = 0;
48 map->total_size = gst_buffer_get_size (buffer);
49 map->offset = 0;
50
51 return TRUE;
52 }
53
54 static gboolean
buffer_memory_map_next(GstBufferMemoryMap * map)55 buffer_memory_map_next (GstBufferMemoryMap * map)
56 {
57 if (!map->mem)
58 return FALSE;
59
60 gst_memory_unmap (map->mem, &map->map);
61 gst_memory_unref (map->mem);
62 map->mem = NULL;
63 map->data = NULL;
64 map->size = 0;
65
66 map->index++;
67
68 if (map->index >= gst_buffer_n_memory (map->buf)) {
69 GST_DEBUG ("no more memory blocks in buffer");
70 return FALSE;
71 }
72
73 map->mem = gst_buffer_get_memory (map->buf, map->index);
74
75 if (!gst_memory_map (map->mem, &map->map, GST_MAP_READ)) {
76 GST_ERROR ("failed to map memory");
77 gst_memory_unref (map->mem);
78 map->mem = NULL;
79 return FALSE;
80 }
81
82 map->data = map->map.data;
83 map->size = map->map.size;
84
85 return TRUE;
86 }
87
88 gboolean
gst_buffer_memory_advance_bytes(GstBufferMemoryMap * map,gsize size)89 gst_buffer_memory_advance_bytes (GstBufferMemoryMap * map, gsize size)
90 {
91 gsize offset = size;
92
93 g_return_val_if_fail (map != NULL, FALSE);
94
95 map->offset += size;
96
97 while (offset >= map->size) {
98 offset -= map->size;
99 GST_DEBUG ("switching memory");
100 if (!buffer_memory_map_next (map))
101 return FALSE;
102 }
103
104 map->data += offset;
105 map->size -= offset;
106
107 return TRUE;
108 }
109
110 void
gst_buffer_memory_unmap(GstBufferMemoryMap * map)111 gst_buffer_memory_unmap (GstBufferMemoryMap * map)
112 {
113 g_return_if_fail (map != NULL);
114
115 if (map->mem) {
116 gst_memory_unmap (map->mem, &map->map);
117 gst_memory_unref (map->mem);
118 map->mem = NULL;
119 }
120 }
121