Most logic from this filter has been co-opted into swscale itself, allowing the resulting filter to be substantially simpler as it no longer has to worry about context initialization, interlacing, etc.
Showing the changes to libavfilter (1 of 1 file). Show all
Unified · Split
| @@ -31,6 +31,7 @@ · 30 unmodified lines | ||
| 31 | 31 | #include "filters.h" |
| 32 | 32 | #include "formats.h" |
| 33 | 33 | #include "framesync.h" |
| 34 | +#include "libavutil/pixfmt.h" | |
| 34 | 35 | #include "scale_eval.h" |
| 35 | 36 | #include "video.h" |
| 36 | 37 | #include "libavutil/eval.h" |
| @@ -131,10 +132,7 @@ enum EvalMode { · 94 unmodified lines | ||
| 131 | 132 | |
| 132 | 133 | typedef struct ScaleContext { |
| 133 | 134 | const AVClass *class; |
| 134 | − struct SwsContext *sws; ///< software scaler context | |
| 135 | − struct SwsContext *isws[2]; ///< software scaler context for interlaced material | |
| 136 | − // context used for forwarding options to sws | |
| 137 | − struct SwsContext *sws_opts; | |
| 135 | + SwsContext *sws; | |
| 138 | 136 | FFFrameSync fs; |
| 139 | 137 | |
| 140 | 138 | /** |
| @@ -149,8 +147,6 @@ typedef struct ScaleContext { · 8 unmodified lines | ||
| 149 | 147 | |
| 150 | 148 | int hsub, vsub; ///< chroma subsampling |
| 151 | 149 | int slice_y; ///< top of current output slice |
| 152 | − int input_is_pal; ///< set to 1 if the input format is paletted | |
| 153 | − int output_is_pal; ///< set to 1 if the output format is paletted | |
| 154 | 150 | int interlaced; |
| 155 | 151 | int uses_ref; |
| 156 | 152 | |
| @@ -334,40 +330,24 @@ revert: · 177 unmodified lines | ||
| 334 | 330 | static av_cold int preinit(AVFilterContext *ctx) |
| 335 | 331 | { |
| 336 | 332 | ScaleContext *scale = ctx->priv; |
| 337 | − int ret; | |
| 338 | 333 | |
| 339 | − scale->sws_opts = sws_alloc_context(); | |
| 340 | − if (!scale->sws_opts) | |
| 334 | + scale->sws = sws_alloc_context(); | |
| 335 | + if (!scale->sws) | |
| 341 | 336 | return AVERROR(ENOMEM); |
| 342 | 337 | |
| 343 | 338 | // set threads=0, so we can later check whether the user modified it |
| 344 | − ret = av_opt_set_int(scale->sws_opts, "threads", 0, 0); | |
| 345 | − if (ret < 0) | |
| 346 | − return ret; | |
| 339 | + scale->sws->threads = 0; | |
| 347 | 340 | |
| 348 | 341 | ff_framesync_preinit(&scale->fs); |
| 349 | 342 | |
| 350 | 343 | return 0; |
| 351 | 344 | } |
| 352 | 345 | |
| 353 | −static const int sws_colorspaces[] = { | |
| 354 | − AVCOL_SPC_UNSPECIFIED, | |
| 355 | − AVCOL_SPC_RGB, | |
| 356 | − AVCOL_SPC_BT709, | |
| 357 | − AVCOL_SPC_BT470BG, | |
| 358 | − AVCOL_SPC_SMPTE170M, | |
| 359 | − AVCOL_SPC_FCC, | |
| 360 | − AVCOL_SPC_SMPTE240M, | |
| 361 | − AVCOL_SPC_BT2020_NCL, | |
| 362 | − -1 | |
| 363 | −}; | |
| 364 | − | |
| 365 | 346 | static int do_scale(FFFrameSync *fs); |
| 366 | 347 | |
| 367 | 348 | static av_cold int init(AVFilterContext *ctx) |
| 368 | 349 | { |
| 369 | 350 | ScaleContext *scale = ctx->priv; |
| 370 | − int64_t threads; | |
| 371 | 351 | int ret; |
| 372 | 352 | |
| 373 | 353 | if (ctx->filter == &ff_vf_scale2ref) |
| @@ -407,14 +387,13 @@ static av_cold int init(AVFilterContext *ctx) · 33 unmodified lines | ||
| 407 | 387 | if (ret < 0) |
| 408 | 388 | return ret; |
| 409 | 389 | |
| 410 | − if (scale->in_color_matrix != -1 && | |
| 411 | − !ff_fmt_is_in(scale->in_color_matrix, sws_colorspaces)) { | |
| 390 | + if (scale->in_color_matrix != -1 && !sws_test_colorspace(scale->in_color_matrix, 0)) { | |
| 412 | 391 | av_log(ctx, AV_LOG_ERROR, "Unsupported input color matrix '%s'\n", |
| 413 | 392 | av_color_space_name(scale->in_color_matrix)); |
| 414 | 393 | return AVERROR(EINVAL); |
| 415 | 394 | } |
| 416 | 395 | |
| 417 | − if (!ff_fmt_is_in(scale->out_color_matrix, sws_colorspaces)) { | |
| 396 | + if (scale->out_color_matrix != -1 && !sws_test_colorspace(scale->out_color_matrix, 1)) { | |
| 418 | 397 | av_log(ctx, AV_LOG_ERROR, "Unsupported output color matrix '%s'\n", |
| 419 | 398 | av_color_space_name(scale->out_color_matrix)); |
| 420 | 399 | return AVERROR(EINVAL); |
| @@ -424,25 +403,23 @@ static av_cold int init(AVFilterContext *ctx) · 3 unmodified lines | ||
| 424 | 403 | scale->w_expr, scale->h_expr, (char *)av_x_if_null(scale->flags_str, ""), scale->interlaced); |
| 425 | 404 | |
| 426 | 405 | if (scale->flags_str && *scale->flags_str) { |
| 427 | − ret = av_opt_set(scale->sws_opts, "sws_flags", scale->flags_str, 0); | |
| 406 | + ret = av_opt_set(scale->sws, "sws_flags", scale->flags_str, 0); | |
| 428 | 407 | if (ret < 0) |
| 429 | 408 | return ret; |
| 430 | 409 | } |
| 431 | 410 | |
| 432 | 411 | for (int i = 0; i < FF_ARRAY_ELEMS(scale->param); i++) |
| 433 | − if (scale->param[i] != DBL_MAX) { | |
| 434 | − ret = av_opt_set_double(scale->sws_opts, i ? "param1" : "param0", | |
| 435 | − scale->param[i], 0); | |
| 436 | − if (ret < 0) | |
| 437 | − return ret; | |
| 438 | − } | |
| 412 | + if (scale->param[i] != DBL_MAX) | |
| 413 | + scale->sws->scaler_params[i] = scale->param[i]; | |
| 414 | + | |
| 415 | + scale->sws->src_h_chr_pos = scale->in_h_chr_pos; | |
| 416 | + scale->sws->src_v_chr_pos = scale->in_v_chr_pos; | |
| 417 | + scale->sws->dst_h_chr_pos = scale->out_h_chr_pos; | |
| 418 | + scale->sws->dst_v_chr_pos = scale->out_v_chr_pos; | |
| 439 | 419 | |
| 440 | 420 | // use generic thread-count if the user did not set it explicitly |
| 441 | − ret = av_opt_get_int(scale->sws_opts, "threads", 0, &threads); | |
| 442 | − if (ret < 0) | |
| 443 | − return ret; | |
| 444 | − if (!threads) | |
| 445 | − av_opt_set_int(scale->sws_opts, "threads", ff_filter_get_nb_threads(ctx), 0); | |
| 421 | + if (!scale->sws->threads) | |
| 422 | + scale->sws->threads = ff_filter_get_nb_threads(ctx); | |
| 446 | 423 | |
| 447 | 424 | if (ctx->filter != &ff_vf_scale2ref && scale->uses_ref) { |
| 448 | 425 | AVFilterPad pad = { |
| @@ -464,11 +441,7 @@ static av_cold void uninit(AVFilterContext *ctx) · 15 unmodified lines | ||
| 464 | 441 | av_expr_free(scale->h_pexpr); |
| 465 | 442 | scale->w_pexpr = scale->h_pexpr = NULL; |
| 466 | 443 | ff_framesync_uninit(&scale->fs); |
| 467 | − sws_freeContext(scale->sws_opts); | |
| 468 | − sws_freeContext(scale->sws); | |
| 469 | − sws_freeContext(scale->isws[0]); | |
| 470 | − sws_freeContext(scale->isws[1]); | |
| 471 | − scale->sws = NULL; | |
| 444 | + sws_free_context(&scale->sws); | |
| 472 | 445 | } |
| 473 | 446 | |
| 474 | 447 | static int query_formats(const AVFilterContext *ctx, |
| @@ -485,10 +458,9 @@ static int query_formats(const AVFilterContext *ctx, · 10 unmodified lines | ||
| 485 | 458 | formats = NULL; |
| 486 | 459 | while ((desc = av_pix_fmt_desc_next(desc))) { |
| 487 | 460 | pix_fmt = av_pix_fmt_desc_get_id(desc); |
| 488 | − if ((sws_isSupportedInput(pix_fmt) || | |
| 489 | − sws_isSupportedEndiannessConversion(pix_fmt)) | |
| 490 | − && (ret = ff_add_format(&formats, pix_fmt)) < 0) { | |
| 491 | − return ret; | |
| 461 | + if (sws_test_format(pix_fmt, 0)) { | |
| 462 | + if ((ret = ff_add_format(&formats, pix_fmt)) < 0) | |
| 463 | + return ret; | |
| 492 | 464 | } |
| 493 | 465 | } |
| 494 | 466 | if ((ret = ff_formats_ref(formats, &cfg_in[0]->formats)) < 0) |
| @@ -498,18 +470,24 @@ static int query_formats(const AVFilterContext *ctx, · 3 unmodified lines | ||
| 498 | 470 | formats = NULL; |
| 499 | 471 | while ((desc = av_pix_fmt_desc_next(desc))) { |
| 500 | 472 | pix_fmt = av_pix_fmt_desc_get_id(desc); |
| 501 | − if ((sws_isSupportedOutput(pix_fmt) || pix_fmt == AV_PIX_FMT_PAL8 || | |
| 502 | − sws_isSupportedEndiannessConversion(pix_fmt)) | |
| 503 | − && (ret = ff_add_format(&formats, pix_fmt)) < 0) { | |
| 504 | − return ret; | |
| 473 | + if (sws_test_format(pix_fmt, 1) || pix_fmt == AV_PIX_FMT_PAL8) { | |
| 474 | + if ((ret = ff_add_format(&formats, pix_fmt)) < 0) | |
| 475 | + return ret; | |
| 505 | 476 | } |
| 506 | 477 | } |
| 507 | 478 | if ((ret = ff_formats_ref(formats, &cfg_out[0]->formats)) < 0) |
| 508 | 479 | return ret; |
| 509 | 480 | |
| 510 | 481 | /* accept all supported inputs, even if user overrides their properties */ |
| 511 | − if ((ret = ff_formats_ref(ff_make_format_list(sws_colorspaces), | |
| 512 | − &cfg_in[0]->color_spaces)) < 0) | |
| 482 | + formats = ff_all_color_spaces(); | |
| 483 | + for (int i = 0; i < formats->nb_formats; i++) { | |
| 484 | + if (!sws_test_colorspace(formats->formats[i], 0)) { | |
| 485 | + for (int j = i--; j < formats->nb_formats; j++) | |
| 486 | + formats->formats[j] = formats->formats[j + 1]; | |
| 487 | + formats->nb_formats--; | |
| 488 | + } | |
| 489 | + } | |
| 490 | + if ((ret = ff_formats_ref(formats, &cfg_in[0]->color_spaces)) < 0) | |
| 513 | 491 | return ret; |
| 514 | 492 | |
| 515 | 493 | if ((ret = ff_formats_ref(ff_all_color_ranges(), |
| @@ -517,9 +495,18 @@ static int query_formats(const AVFilterContext *ctx, · 1 unmodified line | ||
| 517 | 495 | return ret; |
| 518 | 496 | |
| 519 | 497 | /* propagate output properties if overridden */ |
| 520 | − formats = scale->out_color_matrix != AVCOL_SPC_UNSPECIFIED | |
| 521 | − ? ff_make_formats_list_singleton(scale->out_color_matrix) | |
| 522 | − : ff_make_format_list(sws_colorspaces); | |
| 498 | + if (scale->out_color_matrix != AVCOL_SPC_UNSPECIFIED) { | |
| 499 | + formats = ff_make_formats_list_singleton(scale->out_color_matrix); | |
| 500 | + } else { | |
| 501 | + formats = ff_all_color_spaces(); | |
| 502 | + for (int i = 0; i < formats->nb_formats; i++) { | |
| 503 | + if (!sws_test_colorspace(formats->formats[i], 1)) { | |
| 504 | + for (int j = i--; j < formats->nb_formats; j++) | |
| 505 | + formats->formats[j] = formats->formats[j + 1]; | |
| 506 | + formats->nb_formats--; | |
| 507 | + } | |
| 508 | + } | |
| 509 | + } | |
| 523 | 510 | if ((ret = ff_formats_ref(formats, &cfg_out[0]->color_spaces)) < 0) |
| 524 | 511 | return ret; |
| 525 | 512 | |
| @@ -621,50 +608,6 @@ fail: · 95 unmodified lines | ||
| 621 | 608 | return ret; |
| 622 | 609 | } |
| 623 | 610 | |
| 624 | −static void calc_chroma_pos(int *h_pos_out, int *v_pos_out, int chroma_loc, | |
| 625 | − int h_pos_override, int v_pos_override, | |
| 626 | − int h_sub, int v_sub, int index) | |
| 627 | −{ | |
| 628 | − int h_pos, v_pos; | |
| 629 | − | |
| 630 | − /* Explicitly default to center siting for compatibility with swscale */ | |
| 631 | − if (chroma_loc == AVCHROMA_LOC_UNSPECIFIED) | |
| 632 | − chroma_loc = AVCHROMA_LOC_CENTER; | |
| 633 | − | |
| 634 | − /* av_chroma_location_enum_to_pos() always gives us values in the range from | |
| 635 | − * 0 to 256, but we need to adjust this to the true value range of the | |
| 636 | − * subsampling grid, which may be larger for h/v_sub > 1 */ | |
| 637 | − av_chroma_location_enum_to_pos(&h_pos, &v_pos, chroma_loc); | |
| 638 | − h_pos *= (1 << h_sub) - 1; | |
| 639 | − v_pos *= (1 << v_sub) - 1; | |
| 640 | − | |
| 641 | − if (h_pos_override != -513) | |
| 642 | − h_pos = h_pos_override; | |
| 643 | − if (v_pos_override != -513) | |
| 644 | − v_pos = v_pos_override; | |
| 645 | − | |
| 646 | − /* Fix vertical chroma position for interlaced frames */ | |
| 647 | − if (v_sub && index > 0) { | |
| 648 | − /* When vertically subsampling, chroma samples are effectively only | |
| 649 | − * placed next to even rows. To access them from the odd field, we need | |
| 650 | − * to account for this shift by offsetting the distance of one luma row. | |
| 651 | − * | |
| 652 | − * For 4x vertical subsampling (v_sub == 2), they are only placed | |
| 653 | − * next to every *other* even row, so we need to shift by three luma | |
| 654 | − * rows to get to the chroma sample. */ | |
| 655 | − if (index == 2) | |
| 656 | − v_pos += (256 << v_sub) - 256; | |
| 657 | − | |
| 658 | − /* Luma row distance is doubled for fields, so halve offsets */ | |
| 659 | − v_pos >>= 1; | |
| 660 | − } | |
| 661 | − | |
| 662 | − /* Explicitly strip chroma offsets when not subsampling, because it | |
| 663 | − * interferes with the operation of flags like SWS_FULL_CHR_H_INP */ | |
| 664 | − *h_pos_out = h_sub ? h_pos : -513; | |
| 665 | − *v_pos_out = v_sub ? v_pos : -513; | |
| 666 | −} | |
| 667 | − | |
| 668 | 611 | static int config_props(AVFilterLink *outlink) |
| 669 | 612 | { |
| 670 | 613 | AVFilterContext *ctx = outlink->src; |
| @@ -672,12 +615,8 @@ static int config_props(AVFilterLink *outlink) · 1 unmodified line | ||
| 672 | 615 | AVFilterLink *inlink = ctx->filter == &ff_vf_scale2ref ? |
| 673 | 616 | outlink->src->inputs[1] : |
| 674 | 617 | outlink->src->inputs[0]; |
| 675 | − enum AVPixelFormat outfmt = outlink->format; | |
| 676 | − const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); | |
| 677 | − const AVPixFmtDescriptor *outdesc = av_pix_fmt_desc_get(outfmt); | |
| 678 | 618 | ScaleContext *scale = ctx->priv; |
| 679 | 619 | uint8_t *flags_val = NULL; |
| 680 | − int in_range, in_colorspace; | |
| 681 | 620 | int ret; |
| 682 | 621 | |
| 683 | 622 | if ((ret = scale_eval_dimensions(ctx)) < 0) |
| @@ -701,107 +640,12 @@ static int config_props(AVFilterLink *outlink) · 17 unmodified lines | ||
| 701 | 640 | |
| 702 | 641 | /* TODO: make algorithm configurable */ |
| 703 | 642 | |
| 704 | − scale->input_is_pal = desc->flags & AV_PIX_FMT_FLAG_PAL; | |
| 705 | − if (outfmt == AV_PIX_FMT_PAL8) outfmt = AV_PIX_FMT_BGR8; | |
| 706 | − scale->output_is_pal = av_pix_fmt_desc_get(outfmt)->flags & AV_PIX_FMT_FLAG_PAL; | |
| 707 | − | |
| 708 | − in_range = scale->in_range; | |
| 709 | − if (in_range == AVCOL_RANGE_UNSPECIFIED) | |
| 710 | − in_range = inlink0->color_range; | |
| 711 | − | |
| 712 | − in_colorspace = scale->in_color_matrix; | |
| 713 | − if (in_colorspace == -1 /* auto */) | |
| 714 | − in_colorspace = inlink0->colorspace; | |
| 715 | − | |
| 716 | − if (scale->sws) | |
| 717 | − sws_freeContext(scale->sws); | |
| 718 | − if (scale->isws[0]) | |
| 719 | − sws_freeContext(scale->isws[0]); | |
| 720 | − if (scale->isws[1]) | |
| 721 | − sws_freeContext(scale->isws[1]); | |
| 722 | − scale->isws[0] = scale->isws[1] = scale->sws = NULL; | |
| 723 | − if (inlink0->w == outlink->w && | |
| 724 | − inlink0->h == outlink->h && | |
| 725 | − in_range == outlink->color_range && | |
| 726 | − in_colorspace == outlink->colorspace && | |
| 727 | − inlink0->format == outlink->format && | |
| 728 | − scale->in_chroma_loc == scale->out_chroma_loc) | |
| 729 | − ; | |
| 730 | − else { | |
| 731 | − struct SwsContext **swscs[3] = {&scale->sws, &scale->isws[0], &scale->isws[1]}; | |
| 732 | − int i; | |
| 733 | − | |
| 734 | − for (i = 0; i < 3; i++) { | |
| 735 | − int in_full, out_full, brightness, contrast, saturation; | |
| 736 | − int h_chr_pos, v_chr_pos; | |
| 737 | − const int *inv_table, *table; | |
| 738 | − struct SwsContext *const s = sws_alloc_context(); | |
| 739 | − if (!s) | |
| 740 | − return AVERROR(ENOMEM); | |
| 741 | − *swscs[i] = s; | |
| 742 | − | |
| 743 | − ret = av_opt_copy(s, scale->sws_opts); | |
| 744 | − if (ret < 0) | |
| 745 | − return ret; | |
| 746 | − | |
| 747 | − av_opt_set_int(s, "srcw", inlink0 ->w, 0); | |
| 748 | − av_opt_set_int(s, "srch", inlink0 ->h >> !!i, 0); | |
| 749 | − av_opt_set_int(s, "src_format", inlink0->format, 0); | |
| 750 | − av_opt_set_int(s, "dstw", outlink->w, 0); | |
| 751 | − av_opt_set_int(s, "dsth", outlink->h >> !!i, 0); | |
| 752 | − av_opt_set_int(s, "dst_format", outfmt, 0); | |
| 753 | − if (in_range != AVCOL_RANGE_UNSPECIFIED) | |
| 754 | − av_opt_set_int(s, "src_range", | |
| 755 | − in_range == AVCOL_RANGE_JPEG, 0); | |
| 756 | − if (outlink->color_range != AVCOL_RANGE_UNSPECIFIED) | |
| 757 | − av_opt_set_int(s, "dst_range", | |
| 758 | − outlink->color_range == AVCOL_RANGE_JPEG, 0); | |
| 759 | − | |
| 760 | − calc_chroma_pos(&h_chr_pos, &v_chr_pos, scale->in_chroma_loc, | |
| 761 | − scale->in_h_chr_pos, scale->in_v_chr_pos, | |
| 762 | − desc->log2_chroma_w, desc->log2_chroma_h, i); | |
| 763 | − av_opt_set_int(s, "src_h_chr_pos", h_chr_pos, 0); | |
| 764 | − av_opt_set_int(s, "src_v_chr_pos", v_chr_pos, 0); | |
| 765 | − | |
| 766 | − calc_chroma_pos(&h_chr_pos, &v_chr_pos, scale->out_chroma_loc, | |
| 767 | − scale->out_h_chr_pos, scale->out_v_chr_pos, | |
| 768 | − outdesc->log2_chroma_w, outdesc->log2_chroma_h, i); | |
| 769 | − av_opt_set_int(s, "dst_h_chr_pos", h_chr_pos, 0); | |
| 770 | − av_opt_set_int(s, "dst_v_chr_pos", v_chr_pos, 0); | |
| 771 | − | |
| 772 | − if ((ret = sws_init_context(s, NULL, NULL)) < 0) | |
| 773 | − return ret; | |
| 774 | − | |
| 775 | − sws_getColorspaceDetails(s, (int **)&inv_table, &in_full, | |
| 776 | − (int **)&table, &out_full, | |
| 777 | − &brightness, &contrast, &saturation); | |
| 778 | − | |
| 779 | − if (scale->in_color_matrix == -1 /* auto */) | |
| 780 | − inv_table = sws_getCoefficients(inlink0->colorspace); | |
| 781 | − else if (scale->in_color_matrix != AVCOL_SPC_UNSPECIFIED) | |
| 782 | − inv_table = sws_getCoefficients(scale->in_color_matrix); | |
| 783 | − if (outlink->colorspace != AVCOL_SPC_UNSPECIFIED) | |
| 784 | − table = sws_getCoefficients(outlink->colorspace); | |
| 785 | − else if (scale->in_color_matrix != AVCOL_SPC_UNSPECIFIED) | |
| 786 | − table = inv_table; | |
| 787 | − | |
| 788 | − sws_setColorspaceDetails(s, inv_table, in_full, | |
| 789 | − table, out_full, | |
| 790 | − brightness, contrast, saturation); | |
| 791 | − | |
| 792 | − if (!scale->interlaced) | |
| 793 | − break; | |
| 794 | − } | |
| 795 | − } | |
| 796 | − | |
| 797 | 643 | if (inlink0->sample_aspect_ratio.num){ |
| 798 | 644 | outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h * inlink0->w, outlink->w * inlink0->h}, inlink0->sample_aspect_ratio); |
| 799 | 645 | } else |
| 800 | 646 | outlink->sample_aspect_ratio = inlink0->sample_aspect_ratio; |
| 801 | 647 | |
| 802 | − if (scale->sws) | |
| 803 | − av_opt_get(scale->sws, "sws_flags", 0, &flags_val); | |
| 804 | − | |
| 648 | + av_opt_get(scale->sws, "sws_flags", 0, &flags_val); | |
| 805 | 649 | av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d fmt:%s csp:%s range:%s sar:%d/%d -> w:%d h:%d fmt:%s csp:%s range:%s sar:%d/%d flags:%s\n", |
| 806 | 650 | inlink ->w, inlink ->h, av_get_pix_fmt_name( inlink->format), |
| 807 | 651 | av_color_space_name(inlink->colorspace), av_color_range_name(inlink->color_range), |
| @@ -868,56 +712,6 @@ static int request_frame_ref(AVFilterLink *outlink) · 60 unmodified lines | ||
| 868 | 712 | return ff_request_frame(outlink->src->inputs[1]); |
| 869 | 713 | } |
| 870 | 714 | |
| 871 | −static void frame_offset(AVFrame *frame, int dir, int is_pal) | |
| 872 | −{ | |
| 873 | − for (int i = 0; i < 4 && frame->data[i]; i++) { | |
| 874 | − if (i == 1 && is_pal) | |
| 875 | − break; | |
| 876 | − frame->data[i] += frame->linesize[i] * dir; | |
| 877 | − } | |
| 878 | −} | |
| 879 | − | |
| 880 | −static int scale_field(ScaleContext *scale, AVFrame *dst, AVFrame *src, | |
| 881 | − int field) | |
| 882 | −{ | |
| 883 | − int orig_h_src = src->height; | |
| 884 | − int orig_h_dst = dst->height; | |
| 885 | − int ret; | |
| 886 | − | |
| 887 | − // offset the data pointers for the bottom field | |
| 888 | − if (field) { | |
| 889 | − frame_offset(src, 1, scale->input_is_pal); | |
| 890 | − frame_offset(dst, 1, scale->output_is_pal); | |
| 891 | − } | |
| 892 | − | |
| 893 | − // take every second line | |
| 894 | − for (int i = 0; i < 4; i++) { | |
| 895 | − src->linesize[i] *= 2; | |
| 896 | − dst->linesize[i] *= 2; | |
| 897 | − } | |
| 898 | − src->height /= 2; | |
| 899 | − dst->height /= 2; | |
| 900 | − | |
| 901 | − ret = sws_scale_frame(scale->isws[field], dst, src); | |
| 902 | − if (ret < 0) | |
| 903 | − return ret; | |
| 904 | − | |
| 905 | − // undo the changes we made above | |
| 906 | − for (int i = 0; i < 4; i++) { | |
| 907 | − src->linesize[i] /= 2; | |
| 908 | − dst->linesize[i] /= 2; | |
| 909 | − } | |
| 910 | − src->height = orig_h_src; | |
| 911 | − dst->height = orig_h_dst; | |
| 912 | − | |
| 913 | − if (field) { | |
| 914 | − frame_offset(src, -1, scale->input_is_pal); | |
| 915 | − frame_offset(dst, -1, scale->output_is_pal); | |
| 916 | − } | |
| 917 | − | |
| 918 | − return 0; | |
| 919 | −} | |
| 920 | − | |
| 921 | 715 | /* Takes over ownership of *frame_in, passes ownership of *frame_out to caller */ |
| 922 | 716 | static int scale_frame(AVFilterLink *link, AVFrame **frame_in, |
| 923 | 717 | AVFrame **frame_out) |
| @@ -929,12 +723,9 @@ static int scale_frame(AVFilterLink *link, AVFrame **frame_in, · 5 unmodified lines | ||
| 929 | 723 | AVFrame *out, *in = *frame_in; |
| 930 | 724 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format); |
| 931 | 725 | char buf[32]; |
| 932 | − int ret; | |
| 933 | − int frame_changed; | |
| 726 | + int ret, flags_orig, frame_changed; | |
| 934 | 727 | |
| 935 | 728 | *frame_in = NULL; |
| 936 | − if (in->colorspace == AVCOL_SPC_YCGCO) | |
| 937 | − av_log(link->dst, AV_LOG_WARNING, "Detected unsupported YCgCo colorspace.\n"); | |
| 938 | 729 | |
| 939 | 730 | frame_changed = in->width != link->w || |
| 940 | 731 | in->height != link->h || |
| @@ -1013,11 +804,6 @@ FF_ENABLE_DEPRECATION_WARNINGS · 72 unmodified lines | ||
| 1013 | 804 | } |
| 1014 | 805 | |
| 1015 | 806 | scale: |
| 1016 | − if (!scale->sws) { | |
| 1017 | − *frame_out = in; | |
| 1018 | − return 0; | |
| 1019 | − } | |
| 1020 | − | |
| 1021 | 807 | scale->hsub = desc->log2_chroma_w; |
| 1022 | 808 | scale->vsub = desc->log2_chroma_h; |
| 1023 | 809 | |
| @@ -1027,6 +813,18 @@ scale: · 3 unmodified lines | ||
| 1027 | 813 | goto err; |
| 1028 | 814 | } |
| 1029 | 815 | |
| 816 | + if (scale->in_color_matrix != -1) | |
| 817 | + in->colorspace = scale->in_color_matrix; | |
| 818 | + if (scale->in_range != AVCOL_RANGE_UNSPECIFIED) | |
| 819 | + in->color_range = scale->in_range; | |
| 820 | + in->chroma_location = scale->in_chroma_loc; | |
| 821 | + | |
| 822 | + flags_orig = in->flags; | |
| 823 | + if (scale->interlaced > 0) | |
| 824 | + in->flags |= AV_FRAME_FLAG_INTERLACED; | |
| 825 | + else if (!scale->interlaced) | |
| 826 | + in->flags &= ~AV_FRAME_FLAG_INTERLACED; | |
| 827 | + | |
| 1030 | 828 | av_frame_copy_props(out, in); |
| 1031 | 829 | out->width = outlink->w; |
| 1032 | 830 | out->height = outlink->h; |
| @@ -1035,26 +833,31 @@ scale: · 2 unmodified lines | ||
| 1035 | 833 | if (scale->out_chroma_loc != AVCHROMA_LOC_UNSPECIFIED) |
| 1036 | 834 | out->chroma_location = scale->out_chroma_loc; |
| 1037 | 835 | |
| 1038 | − if (scale->output_is_pal) | |
| 1039 | − avpriv_set_systematic_pal2((uint32_t*)out->data[1], outlink->format == AV_PIX_FMT_PAL8 ? AV_PIX_FMT_BGR8 : outlink->format); | |
| 1040 | − | |
| 1041 | 836 | av_reduce(&out->sample_aspect_ratio.num, &out->sample_aspect_ratio.den, |
| 1042 | 837 | (int64_t)in->sample_aspect_ratio.num * outlink->h * link->w, |
| 1043 | 838 | (int64_t)in->sample_aspect_ratio.den * outlink->w * link->h, |
| 1044 | 839 | INT_MAX); |
| 1045 | 840 | |
| 1046 | − if (scale->interlaced>0 || (scale->interlaced<0 && | |
| 1047 | − (in->flags & AV_FRAME_FLAG_INTERLACED))) { | |
| 1048 | − ret = scale_field(scale, out, in, 0); | |
| 1049 | − if (ret >= 0) | |
| 1050 | − ret = scale_field(scale, out, in, 1); | |
| 1051 | − } else { | |
| 1052 | − ret = sws_scale_frame(scale->sws, out, in); | |
| 841 | + if (sws_is_noop(out, in)) { | |
| 842 | + av_frame_free(&out); | |
| 843 | + in->flags = flags_orig; | |
| 844 | + *frame_out = in; | |
| 845 | + return 0; | |
| 1053 | 846 | } |
| 1054 | 847 | |
| 848 | + if (out->format == AV_PIX_FMT_PAL8) { | |
| 849 | + out->format = AV_PIX_FMT_BGR8; | |
| 850 | + avpriv_set_systematic_pal2((uint32_t*) out->data[1], out->format); | |
| 851 | + } | |
| 852 | + | |
| 853 | + ret = sws_scale_frame(scale->sws, out, in); | |
| 854 | + av_frame_free(&in); | |
| 855 | + out->flags = flags_orig; | |
| 856 | + out->format = outlink->format; /* undo PAL8 handling */ | |
| 1055 | 857 | if (ret < 0) |
| 1056 | 858 | av_frame_free(&out); |
| 1057 | 859 | *frame_out = out; |
| 860 | + return ret; | |
| 1058 | 861 | |
| 1059 | 862 | err: |
| 1060 | 863 | av_frame_free(&in); |
| @@ -1232,8 +1035,8 @@ static void *child_next(void *obj, void *prev) · 171 unmodified lines | ||
| 1232 | 1035 | { |
| 1233 | 1036 | ScaleContext *s = obj; |
| 1234 | 1037 | if (!prev) |
| 1235 | − return s->sws_opts; | |
| 1236 | − if (prev == s->sws_opts) | |
| 1038 | + return s->sws; | |
| 1039 | + if (prev == s->sws) | |
| 1237 | 1040 | return &s->fs; |
| 1238 | 1041 | return NULL; |
| 1239 | 1042 | } |
| @@ -1350,7 +1153,7 @@ static void *scale2ref_child_next(void *obj, void *prev) · 110 unmodified lines | ||
| 1350 | 1153 | { |
| 1351 | 1154 | ScaleContext *s = obj; |
| 1352 | 1155 | if (!prev) |
| 1353 | − return s->sws_opts; | |
| 1156 | + return s->sws; | |
| 1354 | 1157 | return NULL; |
| 1355 | 1158 | } |
| 1356 | 1159 | |