summaryrefslogtreecommitdiffstats
path: root/demos/plplay.h
blob: 2036562f0cd9fadd9525d36ac59a491c1fefd3bd (plain)
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>

#include <libplacebo/options.h>
#include <libplacebo/utils/frame_queue.h>

#include "common.h"
#include "pl_thread.h"

#define MAX_FRAME_PASSES 256
#define MAX_BLEND_PASSES 8
#define MAX_BLEND_FRAMES 8

enum {
    ZOOM_PAD = 0,
    ZOOM_CROP,
    ZOOM_STRETCH,
    ZOOM_FIT,
    ZOOM_RAW,
    ZOOM_400,
    ZOOM_200,
    ZOOM_100,
    ZOOM_50,
    ZOOM_25,
    ZOOM_COUNT,
};

struct plplay_args {
    const struct pl_render_params *preset;
    enum pl_log_level verbosity;
    const char *window_impl;
    const char *filename;
    bool hwdec;
};

bool parse_args(struct plplay_args *args, int argc, char *argv[]);

struct plplay {
    struct plplay_args args;
    struct window *win;
    struct ui *ui;
    char cache_file[512];

    // libplacebo
    pl_log log;
    pl_renderer renderer;
    pl_queue queue;
    pl_cache cache;

    // libav*
    AVFormatContext *format;
    AVCodecContext *codec;
    const AVStream *stream; // points to first video stream of `format`
    pl_thread decoder_thread;
    bool decoder_thread_created;
    bool exit_thread;

    // settings / ui state
    pl_options opts;
    pl_rotation target_rot;
    int target_zoom;
    bool colorspace_hint;
    bool colorspace_hint_dynamic;
    bool ignore_dovi;
    bool toggle_fullscreen;
    bool advanced_scalers;

    bool target_override; // if false, fields below are ignored
    struct pl_color_repr force_repr;
    enum pl_color_primaries force_prim;
    enum pl_color_transfer force_trc;
    struct pl_hdr_metadata force_hdr;
    bool force_hdr_enable;
    bool fps_override;
    float fps;

    // ICC profile
    pl_icc_object icc;
    char *icc_name;
    bool use_icc_luma;
    bool force_bpc;

    // custom shaders
    const struct pl_hook **shader_hooks;
    char **shader_paths;
    size_t shader_num;
    size_t shader_size;

    // pass metadata
    struct pl_dispatch_info blend_info[MAX_BLEND_FRAMES][MAX_BLEND_PASSES];
    struct pl_dispatch_info frame_info[MAX_FRAME_PASSES];
    int num_frame_passes;
    int num_blend_passes[MAX_BLEND_FRAMES];

    // playback statistics
    struct {
        _Atomic uint32_t decoded;
        uint32_t rendered;
        uint32_t mapped;
        uint32_t dropped;
        uint32_t missed;
        uint32_t stalled;
        double missed_ms;
        double stalled_ms;
        double current_pts;

        struct timing {
            double sum, sum2, peak;
            uint64_t count;
        } acquire, update, render, draw_ui, sleep, submit, swap,
          vsync_interval, pts_interval;
    } stats;
};

void update_settings(struct plplay *p, const struct pl_frame *target);

static inline void apply_csp_overrides(struct plplay *p, struct pl_color_space *csp)
{
    if (p->force_prim) {
        csp->primaries = p->force_prim;
        csp->hdr.prim = *pl_raw_primaries_get(csp->primaries);
    }
    if (p->force_trc)
        csp->transfer = p->force_trc;
    if (p->force_hdr_enable) {
        struct pl_hdr_metadata fix = p->force_hdr;
        fix.prim = csp->hdr.prim;
        csp->hdr = fix;
    } else if (p->colorspace_hint_dynamic) {
        pl_color_space_nominal_luma_ex(pl_nominal_luma_params(
            .color      = csp,
            .metadata   = PL_HDR_METADATA_ANY,
            .scaling    = PL_HDR_NITS,
            .out_min    = &csp->hdr.min_luma,
            .out_max    = &csp->hdr.max_luma,
        ));
    }
}