xref: /third_party/ffmpeg/libavcodec/mss2dsp.c (revision cabdff1a)
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