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 | API changes, most recent first: | 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 | 2016-xx-xx - xxxxxxx - lavc 59.26.0 - vaapi.h | 20 | 2016-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. |
| @@ -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 | ||
| 255 | void av_image_copy_plane(uint8_t *dst, int dst_linesize, | 256 | static 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 | ||
| 268 | void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], | 269 | static 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 | |||
| 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 | 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 | ||
| 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 | int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4], | 352 | int 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) |
| @@ -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 | */ | ||
| 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 | * Setup the data pointers and linesizes based on the specified image | 139 | * Setup the data pointers and linesizes based on the specified image |
| 122 | * parameters and the provided array. | 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 | #define LIBAVUTIL_VERSION_MAJOR 55 | 56 | #define LIBAVUTIL_VERSION_MAJOR 55 |
| 57 | #define LIBAVUTIL_VERSION_MINOR 20 | 57 | #define LIBAVUTIL_VERSION_MINOR 21 |
| 58 | #define LIBAVUTIL_VERSION_MICRO 0 | 58 | #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, \ |
| @@ -1,8 +1,10 @@ | |||
| 1 | OBJS += x86/cpu.o \ | 1 | OBJS += 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 | ||
| 5 | YASM-OBJS += x86/cpuid.o \ | 6 | YASM-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 \ |
| @@ -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 | } | ||