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  struct pullup_buffer *b;
78  struct pullup_frame *f;
79  int ypitch = filter->context->stride[0];
80  int height = filter->height;
81  int cpitch = filter->context->stride[1];
82  int cheight = filter->height >> 1;
83  int p = frame->top_field_first ^ 1;
84 
85  struct pullup_context *c = filter->context;
86  if (c->bpp[0] == 0)
87  c->bpp[0] = c->bpp[1] = c->bpp[2] = frame->bpp;
88 
89  b = pullup_get_buffer(c,2);
90  if (!b)
91  {
92  f = pullup_get_frame(c);
94  return 0;
95  }
96 
97  memcpy_pic(b->planes[0], frame->buf + frame->offsets[0],
98  height, ypitch, ypitch);
99  memcpy_pic(b->planes[1], frame->buf + frame->offsets[1],
100  cheight, cpitch, cpitch);
101  memcpy_pic(b->planes[2], frame->buf + frame->offsets[2],
102  cheight, cpitch, cpitch);
103 
104  pullup_submit_field(c, b, p);
105  pullup_submit_field(c, b, p^1);
106  if (frame->repeat_pict)
107  pullup_submit_field(c, b, p);
108 
110 
111  f = pullup_get_frame(c);
112 
113  if (!f)
114  return 0;
115 
116 
117  if (f->length < 2)
118  {
120  f = pullup_get_frame(c);
121  if (!f)
122  return 0;
123  if (f->length < 2)
124  {
126  if (!frame->repeat_pict)
127  return 0;
128  f = pullup_get_frame(c);
129  if (!f)
130  return 0;
131  if (f->length < 2)
132  {
134  return 0;
135  }
136  }
137  }
138 
139  if (!f->buffer)
140  {
141  pullup_pack_frame(c, f);
142  }
143 
144  if (!f->buffer)
145  return 0;
146 
147  memcpy_pic(frame->buf + frame->offsets[0], f->buffer->planes[0],
148  height, ypitch, ypitch);
149  memcpy_pic(frame->buf + frame->offsets[1], f->buffer->planes[1],
150  cheight, cpitch, cpitch);
151  memcpy_pic(frame->buf + frame->offsets[2], f->buffer->planes[2],
152  cheight, cpitch, cpitch);
153 
155 
156  return 1;
157 }
158 
159 static void
161 {
162  pullup_free_context((((ThisFilter *)filter)->context));
163 }
164 
165 static void SetupFilter(ThisFilter *vf, int width, int height, const int *pitches)
166 {
167  if (vf->width == width &&
168  vf->height == height &&
169  vf->context->stride[0] == pitches[0] &&
170  vf->context->stride[1] == pitches[1] &&
171  vf->context->stride[2] == pitches[2])
172  {
173  return;
174  }
175 
176  vf->width = width;
177  vf->height = height;
178 
179  vf->context->w[0] = width;
180  vf->context->w[1] = width >> 1;
181  vf->context->w[2] = width >> 1;
182  vf->context->w[3] = 0;
183  vf->context->h[0] = height;
184  vf->context->h[1] = height >> 1;
185  vf->context->h[2] = height >> 1;
186  vf->context->h[3] = 0;
187  vf->context->stride[0] = pitches[0];
188  vf->context->stride[1] = pitches[1];
189  vf->context->stride[2] = pitches[2];
190  vf->context->stride[3] = 0;
191 }
192 
194  VideoFrameType outpixfmt,
195  const int *width, const int *height, const char *options,
196  int threads)
197 {
198  (void) threads;
199  (void) options;
200 
201  ThisFilter *filter;
202 
203  if (inpixfmt != FMT_YV12)
204  return NULL;
205  if (outpixfmt != FMT_YV12)
206  return NULL;
207 
208  filter = malloc (sizeof (ThisFilter));
209 
210  if (filter == NULL)
211  {
212  fprintf (stderr, "Ivtc: failed to allocate memory for filter\n");
213  return NULL;
214  }
215 
216  memset(filter, 0, sizeof(ThisFilter));
217  filter->progressive_frame_seen = 0;
218  filter->interlaced_frame_seen = 0;
219  filter->apply_filter = 0;
220  filter->context = pullup_alloc_context();
221  struct pullup_context *c = filter->context;
222  c->metric_plane = 0;
223  c->strict_breaks = 0;
224  c->junk_left = c->junk_right = 1;
225  c->junk_top = c->junk_bottom = 4;
226  c->verbose = 0;
227  c->format = PULLUP_FMT_Y;
228  c->nplanes = 4;
230  c->bpp[0] = c->bpp[1] = c->bpp[2] = 0;
231  c->background[1] = c->background[2] = 128;
232 
233  int pitches[3] = { *width, *width >> 1, *width >> 1 };
234  SetupFilter(filter, *width, *height, pitches);
235 
236 #if HAVE_MMX
237  c->cpu |= PULLUP_CPU_MMX;
238 #endif
239 
241  filter->vf.filter = &IvtcFilter;
242  filter->vf.cleanup = &IvtcFilterCleanup;
243  return (VideoFilter *) filter;
244 }
245 
246 static FmtConv FmtList[] =
247 {
248  { FMT_YV12, FMT_YV12 },
249  FMT_NULL
250 };
251 
253 {
254  {
256  .name= (char*)"ivtc",
257  .descript= (char*)"inverse telecine filter",
258  .formats= FmtList,
259  .libname= NULL
260  },
261  FILT_NULL
262 };
263 
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
struct pullup_buffer * buffer
Definition: pullup.h:43
void pullup_pack_frame(struct pullup_context *c, struct pullup_frame *fr)
Definition: pullup.c:710
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:246
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:165
void pullup_release_buffer(struct pullup_buffer *b, int parity)
Definition: pullup.c:292
unsigned char b
Definition: ParseText.cpp:329
const FilterInfo filter_table[]
Definition: filter_ivtc.c:252
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:299
struct pullup_context * pullup_alloc_context(void)
Definition: pullup.c:746
int length
Definition: pullup.h:40
void pullup_free_context(struct pullup_context *c)
Definition: pullup.c:805
struct ThisFilter ThisFilter
struct pullup_frame * pullup_get_frame(struct pullup_context *c)
Definition: pullup.c:646
int junk_top
Definition: pullup.h:53
int verbose
Definition: pullup.h:54
int * bpp
Definition: pullup.h:51
int top_field_first
1 if top field is first.
Definition: mythframe.h:58
static void IvtcFilterCleanup(VideoFilter *filter)
Definition: filter_ivtc.c:160
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:764
void pullup_submit_field(struct pullup_context *c, struct pullup_buffer *b, int parity)
Definition: pullup.c:408
void pullup_release_frame(struct pullup_frame *fr)
Definition: pullup.c:730
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:193
#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
int * stride
Definition: pullup.h:51
void pullup_preinit_context(struct pullup_context *c)
Definition: pullup.c:755
int junk_right
Definition: pullup.h:53