Based on patch by Anton Khirnov
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
... | ... |
@@ -329,79 +329,9 @@ fail: |
329 | 329 |
return ret; |
330 | 330 |
} |
331 | 331 |
|
332 |
-static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
|
332 |
+static int scale_slice(AVFilterLink *link, AVFilterBufferRef *out_buf, AVFilterBufferRef *cur_pic, struct SwsContext *sws, int y, int h, int mul, int field) |
|
333 | 333 |
{ |
334 | 334 |
ScaleContext *scale = link->dst->priv; |
335 |
- AVFilterLink *outlink = link->dst->outputs[0]; |
|
336 |
- AVFilterBufferRef *outpicref, *for_next_filter; |
|
337 |
- const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format); |
|
338 |
- char buf[32]; |
|
339 |
- int ret = 0; |
|
340 |
- |
|
341 |
- if( picref->video->w != link->w |
|
342 |
- || picref->video->h != link->h |
|
343 |
- || picref->format != link->format) { |
|
344 |
- int ret; |
|
345 |
- snprintf(buf, sizeof(buf)-1, "%d", outlink->w); |
|
346 |
- av_opt_set(scale, "w", buf, 0); |
|
347 |
- snprintf(buf, sizeof(buf)-1, "%d", outlink->h); |
|
348 |
- av_opt_set(scale, "h", buf, 0); |
|
349 |
- |
|
350 |
- link->dst->inputs[0]->format = picref->format; |
|
351 |
- link->dst->inputs[0]->w = picref->video->w; |
|
352 |
- link->dst->inputs[0]->h = picref->video->h; |
|
353 |
- |
|
354 |
- if ((ret = config_props(outlink)) < 0) |
|
355 |
- return ret; |
|
356 |
- } |
|
357 |
- |
|
358 |
- if (!scale->sws) { |
|
359 |
- outpicref = avfilter_ref_buffer(picref, ~0); |
|
360 |
- if (!outpicref) |
|
361 |
- return AVERROR(ENOMEM); |
|
362 |
- return ff_start_frame(outlink, outpicref); |
|
363 |
- } |
|
364 |
- |
|
365 |
- scale->hsub = desc->log2_chroma_w; |
|
366 |
- scale->vsub = desc->log2_chroma_h; |
|
367 |
- |
|
368 |
- outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE|AV_PERM_ALIGN, outlink->w, outlink->h); |
|
369 |
- if (!outpicref) |
|
370 |
- return AVERROR(ENOMEM); |
|
371 |
- |
|
372 |
- avfilter_copy_buffer_ref_props(outpicref, picref); |
|
373 |
- outpicref->video->w = outlink->w; |
|
374 |
- outpicref->video->h = outlink->h; |
|
375 |
- |
|
376 |
- if(scale->output_is_pal) |
|
377 |
- avpriv_set_systematic_pal2((uint32_t*)outpicref->data[1], outlink->format == AV_PIX_FMT_PAL8 ? AV_PIX_FMT_BGR8 : outlink->format); |
|
378 |
- |
|
379 |
- av_reduce(&outpicref->video->sample_aspect_ratio.num, &outpicref->video->sample_aspect_ratio.den, |
|
380 |
- (int64_t)picref->video->sample_aspect_ratio.num * outlink->h * link->w, |
|
381 |
- (int64_t)picref->video->sample_aspect_ratio.den * outlink->w * link->h, |
|
382 |
- INT_MAX); |
|
383 |
- |
|
384 |
- scale->slice_y = 0; |
|
385 |
- for_next_filter = avfilter_ref_buffer(outpicref, ~0); |
|
386 |
- if (for_next_filter) |
|
387 |
- ret = ff_start_frame(outlink, for_next_filter); |
|
388 |
- else |
|
389 |
- ret = AVERROR(ENOMEM); |
|
390 |
- |
|
391 |
- if (ret < 0) { |
|
392 |
- avfilter_unref_bufferp(&outpicref); |
|
393 |
- return ret; |
|
394 |
- } |
|
395 |
- |
|
396 |
- outlink->out_buf = outpicref; |
|
397 |
- return 0; |
|
398 |
-} |
|
399 |
- |
|
400 |
-static int scale_slice(AVFilterLink *link, struct SwsContext *sws, int y, int h, int mul, int field) |
|
401 |
-{ |
|
402 |
- ScaleContext *scale = link->dst->priv; |
|
403 |
- AVFilterBufferRef *cur_pic = link->cur_buf; |
|
404 |
- AVFilterBufferRef *out_buf = link->dst->outputs[0]->out_buf; |
|
405 | 335 |
const uint8_t *in[4]; |
406 | 336 |
uint8_t *out[4]; |
407 | 337 |
int in_stride[4],out_stride[4]; |
... | ... |
@@ -423,40 +353,71 @@ static int scale_slice(AVFilterLink *link, struct SwsContext *sws, int y, int h, |
423 | 423 |
out,out_stride); |
424 | 424 |
} |
425 | 425 |
|
426 |
-static int draw_slice(AVFilterLink *link, int y, int h, int slice_dir) |
|
426 |
+static int filter_frame(AVFilterLink *link, AVFilterBufferRef *in) |
|
427 | 427 |
{ |
428 | 428 |
ScaleContext *scale = link->dst->priv; |
429 |
- int out_h, ret; |
|
429 |
+ AVFilterLink *outlink = link->dst->outputs[0]; |
|
430 |
+ AVFilterBufferRef *out; |
|
431 |
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format); |
|
432 |
+ char buf[32]; |
|
433 |
+ |
|
434 |
+ if( in->video->w != link->w |
|
435 |
+ || in->video->h != link->h |
|
436 |
+ || in->format != link->format) { |
|
437 |
+ int ret; |
|
438 |
+ snprintf(buf, sizeof(buf)-1, "%d", outlink->w); |
|
439 |
+ av_opt_set(scale, "w", buf, 0); |
|
440 |
+ snprintf(buf, sizeof(buf)-1, "%d", outlink->h); |
|
441 |
+ av_opt_set(scale, "h", buf, 0); |
|
430 | 442 |
|
431 |
- if (!scale->sws) { |
|
432 |
- return ff_draw_slice(link->dst->outputs[0], y, h, slice_dir); |
|
443 |
+ link->dst->inputs[0]->format = in->format; |
|
444 |
+ link->dst->inputs[0]->w = in->video->w; |
|
445 |
+ link->dst->inputs[0]->h = in->video->h; |
|
446 |
+ |
|
447 |
+ if ((ret = config_props(outlink)) < 0) |
|
448 |
+ return ret; |
|
433 | 449 |
} |
434 | 450 |
|
435 |
- if (scale->slice_y == 0 && slice_dir == -1) |
|
436 |
- scale->slice_y = link->dst->outputs[0]->h; |
|
451 |
+ if (!scale->sws) |
|
452 |
+ return ff_filter_frame(outlink, in); |
|
453 |
+ |
|
454 |
+ scale->hsub = desc->log2_chroma_w; |
|
455 |
+ scale->vsub = desc->log2_chroma_h; |
|
456 |
+ |
|
457 |
+ out = ff_get_video_buffer(outlink, AV_PERM_WRITE|AV_PERM_ALIGN, outlink->w, outlink->h); |
|
458 |
+ if (!out) { |
|
459 |
+ avfilter_unref_bufferp(&in); |
|
460 |
+ return AVERROR(ENOMEM); |
|
461 |
+ } |
|
462 |
+ |
|
463 |
+ avfilter_copy_buffer_ref_props(out, in); |
|
464 |
+ out->video->w = outlink->w; |
|
465 |
+ out->video->h = outlink->h; |
|
466 |
+ |
|
467 |
+ if(scale->output_is_pal) |
|
468 |
+ avpriv_set_systematic_pal2((uint32_t*)out->data[1], outlink->format == AV_PIX_FMT_PAL8 ? AV_PIX_FMT_BGR8 : outlink->format); |
|
469 |
+ |
|
470 |
+ av_reduce(&out->video->sample_aspect_ratio.num, &out->video->sample_aspect_ratio.den, |
|
471 |
+ (int64_t)in->video->sample_aspect_ratio.num * outlink->h * link->w, |
|
472 |
+ (int64_t)in->video->sample_aspect_ratio.den * outlink->w * link->h, |
|
473 |
+ INT_MAX); |
|
437 | 474 |
|
438 | 475 |
if(scale->interlaced>0 || (scale->interlaced<0 && link->cur_buf->video->interlaced)){ |
439 |
- av_assert0(y%(2<<scale->vsub) == 0); |
|
440 |
- out_h = scale_slice(link, scale->isws[0], y, (h+1)/2, 2, 0); |
|
441 |
- out_h+= scale_slice(link, scale->isws[1], y, h /2, 2, 1); |
|
476 |
+ scale_slice(link, out, in, scale->isws[0], 0, (link->h+1)/2, 2, 0); |
|
477 |
+ scale_slice(link, out, in, scale->isws[1], 0, link->h /2, 2, 1); |
|
442 | 478 |
}else{ |
443 |
- out_h = scale_slice(link, scale->sws, y, h, 1, 0); |
|
479 |
+ scale_slice(link, out, in, scale->sws, 0, link->h, 1, 0); |
|
444 | 480 |
} |
445 | 481 |
|
446 |
- if (slice_dir == -1) |
|
447 |
- scale->slice_y -= out_h; |
|
448 |
- ret = ff_draw_slice(link->dst->outputs[0], scale->slice_y, out_h, slice_dir); |
|
449 |
- if (slice_dir == 1) |
|
450 |
- scale->slice_y += out_h; |
|
451 |
- return ret; |
|
482 |
+ avfilter_unref_bufferp(&in); |
|
483 |
+ return ff_filter_frame(outlink, out); |
|
452 | 484 |
} |
453 | 485 |
|
454 | 486 |
static const AVFilterPad avfilter_vf_scale_inputs[] = { |
455 | 487 |
{ |
456 | 488 |
.name = "default", |
457 | 489 |
.type = AVMEDIA_TYPE_VIDEO, |
458 |
- .start_frame = start_frame, |
|
459 |
- .draw_slice = draw_slice, |
|
490 |
+ .filter_frame = filter_frame, |
|
460 | 491 |
.min_perms = AV_PERM_READ, |
461 | 492 |
}, |
462 | 493 |
{ NULL } |