1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Microsoft Screen 2 (aka Windows Media Video V9 Screen) decoder 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * This file is part of FFmpeg. 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 9cabdff1aSopenharmony_ci * version 2.1 of the License, or (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 GNU 14cabdff1aSopenharmony_ci * Lesser General Public License for more details. 15cabdff1aSopenharmony_ci * 16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 17cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19cabdff1aSopenharmony_ci */ 20cabdff1aSopenharmony_ci 21cabdff1aSopenharmony_ci/** 22cabdff1aSopenharmony_ci * @file 23cabdff1aSopenharmony_ci * Microsoft Screen 2 (aka Windows Media Video V9 Screen) decoder DSP routines 24cabdff1aSopenharmony_ci */ 25cabdff1aSopenharmony_ci 26cabdff1aSopenharmony_ci#include "mss2dsp.h" 27cabdff1aSopenharmony_ci#include "libavutil/common.h" 28cabdff1aSopenharmony_ci 29cabdff1aSopenharmony_cistatic av_always_inline void mss2_blit_wmv9_template(uint8_t *dst, 30cabdff1aSopenharmony_ci ptrdiff_t dst_stride, 31cabdff1aSopenharmony_ci int gray, 32cabdff1aSopenharmony_ci int use_mask, 33cabdff1aSopenharmony_ci int maskcolor, 34cabdff1aSopenharmony_ci const uint8_t *mask, 35cabdff1aSopenharmony_ci ptrdiff_t mask_stride, 36cabdff1aSopenharmony_ci const uint8_t *srcy, 37cabdff1aSopenharmony_ci ptrdiff_t srcy_stride, 38cabdff1aSopenharmony_ci const uint8_t *srcu, 39cabdff1aSopenharmony_ci const uint8_t *srcv, 40cabdff1aSopenharmony_ci ptrdiff_t srcuv_stride, 41cabdff1aSopenharmony_ci int w, int h) 42cabdff1aSopenharmony_ci{ 43cabdff1aSopenharmony_ci int i, j, k, r = -1; 44cabdff1aSopenharmony_ci while (++r < h) { 45cabdff1aSopenharmony_ci for (i = 0, j = 0, k = 0; i < w; j += (i & 1), i++, k += 3) { 46cabdff1aSopenharmony_ci if (!use_mask || mask[i] == maskcolor) { 47cabdff1aSopenharmony_ci if (gray) { 48cabdff1aSopenharmony_ci dst[k] = dst[k + 1] = dst[k + 2] = 0x80; 49cabdff1aSopenharmony_ci } else { 50cabdff1aSopenharmony_ci int y = srcy[i]; 51cabdff1aSopenharmony_ci int u = srcu[j] - 128; 52cabdff1aSopenharmony_ci int v = srcv[j] - 128; 53cabdff1aSopenharmony_ci dst[k] = av_clip_uint8(y + ( 91881 * v + 32768 >> 16)); 54cabdff1aSopenharmony_ci dst[k + 1] = av_clip_uint8(y + (-22554 * u - 46802 * v + 32768 >> 16)); 55cabdff1aSopenharmony_ci dst[k + 2] = av_clip_uint8(y + (116130 * u + 32768 >> 16)); 56cabdff1aSopenharmony_ci } 57cabdff1aSopenharmony_ci } 58cabdff1aSopenharmony_ci } 59cabdff1aSopenharmony_ci mask += mask_stride; 60cabdff1aSopenharmony_ci dst += dst_stride; 61cabdff1aSopenharmony_ci srcy += srcy_stride; 62cabdff1aSopenharmony_ci srcu += srcuv_stride * (r & 1); 63cabdff1aSopenharmony_ci srcv += srcuv_stride * (r & 1); 64cabdff1aSopenharmony_ci } 65cabdff1aSopenharmony_ci} 66cabdff1aSopenharmony_ci 67cabdff1aSopenharmony_cistatic void mss2_blit_wmv9_c(uint8_t *dst, ptrdiff_t dst_stride, 68cabdff1aSopenharmony_ci const uint8_t *srcy, ptrdiff_t srcy_stride, 69cabdff1aSopenharmony_ci const uint8_t *srcu, const uint8_t *srcv, 70cabdff1aSopenharmony_ci ptrdiff_t srcuv_stride, int w, int h) 71cabdff1aSopenharmony_ci{ 72cabdff1aSopenharmony_ci mss2_blit_wmv9_template(dst, dst_stride, 0, 0, 73cabdff1aSopenharmony_ci 0, NULL, 0, 74cabdff1aSopenharmony_ci srcy, srcy_stride, 75cabdff1aSopenharmony_ci srcu, srcv, srcuv_stride, 76cabdff1aSopenharmony_ci w, h); 77cabdff1aSopenharmony_ci} 78cabdff1aSopenharmony_ci 79cabdff1aSopenharmony_cistatic void mss2_blit_wmv9_masked_c(uint8_t *dst, ptrdiff_t dst_stride, 80cabdff1aSopenharmony_ci int maskcolor, const uint8_t *mask, 81cabdff1aSopenharmony_ci ptrdiff_t mask_stride, 82cabdff1aSopenharmony_ci const uint8_t *srcy, ptrdiff_t srcy_stride, 83cabdff1aSopenharmony_ci const uint8_t *srcu, const uint8_t *srcv, 84cabdff1aSopenharmony_ci ptrdiff_t srcuv_stride, int w, int h) 85cabdff1aSopenharmony_ci{ 86cabdff1aSopenharmony_ci mss2_blit_wmv9_template(dst, dst_stride, 0, 1, 87cabdff1aSopenharmony_ci maskcolor, mask, mask_stride, 88cabdff1aSopenharmony_ci srcy, srcy_stride, 89cabdff1aSopenharmony_ci srcu, srcv, srcuv_stride, 90cabdff1aSopenharmony_ci w, h); 91cabdff1aSopenharmony_ci} 92cabdff1aSopenharmony_ci 93cabdff1aSopenharmony_cistatic void mss2_gray_fill_masked_c(uint8_t *dst, ptrdiff_t dst_stride, 94cabdff1aSopenharmony_ci int maskcolor, const uint8_t *mask, 95cabdff1aSopenharmony_ci ptrdiff_t mask_stride, int w, int h) 96cabdff1aSopenharmony_ci{ 97cabdff1aSopenharmony_ci mss2_blit_wmv9_template(dst, dst_stride, 1, 1, 98cabdff1aSopenharmony_ci maskcolor, mask, mask_stride, 99cabdff1aSopenharmony_ci NULL, 0, 100cabdff1aSopenharmony_ci NULL, NULL, 0, 101cabdff1aSopenharmony_ci w, h); 102cabdff1aSopenharmony_ci} 103cabdff1aSopenharmony_ci 104cabdff1aSopenharmony_cistatic void upsample_plane_c(uint8_t *plane, ptrdiff_t plane_stride, int w, int h) 105cabdff1aSopenharmony_ci{ 106cabdff1aSopenharmony_ci uint8_t *src1, *src2, *dst1, *dst2, *p, a, b; 107cabdff1aSopenharmony_ci int i, j; 108cabdff1aSopenharmony_ci 109cabdff1aSopenharmony_ci if(!w || !h) 110cabdff1aSopenharmony_ci return; 111cabdff1aSopenharmony_ci 112cabdff1aSopenharmony_ci w += (w & 1); 113cabdff1aSopenharmony_ci h += (h & 1); 114cabdff1aSopenharmony_ci 115cabdff1aSopenharmony_ci j = h - 1; 116cabdff1aSopenharmony_ci 117cabdff1aSopenharmony_ci memcpy(plane + plane_stride * j, 118cabdff1aSopenharmony_ci plane + plane_stride * (j >> 1), 119cabdff1aSopenharmony_ci w); 120cabdff1aSopenharmony_ci 121cabdff1aSopenharmony_ci while ((j -= 2) > 0) { 122cabdff1aSopenharmony_ci dst1 = plane + plane_stride * (j + 1); 123cabdff1aSopenharmony_ci dst2 = plane + plane_stride * j; 124cabdff1aSopenharmony_ci src1 = plane + plane_stride * ((j + 1) >> 1); 125cabdff1aSopenharmony_ci src2 = plane + plane_stride * ( j >> 1); 126cabdff1aSopenharmony_ci 127cabdff1aSopenharmony_ci for (i = (w - 1) >> 1; i >= 0; i--) { 128cabdff1aSopenharmony_ci a = src1[i]; 129cabdff1aSopenharmony_ci b = src2[i]; 130cabdff1aSopenharmony_ci dst1[i] = (3 * a + b + 2) >> 2; 131cabdff1aSopenharmony_ci dst2[i] = (a + 3 * b + 2) >> 2; 132cabdff1aSopenharmony_ci } 133cabdff1aSopenharmony_ci } 134cabdff1aSopenharmony_ci 135cabdff1aSopenharmony_ci for (j = h - 1; j >= 0; j--) { 136cabdff1aSopenharmony_ci p = plane + plane_stride * j; 137cabdff1aSopenharmony_ci i = w - 1; 138cabdff1aSopenharmony_ci 139cabdff1aSopenharmony_ci p[i] = p[i >> 1]; 140cabdff1aSopenharmony_ci 141cabdff1aSopenharmony_ci while ((i -= 2) > 0) { 142cabdff1aSopenharmony_ci a = p[ i >> 1]; 143cabdff1aSopenharmony_ci b = p[(i + 1) >> 1]; 144cabdff1aSopenharmony_ci p[i] = (3 * a + b + 1) >> 2; 145cabdff1aSopenharmony_ci p[i + 1] = (a + 3 * b + 1) >> 2; 146cabdff1aSopenharmony_ci } 147cabdff1aSopenharmony_ci } 148cabdff1aSopenharmony_ci} 149cabdff1aSopenharmony_ci 150cabdff1aSopenharmony_ciav_cold void ff_mss2dsp_init(MSS2DSPContext* dsp) 151cabdff1aSopenharmony_ci{ 152cabdff1aSopenharmony_ci dsp->mss2_blit_wmv9 = mss2_blit_wmv9_c; 153cabdff1aSopenharmony_ci dsp->mss2_blit_wmv9_masked = mss2_blit_wmv9_masked_c; 154cabdff1aSopenharmony_ci dsp->mss2_gray_fill_masked = mss2_gray_fill_masked_c; 155cabdff1aSopenharmony_ci dsp->upsample_plane = upsample_plane_c; 156cabdff1aSopenharmony_ci} 157