/usr/include/movit/ycbcr_input.h is in libmovit-dev 1.3.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 139 140 141 142 143 144 145 146 147 148 149 150 | #ifndef _MOVIT_YCBCR_INPUT_H
#define _MOVIT_YCBCR_INPUT_H 1
// YCbCrInput is for handling planar 8-bit Y'CbCr (also sometimes, usually rather
// imprecisely, called “YUV”), which is typically what you get from a video decoder.
// It upsamples planes as needed, using the default linear upsampling OpenGL gives you.
#include <epoxy/gl.h>
#include <assert.h>
#include <string>
#include "effect.h"
#include "effect_chain.h"
#include "image_format.h"
#include "input.h"
#include "ycbcr.h"
namespace movit {
class ResourcePool;
// Whether the data is fully planar (Y', Cb and Cr in one texture each)
// or not. Note that this input does currently not support fully interleaved
// data (Y', Cb and Cr next to each other), as 4:4:4 interleaved Y'CbCr seems
// to be rare; however, YCbCr422InterleavedInput supports the important special
// case of 4:2:2 interleaved.
enum YCbCrInputSplitting {
// The standard, default case; Y', Cb and Cr in one texture each.
YCBCR_INPUT_PLANAR,
// Y' in one texture, and then Cb and Cr interleaved in one texture.
// In particular, this is a superset of the relatively popular NV12 mode.
// If you specify this mode, the “Cr” pointer texture will be unused
// (the ”Cb” texture contains both).
YCBCR_INPUT_SPLIT_Y_AND_CBCR,
};
class YCbCrInput : public Input {
public:
YCbCrInput(const ImageFormat &image_format,
const YCbCrFormat &ycbcr_format,
unsigned width, unsigned height,
YCbCrInputSplitting ycbcr_input_splitting = YCBCR_INPUT_PLANAR);
~YCbCrInput();
virtual std::string effect_type_id() const { return "YCbCrInput"; }
virtual bool can_output_linear_gamma() const { return false; }
virtual AlphaHandling alpha_handling() const { return OUTPUT_BLANK_ALPHA; }
std::string output_fragment_shader();
// Uploads the texture if it has changed since last time.
void set_gl_state(GLuint glsl_program_num, const std::string& prefix, unsigned *sampler_num);
unsigned get_width() const { return width; }
unsigned get_height() const { return height; }
Colorspace get_color_space() const { return image_format.color_space; }
GammaCurve get_gamma_curve() const { return image_format.gamma_curve; }
virtual bool can_supply_mipmaps() const { return false; }
// Tells the input where to fetch the actual pixel data. Note that if you change
// this data, you must either call set_pixel_data() again (using the same pointer
// is fine), or invalidate_pixel_data(). Otherwise, the texture won't be re-uploaded
// on subsequent frames.
//
// The data can either be a regular pointer (if pbo==0), or a byte offset
// into a PBO. The latter will allow you to start uploading the texture data
// asynchronously to the GPU, if you have any CPU-intensive work between the
// call to set_pixel_data() and the actual rendering. In either case,
// the pointer (and PBO, if set) has to be valid at the time of the render call.
void set_pixel_data(unsigned channel, const unsigned char *pixel_data, GLuint pbo = 0)
{
assert(channel >= 0 && channel < num_channels);
this->pixel_data[channel] = pixel_data;
this->pbos[channel] = pbo;
invalidate_pixel_data();
}
void invalidate_pixel_data();
// Note: Sets pitch to width, so even if your pitch is unchanged,
// you will need to re-set it after this call.
void set_width(unsigned width)
{
this->width = width;
assert(width % ycbcr_format.chroma_subsampling_x == 0);
pitch[0] = widths[0] = width;
pitch[1] = widths[1] = width / ycbcr_format.chroma_subsampling_x;
pitch[2] = widths[2] = width / ycbcr_format.chroma_subsampling_x;
invalidate_pixel_data();
}
void set_height(unsigned height)
{
this->height = height;
assert(height % ycbcr_format.chroma_subsampling_y == 0);
heights[0] = height;
heights[1] = height / ycbcr_format.chroma_subsampling_y;
heights[2] = height / ycbcr_format.chroma_subsampling_y;
invalidate_pixel_data();
}
void set_pitch(unsigned channel, unsigned pitch)
{
assert(channel >= 0 && channel < num_channels);
this->pitch[channel] = pitch;
invalidate_pixel_data();
}
// Tells the input to use the specific OpenGL texture as pixel data for the given
// channel. The comments on FlatInput::set_texture_num() also apply here, except
// that this input generally does not use mipmaps.
void set_texture_num(unsigned channel, GLuint texture_num)
{
possibly_release_texture(channel);
this->texture_num[channel] = texture_num;
this->owns_texture[channel] = false;
}
virtual void inform_added(EffectChain *chain)
{
resource_pool = chain->get_resource_pool();
}
bool set_int(const std::string& key, int value);
private:
// Release the texture in the given channel if we have any, and it is owned by us.
void possibly_release_texture(unsigned channel);
ImageFormat image_format;
YCbCrFormat ycbcr_format;
GLuint num_channels;
YCbCrInputSplitting ycbcr_input_splitting;
GLuint pbos[3], texture_num[3];
GLint uniform_tex_y, uniform_tex_cb, uniform_tex_cr;
unsigned width, height, widths[3], heights[3];
const unsigned char *pixel_data[3];
unsigned pitch[3];
bool owns_texture[3];
ResourcePool *resource_pool;
};
} // namespace movit
#endif // !defined(_MOVIT_YCBCR_INPUT_H)
|