Coverage Report

Created: 2026-02-16 07:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/serenity/Userland/Libraries/LibMedia/VideoFrame.h
Line
Count
Source
1
/*
2
 * Copyright (c) 2022, Gregory Bertilson <zaggy1024@gmail.com>
3
 *
4
 * SPDX-License-Identifier: BSD-2-Clause
5
 */
6
7
#pragma once
8
9
#include <AK/ByteBuffer.h>
10
#include <AK/FixedArray.h>
11
#include <AK/Time.h>
12
#include <LibGfx/Bitmap.h>
13
#include <LibGfx/Size.h>
14
#include <LibMedia/Color/CodingIndependentCodePoints.h>
15
16
#include "DecoderError.h"
17
#include "Subsampling.h"
18
19
namespace Media {
20
21
class VideoFrame {
22
23
public:
24
1.18k
    virtual ~VideoFrame() { }
25
26
    virtual DecoderErrorOr<void> output_to_bitmap(Gfx::Bitmap& bitmap) = 0;
27
    virtual DecoderErrorOr<NonnullRefPtr<Gfx::Bitmap>> to_bitmap()
28
0
    {
29
0
        auto bitmap = DECODER_TRY_ALLOC(Gfx::Bitmap::create(Gfx::BitmapFormat::BGRx8888, { width(), height() }));
30
0
        TRY(output_to_bitmap(bitmap));
31
0
        return bitmap;
32
0
    }
33
34
0
    inline Duration timestamp() const { return m_timestamp; }
35
36
0
    inline Gfx::Size<u32> size() const { return m_size; }
37
0
    inline u32 width() const { return size().width(); }
38
0
    inline u32 height() const { return size().height(); }
39
40
3.56k
    inline u8 bit_depth() const { return m_bit_depth; }
41
0
    inline CodingIndependentCodePoints& cicp() { return m_cicp; }
42
43
protected:
44
    VideoFrame(Duration timestamp,
45
        Gfx::Size<u32> size,
46
        u8 bit_depth, CodingIndependentCodePoints cicp)
47
1.18k
        : m_timestamp(timestamp)
48
1.18k
        , m_size(size)
49
1.18k
        , m_bit_depth(bit_depth)
50
1.18k
        , m_cicp(cicp)
51
1.18k
    {
52
1.18k
    }
53
54
    Duration m_timestamp;
55
    Gfx::Size<u32> m_size;
56
    u8 m_bit_depth;
57
    CodingIndependentCodePoints m_cicp;
58
};
59
60
class SubsampledYUVFrame : public VideoFrame {
61
62
public:
63
    static ErrorOr<NonnullOwnPtr<SubsampledYUVFrame>> try_create(
64
        Duration timestamp,
65
        Gfx::Size<u32> size,
66
        u8 bit_depth, CodingIndependentCodePoints cicp,
67
        Subsampling subsampling);
68
69
    static ErrorOr<NonnullOwnPtr<SubsampledYUVFrame>> try_create_from_data(
70
        Duration timestamp,
71
        Gfx::Size<u32> size,
72
        u8 bit_depth, CodingIndependentCodePoints cicp,
73
        Subsampling subsampling,
74
        ReadonlyBytes y_data, ReadonlyBytes u_data, ReadonlyBytes v_data);
75
76
    SubsampledYUVFrame(
77
        Duration timestamp,
78
        Gfx::Size<u32> size,
79
        u8 bit_depth, CodingIndependentCodePoints cicp,
80
        Subsampling subsampling,
81
        u8* plane_y_data, u8* plane_u_data, u8* plane_v_data)
82
1.18k
        : VideoFrame(timestamp, size, bit_depth, cicp)
83
1.18k
        , m_subsampling(subsampling)
84
1.18k
        , m_y_buffer(plane_y_data)
85
1.18k
        , m_u_buffer(plane_u_data)
86
1.18k
        , m_v_buffer(plane_v_data)
87
1.18k
    {
88
1.18k
        VERIFY(m_y_buffer != nullptr);
89
1.18k
        VERIFY(m_u_buffer != nullptr);
90
1.18k
        VERIFY(m_v_buffer != nullptr);
91
1.18k
    }
92
93
    ~SubsampledYUVFrame();
94
95
    DecoderErrorOr<void> output_to_bitmap(Gfx::Bitmap& bitmap) override;
96
97
    u8* get_raw_plane_data(u32 plane)
98
3.56k
    {
99
3.56k
        switch (plane) {
100
1.18k
        case 0:
101
1.18k
            return m_y_buffer;
102
1.18k
        case 1:
103
1.18k
            return m_u_buffer;
104
1.18k
        case 2:
105
1.18k
            return m_v_buffer;
106
3.56k
        }
107
0
        VERIFY_NOT_REACHED();
108
0
    }
109
110
    template<typename T>
111
    T* get_plane_data(u32 plane)
112
3.56k
    {
113
3.56k
        VERIFY((IsSame<T, u8>) == (bit_depth() <= 8));
114
3.56k
        return reinterpret_cast<T*>(get_raw_plane_data(plane));
115
3.56k
    }
unsigned char* Media::SubsampledYUVFrame::get_plane_data<unsigned char>(unsigned int)
Line
Count
Source
112
3.48k
    {
113
3.48k
        VERIFY((IsSame<T, u8>) == (bit_depth() <= 8));
114
3.48k
        return reinterpret_cast<T*>(get_raw_plane_data(plane));
115
3.48k
    }
unsigned short* Media::SubsampledYUVFrame::get_plane_data<unsigned short>(unsigned int)
Line
Count
Source
112
78
    {
113
78
        VERIFY((IsSame<T, u8>) == (bit_depth() <= 8));
114
78
        return reinterpret_cast<T*>(get_raw_plane_data(plane));
115
78
    }
116
117
protected:
118
    Subsampling m_subsampling;
119
    u8* m_y_buffer = nullptr;
120
    u8* m_u_buffer = nullptr;
121
    u8* m_v_buffer = nullptr;
122
};
123
124
}