Coverage Report

Created: 2025-03-04 07:22

/src/serenity/Userland/Libraries/LibMedia/VideoFrame.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2022, Gregory Bertilson <zaggy1024@gmail.com>
3
 *
4
 * SPDX-License-Identifier: BSD-2-Clause
5
 */
6
7
#include <AK/NonnullOwnPtr.h>
8
#include <AK/OwnPtr.h>
9
#include <LibMedia/Color/ColorConverter.h>
10
11
#include "VideoFrame.h"
12
13
namespace Media {
14
15
ErrorOr<NonnullOwnPtr<SubsampledYUVFrame>> SubsampledYUVFrame::try_create(
16
    Duration timestamp,
17
    Gfx::Size<u32> size,
18
    u8 bit_depth, CodingIndependentCodePoints cicp,
19
    Subsampling subsampling)
20
1.39k
{
21
1.39k
    VERIFY(bit_depth < 16);
22
1.39k
    size_t component_size = bit_depth > 8 ? sizeof(u16) : sizeof(u8);
23
1.39k
    size_t alignment_size = max(bit_depth > 8 ? sizeof(u16) : sizeof(u8), sizeof(void*));
24
25
4.18k
    auto alloc_buffer = [&](size_t size) -> ErrorOr<u8*> {
26
4.18k
        void* buffer = nullptr;
27
4.18k
        auto result = posix_memalign(&buffer, alignment_size, size);
28
4.18k
        if (result != 0)
29
0
            return Error::from_errno(result);
30
4.18k
        return reinterpret_cast<u8*>(buffer);
31
4.18k
    };
32
33
1.39k
    auto y_data_size = size.to_type<size_t>().area() * component_size;
34
1.39k
    auto uv_data_size = subsampling.subsampled_size(size).to_type<size_t>().area() * component_size;
35
1.39k
    auto* y_buffer = TRY(alloc_buffer(y_data_size));
36
1.39k
    auto* u_buffer = TRY(alloc_buffer(uv_data_size));
37
1.39k
    auto* v_buffer = TRY(alloc_buffer(uv_data_size));
38
39
0
    return adopt_nonnull_own_or_enomem(new (nothrow) SubsampledYUVFrame(timestamp, size, bit_depth, cicp, subsampling, y_buffer, u_buffer, v_buffer));
40
1.39k
}
41
42
ErrorOr<NonnullOwnPtr<SubsampledYUVFrame>> SubsampledYUVFrame::try_create_from_data(
43
    Duration timestamp,
44
    Gfx::Size<u32> size,
45
    u8 bit_depth, CodingIndependentCodePoints cicp,
46
    Subsampling subsampling,
47
    ReadonlyBytes y_data, ReadonlyBytes u_data, ReadonlyBytes v_data)
48
0
{
49
0
    auto frame = TRY(try_create(timestamp, size, bit_depth, cicp, subsampling));
50
51
0
    size_t component_size = bit_depth > 8 ? sizeof(u16) : sizeof(u8);
52
0
    auto y_data_size = size.to_type<size_t>().area() * component_size;
53
0
    auto uv_data_size = subsampling.subsampled_size(size).to_type<size_t>().area() * component_size;
54
55
0
    VERIFY(y_data.size() >= y_data_size);
56
0
    VERIFY(u_data.size() >= uv_data_size);
57
0
    VERIFY(v_data.size() >= uv_data_size);
58
59
0
    memcpy(frame->m_y_buffer, y_data.data(), y_data_size);
60
0
    memcpy(frame->m_u_buffer, u_data.data(), uv_data_size);
61
0
    memcpy(frame->m_v_buffer, v_data.data(), uv_data_size);
62
0
    return frame;
63
0
}
64
65
SubsampledYUVFrame::~SubsampledYUVFrame()
66
1.39k
{
67
1.39k
    free(m_y_buffer);
68
1.39k
    free(m_u_buffer);
69
1.39k
    free(m_v_buffer);
70
1.39k
}
71
72
template<u32 subsampling_horizontal, typename T>
73
ALWAYS_INLINE void interpolate_row(u32 const row, u32 const width, T const* plane_u, T const* plane_v, T* __restrict__ u_row, T* __restrict__ v_row)
74
0
{
75
    // OPTIMIZATION: __restrict__ allows some load eliminations because the planes and the rows will not alias.
76
77
0
    constexpr auto horizontal_step = 1u << subsampling_horizontal;
78
0
    auto const uv_width = (width + subsampling_horizontal) >> subsampling_horizontal;
79
    // Set the first column to the first chroma samples.
80
0
    u_row[0] = plane_u[row * uv_width];
81
0
    v_row[0] = plane_v[row * uv_width];
82
83
0
    auto const columns_end = width - subsampling_horizontal;
84
    // Interpolate the inner chroma columns.
85
0
    for (u32 column = 1; column < columns_end; column += horizontal_step) {
86
0
        auto uv_column = column >> subsampling_horizontal;
87
0
        u_row[column] = plane_u[row * uv_width + uv_column];
88
0
        v_row[column] = plane_v[row * uv_width + uv_column];
89
90
0
        if constexpr (subsampling_horizontal != 0) {
91
0
            u_row[column + 1] = (plane_u[row * uv_width + uv_column] + plane_u[row * uv_width + uv_column + 1]) >> 1;
92
0
            v_row[column + 1] = (plane_v[row * uv_width + uv_column] + plane_v[row * uv_width + uv_column + 1]) >> 1;
93
0
        }
94
0
    }
95
96
    // If there is a last chroma sample that hasn't been set above, set it now.
97
0
    if constexpr (subsampling_horizontal != 0) {
98
0
        if ((width & 1) == 0) {
99
0
            u_row[width - 1] = u_row[width - 2];
100
0
            v_row[width - 1] = v_row[width - 2];
101
0
        }
102
0
    }
103
0
}
Unexecuted instantiation: void Media::interpolate_row<1u, unsigned char>(unsigned int, unsigned int, unsigned char const*, unsigned char const*, unsigned char*, unsigned char*)
Unexecuted instantiation: void Media::interpolate_row<1u, unsigned short>(unsigned int, unsigned int, unsigned short const*, unsigned short const*, unsigned short*, unsigned short*)
Unexecuted instantiation: void Media::interpolate_row<0u, unsigned char>(unsigned int, unsigned int, unsigned char const*, unsigned char const*, unsigned char*, unsigned char*)
Unexecuted instantiation: void Media::interpolate_row<0u, unsigned short>(unsigned int, unsigned int, unsigned short const*, unsigned short const*, unsigned short*, unsigned short*)
104
105
template<u32 subsampling_horizontal, u32 subsampling_vertical, typename T, typename Convert>
106
ALWAYS_INLINE DecoderErrorOr<void> convert_to_bitmap_subsampled(Convert convert, u32 const width, u32 const height, T const* plane_y, T const* plane_u, T const* plane_v, Gfx::Bitmap& bitmap)
107
0
{
108
0
    VERIFY(bitmap.width() >= 0);
109
0
    VERIFY(bitmap.height() >= 0);
110
0
    VERIFY(static_cast<u32>(bitmap.width()) == width);
111
0
    VERIFY(static_cast<u32>(bitmap.height()) == height);
112
113
0
    auto temporary_buffer = DECODER_TRY_ALLOC(FixedArray<T>::create(static_cast<size_t>(width) * 4));
114
115
    // Above rows
116
0
    auto* u_row_a = temporary_buffer.span().slice(static_cast<size_t>(width) * 0, width).data();
117
0
    auto* v_row_a = temporary_buffer.span().slice(static_cast<size_t>(width) * 1, width).data();
118
119
    // Below rows
120
0
    auto* u_row_b = temporary_buffer.span().slice(static_cast<size_t>(width) * 2, width).data();
121
0
    auto* v_row_b = temporary_buffer.span().slice(static_cast<size_t>(width) * 3, width).data();
122
123
0
    u32 const vertical_step = 1 << subsampling_vertical;
124
125
0
    interpolate_row<subsampling_horizontal>(0, width, plane_u, plane_v, u_row_a, v_row_a);
126
127
    // Do interpolation for all inner rows.
128
0
    u32 const rows_end = height - subsampling_vertical;
129
0
    for (u32 row = 0; row < rows_end; row += vertical_step) {
130
        // Horizontally scale the row if subsampled.
131
0
        auto uv_row = row >> subsampling_vertical;
132
0
        interpolate_row<subsampling_horizontal>(uv_row, width, plane_u, plane_v, u_row_b, v_row_b);
133
134
        // If subsampled vertically, vertically interpolate the middle row between the above and below rows.
135
0
        if constexpr (subsampling_vertical != 0) {
136
            // OPTIMIZATION: Splitting these two lines into separate loops enables vectorization.
137
0
            for (u32 column = 0; column < width; column++) {
138
0
                u_row_a[column] = (u_row_a[column] + u_row_b[column]) >> 1;
139
0
            }
140
0
            for (u32 column = 0; column < width; column++) {
141
0
                v_row_a[column] = (v_row_a[column] + v_row_b[column]) >> 1;
142
0
            }
143
0
        }
144
145
0
        auto const* y_row_a = &plane_y[static_cast<size_t>(row) * width];
146
0
        auto* scan_line_a = bitmap.scanline(static_cast<int>(row));
147
148
0
        for (size_t column = 0; column < width; column++) {
149
0
            scan_line_a[column] = convert(y_row_a[column], u_row_a[column], v_row_a[column]).value();
150
0
        }
151
0
        if constexpr (subsampling_vertical != 0) {
152
0
            auto const* y_row_b = &plane_y[static_cast<size_t>(row + 1) * width];
153
0
            auto* scan_line_b = bitmap.scanline(static_cast<int>(row + 1));
154
0
            for (size_t column = 0; column < width; column++) {
155
0
                scan_line_b[column] = convert(y_row_b[column], u_row_b[column], v_row_b[column]).value();
156
0
            }
157
0
        }
158
159
0
        AK::TypedTransfer<RemoveReference<decltype(*u_row_a)>>::move(u_row_a, u_row_b, width);
160
0
        AK::TypedTransfer<RemoveReference<decltype(*u_row_a)>>::move(v_row_a, v_row_b, width);
161
0
    }
162
163
0
    if constexpr (subsampling_vertical != 0) {
164
        // If there is a final row that hasn't been set above, convert it now.
165
0
        if ((height & 1) == 0) {
166
0
            auto const* y_row = &plane_y[static_cast<size_t>(height - 1) * width];
167
0
            auto* scan_line = bitmap.scanline(static_cast<int>(height - 1));
168
0
            for (size_t column = 0; column < width; column++) {
169
0
                scan_line[column] = convert(y_row[column], u_row_a[column], v_row_a[column]).value();
170
0
            }
171
0
        }
172
0
    }
173
174
0
    return {};
175
0
}
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_subsampled<1u, 1u, unsigned char, Media::convert_to_bitmap_selecting_converter<1u, 1u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#1}>(Media::convert_to_bitmap_selecting_converter<1u, 1u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#1}, unsigned int, unsigned int, unsigned char const*, unsigned char const, unsigned char const, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_subsampled<1u, 1u, unsigned char, Media::convert_to_bitmap_selecting_converter<1u, 1u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#2}>(Media::convert_to_bitmap_selecting_converter<1u, 1u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#2}, unsigned int, unsigned int, unsigned char const*, unsigned char const, unsigned char const, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_subsampled<1u, 1u, unsigned char, Media::convert_to_bitmap_selecting_converter<1u, 1u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#3}>(Media::convert_to_bitmap_selecting_converter<1u, 1u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#3}, unsigned int, unsigned int, unsigned char const*, unsigned char const, unsigned char const, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_subsampled<1u, 1u, unsigned short, Media::convert_to_bitmap_selecting_converter<1u, 1u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#1}>(Media::convert_to_bitmap_selecting_converter<1u, 1u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#1}, unsigned int, unsigned int, unsigned short const*, unsigned short const, unsigned short const, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_subsampled<1u, 1u, unsigned short, Media::convert_to_bitmap_selecting_converter<1u, 1u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#2}>(Media::convert_to_bitmap_selecting_converter<1u, 1u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#2}, unsigned int, unsigned int, unsigned short const*, unsigned short const, unsigned short const, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_subsampled<1u, 1u, unsigned short, Media::convert_to_bitmap_selecting_converter<1u, 1u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#3}>(Media::convert_to_bitmap_selecting_converter<1u, 1u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#3}, unsigned int, unsigned int, unsigned short const*, unsigned short const, unsigned short const, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_subsampled<1u, 0u, unsigned char, Media::convert_to_bitmap_selecting_converter<1u, 0u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#1}>(Media::convert_to_bitmap_selecting_converter<1u, 0u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#1}, unsigned int, unsigned int, unsigned char const*, unsigned char const, unsigned char const, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_subsampled<1u, 0u, unsigned char, Media::convert_to_bitmap_selecting_converter<1u, 0u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#2}>(Media::convert_to_bitmap_selecting_converter<1u, 0u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#2}, unsigned int, unsigned int, unsigned char const*, unsigned char const, unsigned char const, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_subsampled<1u, 0u, unsigned char, Media::convert_to_bitmap_selecting_converter<1u, 0u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#3}>(Media::convert_to_bitmap_selecting_converter<1u, 0u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#3}, unsigned int, unsigned int, unsigned char const*, unsigned char const, unsigned char const, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_subsampled<1u, 0u, unsigned short, Media::convert_to_bitmap_selecting_converter<1u, 0u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#1}>(Media::convert_to_bitmap_selecting_converter<1u, 0u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#1}, unsigned int, unsigned int, unsigned short const*, unsigned short const, unsigned short const, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_subsampled<1u, 0u, unsigned short, Media::convert_to_bitmap_selecting_converter<1u, 0u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#2}>(Media::convert_to_bitmap_selecting_converter<1u, 0u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#2}, unsigned int, unsigned int, unsigned short const*, unsigned short const, unsigned short const, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_subsampled<1u, 0u, unsigned short, Media::convert_to_bitmap_selecting_converter<1u, 0u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#3}>(Media::convert_to_bitmap_selecting_converter<1u, 0u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#3}, unsigned int, unsigned int, unsigned short const*, unsigned short const, unsigned short const, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_subsampled<0u, 1u, unsigned char, Media::convert_to_bitmap_selecting_converter<0u, 1u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#1}>(Media::convert_to_bitmap_selecting_converter<0u, 1u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#1}, unsigned int, unsigned int, unsigned char const*, unsigned char const, unsigned char const, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_subsampled<0u, 1u, unsigned char, Media::convert_to_bitmap_selecting_converter<0u, 1u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#2}>(Media::convert_to_bitmap_selecting_converter<0u, 1u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#2}, unsigned int, unsigned int, unsigned char const*, unsigned char const, unsigned char const, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_subsampled<0u, 1u, unsigned char, Media::convert_to_bitmap_selecting_converter<0u, 1u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#3}>(Media::convert_to_bitmap_selecting_converter<0u, 1u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#3}, unsigned int, unsigned int, unsigned char const*, unsigned char const, unsigned char const, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_subsampled<0u, 1u, unsigned short, Media::convert_to_bitmap_selecting_converter<0u, 1u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#1}>(Media::convert_to_bitmap_selecting_converter<0u, 1u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#1}, unsigned int, unsigned int, unsigned short const*, unsigned short const, unsigned short const, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_subsampled<0u, 1u, unsigned short, Media::convert_to_bitmap_selecting_converter<0u, 1u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#2}>(Media::convert_to_bitmap_selecting_converter<0u, 1u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#2}, unsigned int, unsigned int, unsigned short const*, unsigned short const, unsigned short const, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_subsampled<0u, 1u, unsigned short, Media::convert_to_bitmap_selecting_converter<0u, 1u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#3}>(Media::convert_to_bitmap_selecting_converter<0u, 1u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#3}, unsigned int, unsigned int, unsigned short const*, unsigned short const, unsigned short const, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_subsampled<0u, 0u, unsigned char, Media::convert_to_bitmap_selecting_converter<0u, 0u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#1}>(Media::convert_to_bitmap_selecting_converter<0u, 0u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#1}, unsigned int, unsigned int, unsigned char const*, unsigned char const, unsigned char const, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_subsampled<0u, 0u, unsigned char, Media::convert_to_bitmap_selecting_converter<0u, 0u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#2}>(Media::convert_to_bitmap_selecting_converter<0u, 0u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#2}, unsigned int, unsigned int, unsigned char const*, unsigned char const, unsigned char const, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_subsampled<0u, 0u, unsigned char, Media::convert_to_bitmap_selecting_converter<0u, 0u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#3}>(Media::convert_to_bitmap_selecting_converter<0u, 0u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#3}, unsigned int, unsigned int, unsigned char const*, unsigned char const, unsigned char const, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_subsampled<0u, 0u, unsigned short, Media::convert_to_bitmap_selecting_converter<0u, 0u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#1}>(Media::convert_to_bitmap_selecting_converter<0u, 0u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#1}, unsigned int, unsigned int, unsigned short const*, unsigned short const, unsigned short const, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_subsampled<0u, 0u, unsigned short, Media::convert_to_bitmap_selecting_converter<0u, 0u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#2}>(Media::convert_to_bitmap_selecting_converter<0u, 0u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#2}, unsigned int, unsigned int, unsigned short const*, unsigned short const, unsigned short const, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_subsampled<0u, 0u, unsigned short, Media::convert_to_bitmap_selecting_converter<0u, 0u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#3}>(Media::convert_to_bitmap_selecting_converter<0u, 0u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#3}, unsigned int, unsigned int, unsigned short const*, unsigned short const, unsigned short const, Gfx::Bitmap&)
176
177
template<u32 subsampling_horizontal, u32 subsampling_vertical, typename T>
178
static ALWAYS_INLINE DecoderErrorOr<void> convert_to_bitmap_selecting_converter(CodingIndependentCodePoints cicp, u8 bit_depth, u32 const width, u32 const height, void* plane_y_data, void* plane_u_data, void* plane_v_data, Gfx::Bitmap& bitmap)
179
0
{
180
0
    auto const* plane_y = reinterpret_cast<T const*>(plane_y_data);
181
0
    auto const* plane_u = reinterpret_cast<T const*>(plane_u_data);
182
0
    auto const* plane_v = reinterpret_cast<T const*>(plane_v_data);
183
184
0
    constexpr auto output_cicp = CodingIndependentCodePoints(ColorPrimaries::BT709, TransferCharacteristics::SRGB, MatrixCoefficients::BT709, VideoFullRangeFlag::Full);
185
186
0
    if (bit_depth == 8 && cicp.transfer_characteristics() == output_cicp.transfer_characteristics() && cicp.color_primaries() == output_cicp.color_primaries() && cicp.video_full_range_flag() == VideoFullRangeFlag::Studio) {
187
0
        switch (cicp.matrix_coefficients()) {
188
0
        case MatrixCoefficients::BT470BG:
189
0
        case MatrixCoefficients::BT601:
190
0
            return convert_to_bitmap_subsampled<subsampling_horizontal, subsampling_vertical>([](T y, T u, T v) { return ColorConverter::convert_simple_yuv_to_rgb<MatrixCoefficients::BT601, VideoFullRangeFlag::Studio>(y, u, v); }, width, height, plane_y, plane_u, plane_v, bitmap);
Unexecuted instantiation: VideoFrame.cpp:Media::convert_to_bitmap_selecting_converter<1u, 1u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#1}::operator()(unsigned char, unsigned char, unsigned char) const
Unexecuted instantiation: VideoFrame.cpp:Media::convert_to_bitmap_selecting_converter<1u, 1u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#1}::operator()(unsigned short, unsigned short, unsigned short) const
Unexecuted instantiation: VideoFrame.cpp:Media::convert_to_bitmap_selecting_converter<1u, 0u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#1}::operator()(unsigned char, unsigned char, unsigned char) const
Unexecuted instantiation: VideoFrame.cpp:Media::convert_to_bitmap_selecting_converter<1u, 0u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#1}::operator()(unsigned short, unsigned short, unsigned short) const
Unexecuted instantiation: VideoFrame.cpp:Media::convert_to_bitmap_selecting_converter<0u, 1u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#1}::operator()(unsigned char, unsigned char, unsigned char) const
Unexecuted instantiation: VideoFrame.cpp:Media::convert_to_bitmap_selecting_converter<0u, 1u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#1}::operator()(unsigned short, unsigned short, unsigned short) const
Unexecuted instantiation: VideoFrame.cpp:Media::convert_to_bitmap_selecting_converter<0u, 0u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#1}::operator()(unsigned char, unsigned char, unsigned char) const
Unexecuted instantiation: VideoFrame.cpp:Media::convert_to_bitmap_selecting_converter<0u, 0u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#1}::operator()(unsigned short, unsigned short, unsigned short) const
191
0
        case MatrixCoefficients::BT709:
192
0
            return convert_to_bitmap_subsampled<subsampling_horizontal, subsampling_vertical>([](T y, T u, T v) { return ColorConverter::convert_simple_yuv_to_rgb<MatrixCoefficients::BT709, VideoFullRangeFlag::Studio>(y, u, v); }, width, height, plane_y, plane_u, plane_v, bitmap);
Unexecuted instantiation: VideoFrame.cpp:Media::convert_to_bitmap_selecting_converter<1u, 1u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#2}::operator()(unsigned char, unsigned char, unsigned char) const
Unexecuted instantiation: VideoFrame.cpp:Media::convert_to_bitmap_selecting_converter<1u, 1u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#2}::operator()(unsigned short, unsigned short, unsigned short) const
Unexecuted instantiation: VideoFrame.cpp:Media::convert_to_bitmap_selecting_converter<1u, 0u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#2}::operator()(unsigned char, unsigned char, unsigned char) const
Unexecuted instantiation: VideoFrame.cpp:Media::convert_to_bitmap_selecting_converter<1u, 0u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#2}::operator()(unsigned short, unsigned short, unsigned short) const
Unexecuted instantiation: VideoFrame.cpp:Media::convert_to_bitmap_selecting_converter<0u, 1u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#2}::operator()(unsigned char, unsigned char, unsigned char) const
Unexecuted instantiation: VideoFrame.cpp:Media::convert_to_bitmap_selecting_converter<0u, 1u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#2}::operator()(unsigned short, unsigned short, unsigned short) const
Unexecuted instantiation: VideoFrame.cpp:Media::convert_to_bitmap_selecting_converter<0u, 0u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#2}::operator()(unsigned char, unsigned char, unsigned char) const
Unexecuted instantiation: VideoFrame.cpp:Media::convert_to_bitmap_selecting_converter<0u, 0u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#2}::operator()(unsigned short, unsigned short, unsigned short) const
193
0
        default:
194
0
            break;
195
0
        }
196
0
    }
197
198
0
    auto converter = TRY(ColorConverter::create(bit_depth, cicp, output_cicp));
199
0
    return convert_to_bitmap_subsampled<subsampling_horizontal, subsampling_vertical>([&](T y, T u, T v) { return converter.convert_yuv(y, u, v); }, width, height, plane_y, plane_u, plane_v, bitmap);
Unexecuted instantiation: VideoFrame.cpp:Media::convert_to_bitmap_selecting_converter<1u, 1u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#3}::operator()(unsigned char, unsigned char, unsigned char) const
Unexecuted instantiation: VideoFrame.cpp:Media::convert_to_bitmap_selecting_converter<1u, 1u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#3}::operator()(unsigned short, unsigned short, unsigned short) const
Unexecuted instantiation: VideoFrame.cpp:Media::convert_to_bitmap_selecting_converter<1u, 0u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#3}::operator()(unsigned char, unsigned char, unsigned char) const
Unexecuted instantiation: VideoFrame.cpp:Media::convert_to_bitmap_selecting_converter<1u, 0u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#3}::operator()(unsigned short, unsigned short, unsigned short) const
Unexecuted instantiation: VideoFrame.cpp:Media::convert_to_bitmap_selecting_converter<0u, 1u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#3}::operator()(unsigned char, unsigned char, unsigned char) const
Unexecuted instantiation: VideoFrame.cpp:Media::convert_to_bitmap_selecting_converter<0u, 1u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#3}::operator()(unsigned short, unsigned short, unsigned short) const
Unexecuted instantiation: VideoFrame.cpp:Media::convert_to_bitmap_selecting_converter<0u, 0u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned char, unsigned char, unsigned char)#3}::operator()(unsigned char, unsigned char, unsigned char) const
Unexecuted instantiation: VideoFrame.cpp:Media::convert_to_bitmap_selecting_converter<0u, 0u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)::{lambda(unsigned short, unsigned short, unsigned short)#3}::operator()(unsigned short, unsigned short, unsigned short) const
200
0
}
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_selecting_converter<1u, 1u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_selecting_converter<1u, 1u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_selecting_converter<1u, 0u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_selecting_converter<1u, 0u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_selecting_converter<0u, 1u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_selecting_converter<0u, 1u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_selecting_converter<0u, 0u, unsigned char>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_selecting_converter<0u, 0u, unsigned short>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)
201
202
template<u32 subsampling_horizontal, u32 subsampling_vertical>
203
static ALWAYS_INLINE DecoderErrorOr<void> convert_to_bitmap_selecting_bit_depth(CodingIndependentCodePoints cicp, u8 bit_depth, u32 const width, u32 const height, void* plane_y_data, void* plane_u_data, void* plane_v_data, Gfx::Bitmap& bitmap)
204
0
{
205
0
    if (bit_depth <= 8) {
206
0
        return convert_to_bitmap_selecting_converter<subsampling_horizontal, subsampling_vertical, u8>(cicp, bit_depth, width, height, plane_y_data, plane_u_data, plane_v_data, bitmap);
207
0
    }
208
209
0
    return convert_to_bitmap_selecting_converter<subsampling_horizontal, subsampling_vertical, u16>(cicp, bit_depth, width, height, plane_y_data, plane_u_data, plane_v_data, bitmap);
210
0
}
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_selecting_bit_depth<1u, 1u>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_selecting_bit_depth<1u, 0u>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_selecting_bit_depth<0u, 1u>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)
Unexecuted instantiation: VideoFrame.cpp:AK::ErrorOr<void, Media::DecoderError> Media::convert_to_bitmap_selecting_bit_depth<0u, 0u>(Media::CodingIndependentCodePoints, unsigned char, unsigned int, unsigned int, void*, void*, void*, Gfx::Bitmap&)
211
212
static DecoderErrorOr<void> convert_to_bitmap_selecting_subsampling(Subsampling subsampling, CodingIndependentCodePoints cicp, u8 bit_depth, u32 const width, u32 const height, void* plane_y, void* plane_u, void* plane_v, Gfx::Bitmap& bitmap)
213
0
{
214
0
    if (subsampling.x() && subsampling.y()) {
215
0
        return convert_to_bitmap_selecting_bit_depth<true, true>(cicp, bit_depth, width, height, plane_y, plane_u, plane_v, bitmap);
216
0
    }
217
218
0
    if (subsampling.x() && !subsampling.y()) {
219
0
        return convert_to_bitmap_selecting_bit_depth<true, false>(cicp, bit_depth, width, height, plane_y, plane_u, plane_v, bitmap);
220
0
    }
221
222
0
    if (!subsampling.x() && subsampling.y()) {
223
0
        return convert_to_bitmap_selecting_bit_depth<false, true>(cicp, bit_depth, width, height, plane_y, plane_u, plane_v, bitmap);
224
0
    }
225
226
0
    return convert_to_bitmap_selecting_bit_depth<false, false>(cicp, bit_depth, width, height, plane_y, plane_u, plane_v, bitmap);
227
0
}
228
229
DecoderErrorOr<void> SubsampledYUVFrame::output_to_bitmap(Gfx::Bitmap& bitmap)
230
0
{
231
0
    return convert_to_bitmap_selecting_subsampling(m_subsampling, cicp(), bit_depth(), width(), height(), m_y_buffer, m_u_buffer, m_v_buffer, bitmap);
232
0
}
233
234
}