MythTV  master
filter_ivtc.c
Go to the documentation of this file.
1 /* taken from mplayer */
2 /* inverse telecine video filter */
3 /* requires MMX support to work */
4 
5 #include <stdlib.h>
6 #include <stdio.h>
7 
8 #ifdef HAVE_STDINT_H
9 #include <stdint.h>
10 #endif
11 
12 #include <string.h>
13 
14 #include "config.h"
15 #include "filter.h"
16 #include "mythframe.h"
17 
18 #include "pullup.h"
19 
20 typedef struct ThisFilter
21 {
23 
25  int height;
26  int width;
30 } ThisFilter;
31 
32 static void SetupFilter(ThisFilter *vf, int width, int height, const int *pitches);
33 
34 static inline void * memcpy_pic(void * dst, const void * src, int height, int dstStride, int srcStride)
35 {
36  void *retval=dst;
37 
38  if (dstStride == srcStride)
39  {
40  memcpy(dst, src, srcStride*height);
41  }
42 
43  return retval;
44 }
45 
46 static int
48 {
49  (void)field;
50  ThisFilter *filter = (ThisFilter *) vf;
51 
52  if (!frame->interlaced_frame)
53  {
54  filter->progressive_frame_seen = 1;
55  }
56 
57  if (filter->progressive_frame_seen &&
58  frame->interlaced_frame)
59  {
60  filter->interlaced_frame_seen = 1;
61  }
62 
63  if (!frame->interlaced_frame &&
64  !filter->apply_filter &&
65  filter->interlaced_frame_seen &&
66  filter->progressive_frame_seen)
67  {
68  fprintf(stderr,"turning on inverse telecine filter");
69  filter->apply_filter = 1;
70  }
71 
72  if (!filter->apply_filter)
73  return 1;
74 
75  SetupFilter(filter, frame->width, frame->height, (int*)frame->pitches);
76 
77  int ypitch = filter->context->stride[0];
78  int height = filter->height;
79  int cpitch = filter->context->stride[1];
80  int cheight = filter->height >> 1;
81  int p = frame->top_field_first ^ 1;
82 
83  struct pullup_context *c = filter->context;
84  if (c->bpp[0] == 0)
85  c->bpp[0] = c->bpp[1] = c->bpp[2] = frame->bpp;
86 
87  struct pullup_buffer *b = pullup_get_buffer(c,2);
88  if (!b)
89  {
90  struct pullup_frame *f = pullup_get_frame(c);
92  return 0;
93  }
94 
95  memcpy_pic(b->planes[0], frame->buf + frame->offsets[0],
96  height, ypitch, ypitch);
97  memcpy_pic(b->planes[1], frame->buf + frame->offsets[1],
98  cheight, cpitch, cpitch);
99  memcpy_pic(b->planes[2], frame->buf + frame->offsets[2],
100  cheight, cpitch, cpitch);
101 
102  pullup_submit_field(c, b, p);
103  pullup_submit_field(c, b, p^1);
104  if (frame->repeat_pict)
105  pullup_submit_field(c, b, p);
106 
108 
109  struct pullup_frame *f = pullup_get_frame(c);
110  if (!f)
111  return 0;
112 
113 
114  if (f->length < 2)
115  {
117  f = pullup_get_frame(c);
118  if (!f)
119  return 0;
120  if (f->length < 2)
121  {
123  if (!frame->repeat_pict)
124  return 0;
125  f = pullup_get_frame(c);
126  if (!f)
127  return 0;
128  if (f->length < 2)
129  {
131  return 0;
132  }
133  }
134  }
135 
136  if (!f->buffer)
137  {
138  pullup_pack_frame(c, f);
139  }
140 
141  if (!f->buffer)
142  return 0;
143 
144  memcpy_pic(frame->buf + frame->offsets[0], f->buffer->planes[0],
145  height, ypitch, ypitch);
146  memcpy_pic(frame->buf + frame->offsets[1], f->buffer->planes[1],
147  cheight, cpitch, cpitch);
148  memcpy_pic(frame->buf + frame->offsets[2], f->buffer->planes[2],
149  cheight, cpitch, cpitch);
150 
152 
153  return 1;
154 }
155 
156 static void
158 {
159  pullup_free_context((((ThisFilter *)filter)->context));
160 }
161 
162 static void SetupFilter(ThisFilter *vf, int width, int height, const int *pitches)
163 {
164  if (vf->width == width &&
165  vf->height == height &&
166  vf->context->stride[0] == pitches[0] &&
167  vf->context->stride[1] == pitches[1] &&
168  vf->context->stride[2] == pitches[2])
169  {
170  return;
171  }
172 
173  vf->width = width;
174  vf->height = height;
175 
176  vf->context->w[0] = width;
177  vf->context->w[1] = width >> 1;
178  vf->context->w[2] = width >> 1;
179  vf->context->w[3] = 0;
180  vf->context->h[0] = height;
181  vf->context->h[1] = height >> 1;
182  vf->context->h[2] = height >> 1;
183  vf->context->h[3] = 0;
184  vf->context->stride[0] = pitches[0];
185  vf->context->stride[1] = pitches[1];
186  vf->context->stride[2] = pitches[2];
187  vf->context->stride[3] = 0;
188 }
189 
191  VideoFrameType outpixfmt,
192  const int *width, const int *height, const char *options,
193  int threads)
194 {
195  (void) threads;
196  (void) options;
197 
198  if (inpixfmt != FMT_YV12)
199  return NULL;
200  if (outpixfmt != FMT_YV12)
201  return NULL;
202 
203  ThisFilter *filter = malloc (sizeof (ThisFilter));
204  if (filter == NULL)
205  {
206  fprintf (stderr, "Ivtc: failed to allocate memory for filter\n");
207  return NULL;
208  }
209 
210  memset(filter, 0, sizeof(ThisFilter));
211  filter->progressive_frame_seen = 0;
212  filter->interlaced_frame_seen = 0;
213  filter->apply_filter = 0;
214  filter->context = pullup_alloc_context();
215  struct pullup_context *c = filter->context;
216  c->metric_plane = 0;
217  c->strict_breaks = 0;
218  c->junk_left = c->junk_right = 1;
219  c->junk_top = c->junk_bottom = 4;
220  c->verbose = 0;
221  c->format = PULLUP_FMT_Y;
222  c->nplanes = 4;
224  c->bpp[0] = c->bpp[1] = c->bpp[2] = 0;
225  c->background[1] = c->background[2] = 128;
226 
227  int pitches[3] = { *width, *width >> 1, *width >> 1 };
228  SetupFilter(filter, *width, *height, pitches);
229 
230 #if HAVE_MMX
231  c->cpu |= PULLUP_CPU_MMX;
232 #endif
233 
235  filter->vf.filter = &IvtcFilter;
236  filter->vf.cleanup = &IvtcFilterCleanup;
237  return (VideoFilter *) filter;
238 }
239 
240 static FmtConv FmtList[] =
241 {
242  { FMT_YV12, FMT_YV12 },
243  FMT_NULL
244 };
245 
247 {
248  {
250  .name= (char*)"ivtc",
251  .descript= (char*)"inverse telecine filter",
252  .formats= FmtList,
253  .libname= NULL
254  },
255  FILT_NULL
256 };
257 
int(* filter)(struct VideoFilter_ *, VideoFrame *, int)
Definition: filter.h:37
init_filter filter_init
Definition: filter.h:28
int * background
Definition: pullup.h:51
int junk_bottom
Definition: pullup.h:53
stderr
Definition: ttvdb.py:1426
int format
Definition: pullup.h:49
#define NULL
Definition: H264Parser.h:62
int apply_filter
Definition: filter_ivtc.c:29
#define PULLUP_CPU_MMX
Definition: pullup.h:6
struct pullup_context * context
Definition: filter_ivtc.c:24
int interlaced_frame_seen
Definition: filter_ivtc.c:28
int repeat_pict
Definition: mythframe.h:59
struct pullup_buffer * buffer
Definition: pullup.h:43
void pullup_pack_frame(struct pullup_context *c, struct pullup_frame *fr)
Definition: pullup.c:696
int * h
Definition: pullup.h:51
struct pullup_frame * frame
Definition: pullup.h:66
void(* cleanup)(struct VideoFilter_ *)
Definition: filter.h:38
int metric_plane
Definition: pullup.h:55
enum FrameType_ VideoFrameType
static FmtConv FmtList[]
Definition: filter_ivtc.c:240
int progressive_frame_seen
Definition: filter_ivtc.c:27
static void SetupFilter(ThisFilter *vf, int width, int height, const int *pitches)
Definition: filter_ivtc.c:162
void pullup_release_buffer(struct pullup_buffer *b, int parity)
Definition: pullup.c:291
unsigned char b
Definition: ParseText.cpp:329
const FilterInfo filter_table[]
Definition: filter_ivtc.c:246
int offsets[3]
Y, U, & V offsets.
Definition: mythframe.h:64
VideoFilter vf
Definition: filter_adjust.c:36
unsigned char ** planes
Definition: pullup.h:21
struct pullup_buffer * pullup_get_buffer(struct pullup_context *c, int parity)
Definition: pullup.c:298
struct pullup_context * pullup_alloc_context(void)
Definition: pullup.c:730
int length
Definition: pullup.h:40
void pullup_free_context(struct pullup_context *c)
Definition: pullup.c:785
struct ThisFilter ThisFilter
struct pullup_frame * pullup_get_frame(struct pullup_context *c)
Definition: pullup.c:633
int junk_top
Definition: pullup.h:53
int verbose
Definition: pullup.h:54
int * bpp
Definition: pullup.h:51
static void IvtcFilterCleanup(VideoFilter *filter)
Definition: filter_ivtc.c:157
int strict_breaks
Definition: pullup.h:56
unsigned int cpu
Definition: pullup.h:52
int junk_left
Definition: pullup.h:53
#define FMT_NULL
Definition: filter.h:20
static void * memcpy_pic(void *dst, const void *src, int height, int dstStride, int srcStride)
Definition: filter_ivtc.c:34
void pullup_init_context(struct pullup_context *c)
Definition: pullup.c:744
void pullup_submit_field(struct pullup_context *c, struct pullup_buffer *b, int parity)
Definition: pullup.c:403
void pullup_release_frame(struct pullup_frame *fr)
Definition: pullup.c:715
int * w
Definition: pullup.h:51
static VideoFilter * NewIvtcFilter(VideoFrameType inpixfmt, VideoFrameType outpixfmt, const int *width, const int *height, const char *options, int threads)
Definition: filter_ivtc.c:190
#define PULLUP_FMT_Y
Definition: pullup.h:13
#define FILT_NULL
Definition: filter.h:47
static int IvtcFilter(VideoFilter *vf, VideoFrame *frame, int field)
Definition: filter_ivtc.c:47
int nplanes
Definition: pullup.h:50
unsigned char * buf
Definition: mythframe.h:39
int * stride
Definition: pullup.h:51
void pullup_preinit_context(struct pullup_context *c)
Definition: pullup.c:735
int junk_right
Definition: pullup.h:53