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
13 13
14API changes, most recent first:14API changes, most recent first:
15 15
162016-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
162016-xx-xx - xxxxxxx - lavc 59.26.0 - vaapi.h202016-xx-xx - xxxxxxx - lavc 59.26.0 - vaapi.h
17 Deprecate struct vaapi_context and the vaapi.h installed header.21 Deprecate struct vaapi_context and the vaapi.h installed header.
18 Callers should set AVCodecContext.hw_frames_ctx instead.22 Callers should set AVCodecContext.hw_frames_ctx instead.
libavutil/imgutils.c+62−13
@@ -23,6 +23,7 @@ · 22 unmodified lines
23 23
24#include "common.h"24#include "common.h"
25#include "imgutils.h"25#include "imgutils.h"
26#include "imgutils_internal.h"
26#include "internal.h"27#include "internal.h"
27#include "intreadwrite.h"28#include "intreadwrite.h"
28#include "log.h"29#include "log.h"
@@ -252,9 +253,9 @@ int av_image_check_sar(unsigned int w, unsigned int h, AVRational sar) · 223 unmodified lines
252 return AVERROR(EINVAL);253 return AVERROR(EINVAL);
253}254}
254 255
255void av_image_copy_plane(uint8_t *dst, int dst_linesize,256static void image_copy_plane(uint8_t *dst, ptrdiff_t dst_linesize,
256 const uint8_t *src, int src_linesize,257 const uint8_t *src, ptrdiff_t src_linesize,
257 int bytewidth, int height)258 ptrdiff_t bytewidth, int height)
258{259{
259 if (!dst || !src)260 if (!dst || !src)
260 return;261 return;
@@ -265,9 +266,33 @@ void av_image_copy_plane(uint8_t *dst, int dst_linesize, · 4 unmodified lines
265 }266 }
266}267}
267 268
268void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4],269static void image_copy_plane_uc_from(uint8_t *dst, ptrdiff_t dst_linesize,
269 const uint8_t *src_data[4], const int src_linesizes[4],270 const uint8_t *src, ptrdiff_t src_linesize,
270 enum AVPixelFormat pix_fmt, int width, int height)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
284void 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
291static 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))
271{296{
272 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);297 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
273 298
@@ -276,9 +301,9 @@ void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], · 2 unmodified lines
276 301
277 if (desc->flags & AV_PIX_FMT_FLAG_PAL ||302 if (desc->flags & AV_PIX_FMT_FLAG_PAL ||
278 desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) {303 desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) {
279 av_image_copy_plane(dst_data[0], dst_linesizes[0],304 copy_plane(dst_data[0], dst_linesizes[0],
280 src_data[0], src_linesizes[0],305 src_data[0], src_linesizes[0],
281 width, height);306 width, height);
282 /* copy the palette */307 /* copy the palette */
283 memcpy(dst_data[1], src_data[1], 4*256);308 memcpy(dst_data[1], src_data[1], 4*256);
284 } else {309 } else {
@@ -289,17 +314,41 @@ void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], · 4 unmodified lines
289 314
290 for (i = 0; i < planes_nb; i++) {315 for (i = 0; i < planes_nb; i++) {
291 int h = height;316 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);
293 if (i == 1 || i == 2) {318 if (i == 1 || i == 2) {
294 h = AV_CEIL_RSHIFT(height, desc->log2_chroma_h);319 h = AV_CEIL_RSHIFT(height, desc->log2_chroma_h);
295 }320 }
296 av_image_copy_plane(dst_data[i], dst_linesizes[i],321 copy_plane(dst_data[i], dst_linesizes[i],
297 src_data[i], src_linesizes[i],322 src_data[i], src_linesizes[i],
298 bwidth, h);323 bwidth, h);
299 }324 }
300 }325 }
301}326}
302 327
328void 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
344void 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
303int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4],352int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4],
304 const uint8_t *src, enum AVPixelFormat pix_fmt,353 const uint8_t *src, enum AVPixelFormat pix_fmt,
305 int width, int height, int align)354 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
117 const uint8_t *src_data[4], const int src_linesizes[4],117 const uint8_t *src_data[4], const int src_linesizes[4],
118 enum AVPixelFormat pix_fmt, int width, int height);118 enum AVPixelFormat pix_fmt, int width, int height);
119 119
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 */
134void 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
120/**138/**
121 * Setup the data pointers and linesizes based on the specified image139 * Setup the data pointers and linesizes based on the specified image
122 * parameters and the provided array.140 * 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
25int 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
54 */54 */
55 55
56#define LIBAVUTIL_VERSION_MAJOR 5556#define LIBAVUTIL_VERSION_MAJOR 55
57#define LIBAVUTIL_VERSION_MINOR 2057#define LIBAVUTIL_VERSION_MINOR 21
58#define LIBAVUTIL_VERSION_MICRO 058#define LIBAVUTIL_VERSION_MICRO 0
59 59
60#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \60#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
libavutil/x86/Makefile+2−0
@@ -1,8 +1,10 @@
1OBJS += x86/cpu.o \1OBJS += x86/cpu.o \
2 x86/float_dsp_init.o \2 x86/float_dsp_init.o \
3 x86/imgutils_init.o \
3 x86/lls_init.o \4 x86/lls_init.o \
4 5
5YASM-OBJS += x86/cpuid.o \6YASM-OBJS += x86/cpuid.o \
6 x86/emms.o \7 x86/emms.o \
7 x86/float_dsp.o \8 x86/float_dsp.o \
9 x86/imgutils.o \
8 x86/lls.o \10 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
23SECTION .text
24
25INIT_XMM sse4
26cglobal 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
30void 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
34int 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