1/* 2 * Copyright (c) 2016 Alexandra Hájková 3 * 4 * This file is part of FFmpeg. 5 * 6 * FFmpeg is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * FFmpeg 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 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License along 17 * with FFmpeg; if not, write to the Free Software Foundation, Inc., 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 */ 20 21#include <string.h> 22 23#include "libavutil/common.h" 24#include "libavutil/intreadwrite.h" 25#include "libavutil/mem_internal.h" 26 27#include "libavcodec/lossless_videoencdsp.h" 28 29#include "checkasm.h" 30 31#define randomize_buffers(buf, size) \ 32 do { \ 33 int j; \ 34 for (j = 0; j < size; j+=4) \ 35 AV_WN32(buf + j, rnd()); \ 36 } while (0) 37 38static const struct {uint8_t w, h, s;} planes[] = { 39 {16,16,16}, {21,23,25}, {32,17,48}, {15,128,16}, {128,127,128} 40}; 41 42#define MAX_STRIDE 128 43#define MAX_HEIGHT 127 44 45static void check_diff_bytes(LLVidEncDSPContext *c) 46{ 47 int i; 48 LOCAL_ALIGNED_32(uint8_t, dst0, [MAX_STRIDE]); 49 LOCAL_ALIGNED_32(uint8_t, dst1, [MAX_STRIDE]); 50 LOCAL_ALIGNED_32(uint8_t, src0, [MAX_STRIDE]); 51 LOCAL_ALIGNED_32(uint8_t, src1, [MAX_STRIDE]); 52 LOCAL_ALIGNED_32(uint8_t, src2, [MAX_STRIDE]); 53 LOCAL_ALIGNED_32(uint8_t, src3, [MAX_STRIDE]); 54 55 declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, const uint8_t *src1, 56 const uint8_t *src2, intptr_t w); 57 58 memset(dst0, 0, MAX_STRIDE); 59 memset(dst1, 0, MAX_STRIDE); 60 randomize_buffers(src0, MAX_STRIDE); 61 memcpy(src1, src0, MAX_STRIDE); 62 randomize_buffers(src2, MAX_STRIDE); 63 memcpy(src3, src2, MAX_STRIDE); 64 65 if (check_func(c->diff_bytes, "diff_bytes")) { 66 for (i = 0; i < 5; i ++) { 67 call_ref(dst0, src0, src2, planes[i].w); 68 call_new(dst1, src1, src3, planes[i].w); 69 if (memcmp(dst0, dst1, planes[i].w)) 70 fail(); 71 } 72 bench_new(dst1, src0, src2, planes[4].w); 73 } 74} 75 76static void check_sub_left_pred(LLVidEncDSPContext *c) 77{ 78 int i; 79 LOCAL_ALIGNED_32(uint8_t, dst0, [MAX_STRIDE * MAX_HEIGHT]); 80 LOCAL_ALIGNED_32(uint8_t, dst1, [MAX_STRIDE * MAX_HEIGHT]); 81 LOCAL_ALIGNED_32(uint8_t, src0, [MAX_STRIDE * MAX_HEIGHT]); 82 LOCAL_ALIGNED_32(uint8_t, src1, [MAX_STRIDE * MAX_HEIGHT]); 83 84 declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, const uint8_t *src, 85 ptrdiff_t stride, ptrdiff_t width, int height); 86 87 memset(dst0, 0, MAX_STRIDE * MAX_HEIGHT); 88 memset(dst1, 0, MAX_STRIDE * MAX_HEIGHT); 89 randomize_buffers(src0, MAX_STRIDE * MAX_HEIGHT); 90 memcpy(src1, src0, MAX_STRIDE * MAX_HEIGHT); 91 92 if (check_func(c->sub_left_predict, "sub_left_predict")) { 93 for (i = 0; i < 5; i ++) { 94 call_ref(dst0, src0, planes[i].s, planes[i].w, planes[i].h); 95 call_new(dst1, src1, planes[i].s, planes[i].w, planes[i].h); 96 if (memcmp(dst0, dst1, planes[i].w * planes[i].h)) 97 fail(); 98 break; 99 } 100 bench_new(dst1, src0, planes[4].s, planes[4].w, planes[4].h); 101 } 102} 103 104void checkasm_check_llviddspenc(void) 105{ 106 LLVidEncDSPContext c; 107 ff_llvidencdsp_init(&c); 108 109 check_diff_bytes(&c); 110 report("diff_bytes"); 111 112 check_sub_left_pred(&c); 113 report("sub_left_predict"); 114} 115