See https://software.intel.com/en-us/articles/copying-accelerated-video-decode-frame-buffers
Unified · Split
| @@ -13,6 +13,10 @@ libavutil: 2015-08-28 · 12 unmodified lines | ||
| 13 | 13 | |
| 14 | 14 | API changes, most recent first: |
| 15 | 15 | |
| 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 | + | |
| 16 | 20 | 2016-xx-xx - xxxxxxx - lavc 59.26.0 - vaapi.h |
| 17 | 21 | Deprecate struct vaapi_context and the vaapi.h installed header. |
| 18 | 22 | Callers should set AVCodecContext.hw_frames_ctx instead. |
| @@ -23,6 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | |
| 24 | 24 | #include "common.h" |
| 25 | 25 | #include "imgutils.h" |
| 26 | +#include "imgutils_internal.h" | |
| 26 | 27 | #include "internal.h" |
| 27 | 28 | #include "intreadwrite.h" |
| 28 | 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 | 253 | return AVERROR(EINVAL); |
| 253 | 254 | } |
| 254 | 255 | |
| 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) | |
| 258 | 259 | { |
| 259 | 260 | if (!dst || !src) |
| 260 | 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 | |
| 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)) | |
| 271 | 296 | { |
| 272 | 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 | 302 | if (desc->flags & AV_PIX_FMT_FLAG_PAL || |
| 278 | 303 | 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); | |
| 282 | 307 | /* copy the palette */ |
| 283 | 308 | memcpy(dst_data[1], src_data[1], 4*256); |
| 284 | 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 | 315 | for (i = 0; i < planes_nb; i++) { |
| 291 | 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 | 318 | if (i == 1 || i == 2) { |
| 294 | 319 | h = AV_CEIL_RSHIFT(height, desc->log2_chroma_h); |
| 295 | 320 | } |
| 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); | |
| 299 | 324 | } |
| 300 | 325 | } |
| 301 | 326 | } |
| 302 | 327 | |
| 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 | + | |
| 303 | 352 | int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4], |
| 304 | 353 | const uint8_t *src, enum AVPixelFormat pix_fmt, |
| 305 | 354 | int width, int height, int align) |
| @@ -117,6 +117,24 @@ void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], · 116 unmodified lines | ||
| 117 | 117 | const uint8_t *src_data[4], const int src_linesizes[4], |
| 118 | 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 | + */ | |
| 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 | + | |
| 120 | 138 | /** |
| 121 | 139 | * Setup the data pointers and linesizes based on the specified image |
| 122 | 140 | * parameters and the provided array. |
| @@ -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 */ | |
| @@ -54,7 +54,7 @@ · 53 unmodified lines | ||
| 54 | 54 | */ |
| 55 | 55 | |
| 56 | 56 | #define LIBAVUTIL_VERSION_MAJOR 55 |
| 57 | −#define LIBAVUTIL_VERSION_MINOR 20 | |
| 57 | +#define LIBAVUTIL_VERSION_MINOR 21 | |
| 58 | 58 | #define LIBAVUTIL_VERSION_MICRO 0 |
| 59 | 59 | |
| 60 | 60 | #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ |
| @@ -1,8 +1,10 @@ | ||
| 1 | 1 | OBJS += x86/cpu.o \ |
| 2 | 2 | x86/float_dsp_init.o \ |
| 3 | + x86/imgutils_init.o \ | |
| 3 | 4 | x86/lls_init.o \ |
| 4 | 5 | |
| 5 | 6 | YASM-OBJS += x86/cpuid.o \ |
| 6 | 7 | x86/emms.o \ |
| 7 | 8 | x86/float_dsp.o \ |
| 9 | + x86/imgutils.o \ | |
| 8 | 10 | x86/lls.o \ |
| @@ -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 | |
| @@ -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 | +} | |