aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/host1x/nx2_video_decoder.h
blob: 347b0e6525a9e00d799d692709f33dc6386e8d52 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once

#include <memory>
#include <span>
#include <string>
#include <string_view>
#include <vector>

#include "common/common_types.h"

namespace FFmpeg {
class Frame;
}

namespace Tegra::Host1x {

/// A picture decoded by Nx2VideoDecoder, in display order.
struct Nx2Picture {
    u32 width{};
    u32 height{};
    u64 pts{}; ///< As submitted with the compressed frame
    std::shared_ptr<FFmpeg::Frame> frame;
};

/// Pixel layouts of a Switch 2 decoder output image.
enum class Nx2PictureFormat : u32 {
    Nv12,  ///< Luma rows, then interleaved Cb/Cr rows at chroma_offset
    Rgba8,
    Bgra8,
};

/// Checks if stream data begins with an H.264 Annex-B start code or avcC/MP4 length-prefixed NALUs.
bool IsH264Stream(std::span<const u8> data);

/// The decoder behind the Switch 2 video decoder service (nn::codec::video): FFmpeg decodes the
/// elementary stream the game demuxed, in software or on the host GPU (NVDEC emulation setting).
/// Used from one thread at a time.
class Nx2VideoDecoder {
public:
    /// mime: the codec name nn::codec sends with Configure ("video/vp9", "video/vp8", ...).
    explicit Nx2VideoDecoder(std::string_view mime);
    ~Nx2VideoDecoder();

    bool IsOpen() const;

    const std::string& Name() const;

    /// Decodes one compressed frame and appends the pictures it completes.
    void Decode(std::span<const u8> data, u64 pts, std::vector<Nx2Picture>& pictures);

    /// End of stream: appends the pictures the decoder still holds, then starts over.
    void Drain(std::vector<Nx2Picture>& pictures);

    /// Drops everything queued in the decoder (the game flushed it to seek).
    void Reset();

    /// Converts a picture to `format` in `out`: rows `pitch` bytes apart, NV12's chroma plane at
    /// `chroma_offset`, scaled to width x height.
    void Render(const Nx2Picture& picture, Nx2PictureFormat format, u32 width, u32 height,
                u64 pitch, u64 chroma_offset, std::span<u8> out);

private:
    struct Impl;
    std::unique_ptr<Impl> impl;
};

} // namespace Tegra::Host1x