FFmpeg
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavfilter
libmpcodecs
vf_pullup.c
Go to the documentation of this file.
1
/*
2
* This file is part of MPlayer.
3
*
4
* MPlayer is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2 of the License, or
7
* (at your option) any later version.
8
*
9
* MPlayer is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
13
*
14
* You should have received a copy of the GNU General Public License along
15
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
16
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
*/
18
19
#include <stdio.h>
20
#include <stdlib.h>
21
#include <string.h>
22
23
#include "config.h"
24
#include "
mp_msg.h
"
25
#include "
cpudetect.h
"
26
27
#include "
img_format.h
"
28
#include "
mp_image.h
"
29
#include "
vf.h
"
30
31
#include "
libvo/fastmemcpy.h
"
32
33
#include "
pullup.h
"
34
35
#undef MAX
36
#define MAX(a,b) ((a)>(b)?(a):(b))
37
38
struct
vf_priv_s
{
39
struct
pullup_context
*
ctx
;
40
int
init
;
41
int
fakecount
;
42
char
*
qbuf
;
43
};
44
45
static
void
init_pullup
(
struct
vf_instance *vf,
mp_image_t
*mpi)
46
{
47
struct
pullup_context
*
c
= vf->priv->ctx;
48
49
if
(mpi->
flags
&
MP_IMGFLAG_PLANAR
) {
50
c->
format
=
PULLUP_FMT_Y
;
51
c->
nplanes
= 4;
52
ff_pullup_preinit_context
(c);
53
c->
bpp
[0] = c->
bpp
[1] = c->
bpp
[2] = 8;
54
c->
w
[0] = mpi->
w
;
55
c->
h
[0] = mpi->
h
;
56
c->
w
[1] = c->
w
[2] = mpi->
chroma_width
;
57
c->
h
[1] = c->
h
[2] = mpi->
chroma_height
;
58
c->
w
[3] = ((mpi->
w
+15)/16) * ((mpi->
h
+15)/16);
59
c->
h
[3] = 2;
60
c->
stride
[0] = mpi->
width
;
61
c->
stride
[1] = c->
stride
[2] = mpi->
chroma_width
;
62
c->
stride
[3] = c->
w
[3];
63
c->
background
[1] = c->
background
[2] = 128;
64
}
65
66
if
(
ff_gCpuCaps
.
hasMMX
) c->
cpu
|=
PULLUP_CPU_MMX
;
67
if
(
ff_gCpuCaps
.
hasMMX2
) c->
cpu
|=
PULLUP_CPU_MMX2
;
68
if
(
ff_gCpuCaps
.
has3DNow
) c->
cpu
|=
PULLUP_CPU_3DNOW
;
69
if
(
ff_gCpuCaps
.
has3DNowExt
) c->
cpu
|=
PULLUP_CPU_3DNOWEXT
;
70
if
(
ff_gCpuCaps
.
hasSSE
) c->
cpu
|=
PULLUP_CPU_SSE
;
71
if
(
ff_gCpuCaps
.
hasSSE2
) c->
cpu
|=
PULLUP_CPU_SSE2
;
72
73
ff_pullup_init_context
(c);
74
75
vf->priv->init = 1;
76
vf->priv->qbuf = malloc(c->
w
[3]);
77
}
78
79
80
#if 0
81
static
void
get_image
(
struct
vf_instance *vf,
mp_image_t
*mpi)
82
{
83
struct
pullup_context
*
c
= vf->priv->ctx;
84
struct
pullup_buffer
*
b
;
85
86
if
(mpi->
type
==
MP_IMGTYPE_STATIC
)
return
;
87
88
if
(!vf->priv->init)
init_pullup
(vf, mpi);
89
90
b =
ff_pullup_get_buffer
(c, 2);
91
if
(!b)
return
;
/* shouldn't happen... */
92
93
mpi->
priv
=
b
;
94
95
mpi->
planes
[0] = b->
planes
[0];
96
mpi->
planes
[1] = b->
planes
[1];
97
mpi->
planes
[2] = b->
planes
[2];
98
mpi->
stride
[0] = c->
stride
[0];
99
mpi->
stride
[1] = c->
stride
[1];
100
mpi->
stride
[2] = c->
stride
[2];
101
102
mpi->
flags
|=
MP_IMGFLAG_DIRECT
;
103
mpi->
flags
&= ~
MP_IMGFLAG_DRAW_CALLBACK
;
104
}
105
#endif
106
107
static
int
put_image
(
struct
vf_instance *vf,
mp_image_t
*mpi,
double
pts)
108
{
109
struct
pullup_context
*c = vf->priv->ctx;
110
struct
pullup_buffer
*
b
;
111
struct
pullup_frame
*f;
112
mp_image_t
*dmpi;
113
int
ret;
114
int
p;
115
int
i;
116
117
if
(!vf->priv->init)
init_pullup
(vf, mpi);
118
119
if
(mpi->
flags
&
MP_IMGFLAG_DIRECT
) {
120
b = mpi->
priv
;
121
mpi->
priv
= 0;
122
}
else
{
123
b =
ff_pullup_get_buffer
(c, 2);
124
if
(!b) {
125
ff_mp_msg
(
MSGT_VFILTER
,
MSGL_ERR
,
"Could not get buffer from pullup!\n"
);
126
f =
ff_pullup_get_frame
(c);
127
ff_pullup_release_frame
(f);
128
return
0;
129
}
130
memcpy_pic
(b->
planes
[0], mpi->
planes
[0], mpi->
w
, mpi->
h
,
131
c->
stride
[0], mpi->
stride
[0]);
132
if
(mpi->
flags
&
MP_IMGFLAG_PLANAR
) {
133
memcpy_pic
(b->
planes
[1], mpi->
planes
[1],
134
mpi->
chroma_width
, mpi->
chroma_height
,
135
c->
stride
[1], mpi->
stride
[1]);
136
memcpy_pic
(b->
planes
[2], mpi->
planes
[2],
137
mpi->
chroma_width
, mpi->
chroma_height
,
138
c->
stride
[2], mpi->
stride
[2]);
139
}
140
}
141
if
(mpi->
qscale
) {
142
fast_memcpy
(b->
planes
[3], mpi->
qscale
, c->
w
[3]);
143
fast_memcpy
(b->
planes
[3]+c->
w
[3], mpi->
qscale
, c->
w
[3]);
144
}
145
146
p = mpi->
fields
&
MP_IMGFIELD_TOP_FIRST
? 0 :
147
(mpi->
fields
&
MP_IMGFIELD_ORDERED
? 1 : 0);
148
ff_pullup_submit_field
(c, b, p);
149
ff_pullup_submit_field
(c, b, p^1);
150
if
(mpi->
fields
&
MP_IMGFIELD_REPEAT_FIRST
)
151
ff_pullup_submit_field
(c, b, p);
152
153
ff_pullup_release_buffer
(b, 2);
154
155
f =
ff_pullup_get_frame
(c);
156
157
/* Fake yes for first few frames (buffer depth) to keep from
158
* breaking A/V sync with G1's bad architecture... */
159
if
(!f)
return
vf->priv->fakecount ? (--vf->priv->fakecount,1) : 0;
160
161
if
(f->
length
< 2) {
162
ff_pullup_release_frame
(f);
163
f =
ff_pullup_get_frame
(c);
164
if
(!f)
return
0;
165
if
(f->
length
< 2) {
166
ff_pullup_release_frame
(f);
167
if
(!(mpi->
fields
&
MP_IMGFIELD_REPEAT_FIRST
))
168
return
0;
169
f =
ff_pullup_get_frame
(c);
170
if
(!f)
return
0;
171
if
(f->
length
< 2) {
172
ff_pullup_release_frame
(f);
173
return
0;
174
}
175
}
176
}
177
178
#if 0
179
/* Average qscale tables from both frames. */
180
if
(mpi->
qscale
) {
181
for
(i=0; i<c->
w
[3]; i++) {
182
vf->priv->qbuf[i] = (f->
ofields
[0]->
planes
[3][i]
183
+ f->
ofields
[1]->
planes
[3][i+c->
w
[3]])>>1;
184
}
185
}
186
#else
187
/* Take worst of qscale tables from both frames. */
188
if
(mpi->
qscale
) {
189
for
(i=0; i<c->
w
[3]; i++) {
190
vf->priv->qbuf[i] =
MAX
(f->
ofields
[0]->
planes
[3][i], f->
ofields
[1]->
planes
[3][i+c->
w
[3]]);
191
}
192
}
193
#endif
194
195
/* If the frame isn't already exportable... */
196
while
(!f->
buffer
) {
197
dmpi =
ff_vf_get_image
(vf->next, mpi->
imgfmt
,
198
MP_IMGTYPE_TEMP
,
MP_IMGFLAG_ACCEPT_STRIDE
,
199
mpi->
width
, mpi->
height
);
200
/* FIXME: Is it ok to discard dmpi if it's not direct? */
201
if
(!(dmpi->
flags
&
MP_IMGFLAG_DIRECT
)) {
202
ff_pullup_pack_frame
(c, f);
203
break
;
204
}
205
/* Direct render fields into output buffer */
206
my_memcpy_pic
(dmpi->
planes
[0], f->
ofields
[0]->
planes
[0],
207
mpi->
w
, mpi->
h
/2, dmpi->
stride
[0]*2, c->
stride
[0]*2);
208
my_memcpy_pic
(dmpi->
planes
[0] + dmpi->
stride
[0],
209
f->
ofields
[1]->
planes
[0] + c->
stride
[0],
210
mpi->
w
, mpi->
h
/2, dmpi->
stride
[0]*2, c->
stride
[0]*2);
211
if
(mpi->
flags
&
MP_IMGFLAG_PLANAR
) {
212
my_memcpy_pic
(dmpi->
planes
[1], f->
ofields
[0]->
planes
[1],
213
mpi->
chroma_width
, mpi->
chroma_height
/2,
214
dmpi->
stride
[1]*2, c->
stride
[1]*2);
215
my_memcpy_pic
(dmpi->
planes
[1] + dmpi->
stride
[1],
216
f->
ofields
[1]->
planes
[1] + c->
stride
[1],
217
mpi->
chroma_width
, mpi->
chroma_height
/2,
218
dmpi->
stride
[1]*2, c->
stride
[1]*2);
219
my_memcpy_pic
(dmpi->
planes
[2], f->
ofields
[0]->
planes
[2],
220
mpi->
chroma_width
, mpi->
chroma_height
/2,
221
dmpi->
stride
[2]*2, c->
stride
[2]*2);
222
my_memcpy_pic
(dmpi->
planes
[2] + dmpi->
stride
[2],
223
f->
ofields
[1]->
planes
[2] + c->
stride
[2],
224
mpi->
chroma_width
, mpi->
chroma_height
/2,
225
dmpi->
stride
[2]*2, c->
stride
[2]*2);
226
}
227
ff_pullup_release_frame
(f);
228
if
(mpi->
qscale
) {
229
dmpi->
qscale
= vf->priv->qbuf;
230
dmpi->
qstride
= mpi->
qstride
;
231
dmpi->
qscale_type
= mpi->
qscale_type
;
232
}
233
return
ff_vf_next_put_image
(vf, dmpi,
MP_NOPTS_VALUE
);
234
}
235
dmpi =
ff_vf_get_image
(vf->next, mpi->
imgfmt
,
236
MP_IMGTYPE_EXPORT
,
MP_IMGFLAG_ACCEPT_STRIDE
,
237
mpi->
width
, mpi->
height
);
238
239
dmpi->
planes
[0] = f->
buffer
->
planes
[0];
240
dmpi->
planes
[1] = f->
buffer
->
planes
[1];
241
dmpi->
planes
[2] = f->
buffer
->
planes
[2];
242
243
dmpi->
stride
[0] = c->
stride
[0];
244
dmpi->
stride
[1] = c->
stride
[1];
245
dmpi->
stride
[2] = c->
stride
[2];
246
247
if
(mpi->
qscale
) {
248
dmpi->
qscale
= vf->priv->qbuf;
249
dmpi->
qstride
= mpi->
qstride
;
250
dmpi->
qscale_type
= mpi->
qscale_type
;
251
}
252
ret =
ff_vf_next_put_image
(vf, dmpi,
MP_NOPTS_VALUE
);
253
ff_pullup_release_frame
(f);
254
return
ret;
255
}
256
257
static
int
query_format
(
struct
vf_instance *vf,
unsigned
int
fmt
)
258
{
259
/* FIXME - support more formats */
260
switch
(fmt) {
261
case
IMGFMT_YV12
:
262
case
IMGFMT_IYUV
:
263
case
IMGFMT_I420
:
264
return
ff_vf_next_query_format
(vf, fmt);
265
}
266
return
0;
267
}
268
269
static
int
config
(
struct
vf_instance *vf,
270
int
width
,
int
height
,
int
d_width,
int
d_height,
271
unsigned
int
flags
,
unsigned
int
outfmt)
272
{
273
if
(height&3)
return
0;
274
return
ff_vf_next_config
(vf, width, height, d_width, d_height, flags, outfmt);
275
}
276
277
static
void
uninit
(
struct
vf_instance *vf)
278
{
279
ff_pullup_free_context
(vf->priv->ctx);
280
free(vf->priv);
281
}
282
283
static
int
vf_open
(
vf_instance_t
*vf,
char
*args)
284
{
285
struct
vf_priv_s
*p;
286
struct
pullup_context
*
c
;
287
//vf->get_image = get_image;
288
vf->
put_image
=
put_image
;
289
vf->
config
=
config
;
290
vf->
query_format
=
query_format
;
291
vf->
uninit
=
uninit
;
292
vf->
default_reqs
=
VFCAP_ACCEPT_STRIDE
;
293
vf->
priv
= p = calloc(1,
sizeof
(
struct
vf_priv_s
));
294
p->
ctx
= c =
ff_pullup_alloc_context
();
295
p->
fakecount
= 1;
296
c->
junk_left
= c->
junk_right
= 1;
297
c->
junk_top
= c->
junk_bottom
= 4;
298
c->
strict_breaks
= 0;
299
c->
metric_plane
= 0;
300
if
(args) {
301
sscanf(args,
"%d:%d:%d:%d:%d:%d"
, &c->
junk_left
, &c->
junk_right
, &c->
junk_top
, &c->
junk_bottom
, &c->
strict_breaks
, &c->
metric_plane
);
302
}
303
return
1;
304
}
305
306
const
vf_info_t
ff_vf_info_pullup
= {
307
"pullup (from field sequence to frames)"
,
308
"pullup"
,
309
"Rich Felker"
,
310
""
,
311
vf_open
,
312
NULL
313
};
Generated on Sat May 25 2013 03:58:45 for FFmpeg by
1.8.2