| @@ -54,6 +54,7 @@ enum DirectionMode { · 53 unmodified lines |
| 54 | enum SlideMode { | 54 | enum SlideMode { |
| 55 | SLIDE_REPLACE, | 55 | SLIDE_REPLACE, |
| 56 | SLIDE_SCROLL, | 56 | SLIDE_SCROLL, |
| | 57 | SLIDE_FRAME, |
| 57 | NB_SLIDE | 58 | NB_SLIDE |
| 58 | }; | 59 | }; |
| 59 | | 60 | |
| @@ -94,6 +95,7 @@ typedef struct ShowCWTContext { · 34 unmodified lines |
| 94 | int pps; | 95 | int pps; |
| 95 | int eof; | 96 | int eof; |
| 96 | int slide; | 97 | int slide; |
| | 98 | int new_frame; |
| 97 | int direction; | 99 | int direction; |
| 98 | int hop_size; | 100 | int hop_size; |
| 99 | int hop_index; | 101 | int hop_index; |
| @@ -138,6 +140,7 @@ static const AVOption showcwt_options[] = { · 38 unmodified lines |
| 138 | { "slide", "set slide mode", OFFSET(slide), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_SLIDE-1, FLAGS, "slide" }, | 140 | { "slide", "set slide mode", OFFSET(slide), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_SLIDE-1, FLAGS, "slide" }, |
| 139 | { "replace", "replace", 0, AV_OPT_TYPE_CONST,{.i64=SLIDE_REPLACE},0, 0, FLAGS, "slide" }, | 141 | { "replace", "replace", 0, AV_OPT_TYPE_CONST,{.i64=SLIDE_REPLACE},0, 0, FLAGS, "slide" }, |
| 140 | { "scroll", "scroll", 0, AV_OPT_TYPE_CONST,{.i64=SLIDE_SCROLL}, 0, 0, FLAGS, "slide" }, | 142 | { "scroll", "scroll", 0, AV_OPT_TYPE_CONST,{.i64=SLIDE_SCROLL}, 0, 0, FLAGS, "slide" }, |
| | 143 | { "frame", "frame", 0, AV_OPT_TYPE_CONST,{.i64=SLIDE_FRAME}, 0, 0, FLAGS, "slide" }, |
| 141 | { "direction", "set direction mode", OFFSET(direction), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_DIRECTION-1, FLAGS, "direction" }, | 144 | { "direction", "set direction mode", OFFSET(direction), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_DIRECTION-1, FLAGS, "direction" }, |
| 142 | { "lr", "left to right", 0, AV_OPT_TYPE_CONST,{.i64=DIRECTION_LR}, 0, 0, FLAGS, "direction" }, | 145 | { "lr", "left to right", 0, AV_OPT_TYPE_CONST,{.i64=DIRECTION_LR}, 0, 0, FLAGS, "direction" }, |
| 143 | { "rl", "right to left", 0, AV_OPT_TYPE_CONST,{.i64=DIRECTION_RL}, 0, 0, FLAGS, "direction" }, | 146 | { "rl", "right to left", 0, AV_OPT_TYPE_CONST,{.i64=DIRECTION_RL}, 0, 0, FLAGS, "direction" }, |
| @@ -330,6 +333,7 @@ static int draw(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) · 186 unmodified lines |
| 330 | | 333 | |
| 331 | switch (s->slide) { | 334 | switch (s->slide) { |
| 332 | case SLIDE_REPLACE: | 335 | case SLIDE_REPLACE: |
| | 336 | case SLIDE_FRAME: |
| 333 | /* nothing to do here */ | 337 | /* nothing to do here */ |
| 334 | break; | 338 | break; |
| 335 | case SLIDE_SCROLL: | 339 | case SLIDE_SCROLL: |
| @@ -515,6 +519,7 @@ static int config_output(AVFilterLink *outlink) · 179 unmodified lines |
| 515 | break; | 519 | break; |
| 516 | } | 520 | } |
| 517 | | 521 | |
| | 522 | s->new_frame = 1; |
| 518 | s->nb_threads = FFMIN(s->frequency_band_count, ff_filter_get_nb_threads(ctx)); | 523 | s->nb_threads = FFMIN(s->frequency_band_count, ff_filter_get_nb_threads(ctx)); |
| 519 | s->nb_channels = inlink->ch_layout.nb_channels; | 524 | s->nb_channels = inlink->ch_layout.nb_channels; |
| 520 | s->old_pts = AV_NOPTS_VALUE; | 525 | s->old_pts = AV_NOPTS_VALUE; |
| @@ -675,7 +680,6 @@ static int output_frame(AVFilterContext *ctx) · 154 unmodified lines |
| 675 | AVFilterLink *outlink = ctx->outputs[0]; | 680 | AVFilterLink *outlink = ctx->outputs[0]; |
| 676 | AVFilterLink *inlink = ctx->inputs[0]; | 681 | AVFilterLink *inlink = ctx->inputs[0]; |
| 677 | ShowCWTContext *s = ctx->priv; | 682 | ShowCWTContext *s = ctx->priv; |
| 678 | int64_t pts_offset; | | |
| 679 | int ret; | 683 | int ret; |
| 680 | | 684 | |
| 681 | switch (s->slide) { | 685 | switch (s->slide) { |
| @@ -709,35 +713,37 @@ static int output_frame(AVFilterContext *ctx) · 27 unmodified lines |
| 709 | | 713 | |
| 710 | ff_filter_execute(ctx, draw, NULL, NULL, s->nb_threads); | 714 | ff_filter_execute(ctx, draw, NULL, NULL, s->nb_threads); |
| 711 | | 715 | |
| 712 | pts_offset = av_rescale(s->ihop_index, s->hop_size, s->ihop_size); | | |
| 713 | s->outpicref->pts = av_rescale_q(s->in_pts + pts_offset, inlink->time_base, outlink->time_base); | | |
| 714 | | | |
| 715 | s->ihop_index++; | | |
| 716 | if (s->ihop_index >= s->ihop_size) | | |
| 717 | s->ihop_index = 0; | | |
| 718 | | | |
| 719 | switch (s->slide) { | 716 | switch (s->slide) { |
| 720 | case SLIDE_REPLACE: | 717 | case SLIDE_REPLACE: |
| | 718 | case SLIDE_FRAME: |
| 721 | switch (s->direction) { | 719 | switch (s->direction) { |
| 722 | case DIRECTION_LR: | 720 | case DIRECTION_LR: |
| 723 | s->pos++; | 721 | s->pos++; |
| 724 | if (s->pos >= s->w) | 722 | if (s->pos >= s->w) { |
| 725 | s->pos = 0; | 723 | s->pos = 0; |
| | 724 | s->new_frame = 1; |
| | 725 | } |
| 726 | break; | 726 | break; |
| 727 | case DIRECTION_RL: | 727 | case DIRECTION_RL: |
| 728 | s->pos--; | 728 | s->pos--; |
| 729 | if (s->pos < 0) | 729 | if (s->pos < 0) { |
| 730 | s->pos = s->w - 1; | 730 | s->pos = s->w - 1; |
| | 731 | s->new_frame = 1; |
| | 732 | } |
| 731 | break; | 733 | break; |
| 732 | case DIRECTION_UD: | 734 | case DIRECTION_UD: |
| 733 | s->pos++; | 735 | s->pos++; |
| 734 | if (s->pos >= s->h) | 736 | if (s->pos >= s->h) { |
| 735 | s->pos = 0; | 737 | s->pos = 0; |
| | 738 | s->new_frame = 1; |
| | 739 | } |
| 736 | break; | 740 | break; |
| 737 | case DIRECTION_DU: | 741 | case DIRECTION_DU: |
| 738 | s->pos--; | 742 | s->pos--; |
| 739 | if (s->pos < 0) | 743 | if (s->pos < 0) { |
| 740 | s->pos = s->h - 1; | 744 | s->pos = s->h - 1; |
| | 745 | s->new_frame = 1; |
| | 746 | } |
| 741 | break; | 747 | break; |
| 742 | } | 748 | } |
| 743 | break; | 749 | break; |
| @@ -757,6 +763,77 @@ static int output_frame(AVFilterContext *ctx) · 13 unmodified lines |
| 757 | break; | 763 | break; |
| 758 | } | 764 | } |
| 759 | | 765 | |
| | 766 | if (s->slide == SLIDE_FRAME && s->eof) { |
| | 767 | switch (s->direction) { |
| | 768 | case DIRECTION_LR: |
| | 769 | for (int p = 0; p < 3; p++) { |
| | 770 | ptrdiff_t linesize = s->outpicref->linesize[p]; |
| | 771 | const int size = s->w - s->pos; |
| | 772 | const int fill = p ? 128 : 0; |
| | 773 | const int x = s->pos; |
| | 774 | |
| | 775 | for (int y = 0; y < s->h; y++) { |
| | 776 | uint8_t *dst = s->outpicref->data[p] + y * linesize + x; |
| | 777 | |
| | 778 | memset(dst, fill, size); |
| | 779 | } |
| | 780 | } |
| | 781 | break; |
| | 782 | case DIRECTION_RL: |
| | 783 | for (int p = 0; p < 3; p++) { |
| | 784 | ptrdiff_t linesize = s->outpicref->linesize[p]; |
| | 785 | const int size = s->w - s->pos; |
| | 786 | const int fill = p ? 128 : 0; |
| | 787 | |
| | 788 | for (int y = 0; y < s->h; y++) { |
| | 789 | uint8_t *dst = s->outpicref->data[p] + y * linesize; |
| | 790 | |
| | 791 | memset(dst, fill, size); |
| | 792 | } |
| | 793 | } |
| | 794 | break; |
| | 795 | case DIRECTION_UD: |
| | 796 | for (int p = 0; p < 3; p++) { |
| | 797 | ptrdiff_t linesize = s->outpicref->linesize[p]; |
| | 798 | const int fill = p ? 128 : 0; |
| | 799 | |
| | 800 | for (int y = s->pos; y < s->h; y++) { |
| | 801 | uint8_t *dst = s->outpicref->data[p] + y * linesize; |
| | 802 | |
| | 803 | memset(dst, fill, s->w); |
| | 804 | } |
| | 805 | } |
| | 806 | break; |
| | 807 | case DIRECTION_DU: |
| | 808 | for (int p = 0; p < 3; p++) { |
| | 809 | ptrdiff_t linesize = s->outpicref->linesize[p]; |
| | 810 | const int fill = p ? 128 : 0; |
| | 811 | |
| | 812 | for (int y = s->h - s->pos; y >= 0; y--) { |
| | 813 | uint8_t *dst = s->outpicref->data[p] + y * linesize; |
| | 814 | |
| | 815 | memset(dst, fill, s->w); |
| | 816 | } |
| | 817 | } |
| | 818 | break; |
| | 819 | } |
| | 820 | } |
| | 821 | |
| | 822 | s->new_frame = s->slide == SLIDE_FRAME && (s->new_frame || s->eof); |
| | 823 | |
| | 824 | if (s->slide != SLIDE_FRAME || s->new_frame == 1) { |
| | 825 | int64_t pts_offset = s->new_frame ? 0LL : av_rescale(s->ihop_index, s->hop_size, s->ihop_size); |
| | 826 | |
| | 827 | s->outpicref->pts = av_rescale_q(s->in_pts + pts_offset, inlink->time_base, outlink->time_base); |
| | 828 | } |
| | 829 | |
| | 830 | s->ihop_index++; |
| | 831 | if (s->ihop_index >= s->ihop_size) |
| | 832 | s->ihop_index = 0; |
| | 833 | |
| | 834 | if (s->slide == SLIDE_FRAME && s->new_frame == 0) |
| | 835 | return 1; |
| | 836 | |
| 760 | if (s->old_pts < s->outpicref->pts) { | 837 | if (s->old_pts < s->outpicref->pts) { |
| 761 | AVFrame *out = ff_get_video_buffer(outlink, outlink->w, outlink->h); | 838 | AVFrame *out = ff_get_video_buffer(outlink, outlink->w, outlink->h); |
| 762 | if (!out) | 839 | if (!out) |
| @@ -768,6 +845,7 @@ static int output_frame(AVFilterContext *ctx) · 5 unmodified lines |
| 768 | if (ret < 0) | 845 | if (ret < 0) |
| 769 | goto fail; | 846 | goto fail; |
| 770 | s->old_pts = s->outpicref->pts; | 847 | s->old_pts = s->outpicref->pts; |
| | 848 | s->new_frame = 0; |
| 771 | ret = ff_filter_frame(outlink, out); | 849 | ret = ff_filter_frame(outlink, out); |
| 772 | if (ret <= 0) | 850 | if (ret <= 0) |
| 773 | return ret; | 851 | return ret; |
| @@ -816,8 +894,10 @@ static int activate(AVFilterContext *ctx) · 42 unmodified lines |
| 816 | ff_filter_execute(ctx, run_channels_cwt_prepare, fin, NULL, | 894 | ff_filter_execute(ctx, run_channels_cwt_prepare, fin, NULL, |
| 817 | FFMIN(s->nb_threads, s->nb_channels)); | 895 | FFMIN(s->nb_threads, s->nb_channels)); |
| 818 | if (fin) { | 896 | if (fin) { |
| 819 | if (s->hop_index == 0) | 897 | if ((s->hop_index == 0 && s->slide != SLIDE_FRAME) || s->new_frame) { |
| 820 | s->in_pts = fin->pts; | 898 | s->in_pts = fin->pts; |
| | 899 | s->new_frame = 0; |
| | 900 | } |
| 821 | s->hop_index += fin->nb_samples; | 901 | s->hop_index += fin->nb_samples; |
| 822 | av_frame_free(&fin); | 902 | av_frame_free(&fin); |
| 823 | } else { | 903 | } else { |
| @@ -843,9 +923,12 @@ static int activate(AVFilterContext *ctx) · 19 unmodified lines |
| 843 | } | 923 | } |
| 844 | } | 924 | } |
| 845 | | 925 | |
| 846 | if (s->eof && s->eof_pts != AV_NOPTS_VALUE && s->old_pts + 1 >= s->eof_pts) { | 926 | if (s->eof && s->eof_pts != AV_NOPTS_VALUE && |
| | 927 | (s->old_pts + 1 >= s->eof_pts || (s->slide == SLIDE_FRAME))) { |
| | 928 | if (s->slide == SLIDE_FRAME) |
| | 929 | ret = output_frame(ctx); |
| 847 | ff_outlink_set_status(outlink, AVERROR_EOF, s->eof_pts); | 930 | ff_outlink_set_status(outlink, AVERROR_EOF, s->eof_pts); |
| 848 | return 0; | 931 | return ret; |
| 849 | } | 932 | } |
| 850 | | 933 | |
| 851 | if (!s->eof && ff_inlink_acknowledge_status(inlink, &status, &pts)) { | 934 | if (!s->eof && ff_inlink_acknowledge_status(inlink, &status, &pts)) { |