1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Copyright (c) 2016 Alexandra Hájková 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * This file is part of FFmpeg. 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or modify 7cabdff1aSopenharmony_ci * it under the terms of the GNU General Public License as published by 8cabdff1aSopenharmony_ci * the Free Software Foundation; either version 2 of the License, or 9cabdff1aSopenharmony_ci * (at your option) any later version. 10cabdff1aSopenharmony_ci * 11cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14cabdff1aSopenharmony_ci * GNU General Public License for more details. 15cabdff1aSopenharmony_ci * 16cabdff1aSopenharmony_ci * You should have received a copy of the GNU General Public License along 17cabdff1aSopenharmony_ci * with FFmpeg; if not, write to the Free Software Foundation, Inc., 18cabdff1aSopenharmony_ci * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19cabdff1aSopenharmony_ci */ 20cabdff1aSopenharmony_ci 21cabdff1aSopenharmony_ci#include <string.h> 22cabdff1aSopenharmony_ci 23cabdff1aSopenharmony_ci#include "libavutil/common.h" 24cabdff1aSopenharmony_ci#include "libavutil/intreadwrite.h" 25cabdff1aSopenharmony_ci#include "libavutil/mem.h" 26cabdff1aSopenharmony_ci 27cabdff1aSopenharmony_ci#include "libavcodec/lossless_videodsp.h" 28cabdff1aSopenharmony_ci 29cabdff1aSopenharmony_ci#include "checkasm.h" 30cabdff1aSopenharmony_ci 31cabdff1aSopenharmony_ci#define randomize_buffers(buf, size) \ 32cabdff1aSopenharmony_ci do { \ 33cabdff1aSopenharmony_ci int j; \ 34cabdff1aSopenharmony_ci uint8_t *tmp_buf = (uint8_t *)buf;\ 35cabdff1aSopenharmony_ci for (j = 0; j < size; j++) \ 36cabdff1aSopenharmony_ci tmp_buf[j] = rnd() & 0xFF; \ 37cabdff1aSopenharmony_ci } while (0) 38cabdff1aSopenharmony_ci 39cabdff1aSopenharmony_ci#define init_buffer(a0, a1, type, width)\ 40cabdff1aSopenharmony_ci if (!a0 || !a1)\ 41cabdff1aSopenharmony_ci fail();\ 42cabdff1aSopenharmony_ci randomize_buffers(a0, width * sizeof(type));\ 43cabdff1aSopenharmony_ci memcpy(a1, a0, width*sizeof(type));\ 44cabdff1aSopenharmony_ci 45cabdff1aSopenharmony_cistatic void check_add_bytes(LLVidDSPContext c, int width) 46cabdff1aSopenharmony_ci{ 47cabdff1aSopenharmony_ci uint8_t *dst0 = av_mallocz(width); 48cabdff1aSopenharmony_ci uint8_t *dst1 = av_mallocz(width); 49cabdff1aSopenharmony_ci uint8_t *src0 = av_calloc(width, sizeof(*src0)); 50cabdff1aSopenharmony_ci uint8_t *src1 = av_calloc(width, sizeof(*src1)); 51cabdff1aSopenharmony_ci declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, uint8_t *src, ptrdiff_t w); 52cabdff1aSopenharmony_ci 53cabdff1aSopenharmony_ci init_buffer(src0, src1, uint8_t, width); 54cabdff1aSopenharmony_ci 55cabdff1aSopenharmony_ci if (!dst0 || !dst1) 56cabdff1aSopenharmony_ci fail(); 57cabdff1aSopenharmony_ci 58cabdff1aSopenharmony_ci 59cabdff1aSopenharmony_ci if (check_func(c.add_bytes, "add_bytes")) { 60cabdff1aSopenharmony_ci call_ref(dst0, src0, width); 61cabdff1aSopenharmony_ci call_new(dst1, src1, width); 62cabdff1aSopenharmony_ci if (memcmp(dst0, dst1, width)) 63cabdff1aSopenharmony_ci fail(); 64cabdff1aSopenharmony_ci bench_new(dst1, src1, width); 65cabdff1aSopenharmony_ci } 66cabdff1aSopenharmony_ci 67cabdff1aSopenharmony_ci av_free(src0); 68cabdff1aSopenharmony_ci av_free(src1); 69cabdff1aSopenharmony_ci av_free(dst0); 70cabdff1aSopenharmony_ci av_free(dst1); 71cabdff1aSopenharmony_ci} 72cabdff1aSopenharmony_ci 73cabdff1aSopenharmony_cistatic void check_add_median_pred(LLVidDSPContext c, int width) { 74cabdff1aSopenharmony_ci int A0, A1, B0, B1; 75cabdff1aSopenharmony_ci uint8_t *dst0 = av_mallocz(width); 76cabdff1aSopenharmony_ci uint8_t *dst1 = av_mallocz(width); 77cabdff1aSopenharmony_ci uint8_t *src0 = av_calloc(width, sizeof(*src0)); 78cabdff1aSopenharmony_ci uint8_t *src1 = av_calloc(width, sizeof(*src1)); 79cabdff1aSopenharmony_ci uint8_t *diff0 = av_calloc(width, sizeof(*diff0)); 80cabdff1aSopenharmony_ci uint8_t *diff1 = av_calloc(width, sizeof(*diff1)); 81cabdff1aSopenharmony_ci declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, const uint8_t *src1, 82cabdff1aSopenharmony_ci const uint8_t *diff, ptrdiff_t w, 83cabdff1aSopenharmony_ci int *left, int *left_top); 84cabdff1aSopenharmony_ci 85cabdff1aSopenharmony_ci init_buffer(src0, src1, uint8_t, width); 86cabdff1aSopenharmony_ci init_buffer(diff0, diff1, uint8_t, width); 87cabdff1aSopenharmony_ci 88cabdff1aSopenharmony_ci A0 = rnd() & 0xFF; 89cabdff1aSopenharmony_ci B0 = rnd() & 0xFF; 90cabdff1aSopenharmony_ci A1 = A0; 91cabdff1aSopenharmony_ci B1 = B0; 92cabdff1aSopenharmony_ci 93cabdff1aSopenharmony_ci 94cabdff1aSopenharmony_ci if (check_func(c.add_median_pred, "add_median_pred")) { 95cabdff1aSopenharmony_ci call_ref(dst0, src0, diff0, width, &A0, &B0); 96cabdff1aSopenharmony_ci call_new(dst1, src1, diff1, width, &A1, &B1); 97cabdff1aSopenharmony_ci if (memcmp(dst0, dst1, width) || (A0 != A1) || (B0 != B1)) 98cabdff1aSopenharmony_ci fail(); 99cabdff1aSopenharmony_ci bench_new(dst1, src1, diff1, width, &A1, &B1); 100cabdff1aSopenharmony_ci } 101cabdff1aSopenharmony_ci 102cabdff1aSopenharmony_ci av_free(src0); 103cabdff1aSopenharmony_ci av_free(src1); 104cabdff1aSopenharmony_ci av_free(diff0); 105cabdff1aSopenharmony_ci av_free(diff1); 106cabdff1aSopenharmony_ci av_free(dst0); 107cabdff1aSopenharmony_ci av_free(dst1); 108cabdff1aSopenharmony_ci} 109cabdff1aSopenharmony_ci 110cabdff1aSopenharmony_cistatic void check_add_left_pred(LLVidDSPContext c, int width, int acc, const char * report) 111cabdff1aSopenharmony_ci{ 112cabdff1aSopenharmony_ci int res0, res1; 113cabdff1aSopenharmony_ci uint8_t *dst0 = av_mallocz(width); 114cabdff1aSopenharmony_ci uint8_t *dst1 = av_mallocz(width); 115cabdff1aSopenharmony_ci uint8_t *src0 = av_calloc(width, sizeof(*src0)); 116cabdff1aSopenharmony_ci uint8_t *src1 = av_calloc(width, sizeof(*src1)); 117cabdff1aSopenharmony_ci declare_func_emms(AV_CPU_FLAG_MMX, int, uint8_t *dst, uint8_t *src, ptrdiff_t w, int acc); 118cabdff1aSopenharmony_ci 119cabdff1aSopenharmony_ci init_buffer(src0, src1, uint8_t, width); 120cabdff1aSopenharmony_ci 121cabdff1aSopenharmony_ci if (!dst0 || !dst1) 122cabdff1aSopenharmony_ci fail(); 123cabdff1aSopenharmony_ci 124cabdff1aSopenharmony_ci if (check_func(c.add_left_pred, "%s", report)) { 125cabdff1aSopenharmony_ci res0 = call_ref(dst0, src0, width, acc); 126cabdff1aSopenharmony_ci res1 = call_new(dst1, src1, width, acc); 127cabdff1aSopenharmony_ci if ((res0 & 0xFF) != (res1 & 0xFF)||\ 128cabdff1aSopenharmony_ci memcmp(dst0, dst1, width)) 129cabdff1aSopenharmony_ci fail(); 130cabdff1aSopenharmony_ci bench_new(dst1, src1, width, acc); 131cabdff1aSopenharmony_ci } 132cabdff1aSopenharmony_ci 133cabdff1aSopenharmony_ci av_free(src0); 134cabdff1aSopenharmony_ci av_free(src1); 135cabdff1aSopenharmony_ci av_free(dst0); 136cabdff1aSopenharmony_ci av_free(dst1); 137cabdff1aSopenharmony_ci} 138cabdff1aSopenharmony_ci 139cabdff1aSopenharmony_cistatic void check_add_left_pred_16(LLVidDSPContext c, unsigned mask, int width, unsigned acc, const char * report) 140cabdff1aSopenharmony_ci{ 141cabdff1aSopenharmony_ci int res0, res1; 142cabdff1aSopenharmony_ci uint16_t *dst0 = av_calloc(width, sizeof(*dst0)); 143cabdff1aSopenharmony_ci uint16_t *dst1 = av_calloc(width, sizeof(*dst1)); 144cabdff1aSopenharmony_ci uint16_t *src0 = av_calloc(width, sizeof(*src0)); 145cabdff1aSopenharmony_ci uint16_t *src1 = av_calloc(width, sizeof(*src1)); 146cabdff1aSopenharmony_ci declare_func_emms(AV_CPU_FLAG_MMX, int, uint16_t *dst, uint16_t *src, unsigned mask, ptrdiff_t w, unsigned acc); 147cabdff1aSopenharmony_ci 148cabdff1aSopenharmony_ci init_buffer(src0, src1, uint16_t, width); 149cabdff1aSopenharmony_ci 150cabdff1aSopenharmony_ci if (!dst0 || !dst1) 151cabdff1aSopenharmony_ci fail(); 152cabdff1aSopenharmony_ci 153cabdff1aSopenharmony_ci if (check_func(c.add_left_pred_int16, "%s", report)) { 154cabdff1aSopenharmony_ci res0 = call_ref(dst0, src0, mask, width, acc); 155cabdff1aSopenharmony_ci res1 = call_new(dst1, src1, mask, width, acc); 156cabdff1aSopenharmony_ci if ((res0 &0xFFFF) != (res1 &0xFFFF)||\ 157cabdff1aSopenharmony_ci memcmp(dst0, dst1, width)) 158cabdff1aSopenharmony_ci fail(); 159cabdff1aSopenharmony_ci bench_new(dst1, src1, mask, width, acc); 160cabdff1aSopenharmony_ci } 161cabdff1aSopenharmony_ci 162cabdff1aSopenharmony_ci av_free(src0); 163cabdff1aSopenharmony_ci av_free(src1); 164cabdff1aSopenharmony_ci av_free(dst0); 165cabdff1aSopenharmony_ci av_free(dst1); 166cabdff1aSopenharmony_ci} 167cabdff1aSopenharmony_ci 168cabdff1aSopenharmony_cistatic void check_add_gradient_pred(LLVidDSPContext c, int w) { 169cabdff1aSopenharmony_ci int src_size, stride; 170cabdff1aSopenharmony_ci uint8_t *src0, *src1; 171cabdff1aSopenharmony_ci declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *src, const ptrdiff_t stride, 172cabdff1aSopenharmony_ci const ptrdiff_t width); 173cabdff1aSopenharmony_ci 174cabdff1aSopenharmony_ci stride = w + 32; 175cabdff1aSopenharmony_ci src_size = (stride + 32) * 2; /* dsp need previous line, and ignore the start of the line */ 176cabdff1aSopenharmony_ci src0 = av_mallocz(src_size); 177cabdff1aSopenharmony_ci src1 = av_mallocz(src_size); 178cabdff1aSopenharmony_ci 179cabdff1aSopenharmony_ci init_buffer(src0, src1, uint8_t, src_size); 180cabdff1aSopenharmony_ci 181cabdff1aSopenharmony_ci if (check_func(c.add_gradient_pred, "add_gradient_pred")) { 182cabdff1aSopenharmony_ci call_ref(src0 + stride + 32, stride, w); 183cabdff1aSopenharmony_ci call_new(src1 + stride + 32, stride, w); 184cabdff1aSopenharmony_ci if (memcmp(src0, src1, stride)||/* previous line doesn't change */ 185cabdff1aSopenharmony_ci memcmp(src0+stride, src1 + stride, w + 32)) { 186cabdff1aSopenharmony_ci fail(); 187cabdff1aSopenharmony_ci } 188cabdff1aSopenharmony_ci bench_new(src1 + stride + 32, stride, w); 189cabdff1aSopenharmony_ci } 190cabdff1aSopenharmony_ci 191cabdff1aSopenharmony_ci av_free(src0); 192cabdff1aSopenharmony_ci av_free(src1); 193cabdff1aSopenharmony_ci} 194cabdff1aSopenharmony_ci 195cabdff1aSopenharmony_civoid checkasm_check_llviddsp(void) 196cabdff1aSopenharmony_ci{ 197cabdff1aSopenharmony_ci LLVidDSPContext c; 198cabdff1aSopenharmony_ci int width = 16 * av_clip(rnd(), 16, 128); 199cabdff1aSopenharmony_ci int accRnd = rnd() & 0xFF; 200cabdff1aSopenharmony_ci 201cabdff1aSopenharmony_ci ff_llviddsp_init(&c); 202cabdff1aSopenharmony_ci 203cabdff1aSopenharmony_ci check_add_bytes(c, width); 204cabdff1aSopenharmony_ci report("add_bytes"); 205cabdff1aSopenharmony_ci 206cabdff1aSopenharmony_ci check_add_median_pred(c, width); 207cabdff1aSopenharmony_ci report("add_median_pred"); 208cabdff1aSopenharmony_ci 209cabdff1aSopenharmony_ci check_add_left_pred(c, width, 0, "add_left_pred_zero"); 210cabdff1aSopenharmony_ci report("add_left_pred_zero"); 211cabdff1aSopenharmony_ci 212cabdff1aSopenharmony_ci check_add_left_pred(c, width, accRnd, "add_left_pred_rnd_acc"); 213cabdff1aSopenharmony_ci report("add_left_pred_rnd_acc"); 214cabdff1aSopenharmony_ci 215cabdff1aSopenharmony_ci check_add_left_pred_16(c, 255, width, accRnd, "add_left_pred_int16"); 216cabdff1aSopenharmony_ci report("add_left_pred_int16"); 217cabdff1aSopenharmony_ci 218cabdff1aSopenharmony_ci check_add_gradient_pred(c, width); 219cabdff1aSopenharmony_ci report("add_gradient_pred"); 220cabdff1aSopenharmony_ci} 221