213
208
// For the vf option
214
209
const m_obj_list_t vf_obj_list = {
216
M_ST_OFF(vf_info_t,name),
217
M_ST_OFF(vf_info_t,info),
218
M_ST_OFF(vf_info_t,opts)
210
(void **)filter_list,
211
M_ST_OFF(vf_info_t, name),
212
M_ST_OFF(vf_info_t, info),
213
M_ST_OFF(vf_info_t, opts)
221
216
//============================================================================
224
void vf_mpi_clear(mp_image_t* mpi,int x0,int y0,int w,int h){
219
void vf_mpi_clear(mp_image_t *mpi, int x0, int y0, int w, int h)
226
if(mpi->flags&MP_IMGFLAG_PLANAR){
228
if(x0==0 && w==mpi->width){
230
memset(mpi->planes[0]+mpi->stride[0]*y0,0,mpi->stride[0]*h);
231
memset(mpi->planes[1]+mpi->stride[1]*(y0>>mpi->chroma_y_shift),128,mpi->stride[1]*(h>>mpi->chroma_y_shift));
232
memset(mpi->planes[2]+mpi->stride[2]*(y0>>mpi->chroma_y_shift),128,mpi->stride[2]*(h>>mpi->chroma_y_shift));
234
for(y=y0;y<y0+h;y+=2){
235
memset(mpi->planes[0]+x0+mpi->stride[0]*y,0,w);
236
memset(mpi->planes[0]+x0+mpi->stride[0]*(y+1),0,w);
237
memset(mpi->planes[1]+(x0>>mpi->chroma_x_shift)+mpi->stride[1]*(y>>mpi->chroma_y_shift),128,(w>>mpi->chroma_x_shift));
238
memset(mpi->planes[2]+(x0>>mpi->chroma_x_shift)+mpi->stride[2]*(y>>mpi->chroma_y_shift),128,(w>>mpi->chroma_x_shift));
222
if (mpi->flags & MP_IMGFLAG_PLANAR) {
225
if (x0 == 0 && w == mpi->width) {
227
memset(mpi->planes[0] + mpi->stride[0] * y0, 0, mpi->stride[0] * h);
228
memset(mpi->planes[1] + mpi->stride[1] *(y0 >> mpi->chroma_y_shift),
229
128, mpi->stride[1] * (h >> mpi->chroma_y_shift));
230
memset(mpi->planes[2] + mpi->stride[2] *(y0 >> mpi->chroma_y_shift),
231
128, mpi->stride[2] * (h >> mpi->chroma_y_shift));
233
for (y = y0; y < y0 + h; y += 2) {
234
memset(mpi->planes[0] + x0 + mpi->stride[0] * y, 0, w);
235
memset(mpi->planes[0] + x0 + mpi->stride[0] * (y + 1), 0, w);
236
memset(mpi->planes[1] + (x0 >> mpi->chroma_x_shift) +
237
mpi->stride[1] * (y >> mpi->chroma_y_shift),
238
128, (w >> mpi->chroma_x_shift));
239
memset(mpi->planes[2] + (x0 >> mpi->chroma_x_shift) +
240
mpi->stride[2] * (y >> mpi->chroma_y_shift),
241
128, (w >> mpi->chroma_x_shift));
243
for(y=y0;y<y0+h;y++){
244
unsigned char* dst=mpi->planes[0]+mpi->stride[0]*y+(mpi->bpp>>3)*x0;
245
if(mpi->flags&MP_IMGFLAG_YUV){
246
unsigned int* p=(unsigned int*) dst;
247
int size=(mpi->bpp>>3)*w/4;
246
for (y = y0; y < y0 + h; y++) {
247
unsigned char *dst = mpi->planes[0] + mpi->stride[0] * y +
248
(mpi->bpp >> 3) * x0;
249
if (mpi->flags & MP_IMGFLAG_YUV) {
250
unsigned int *p = (unsigned int *) dst;
251
int size = (mpi->bpp >> 3) * w / 4;
249
253
#if HAVE_BIGENDIAN
250
254
#define CLEAR_PACKEDYUV_PATTERN 0x00800080
251
255
#define CLEAR_PACKEDYUV_PATTERN_SWAPPED 0x80008000
253
257
#define CLEAR_PACKEDYUV_PATTERN 0x80008000
254
258
#define CLEAR_PACKEDYUV_PATTERN_SWAPPED 0x00800080
256
if(mpi->flags&MP_IMGFLAG_SWAPPED){
257
for(i=0;i<size-3;i+=4) p[i]=p[i+1]=p[i+2]=p[i+3]=CLEAR_PACKEDYUV_PATTERN_SWAPPED;
258
for(;i<size;i++) p[i]=CLEAR_PACKEDYUV_PATTERN_SWAPPED;
260
for(i=0;i<size-3;i+=4) p[i]=p[i+1]=p[i+2]=p[i+3]=CLEAR_PACKEDYUV_PATTERN;
261
for(;i<size;i++) p[i]=CLEAR_PACKEDYUV_PATTERN;
264
memset(dst,0,(mpi->bpp>>3)*w);
260
if (mpi->flags & MP_IMGFLAG_SWAPPED) {
261
for (i = 0; i < size - 3; i += 4)
262
p[i] = p[i + 1] = p[i + 2] = p[i + 3] = CLEAR_PACKEDYUV_PATTERN_SWAPPED;
263
for (; i < size; i++)
264
p[i] = CLEAR_PACKEDYUV_PATTERN_SWAPPED;
266
for (i = 0; i < size - 3; i += 4)
267
p[i] = p[i + 1] = p[i + 2] = p[i + 3] = CLEAR_PACKEDYUV_PATTERN;
268
for (; i < size; i++)
269
p[i] = CLEAR_PACKEDYUV_PATTERN;
272
memset(dst, 0, (mpi->bpp >> 3) * w);
268
mp_image_t* vf_get_image(vf_instance_t* vf, unsigned int outfmt, int mp_imgtype, int mp_imgflag, int w, int h){
269
mp_image_t* mpi=NULL;
271
int number = mp_imgtype >> 16;
274
assert(w == -1 || w >= vf->w);
275
assert(h == -1 || h >= vf->h);
280
// fprintf(stderr, "get_image: %d:%d, vf: %d:%d\n", w,h,vf->w,vf->h);
282
if (w == -1) w = vf->w;
283
if (h == -1) h = vf->h;
285
w2=(mp_imgflag&MP_IMGFLAG_ACCEPT_ALIGNED_STRIDE)?((w+15)&(~15)):w;
287
if(vf->put_image==vf_next_put_image){
288
// passthru mode, if the filter uses the fallback/default put_image() code
289
return vf_get_image(vf->next,outfmt,mp_imgtype,mp_imgflag,w,h);
292
// Note: we should call libvo first to check if it supports direct rendering
293
// and if not, then fallback to software buffers:
294
switch(mp_imgtype & 0xff){
295
case MP_IMGTYPE_EXPORT:
296
if(!vf->imgctx.export_images[0]) vf->imgctx.export_images[0]=new_mp_image(w2,h);
297
mpi=vf->imgctx.export_images[0];
299
case MP_IMGTYPE_STATIC:
300
if(!vf->imgctx.static_images[0]) vf->imgctx.static_images[0]=new_mp_image(w2,h);
301
mpi=vf->imgctx.static_images[0];
303
case MP_IMGTYPE_TEMP:
304
if(!vf->imgctx.temp_images[0]) vf->imgctx.temp_images[0]=new_mp_image(w2,h);
305
mpi=vf->imgctx.temp_images[0];
308
if(!(mp_imgflag&MP_IMGFLAG_READABLE)){ // B frame:
309
if(!vf->imgctx.temp_images[0]) vf->imgctx.temp_images[0]=new_mp_image(w2,h);
310
mpi=vf->imgctx.temp_images[0];
314
if(!vf->imgctx.static_images[vf->imgctx.static_idx]) vf->imgctx.static_images[vf->imgctx.static_idx]=new_mp_image(w2,h);
315
mpi=vf->imgctx.static_images[vf->imgctx.static_idx];
316
vf->imgctx.static_idx^=1;
318
case MP_IMGTYPE_NUMBERED:
321
for (i = 0; i < NUM_NUMBERED_MPI; i++)
322
if (!vf->imgctx.numbered_images[i] || !vf->imgctx.numbered_images[i]->usage_count)
326
if (number < 0 || number >= NUM_NUMBERED_MPI) return NULL;
327
if (!vf->imgctx.numbered_images[number]) vf->imgctx.numbered_images[number] = new_mp_image(w2,h);
328
mpi = vf->imgctx.numbered_images[number];
329
mpi->number = number;
333
mpi->type=mp_imgtype;
334
mpi->w=vf->w; mpi->h=vf->h;
335
// keep buffer allocation status & color flags only:
336
// mpi->flags&=~(MP_IMGFLAG_PRESERVE|MP_IMGFLAG_READABLE|MP_IMGFLAG_DIRECT);
337
mpi->flags&=MP_IMGFLAG_ALLOCATED|MP_IMGFLAG_TYPE_DISPLAYED|MP_IMGFLAGMASK_COLORS;
338
// accept restrictions, draw_slice and palette flags only:
339
mpi->flags|=mp_imgflag&(MP_IMGFLAGMASK_RESTRICTIONS|MP_IMGFLAG_DRAW_CALLBACK|MP_IMGFLAG_RGB_PALETTE);
340
if(!vf->draw_slice) mpi->flags&=~MP_IMGFLAG_DRAW_CALLBACK;
341
if(mpi->width!=w2 || mpi->height!=h){
342
// printf("vf.c: MPI parameters changed! %dx%d -> %dx%d \n", mpi->width,mpi->height,w2,h);
343
if(mpi->flags&MP_IMGFLAG_ALLOCATED){
344
if(mpi->width<w2 || mpi->height<h){
345
// need to re-allocate buffer memory:
346
av_free(mpi->planes[0]);
347
mpi->flags&=~MP_IMGFLAG_ALLOCATED;
348
mp_msg(MSGT_VFILTER,MSGL_V,"vf.c: have to REALLOCATE buffer memory :(\n");
352
mpi->width=w2; mpi->chroma_width=(w2 + (1<<mpi->chroma_x_shift) - 1)>>mpi->chroma_x_shift;
353
mpi->height=h; mpi->chroma_height=(h + (1<<mpi->chroma_y_shift) - 1)>>mpi->chroma_y_shift;
356
if(!mpi->bpp) mp_image_setfmt(mpi,outfmt);
357
if(!(mpi->flags&MP_IMGFLAG_ALLOCATED) && mpi->type>MP_IMGTYPE_EXPORT){
359
// check libvo first!
360
if(vf->get_image) vf->get_image(vf,mpi);
362
if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
363
// non-direct and not yet allocated image. allocate it!
364
if (!mpi->bpp) { // no way we can allocate this
365
mp_msg(MSGT_DECVIDEO, MSGL_FATAL,
366
"vf_get_image: Tried to allocate a format that can not be allocated!\n");
370
// check if codec prefer aligned stride:
371
if(mp_imgflag&MP_IMGFLAG_PREFER_ALIGNED_STRIDE){
372
int align=(mpi->flags&MP_IMGFLAG_PLANAR &&
373
mpi->flags&MP_IMGFLAG_YUV) ?
374
(8<<mpi->chroma_x_shift)-1 : 15; // -- maybe FIXME
375
w2=((w+align)&(~align));
377
// we have to change width... check if we CAN co it:
378
int flags=vf->query_format(vf,outfmt); // should not fail
379
if(!(flags&3)) mp_msg(MSGT_DECVIDEO,MSGL_WARN,"??? vf_get_image{vf->query_format(outfmt)} failed!\n");
380
// printf("query -> 0x%X \n",flags);
381
if(flags&VFCAP_ACCEPT_STRIDE){
383
mpi->chroma_width=(w2 + (1<<mpi->chroma_x_shift) - 1)>>mpi->chroma_x_shift;
388
mp_image_alloc_planes(mpi);
389
// printf("clearing img!\n");
390
vf_mpi_clear(mpi,0,0,mpi->width,mpi->height);
393
if(mpi->flags&MP_IMGFLAG_DRAW_CALLBACK)
394
if(vf->start_slice) vf->start_slice(vf,mpi);
395
if(!(mpi->flags&MP_IMGFLAG_TYPE_DISPLAYED)){
396
mp_msg(MSGT_DECVIDEO,MSGL_V,"*** [%s] %s%s mp_image_t, %dx%dx%dbpp %s %s, %d bytes\n",
398
(mpi->type==MP_IMGTYPE_EXPORT)?"Exporting":
399
((mpi->flags&MP_IMGFLAG_DIRECT)?"Direct Rendering":"Allocating"),
400
(mpi->flags&MP_IMGFLAG_DRAW_CALLBACK)?" (slices)":"",
401
mpi->width,mpi->height,mpi->bpp,
402
(mpi->flags&MP_IMGFLAG_YUV)?"YUV":((mpi->flags&MP_IMGFLAG_SWAPPED)?"BGR":"RGB"),
403
(mpi->flags&MP_IMGFLAG_PLANAR)?"planar":"packed",
404
mpi->bpp*mpi->width*mpi->height/8);
405
mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"(imgfmt: %x, planes: %p,%p,%p strides: %d,%d,%d, chroma: %dx%d, shift: h:%d,v:%d)\n",
406
mpi->imgfmt, mpi->planes[0], mpi->planes[1], mpi->planes[2],
407
mpi->stride[0], mpi->stride[1], mpi->stride[2],
408
mpi->chroma_width, mpi->chroma_height, mpi->chroma_x_shift, mpi->chroma_y_shift);
409
mpi->flags|=MP_IMGFLAG_TYPE_DISPLAYED;
415
// printf("\rVF_MPI: %p %p %p %d %d %d \n",
416
// mpi->planes[0],mpi->planes[1],mpi->planes[2],
417
// mpi->stride[0],mpi->stride[1],mpi->stride[2]);
276
mp_image_t *vf_get_image(vf_instance_t *vf, unsigned int outfmt,
277
int mp_imgtype, int mp_imgflag, int w, int h)
279
mp_image_t *mpi = NULL;
281
int number = mp_imgtype >> 16;
283
assert(w == -1 || w >= vf->w);
284
assert(h == -1 || h >= vf->h);
293
w2 = (mp_imgflag & MP_IMGFLAG_ACCEPT_ALIGNED_STRIDE) ?
294
((w + 15) & (~15)) : w;
296
if (vf->put_image == vf_next_put_image) {
297
// passthru mode, if the filter uses the fallback/default put_image()
298
return vf_get_image(vf->next, outfmt, mp_imgtype, mp_imgflag, w, h);
301
// Note: we should call libvo first to check if it supports direct rendering
302
// and if not, then fallback to software buffers:
303
switch (mp_imgtype & 0xff) {
304
case MP_IMGTYPE_EXPORT:
305
if (!vf->imgctx.export_images[0])
306
vf->imgctx.export_images[0] = new_mp_image(w2, h);
307
mpi = vf->imgctx.export_images[0];
309
case MP_IMGTYPE_STATIC:
310
if (!vf->imgctx.static_images[0])
311
vf->imgctx.static_images[0] = new_mp_image(w2, h);
312
mpi = vf->imgctx.static_images[0];
314
case MP_IMGTYPE_TEMP:
315
if (!vf->imgctx.temp_images[0])
316
vf->imgctx.temp_images[0] = new_mp_image(w2, h);
317
mpi = vf->imgctx.temp_images[0];
320
if (!(mp_imgflag & MP_IMGFLAG_READABLE)) { // B frame:
321
if (!vf->imgctx.temp_images[0])
322
vf->imgctx.temp_images[0] = new_mp_image(w2, h);
323
mpi = vf->imgctx.temp_images[0];
327
if (!vf->imgctx.static_images[vf->imgctx.static_idx])
328
vf->imgctx.static_images[vf->imgctx.static_idx] = new_mp_image(w2, h);
329
mpi = vf->imgctx.static_images[vf->imgctx.static_idx];
330
vf->imgctx.static_idx ^= 1;
332
case MP_IMGTYPE_NUMBERED:
335
for (i = 0; i < NUM_NUMBERED_MPI; i++)
336
if (!vf->imgctx.numbered_images[i] ||
337
!vf->imgctx.numbered_images[i]->usage_count)
341
if (number < 0 || number >= NUM_NUMBERED_MPI)
343
if (!vf->imgctx.numbered_images[number])
344
vf->imgctx.numbered_images[number] = new_mp_image(w2, h);
345
mpi = vf->imgctx.numbered_images[number];
346
mpi->number = number;
350
mpi->type = mp_imgtype;
353
// keep buffer allocation status & color flags only:
354
mpi->flags &= MP_IMGFLAG_ALLOCATED | MP_IMGFLAG_TYPE_DISPLAYED |
355
MP_IMGFLAGMASK_COLORS;
356
// accept restrictions, draw_slice and palette flags only:
357
mpi->flags |= mp_imgflag & (MP_IMGFLAGMASK_RESTRICTIONS |
358
MP_IMGFLAG_DRAW_CALLBACK | MP_IMGFLAG_RGB_PALETTE);
360
mpi->flags &= ~MP_IMGFLAG_DRAW_CALLBACK;
361
if (mpi->width != w2 || mpi->height != h) {
362
if (mpi->flags & MP_IMGFLAG_ALLOCATED) {
363
if (mpi->width < w2 || mpi->height < h) {
364
// need to re-allocate buffer memory:
365
av_free(mpi->planes[0]);
366
mpi->flags &= ~MP_IMGFLAG_ALLOCATED;
367
mp_msg(MSGT_VFILTER, MSGL_V,
368
"vf.c: have to REALLOCATE buffer memory :(\n");
372
mpi->chroma_width = (w2 + (1 << mpi->chroma_x_shift) - 1) >>
375
mpi->chroma_height = (h + (1 << mpi->chroma_y_shift) - 1) >>
379
mp_image_setfmt(mpi, outfmt);
380
if (!(mpi->flags & MP_IMGFLAG_ALLOCATED) &&
381
mpi->type > MP_IMGTYPE_EXPORT) {
382
// check libvo first!
384
vf->get_image(vf, mpi);
386
if (!(mpi->flags & MP_IMGFLAG_DIRECT)) {
387
// non-direct and not yet allocated image. allocate it!
388
if (!mpi->bpp) { // no way we can allocate this
389
mp_msg(MSGT_DECVIDEO, MSGL_FATAL,
390
"vf_get_image: Tried to allocate a format that "
391
"can not be allocated!\n");
395
// check if codec prefer aligned stride:
396
if (mp_imgflag & MP_IMGFLAG_PREFER_ALIGNED_STRIDE) {
397
int align = (mpi->flags & MP_IMGFLAG_PLANAR &&
398
mpi->flags & MP_IMGFLAG_YUV) ?
399
(8 << mpi->chroma_x_shift) - 1 : 15; // OK?
400
w2 = ((w + align) & (~align));
401
if (mpi->width != w2) {
402
// we have to change width... check if we CAN co it:
403
int flags = vf->query_format(vf, outfmt);
405
if (!(flags & (VFCAP_CSP_SUPPORTED |
406
VFCAP_CSP_SUPPORTED_BY_HW)))
407
mp_msg(MSGT_DECVIDEO, MSGL_WARN,
408
"??? vf_get_image{vf->query_format(outfmt)} "
410
if (flags & VFCAP_ACCEPT_STRIDE) {
413
(w2 + (1 << mpi->chroma_x_shift) - 1) >>
419
mp_image_alloc_planes(mpi);
420
vf_mpi_clear(mpi, 0, 0, mpi->width, mpi->height);
423
if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK)
425
vf->start_slice(vf, mpi);
426
if (!(mpi->flags & MP_IMGFLAG_TYPE_DISPLAYED)) {
427
mp_msg(MSGT_DECVIDEO, MSGL_V,
428
"*** [%s] %s%s mp_image_t, %dx%dx%dbpp %s %s, %d bytes\n",
430
(mpi->type == MP_IMGTYPE_EXPORT) ? "Exporting" :
431
((mpi->flags & MP_IMGFLAG_DIRECT) ?
432
"Direct Rendering" : "Allocating"),
433
(mpi->flags & MP_IMGFLAG_DRAW_CALLBACK) ? " (slices)" : "",
434
mpi->width, mpi->height, mpi->bpp,
435
(mpi->flags & MP_IMGFLAG_YUV) ? "YUV" :
436
((mpi->flags & MP_IMGFLAG_SWAPPED) ? "BGR" : "RGB"),
437
(mpi->flags & MP_IMGFLAG_PLANAR) ? "planar" : "packed",
438
mpi->bpp * mpi->width * mpi->height / 8);
439
mp_msg(MSGT_DECVIDEO, MSGL_DBG2, "(imgfmt: %x, planes: %p,%p,%p "
440
"strides: %d,%d,%d, chroma: %dx%d, shift: h:%d,v:%d)\n",
441
mpi->imgfmt, mpi->planes[0], mpi->planes[1], mpi->planes[2],
442
mpi->stride[0], mpi->stride[1], mpi->stride[2],
443
mpi->chroma_width, mpi->chroma_height,
444
mpi->chroma_x_shift, mpi->chroma_y_shift);
445
mpi->flags |= MP_IMGFLAG_TYPE_DISPLAYED;
421
453
//============================================================================
423
455
// By default vf doesn't accept MPEGPES
424
static int vf_default_query_format(struct vf_instance *vf, unsigned int fmt){
425
if(fmt == IMGFMT_MPEGPES) return 0;
426
return vf_next_query_format(vf,fmt);
456
static int vf_default_query_format(struct vf_instance *vf, unsigned int fmt)
458
if (fmt == IMGFMT_MPEGPES)
460
return vf_next_query_format(vf, fmt);
429
463
struct vf_instance *vf_open_plugin_noerr(struct MPOpts *opts,
430
const vf_info_t * const *filter_list,
464
const vf_info_t *const *filter_list,
431
465
vf_instance_t *next, const char *name,
432
466
char **args, int *retcode)
438
mp_tmsg(MSGT_VFILTER,MSGL_ERR,"Couldn't find video filter '%s'.\n",name);
439
return NULL; // no such filter!
441
if(!strcmp(filter_list[i]->name,name)) break;
471
if (!filter_list[i]) {
472
mp_tmsg(MSGT_VFILTER, MSGL_ERR,
473
"Couldn't find video filter '%s'.\n", name);
474
return NULL; // no such filter!
476
if (!strcmp(filter_list[i]->name, name))
443
479
vf = calloc(1, sizeof *vf);
445
vf->info=filter_list[i];
447
vf->config=vf_next_config;
448
vf->control=vf_next_control;
449
vf->query_format=vf_default_query_format;
450
vf->put_image=vf_next_put_image;
451
vf->default_caps=VFCAP_ACCEPT_STRIDE;
453
if(vf->info->opts) { // vf_vo get some special argument
454
const m_struct_t* st = vf->info->opts;
455
void* vf_priv = m_struct_alloc(st);
457
for(n = 0 ; args && args[2*n] ; n++)
458
m_struct_set(st,vf_priv,args[2*n],args[2*n+1]);
481
vf->info = filter_list[i];
483
vf->config = vf_next_config;
484
vf->control = vf_next_control;
485
vf->query_format = vf_default_query_format;
486
vf->put_image = vf_next_put_image;
487
vf->default_caps = VFCAP_ACCEPT_STRIDE;
488
vf->default_reqs = 0;
489
if (vf->info->opts) { // vf_vo get some special argument
490
const m_struct_t *st = vf->info->opts;
491
void *vf_priv = m_struct_alloc(st);
493
for (n = 0; args && args[2 * n]; n++)
494
m_struct_set(st, vf_priv, args[2 * n], bstr(args[2 * n + 1]));
461
497
} else // Otherwise we should have the '_oldargs_'
462
if(args && !strcmp(args[0],"_oldargs_"))
463
args = (char**)args[1];
466
*retcode = vf->info->vf_open(vf,(char*)args);
498
if (args && !strcmp(args[0], "_oldargs_"))
499
args = (char **)args[1];
502
*retcode = vf->info->vf_open(vf, (char *)args);
467
503
if (*retcode > 0)
516
554
* \param args argument list for the filter.
517
555
* \return pointer to the filter instance that was created.
519
vf_instance_t* vf_add_before_vo(vf_instance_t **vf, char *name, char **args) {
520
struct MPOpts *opts = (*vf)->opts;
521
vf_instance_t *vo, *prev = NULL, *new;
522
// Find the last filter (should be vf_vo)
523
for (vo = *vf; vo->next; vo = vo->next)
525
new = vf_open_filter(opts, vo, name, args);
557
vf_instance_t *vf_add_before_vo(vf_instance_t **vf, char *name, char **args)
559
struct MPOpts *opts = (*vf)->opts;
560
vf_instance_t *vo, *prev = NULL, *new;
561
// Find the last filter (should be vf_vo)
562
for (vo = *vf; vo->next; vo = vo->next)
564
new = vf_open_filter(opts, vo, name, args);
533
572
//============================================================================
535
unsigned int vf_match_csp(vf_instance_t** vfp,const unsigned int* list,unsigned int preferred){
536
vf_instance_t* vf=*vfp;
574
unsigned int vf_match_csp(vf_instance_t **vfp, const unsigned int *list,
575
unsigned int preferred)
577
vf_instance_t *vf = *vfp;
537
578
struct MPOpts *opts = vf->opts;
538
const unsigned int* p;
579
const unsigned int *p;
580
unsigned int best = 0;
541
if((p=list)) while(*p){
542
ret=vf->query_format(vf,*p);
543
mp_msg(MSGT_VFILTER,MSGL_V,"[%s] query(%s) -> %d\n",vf->info->name,vo_format_name(*p),ret&3);
544
if(ret&2){ best=*p; break;} // no conversion -> bingo!
545
if(ret&1 && !best) best=*p; // best with conversion
548
if(best) return best; // bingo, they have common csp!
584
ret = vf->query_format(vf, *p);
585
mp_msg(MSGT_VFILTER, MSGL_V, "[%s] query(%s) -> %x\n",
586
vf->info->name, vo_format_name(*p), ret);
587
if (ret & VFCAP_CSP_SUPPORTED_BY_HW) {
591
if (ret & VFCAP_CSP_SUPPORTED && !best)
596
return best; // bingo, they have common csp!
549
597
// ok, then try with scale:
550
if(vf->info == &vf_info_scale) return 0; // avoid infinite recursion!
551
vf=vf_open_filter(opts, vf,"scale",NULL);
552
if(!vf) return 0; // failed to init "scale"
598
if (vf->info == &vf_info_scale)
599
return 0; // avoid infinite recursion!
600
vf = vf_open_filter(opts, vf, "scale", NULL);
602
return 0; // failed to init "scale"
553
603
// try the preferred csp first:
554
if(preferred && vf->query_format(vf,preferred)) best=preferred; else
555
// try the list again, now with "scaler" :
556
if((p=list)) while(*p){
557
ret=vf->query_format(vf,*p);
558
mp_msg(MSGT_VFILTER,MSGL_V,"[%s] query(%s) -> %d\n",vf->info->name,vo_format_name(*p),ret&3);
559
if(ret&2){ best=*p; break;} // no conversion -> bingo!
560
if(ret&1 && !best) best=*p; // best with conversion
563
if(best) *vfp=vf; // else uninit vf !FIXME!
604
if (preferred && vf->query_format(vf, preferred))
607
// try the list again, now with "scaler" :
610
ret = vf->query_format(vf, *p);
611
mp_msg(MSGT_VFILTER, MSGL_V, "[%s] query(%s) -> %x\n",
612
vf->info->name, vo_format_name(*p), ret);
613
if (ret & VFCAP_CSP_SUPPORTED_BY_HW) {
617
if (ret & VFCAP_CSP_SUPPORTED && !best)
622
*vfp = vf; // else uninit vf !FIXME!
567
void vf_clone_mpi_attributes(mp_image_t* dst, mp_image_t* src){
568
dst->pict_type= src->pict_type;
626
void vf_clone_mpi_attributes(mp_image_t *dst, mp_image_t *src)
628
dst->pict_type = src->pict_type;
569
629
dst->fields = src->fields;
570
dst->qscale_type= src->qscale_type;
571
if(dst->width == src->width && dst->height == src->height){
572
dst->qstride= src->qstride;
573
dst->qscale= src->qscale;
630
dst->qscale_type = src->qscale_type;
631
if (dst->width == src->width && dst->height == src->height) {
632
dst->qstride = src->qstride;
633
dst->qscale = src->qscale;
636
697
vf->fmt.orig_width = width;
637
698
vf->fmt.orig_fmt = outfmt;
638
699
r = vf->config(vf, width, height, d_width, d_height, flags, outfmt);
639
if (!r) vf->fmt.have_configured = 0;
701
vf->fmt.have_configured = 0;
643
705
int vf_next_config(struct vf_instance *vf,
644
int width, int height, int d_width, int d_height,
645
unsigned int voflags, unsigned int outfmt){
706
int width, int height, int d_width, int d_height,
707
unsigned int voflags, unsigned int outfmt)
646
709
struct MPOpts *opts = vf->opts;
648
int flags=vf->next->query_format(vf->next,outfmt);
650
// hmm. colorspace mismatch!!!
651
// let's insert the 'scale' filter, it does the job for us:
653
if(vf->next->info==&vf_info_scale) return 0; // scale->scale
654
vf2=vf_open_filter(opts, vf->next,"scale",NULL);
655
if(!vf2) return 0; // shouldn't happen!
657
flags=vf->next->query_format(vf->next,outfmt);
659
mp_tmsg(MSGT_VFILTER,MSGL_ERR,"Cannot find matching colorspace, even by inserting 'scale' :(\n");
663
mp_msg(MSGT_VFILTER,MSGL_V,"REQ: flags=0x%X req=0x%X \n",flags,vf->default_reqs);
664
miss=vf->default_reqs - (flags&vf->default_reqs);
665
if(miss&VFCAP_ACCEPT_STRIDE){
666
// vf requires stride support but vf->next doesn't support it!
667
// let's insert the 'expand' filter, it does the job for us:
668
vf_instance_t* vf2=vf_open_filter(opts, vf->next,"expand",NULL);
669
if(!vf2) return 0; // shouldn't happen!
672
vf->next->w = width; vf->next->h = height;
673
return vf_config_wrapper(vf->next,width,height,d_width,d_height,voflags,outfmt);
676
int vf_next_control(struct vf_instance *vf, int request, void* data){
677
return vf->next->control(vf->next,request,data);
680
int vf_next_query_format(struct vf_instance *vf, unsigned int fmt){
681
int flags=vf->next->query_format(vf->next,fmt);
682
if(flags) flags|=vf->default_caps;
711
int flags = vf->next->query_format(vf->next, outfmt);
713
// hmm. colorspace mismatch!!!
714
// let's insert the 'scale' filter, it does the job for us:
716
if (vf->next->info == &vf_info_scale)
717
return 0; // scale->scale
718
vf2 = vf_open_filter(opts, vf->next, "scale", NULL);
720
return 0; // shouldn't happen!
722
flags = vf->next->query_format(vf->next, outfmt);
724
mp_tmsg(MSGT_VFILTER, MSGL_ERR, "Cannot find matching colorspace, "
725
"even by inserting 'scale' :(\n");
729
mp_msg(MSGT_VFILTER, MSGL_V, "REQ: flags=0x%X req=0x%X \n",
730
flags, vf->default_reqs);
731
miss = vf->default_reqs - (flags & vf->default_reqs);
732
if (miss & VFCAP_ACCEPT_STRIDE) {
733
// vf requires stride support but vf->next doesn't support it!
734
// let's insert the 'expand' filter, it does the job for us:
735
vf_instance_t *vf2 = vf_open_filter(opts, vf->next, "expand", NULL);
737
return 0; // shouldn't happen!
741
vf->next->h = height;
742
return vf_config_wrapper(vf->next, width, height, d_width, d_height,
746
int vf_next_control(struct vf_instance *vf, int request, void *data)
748
return vf->next->control(vf->next, request, data);
751
int vf_next_query_format(struct vf_instance *vf, unsigned int fmt)
753
int flags = vf->next->query_format(vf->next, fmt);
755
flags |= vf->default_caps;
686
int vf_next_put_image(struct vf_instance *vf,mp_image_t *mpi, double pts){
687
return vf->next->put_image(vf->next,mpi, pts);
759
int vf_next_put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
761
return vf->next->put_image(vf->next, mpi, pts);
690
void vf_next_draw_slice(struct vf_instance *vf,unsigned char** src, int * stride,int w, int h, int x, int y){
764
void vf_next_draw_slice(struct vf_instance *vf, unsigned char **src,
765
int *stride, int w, int h, int x, int y)
691
767
if (vf->next->draw_slice) {
692
vf->next->draw_slice(vf->next,src,stride,w,h,x,y);
768
vf->next->draw_slice(vf->next, src, stride, w, h, x, y);
696
mp_msg(MSGT_VFILTER,MSGL_ERR,"draw_slice: dmpi not stored by vf_%s\n", vf->info->name);
772
mp_msg(MSGT_VFILTER, MSGL_ERR,
773
"draw_slice: dmpi not stored by vf_%s\n", vf->info->name);
699
776
if (!(vf->dmpi->flags & MP_IMGFLAG_PLANAR)) {
700
memcpy_pic(vf->dmpi->planes[0]+y*vf->dmpi->stride[0]+vf->dmpi->bpp/8*x,
701
src[0], vf->dmpi->bpp/8*w, h, vf->dmpi->stride[0], stride[0]);
777
memcpy_pic(vf->dmpi->planes[0] + y * vf->dmpi->stride[0] +
778
vf->dmpi->bpp / 8 * x,
779
src[0], vf->dmpi->bpp / 8 * w, h, vf->dmpi->stride[0],
704
memcpy_pic(vf->dmpi->planes[0]+y*vf->dmpi->stride[0]+x, src[0],
705
w, h, vf->dmpi->stride[0], stride[0]);
706
memcpy_pic(vf->dmpi->planes[1]+(y>>vf->dmpi->chroma_y_shift)*vf->dmpi->stride[1]+(x>>vf->dmpi->chroma_x_shift),
707
src[1], w>>vf->dmpi->chroma_x_shift, h>>vf->dmpi->chroma_y_shift, vf->dmpi->stride[1], stride[1]);
708
memcpy_pic(vf->dmpi->planes[2]+(y>>vf->dmpi->chroma_y_shift)*vf->dmpi->stride[2]+(x>>vf->dmpi->chroma_x_shift),
709
src[2], w>>vf->dmpi->chroma_x_shift, h>>vf->dmpi->chroma_y_shift, vf->dmpi->stride[2], stride[2]);
783
memcpy_pic(vf->dmpi->planes[0] + y * vf->dmpi->stride[0] + x, src[0],
784
w, h, vf->dmpi->stride[0], stride[0]);
785
memcpy_pic(vf->dmpi->planes[1]
786
+ (y >> vf->dmpi->chroma_y_shift) * vf->dmpi->stride[1]
787
+ (x >> vf->dmpi->chroma_x_shift),
788
src[1], w >> vf->dmpi->chroma_x_shift,
789
h >> vf->dmpi->chroma_y_shift, vf->dmpi->stride[1], stride[1]);
790
memcpy_pic(vf->dmpi->planes[2]
791
+ (y >> vf->dmpi->chroma_y_shift) * vf->dmpi->stride[2]
792
+ (x >> vf->dmpi->chroma_x_shift),
793
src[2], w >> vf->dmpi->chroma_x_shift,
794
h >> vf->dmpi->chroma_y_shift, vf->dmpi->stride[2], stride[2]);
712
797
//============================================================================
714
vf_instance_t *append_filters(vf_instance_t* last,
799
vf_instance_t *append_filters(vf_instance_t *last,
715
800
struct m_obj_settings *vf_settings)
717
struct MPOpts *opts = last->opts;
802
struct MPOpts *opts = last->opts;
722
// We want to add them in the 'right order'
723
for(i = 0 ; vf_settings[i].name ; i++)
725
for(i-- ; i >= 0 ; i--) {
726
//printf("Open filter %s\n",vf_settings[i].name);
727
vf = vf_open_filter(opts, last,vf_settings[i].name,vf_settings[i].attribs);
807
// We want to add them in the 'right order'
808
for (i = 0; vf_settings[i].name; i++)
810
for (i--; i >= 0; i--) {
811
//printf("Open filter %s\n",vf_settings[i].name);
812
vf = vf_open_filter(opts, last, vf_settings[i].name,
813
vf_settings[i].attribs);
734
821
//============================================================================
736
void vf_uninit_filter(vf_instance_t* vf){
737
if(vf->uninit) vf->uninit(vf);
823
void vf_uninit_filter(vf_instance_t *vf)
738
827
free_mp_image(vf->imgctx.static_images[0]);
739
828
free_mp_image(vf->imgctx.static_images[1]);
740
829
free_mp_image(vf->imgctx.temp_images[0]);