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.
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 | |