History

imgutils: add a function for copying image data from GPU mapped memory

See https://software.intel.com/en-us/articles/copying-accelerated-video-decode-frame-buffers

Anton Khirnov committed 10 years ago

Commit d7bc52b1 parent 24da4308 files · +219 −14Browse files

Unified · Split

8 files
  1. doc/APIchanges +4 −0
  2. libavutil/imgutils.c +62 −13
  3. libavutil/imgutils.h +18 −0
  4. libavutil/imgutils_internal.h +30 −0
  5. libavutil/version.h +1 −1
  6. libavutil/x86/Makefile +2 −0
  7. libavutil/x86/imgutils.asm +53 −0
  8. libavutil/x86/imgutils_init.c +49 −0
doc/APIchanges+4−0
@@ -13,6 +13,10 @@ libavutil: 2015-08-28 · 12 unmodified lines
1313
1414 API changes, most recent first:
1515
16+2016-08-24 - xxxxxxx - lavu 55.21.0 - imgutils.h
17+ Add av_image_copy_uc_from(), a version of av_image_copy() for copying
18+ from GPU mapped memory.
19+
1620 2016-xx-xx - xxxxxxx - lavc 59.26.0 - vaapi.h
1721 Deprecate struct vaapi_context and the vaapi.h installed header.
1822 Callers should set AVCodecContext.hw_frames_ctx instead.
libavutil/imgutils.c+62−13
@@ -23,6 +23,7 @@ · 22 unmodified lines
2323
2424 #include "common.h"
2525 #include "imgutils.h"
26+#include "imgutils_internal.h"
2627 #include "internal.h"
2728 #include "intreadwrite.h"
2829 #include "log.h"
@@ -252,9 +253,9 @@ int av_image_check_sar(unsigned int w, unsigned int h, AVRational sar) · 223 unmodified lines
252253 return AVERROR(EINVAL);
253254 }
254255
255−void av_image_copy_plane(uint8_t *dst, int dst_linesize,
256− const uint8_t *src, int src_linesize,
257− int bytewidth, int height)
256+static void image_copy_plane(uint8_t *dst, ptrdiff_t dst_linesize,
257+ const uint8_t *src, ptrdiff_t src_linesize,
258+ ptrdiff_t bytewidth, int height)
258259 {
259260 if (!dst || !src)
260261 return;
@@ -265,9 +266,33 @@ void av_image_copy_plane(uint8_t *dst, int dst_linesize, · 4 unmodified lines
265266 }
266267 }
267268
268−void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4],
269− const uint8_t *src_data[4], const int src_linesizes[4],
270− enum AVPixelFormat pix_fmt, int width, int height)
269+static void image_copy_plane_uc_from(uint8_t *dst, ptrdiff_t dst_linesize,
270+ const uint8_t *src, ptrdiff_t src_linesize,
271+ ptrdiff_t bytewidth, int height)
272+{
273+ int ret = -1;
274+
275+#if ARCH_X86
276+ ret = ff_image_copy_plane_uc_from_x86(dst, dst_linesize, src, src_linesize,
277+ bytewidth, height);
278+#endif
279+
280+ if (ret < 0)
281+ image_copy_plane(dst, dst_linesize, src, src_linesize, bytewidth, height);
282+}
283+
284+void av_image_copy_plane(uint8_t *dst, int dst_linesize,
285+ const uint8_t *src, int src_linesize,
286+ int bytewidth, int height)
287+{
288+ image_copy_plane(dst, dst_linesize, src, src_linesize, bytewidth, height);
289+}
290+
291+static void image_copy(uint8_t *dst_data[4], const ptrdiff_t dst_linesizes[4],
292+ const uint8_t *src_data[4], const ptrdiff_t src_linesizes[4],
293+ enum AVPixelFormat pix_fmt, int width, int height,
294+ void (*copy_plane)(uint8_t *, ptrdiff_t, const uint8_t *,
295+ ptrdiff_t, ptrdiff_t, int))
271296 {
272297 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
273298
@@ -276,9 +301,9 @@ void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], · 2 unmodified lines
276301
277302 if (desc->flags & AV_PIX_FMT_FLAG_PAL ||
278303 desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) {
279− av_image_copy_plane(dst_data[0], dst_linesizes[0],
280− src_data[0], src_linesizes[0],
281− width, height);
304+ copy_plane(dst_data[0], dst_linesizes[0],
305+ src_data[0], src_linesizes[0],
306+ width, height);
282307 /* copy the palette */
283308 memcpy(dst_data[1], src_data[1], 4*256);
284309 } else {
@@ -289,17 +314,41 @@ void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], · 4 unmodified lines
289314
290315 for (i = 0; i < planes_nb; i++) {
291316 int h = height;
292− int bwidth = av_image_get_linesize(pix_fmt, width, i);
317+ ptrdiff_t bwidth = av_image_get_linesize(pix_fmt, width, i);
293318 if (i == 1 || i == 2) {
294319 h = AV_CEIL_RSHIFT(height, desc->log2_chroma_h);
295320 }
296− av_image_copy_plane(dst_data[i], dst_linesizes[i],
297− src_data[i], src_linesizes[i],
298− bwidth, h);
321+ copy_plane(dst_data[i], dst_linesizes[i],
322+ src_data[i], src_linesizes[i],
323+ bwidth, h);
299324 }
300325 }
301326 }
302327
328+void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4],
329+ const uint8_t *src_data[4], const int src_linesizes[4],
330+ enum AVPixelFormat pix_fmt, int width, int height)
331+{
332+ ptrdiff_t dst_linesizes1[4], src_linesizes1[4];
333+ int i;
334+
335+ for (i = 0; i < 4; i++) {
336+ dst_linesizes1[i] = dst_linesizes[i];
337+ src_linesizes1[i] = src_linesizes[i];
338+ }
339+
340+ image_copy(dst_data, dst_linesizes1, src_data, src_linesizes1, pix_fmt,
341+ width, height, image_copy_plane);
342+}
343+
344+void av_image_copy_uc_from(uint8_t *dst_data[4], const ptrdiff_t dst_linesizes[4],
345+ const uint8_t *src_data[4], const ptrdiff_t src_linesizes[4],
346+ enum AVPixelFormat pix_fmt, int width, int height)
347+{
348+ image_copy(dst_data, dst_linesizes, src_data, src_linesizes, pix_fmt,
349+ width, height, image_copy_plane_uc_from);
350+}
351+
303352 int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4],
304353 const uint8_t *src, enum AVPixelFormat pix_fmt,
305354 int width, int height, int align)
libavutil/imgutils.h+18−0
@@ -117,6 +117,24 @@ void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], · 116 unmodified lines
117117 const uint8_t *src_data[4], const int src_linesizes[4],
118118 enum AVPixelFormat pix_fmt, int width, int height);
119119
120+/**
121+ * Copy image data located in uncacheable (e.g. GPU mapped) memory. Where
122+ * available, this function will use special functionality for reading from such
123+ * memory, which may result in greatly improved performance compared to plain
124+ * av_image_copy().
125+ *
126+ * The data pointers and the linesizes must be aligned to the maximum required
127+ * by the CPU architecture.
128+ *
129+ * @note The linesize parameters have the type ptrdiff_t here, while they are
130+ * int for av_image_copy().
131+ * @note On x86, the linesizes currently need to be aligned to the cacheline
132+ * size (i.e. 64) to get improved performance.
133+ */
134+void av_image_copy_uc_from(uint8_t *dst_data[4], const ptrdiff_t dst_linesizes[4],
135+ const uint8_t *src_data[4], const ptrdiff_t src_linesizes[4],
136+ enum AVPixelFormat pix_fmt, int width, int height);
137+
120138 /**
121139 * Setup the data pointers and linesizes based on the specified image
122140 * parameters and the provided array.
libavutil/imgutils_internal.h+30−0
@@ -0,0 +1,30 @@
1+/*
2+ * This file is part of Libav.
3+ *
4+ * Libav is free software; you can redistribute it and/or
5+ * modify it under the terms of the GNU Lesser General Public
6+ * License as published by the Free Software Foundation; either
7+ * version 2.1 of the License, or (at your option) any later version.
8+ *
9+ * Libav 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+ * Lesser General Public License for more details.
13+ *
14+ * You should have received a copy of the GNU Lesser General Public
15+ * License along with Libav; if not, write to the Free Software
16+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17+ */
18+
19+#ifndef AVUTIL_IMGUTILS_INTERNAL_H
20+#define AVUTIL_IMGUTILS_INTERNAL_H
21+
22+#include <stddef.h>
23+#include <stdint.h>
24+
25+int ff_image_copy_plane_uc_from_x86(uint8_t *dst, ptrdiff_t dst_linesize,
26+ const uint8_t *src, ptrdiff_t src_linesize,
27+ ptrdiff_t bytewidth, int height);
28+
29+
30+#endif /* AVUTIL_IMGUTILS_INTERNAL_H */
libavutil/version.h+1−1
@@ -54,7 +54,7 @@ · 53 unmodified lines
5454 */
5555
5656 #define LIBAVUTIL_VERSION_MAJOR 55
57−#define LIBAVUTIL_VERSION_MINOR 20
57+#define LIBAVUTIL_VERSION_MINOR 21
5858 #define LIBAVUTIL_VERSION_MICRO 0
5959
6060 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
libavutil/x86/Makefile+2−0
@@ -1,8 +1,10 @@
11 OBJS += x86/cpu.o \
22 x86/float_dsp_init.o \
3+ x86/imgutils_init.o \
34 x86/lls_init.o \
45
56 YASM-OBJS += x86/cpuid.o \
67 x86/emms.o \
78 x86/float_dsp.o \
9+ x86/imgutils.o \
810 x86/lls.o \
libavutil/x86/imgutils.asm+53−0
@@ -0,0 +1,53 @@
1+;*****************************************************************************
2+;* Copyright 2016 Anton Khirnov
3+;*
4+;* This file is part of Libav.
5+;*
6+;* Libav is free software; you can redistribute it and/or
7+;* modify it under the terms of the GNU Lesser General Public
8+;* License as published by the Free Software Foundation; either
9+;* version 2.1 of the License, or (at your option) any later version.
10+;*
11+;* Libav is distributed in the hope that it will be useful,
12+;* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+;* Lesser General Public License for more details.
15+;*
16+;* You should have received a copy of the GNU Lesser General Public
17+;* License along with Libav; if not, write to the Free Software
18+;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19+;******************************************************************************
20+
21+%include "libavutil/x86/x86util.asm"
22+
23+SECTION .text
24+
25+INIT_XMM sse4
26+cglobal image_copy_plane_uc_from, 6, 7, 4, dst, dst_linesize, src, src_linesize, bw, height, rowpos
27+ add dstq, bwq
28+ add srcq, bwq
29+ neg bwq
30+
31+.row_start
32+ mov rowposq, bwq
33+
34+.loop
35+ movntdqa m0, [srcq + rowposq + 0 * mmsize]
36+ movntdqa m1, [srcq + rowposq + 1 * mmsize]
37+ movntdqa m2, [srcq + rowposq + 2 * mmsize]
38+ movntdqa m3, [srcq + rowposq + 3 * mmsize]
39+
40+ mova [dstq + rowposq + 0 * mmsize], m0
41+ mova [dstq + rowposq + 1 * mmsize], m1
42+ mova [dstq + rowposq + 2 * mmsize], m2
43+ mova [dstq + rowposq + 3 * mmsize], m3
44+
45+ add rowposq, 4 * mmsize
46+ jnz .loop
47+
48+ add srcq, src_linesizeq
49+ add dstq, dst_linesizeq
50+ dec heightd
51+ jnz .row_start
52+
53+ RET
libavutil/x86/imgutils_init.c+49−0
@@ -0,0 +1,49 @@
1+/*
2+ * This file is part of Libav.
3+ *
4+ * Libav is free software; you can redistribute it and/or
5+ * modify it under the terms of the GNU Lesser General Public
6+ * License as published by the Free Software Foundation; either
7+ * version 2.1 of the License, or (at your option) any later version.
8+ *
9+ * Libav 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+ * Lesser General Public License for more details.
13+ *
14+ * You should have received a copy of the GNU Lesser General Public
15+ * License along with Libav; if not, write to the Free Software
16+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17+ */
18+
19+#include <stddef.h>
20+#include <stdint.h>
21+
22+#include "libavutil/cpu.h"
23+#include "libavutil/error.h"
24+#include "libavutil/imgutils.h"
25+#include "libavutil/imgutils_internal.h"
26+#include "libavutil/internal.h"
27+
28+#include "cpu.h"
29+
30+void ff_image_copy_plane_uc_from_sse4(uint8_t *dst, ptrdiff_t dst_linesize,
31+ const uint8_t *src, ptrdiff_t src_linesize,
32+ ptrdiff_t bytewidth, int height);
33+
34+int ff_image_copy_plane_uc_from_x86(uint8_t *dst, ptrdiff_t dst_linesize,
35+ const uint8_t *src, ptrdiff_t src_linesize,
36+ ptrdiff_t bytewidth, int height)
37+{
38+ int cpu_flags = av_get_cpu_flags();
39+ ptrdiff_t bw_aligned = FFALIGN(bytewidth, 64);
40+
41+ if (EXTERNAL_SSE4(cpu_flags) &&
42+ bw_aligned <= dst_linesize && bw_aligned <= src_linesize)
43+ ff_image_copy_plane_uc_from_sse4(dst, dst_linesize, src, src_linesize,
44+ bw_aligned, height);
45+ else
46+ return AVERROR(ENOSYS);
47+
48+ return 0;
49+}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t