60#define MOD_NAME "[temporal deint] "
62#define DFR_DEINTERLACE_IMPOSSIBLE_MSG_ID 0x27ff0a78
79 color_printf(
"\t" TBOLD(
"force ")
" - apply deinterlacing even if input is not interlaced\n");
80 color_printf(
"\t" TBOLD(
"nodelay")
" - do not delay the other frame to keep timing. Both frames are output in burst. May not work correctly (depends on display).\n");
85 char desc[] =
TBOLD(
"double-framerate")
" is an interleaver that "
86 "creates creates a progressive stream by consecutive "
87 "interleaving fields, eg. f1f2f3f4f5f6 -> \"f1-- f1f2 f3f2 "
88 "f3f4 f5f4 f5f6 --f6\". So saw-like artifacts will still occur "
89 "and blending can be used.\n\n";
99 bool deinterlace =
false;
101 bool nodelay =
false;
103 if (strcmp(config,
"d") == 0) {
105 }
else if (strcmp(config,
"nodelay") == 0) {
107 }
else if (strcmp(config,
"force") == 0) {
109 }
else if (strlen(config) > 0) {
114 struct state_df *s = calloc(1,
sizeof *s);
134 if (strcmp(config,
"help") == 0) {
142 if (strcmp(config,
"help") == 0) {
144 "every field line to achieve full resolution.\n\n");
153 if (strcmp(config,
"help") == 0) {
155 "full resolution by interpolating missing lines.\n\n");
187 "mainly for interlaced merged video. Framerate will be needlessly doubled.\n",
219 char *dst = out->
tiles[0].
data + req_pitch;
220 for (
unsigned y = 0; y < out->
tiles[0].
height; y += 2) {
222 dst += 2 * req_pitch;
227 for (
unsigned y = 1; y < out->
tiles[0].
height; y += 2) {
229 dst += 2 * req_pitch;
235 for (
unsigned y = 0; y < out->
tiles[0].
height; ++y) {
258 memcpy(dst, src, linesize);
261 unsigned y =
in ? 0 : 1;
263 memcpy(dst, src, linesize);
264 memcpy(dst + pitch, src, linesize);
268 if (y < out->tiles[0].height) {
269 memcpy(dst, dst - pitch, linesize);
281 char *s1 = (
char *) src1;
282 char *s2 = (
char *) src2;
283 char *d = (
char *) dst;
288 if (bpp == 8 || bpp == 16) {
291 typedef unsigned char v16uc
__attribute__ ((vector_size (16)));
292 for ( ; x < linesize / 16; ++x) {
294 memcpy(&i1, s1,
sizeof i1);
295 memcpy(&i2, s2,
sizeof i2);
296 v16uc res = ((i1 / 2) + (i2 / 2) + (i1 % 2 + i1 % 2) / 2);
297 memcpy(d, &res,
sizeof res);
303 typedef unsigned short v16us
__attribute__ ((vector_size (16)));
304 for ( ; x < linesize / 16; ++x) {
306 memcpy(&i1, s1,
sizeof i1);
307 memcpy(&i2, s2,
sizeof i2);
308 v16us res = ((i1 / 2) + (i2 / 2) + (i1 % 2 + i1 % 2) / 2);
309 memcpy(d, &res,
sizeof res);
317 for ( ; x < linesize; ++x) {
318 *d++ = (*s1++ + *s2++ + 1) >> 1;
321 uint16_t *d16 = (uint16_t *)(
void *) d;
322 uint16_t *s16_1 = (uint16_t *)(
void *) s1;
323 uint16_t *s16_2 = (uint16_t *)(
void *) s2;
324 for ( ; x < linesize / 2; ++x) {
325 *d16++ = (*s16_1++ + *s16_2++ + 1) >> 1;
329 uint32_t *s32_1 = (uint32_t *)(
void *) s1;
330 uint32_t *s32_2 = (uint32_t *)(
void *) s2;
331 uint32_t *d32 = (uint32_t *)(
void *) d;
332 for (
size_t x = 0; x < linesize / 16; ++x) {
334 for (
int y = 0; y < 4; ++y) {
335 uint32_t v1 = *s32_1++;
336 uint32_t v2 = *s32_2++;
338 (((v1 >> 20 ) + (v2 >> 20 ) + 1) / 2) << 20 |
339 (((v1 >> 10 & 0x3ff) + (v2 >> 10 & 0x3ff) + 1) / 2) << 10 |
340 (((v1 & 0x3ff) + (v2 & 0x3ff) + 1) / 2);
344 uint32_t *s32_1 = (uint32_t *)(
void *) s1;
345 uint32_t *s32_2 = (uint32_t *)(
void *) s2;
346 uint32_t *d32 = (uint32_t *)(
void *) d;
347 for (
size_t x = 0; x < linesize / 4; ++x) {
349 for (
int y = 0; y < 4; ++y) {
350 uint32_t v1 = ntohl(*s32_1++);
351 uint32_t v2 = ntohl(*s32_2++);
353 (((v1 >> 22 ) + (v2 >> 22 ) + 1) / 2) << 22 |
354 (((v1 >> 12 & 0x3ff) + (v2 >> 12 & 0x3ff) + 1) / 2) << 12 |
355 (((v1 >> 2 & 0x3ff) + (v2 >> 2 & 0x3ff) + 1) / 2) << 2;
359 uint32_t *s32_1 = (uint32_t *)(
void *) s1;
360 uint32_t *s32_2 = (uint32_t *)(
void *) s2;
361 uint32_t *d32 = (uint32_t *)(
void *) d;
363 uint32_t remain1 = 0;
364 uint32_t remain2 = 0;
366 for (
size_t x = 0; x < linesize / 16; ++x) {
368 for (
int y = 0; y < 4; ++y) {
369 uint32_t in1 = *s32_1++;
370 uint32_t in2 = *s32_2++;
372 remain1 = remain1 | (in1 & ((1<<((shift + 12) % 32)) - 1)) << (32-shift);
373 remain2 = remain2 | (in2 & ((1<<((shift + 12) % 32)) - 1)) << (32-shift);
374 uint32_t ret = (remain1 + remain2 + 1) / 2;
377 out = ret >> (32-shift);
378 shift = (shift + 12) % 32;
382 while (shift <= 32 - 12) {
383 out |= ((((in1 & 0xfff) + (in2 & 0xfff)) + 1) / 2) << shift;
410 memcpy(dst, src, linesize);
413 unsigned y =
in ? 0 : 1;
415 memcpy(dst, src, linesize);
417 memcpy(dst + pitch, src, linesize);
423 memcpy(dst, src, linesize);
struct video_frame * vf_alloc(int count)
Allocates blank video frame.
void vf_free(struct video_frame *buf)
Frees video_frame structure.
int vc_get_linesize(unsigned int width, codec_t codec)
const char * get_codec_name(codec_t codec)
int color_printf(const char *format,...)
void log_msg(int level, const char *format,...)
void log_msg_once(int level, uint32_t id, const char *msg,...)
#define LOG_LEVEL_NOTICE
information that may be interesting
#define LOG_LEVEL_ERROR
general errors
#define LOG_LEVEL_WARNING
less severe errors
@ DISPLAY_PROPERTY_VIDEO_MERGED
monolithic framebuffer
const char * get_commandline_param(const char *key)
void set_commandline_param(const char *key, const char *val)
@ LIBRARY_CLASS_VIDEO_POSTPROCESS
#define REGISTER_MODULE(name, info, lclass, abi)
Registers module to global modules' registry.
struct __attribute__((packed))
Struct tile is an area of video_frame.
char * data
Raw tile data. Pointer must be at least 4B aligned.
unsigned int data_len
length of the data
enum interlacing_t interlacing
unsigned int width
width of every tile (!)
unsigned int height
height of every tile (!)
Struct video_frame represents a video frame and contains video description.
enum interlacing_t interlacing
struct tile tiles[FLEXIBLE_ARRAY_MEMBER]
static void perform_linear(struct state_df *s, struct video_frame *in, struct video_frame *out, int pitch)
#define DFR_DEINTERLACE_IMPOSSIBLE_MSG_ID
static bool common_postprocess_reconfigure(void *state, struct video_desc desc)
static void common_done(void *state)
static const struct vo_postprocess_info vo_pp_bob_info
static void perform_bob(struct state_df *s, struct video_frame *in, struct video_frame *out, int pitch)
static void * init_common(enum algo algo, const char *config)
static bool common_get_property(void *state, int property, void *val, size_t *len)
static struct video_frame * common_getf(void *state)
static void print_common_opts()
static void perform_df(struct state_df *s, struct video_frame *in, struct video_frame *out, int req_pitch)
static void * df_init(const char *config)
static const struct vo_postprocess_info vo_pp_df_info
static void common_get_out_desc(void *state, struct video_desc *out, int *in_display_mode, int *out_frames)
static const struct vo_postprocess_info vo_pp_linear_info
static void * linear_init(const char *config)
static bool avg_lines(codec_t codec, size_t linesize, char *src1, char *src2, char *dst)
static void * bob_init(const char *config)
static bool common_postprocess(void *state, struct video_frame *in, struct video_frame *out, int req_pitch)
static time_ns_t get_time_in_ns()
@ PROGRESSIVE
progressive frame
@ INTERLACED_MERGED
Columngs of both fields are interlaced together.
@ R10k
RGB 10-bit packed - RGBX, big-endian (2 bit padding)
@ R12L
RGB 12-bit packed, little-endian.
@ v210
YCbCr 422 10-bit - xVY0U|xY2UY1|xUY3V|xY5VY4, little-endian (2 bit padding /'x'/),...
char * wrap_paragraph(char *text)
This is an umbrella header for video functions.
bool is_codec_opaque(codec_t codec)
bool vc_deinterlace_ex(codec_t codec, unsigned char *src, size_t src_linesize, unsigned char *dst, size_t dst_pitch, size_t lines)
bool codec_is_planar(codec_t codec)
int get_bits_per_component(codec_t codec)
struct tile * vf_get_tile(struct video_frame *buf, int pos)
Returns pointer to n-th tile from video frame Equivalent to &video_frame::tiles[pos].
const char * get_interlacing_description(enum interlacing_t interlacing)
Returns description of interlacing Eg. "progressive".
#define VO_PP_ABI_VERSION