History

avfilter/vf_scale: switch to new swscale API

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.

Niklas Haas committed 2 years ago

Commit 04ce01d1 parent 3edd1e41 file · +77 −274Browse files

Showing the changes to libavfilter (1 of 1 file). Show all

Unified · Split

libavfilter/vf_scale.c+77−274
@@ -31,6 +31,7 @@ · 30 unmodified lines
31#include "filters.h"31#include "filters.h"
32#include "formats.h"32#include "formats.h"
33#include "framesync.h"33#include "framesync.h"
34#include "libavutil/pixfmt.h"
34#include "scale_eval.h"35#include "scale_eval.h"
35#include "video.h"36#include "video.h"
36#include "libavutil/eval.h"37#include "libavutil/eval.h"
@@ -131,10 +132,7 @@ enum EvalMode { · 94 unmodified lines
131 132
132typedef struct ScaleContext {133typedef struct ScaleContext {
133 const AVClass *class;134 const AVClass *class;
134 struct SwsContext *sws; ///< software scaler context135 SwsContext *sws;
135 struct SwsContext *isws[2]; ///< software scaler context for interlaced material
136 // context used for forwarding options to sws
137 struct SwsContext *sws_opts;
138 FFFrameSync fs;136 FFFrameSync fs;
139 137
140 /**138 /**
@@ -149,8 +147,6 @@ typedef struct ScaleContext { · 8 unmodified lines
149 147
150 int hsub, vsub; ///< chroma subsampling148 int hsub, vsub; ///< chroma subsampling
151 int slice_y; ///< top of current output slice149 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 int interlaced;150 int interlaced;
155 int uses_ref;151 int uses_ref;
156 152
@@ -334,40 +330,24 @@ revert: · 177 unmodified lines
334static av_cold int preinit(AVFilterContext *ctx)330static av_cold int preinit(AVFilterContext *ctx)
335{331{
336 ScaleContext *scale = ctx->priv;332 ScaleContext *scale = ctx->priv;
337 int ret;
338 333
339 scale->sws_opts = sws_alloc_context();334 scale->sws = sws_alloc_context();
340 if (!scale->sws_opts)335 if (!scale->sws)
341 return AVERROR(ENOMEM);336 return AVERROR(ENOMEM);
342 337
343 // set threads=0, so we can later check whether the user modified it338 // 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);339 scale->sws->threads = 0;
345 if (ret < 0)
346 return ret;
347 340
348 ff_framesync_preinit(&scale->fs);341 ff_framesync_preinit(&scale->fs);
349 342
350 return 0;343 return 0;
351}344}
352 345
353static 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
365static int do_scale(FFFrameSync *fs);346static int do_scale(FFFrameSync *fs);
366 347
367static av_cold int init(AVFilterContext *ctx)348static av_cold int init(AVFilterContext *ctx)
368{349{
369 ScaleContext *scale = ctx->priv;350 ScaleContext *scale = ctx->priv;
370 int64_t threads;
371 int ret;351 int ret;
372 352
373 if (ctx->filter == &ff_vf_scale2ref)353 if (ctx->filter == &ff_vf_scale2ref)
@@ -407,14 +387,13 @@ static av_cold int init(AVFilterContext *ctx) · 33 unmodified lines
407 if (ret < 0)387 if (ret < 0)
408 return ret;388 return ret;
409 389
410 if (scale->in_color_matrix != -1 &&390 if (scale->in_color_matrix != -1 && !sws_test_colorspace(scale->in_color_matrix, 0)) {
411 !ff_fmt_is_in(scale->in_color_matrix, sws_colorspaces)) {
412 av_log(ctx, AV_LOG_ERROR, "Unsupported input color matrix '%s'\n",391 av_log(ctx, AV_LOG_ERROR, "Unsupported input color matrix '%s'\n",
413 av_color_space_name(scale->in_color_matrix));392 av_color_space_name(scale->in_color_matrix));
414 return AVERROR(EINVAL);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 av_log(ctx, AV_LOG_ERROR, "Unsupported output color matrix '%s'\n",397 av_log(ctx, AV_LOG_ERROR, "Unsupported output color matrix '%s'\n",
419 av_color_space_name(scale->out_color_matrix));398 av_color_space_name(scale->out_color_matrix));
420 return AVERROR(EINVAL);399 return AVERROR(EINVAL);
@@ -424,25 +403,23 @@ static av_cold int init(AVFilterContext *ctx) · 3 unmodified lines
424 scale->w_expr, scale->h_expr, (char *)av_x_if_null(scale->flags_str, ""), scale->interlaced);403 scale->w_expr, scale->h_expr, (char *)av_x_if_null(scale->flags_str, ""), scale->interlaced);
425 404
426 if (scale->flags_str && *scale->flags_str) {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 if (ret < 0)407 if (ret < 0)
429 return ret;408 return ret;
430 }409 }
431 410
432 for (int i = 0; i < FF_ARRAY_ELEMS(scale->param); i++)411 for (int i = 0; i < FF_ARRAY_ELEMS(scale->param); i++)
433 if (scale->param[i] != DBL_MAX) {412 if (scale->param[i] != DBL_MAX)
434 ret = av_opt_set_double(scale->sws_opts, i ? "param1" : "param0",413 scale->sws->scaler_params[i] = scale->param[i];
435 scale->param[i], 0);414
436 if (ret < 0)415 scale->sws->src_h_chr_pos = scale->in_h_chr_pos;
437 return ret;416 scale->sws->src_v_chr_pos = scale->in_v_chr_pos;
438 }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 // use generic thread-count if the user did not set it explicitly420 // use generic thread-count if the user did not set it explicitly
441 ret = av_opt_get_int(scale->sws_opts, "threads", 0, &threads);421 if (!scale->sws->threads)
442 if (ret < 0)422 scale->sws->threads = ff_filter_get_nb_threads(ctx);
443 return ret;
444 if (!threads)
445 av_opt_set_int(scale->sws_opts, "threads", ff_filter_get_nb_threads(ctx), 0);
446 423
447 if (ctx->filter != &ff_vf_scale2ref && scale->uses_ref) {424 if (ctx->filter != &ff_vf_scale2ref && scale->uses_ref) {
448 AVFilterPad pad = {425 AVFilterPad pad = {
@@ -464,11 +441,7 @@ static av_cold void uninit(AVFilterContext *ctx) · 15 unmodified lines
464 av_expr_free(scale->h_pexpr);441 av_expr_free(scale->h_pexpr);
465 scale->w_pexpr = scale->h_pexpr = NULL;442 scale->w_pexpr = scale->h_pexpr = NULL;
466 ff_framesync_uninit(&scale->fs);443 ff_framesync_uninit(&scale->fs);
467 sws_freeContext(scale->sws_opts);444 sws_free_context(&scale->sws);
468 sws_freeContext(scale->sws);
469 sws_freeContext(scale->isws[0]);
470 sws_freeContext(scale->isws[1]);
471 scale->sws = NULL;
472}445}
473 446
474static int query_formats(const AVFilterContext *ctx,447static int query_formats(const AVFilterContext *ctx,
@@ -485,10 +458,9 @@ static int query_formats(const AVFilterContext *ctx, · 10 unmodified lines
485 formats = NULL;458 formats = NULL;
486 while ((desc = av_pix_fmt_desc_next(desc))) {459 while ((desc = av_pix_fmt_desc_next(desc))) {
487 pix_fmt = av_pix_fmt_desc_get_id(desc);460 pix_fmt = av_pix_fmt_desc_get_id(desc);
488 if ((sws_isSupportedInput(pix_fmt) ||461 if (sws_test_format(pix_fmt, 0)) {
489 sws_isSupportedEndiannessConversion(pix_fmt))462 if ((ret = ff_add_format(&formats, pix_fmt)) < 0)
490 && (ret = ff_add_format(&formats, pix_fmt)) < 0) {463 return ret;
491 return ret;
492 }464 }
493 }465 }
494 if ((ret = ff_formats_ref(formats, &cfg_in[0]->formats)) < 0)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 formats = NULL;470 formats = NULL;
499 while ((desc = av_pix_fmt_desc_next(desc))) {471 while ((desc = av_pix_fmt_desc_next(desc))) {
500 pix_fmt = av_pix_fmt_desc_get_id(desc);472 pix_fmt = av_pix_fmt_desc_get_id(desc);
501 if ((sws_isSupportedOutput(pix_fmt) || pix_fmt == AV_PIX_FMT_PAL8 ||473 if (sws_test_format(pix_fmt, 1) || pix_fmt == AV_PIX_FMT_PAL8) {
502 sws_isSupportedEndiannessConversion(pix_fmt))474 if ((ret = ff_add_format(&formats, pix_fmt)) < 0)
503 && (ret = ff_add_format(&formats, pix_fmt)) < 0) {475 return ret;
504 return ret;
505 }476 }
506 }477 }
507 if ((ret = ff_formats_ref(formats, &cfg_out[0]->formats)) < 0)478 if ((ret = ff_formats_ref(formats, &cfg_out[0]->formats)) < 0)
508 return ret;479 return ret;
509 480
510 /* accept all supported inputs, even if user overrides their properties */481 /* accept all supported inputs, even if user overrides their properties */
511 if ((ret = ff_formats_ref(ff_make_format_list(sws_colorspaces),482 formats = ff_all_color_spaces();
512 &cfg_in[0]->color_spaces)) < 0)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 return ret;491 return ret;
514 492
515 if ((ret = ff_formats_ref(ff_all_color_ranges(),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 return ret;495 return ret;
518 496
519 /* propagate output properties if overridden */497 /* propagate output properties if overridden */
520 formats = scale->out_color_matrix != AVCOL_SPC_UNSPECIFIED498 if (scale->out_color_matrix != AVCOL_SPC_UNSPECIFIED) {
521 ? ff_make_formats_list_singleton(scale->out_color_matrix)499 formats = ff_make_formats_list_singleton(scale->out_color_matrix);
522 : ff_make_format_list(sws_colorspaces);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 if ((ret = ff_formats_ref(formats, &cfg_out[0]->color_spaces)) < 0)510 if ((ret = ff_formats_ref(formats, &cfg_out[0]->color_spaces)) < 0)
524 return ret;511 return ret;
525 512
@@ -621,50 +608,6 @@ fail: · 95 unmodified lines
621 return ret;608 return ret;
622}609}
623 610
624static 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
668static int config_props(AVFilterLink *outlink)611static int config_props(AVFilterLink *outlink)
669{612{
670 AVFilterContext *ctx = outlink->src;613 AVFilterContext *ctx = outlink->src;
@@ -672,12 +615,8 @@ static int config_props(AVFilterLink *outlink) · 1 unmodified line
672 AVFilterLink *inlink = ctx->filter == &ff_vf_scale2ref ?615 AVFilterLink *inlink = ctx->filter == &ff_vf_scale2ref ?
673 outlink->src->inputs[1] :616 outlink->src->inputs[1] :
674 outlink->src->inputs[0];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 ScaleContext *scale = ctx->priv;618 ScaleContext *scale = ctx->priv;
679 uint8_t *flags_val = NULL;619 uint8_t *flags_val = NULL;
680 int in_range, in_colorspace;
681 int ret;620 int ret;
682 621
683 if ((ret = scale_eval_dimensions(ctx)) < 0)622 if ((ret = scale_eval_dimensions(ctx)) < 0)
@@ -701,107 +640,12 @@ static int config_props(AVFilterLink *outlink) · 17 unmodified lines
701 640
702 /* TODO: make algorithm configurable */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 if (inlink0->sample_aspect_ratio.num){643 if (inlink0->sample_aspect_ratio.num){
798 outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h * inlink0->w, outlink->w * inlink0->h}, inlink0->sample_aspect_ratio);644 outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h * inlink0->w, outlink->w * inlink0->h}, inlink0->sample_aspect_ratio);
799 } else645 } else
800 outlink->sample_aspect_ratio = inlink0->sample_aspect_ratio;646 outlink->sample_aspect_ratio = inlink0->sample_aspect_ratio;
801 647
802 if (scale->sws)648 av_opt_get(scale->sws, "sws_flags", 0, &flags_val);
803 av_opt_get(scale->sws, "sws_flags", 0, &flags_val);
804
805 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",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 inlink ->w, inlink ->h, av_get_pix_fmt_name( inlink->format),650 inlink ->w, inlink ->h, av_get_pix_fmt_name( inlink->format),
807 av_color_space_name(inlink->colorspace), av_color_range_name(inlink->color_range),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 return ff_request_frame(outlink->src->inputs[1]);712 return ff_request_frame(outlink->src->inputs[1]);
869}713}
870 714
871static 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
880static 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/* Takes over ownership of *frame_in, passes ownership of *frame_out to caller */715/* Takes over ownership of *frame_in, passes ownership of *frame_out to caller */
922static int scale_frame(AVFilterLink *link, AVFrame **frame_in,716static int scale_frame(AVFilterLink *link, AVFrame **frame_in,
923 AVFrame **frame_out)717 AVFrame **frame_out)
@@ -929,12 +723,9 @@ static int scale_frame(AVFilterLink *link, AVFrame **frame_in, · 5 unmodified lines
929 AVFrame *out, *in = *frame_in;723 AVFrame *out, *in = *frame_in;
930 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format);724 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format);
931 char buf[32];725 char buf[32];
932 int ret;726 int ret, flags_orig, frame_changed;
933 int frame_changed;
934 727
935 *frame_in = NULL;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 frame_changed = in->width != link->w ||730 frame_changed = in->width != link->w ||
940 in->height != link->h ||731 in->height != link->h ||
@@ -1013,11 +804,6 @@ FF_ENABLE_DEPRECATION_WARNINGS · 72 unmodified lines
1013 }804 }
1014 805
1015scale:806scale:
1016 if (!scale->sws) {
1017 *frame_out = in;
1018 return 0;
1019 }
1020
1021 scale->hsub = desc->log2_chroma_w;807 scale->hsub = desc->log2_chroma_w;
1022 scale->vsub = desc->log2_chroma_h;808 scale->vsub = desc->log2_chroma_h;
1023 809
@@ -1027,6 +813,18 @@ scale: · 3 unmodified lines
1027 goto err;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 av_frame_copy_props(out, in);828 av_frame_copy_props(out, in);
1031 out->width = outlink->w;829 out->width = outlink->w;
1032 out->height = outlink->h;830 out->height = outlink->h;
@@ -1035,26 +833,31 @@ scale: · 2 unmodified lines
1035 if (scale->out_chroma_loc != AVCHROMA_LOC_UNSPECIFIED)833 if (scale->out_chroma_loc != AVCHROMA_LOC_UNSPECIFIED)
1036 out->chroma_location = scale->out_chroma_loc;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 av_reduce(&out->sample_aspect_ratio.num, &out->sample_aspect_ratio.den,836 av_reduce(&out->sample_aspect_ratio.num, &out->sample_aspect_ratio.den,
1042 (int64_t)in->sample_aspect_ratio.num * outlink->h * link->w,837 (int64_t)in->sample_aspect_ratio.num * outlink->h * link->w,
1043 (int64_t)in->sample_aspect_ratio.den * outlink->w * link->h,838 (int64_t)in->sample_aspect_ratio.den * outlink->w * link->h,
1044 INT_MAX);839 INT_MAX);
1045 840
1046 if (scale->interlaced>0 || (scale->interlaced<0 &&841 if (sws_is_noop(out, in)) {
1047 (in->flags & AV_FRAME_FLAG_INTERLACED))) {842 av_frame_free(&out);
1048 ret = scale_field(scale, out, in, 0);843 in->flags = flags_orig;
1049 if (ret >= 0)844 *frame_out = in;
1050 ret = scale_field(scale, out, in, 1);845 return 0;
1051 } else {
1052 ret = sws_scale_frame(scale->sws, out, in);
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 if (ret < 0)857 if (ret < 0)
1056 av_frame_free(&out);858 av_frame_free(&out);
1057 *frame_out = out;859 *frame_out = out;
860 return ret;
1058 861
1059err:862err:
1060 av_frame_free(&in);863 av_frame_free(&in);
@@ -1232,8 +1035,8 @@ static void *child_next(void *obj, void *prev) · 171 unmodified lines
1232{1035{
1233 ScaleContext *s = obj;1036 ScaleContext *s = obj;
1234 if (!prev)1037 if (!prev)
1235 return s->sws_opts;1038 return s->sws;
1236 if (prev == s->sws_opts)1039 if (prev == s->sws)
1237 return &s->fs;1040 return &s->fs;
1238 return NULL;1041 return NULL;
1239}1042}
@@ -1350,7 +1153,7 @@ static void *scale2ref_child_next(void *obj, void *prev) · 110 unmodified lines
1350{1153{
1351 ScaleContext *s = obj;1154 ScaleContext *s = obj;
1352 if (!prev)1155 if (!prev)
1353 return s->sws_opts;1156 return s->sws;
1354 return NULL;1157 return NULL;
1355}1158}
1356 1159

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t