diff mbox series

[FFmpeg-devel] avformat/img2dec: Option to play sequence backwards

Message ID 29BFC8DD-910E-4AE4-A5F0-65CB449147BF@gmail.com
State New
Headers show
Series [FFmpeg-devel] avformat/img2dec: Option to play sequence backwards | expand

Checks

Context Check Description
andriy/configure_armv7_RPi4 warning Failed to apply patch
andriy/configure_aarch64_jetson warning Failed to apply patch
andriy/configure_x86 warning Failed to apply patch
andriy/configure_ppc warning Failed to apply patch

Commit Message

Sergio Acereda Feb. 10, 2022, 9:31 a.m. UTC
Signed-off-by: Sergio Acereda <sergio.acereda@gmail.com>
---
This patch should allow to play a image sequence in backwards direction, without needing to apply a reverse filter.

$ ffmpeg -i sequence%05.png forward.mkv
$ ffmpeg -reverse 1 sequence%05.png backward.mkv

---
libavformat/img2.h    |  1 +
libavformat/img2dec.c | 32 ++++++++++++++++++++++----------
2 files changed, 23 insertions(+), 10 deletions(-)

Comments

Gyan Doshi Feb. 10, 2022, 10:37 a.m. UTC | #1
On 2022-02-10 03:01 pm, Sergio Acereda wrote:
> Signed-off-by: Sergio Acereda <sergio.acereda@gmail.com>
> ---
> This patch should allow to play a image sequence in backwards direction, without needing to apply a reverse filter.

Have you considered this:  https://stackoverflow.com/a/40479257/ ?

Regards,
Gyan
Sergio Acereda Feb. 10, 2022, 12:59 p.m. UTC | #2
Yes, I tried, but this only works if your sequence has the '-' before the numeric elements. You can see they comment that in the thread, by saying you have to remove the '-' from the expression.

$ ffmpeg -v debug -start_number -24 -i Comentaris_prova_%05d.png out.mkv
ffmpeg version 2020-10-17-git-62073cfa97-essentials_build-www.gyan.dev Copyright (c) 2000-2020 the FFmpeg developers
 built with gcc 10.2.0 (Rev3, Built by MSYS2 project)
 configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-lzma --enable-zlib --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-sdl2 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libaom --enable-libopenjpeg --enable-libvpx --enable-libass --enable-libfreetype --enable-libfribidi --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-d3d11va --enable-dxva2 --enable-libmfx --enable-libgme --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libtheora --enable-libvo-amrwbenc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-librubberband
 libavutil      56. 60.100 / 56. 60.100
 libavcodec     58.111.101 / 58.111.101
 libavformat    58. 62.100 / 58. 62.100
 libavdevice    58. 11.102 / 58. 11.102
 libavfilter     7. 87.100 /  7. 87.100
 libswscale      5.  8.100 /  5.  8.100
 libswresample   3.  8.100 /  3.  8.100
 libpostproc    55.  8.100 / 55.  8.100
Splitting the commandline.
Reading option '-v' ... matched as option 'v' (set logging level) with argument 'debug'.
Reading option '-start_number' ... matched as AVOption 'start_number' with argument '-24'.
Reading option '-i' ... matched as input url with argument 'Comentaris_prova_%05d.png'.
Reading option 'out.mkv' ... matched as output url.
Finished splitting the commandline.
Parsing a group of options: global .
Applying option v (set logging level) with argument debug.
Successfully parsed a group of options.
Parsing a group of options: input url Comentaris_prova_%05d.png.
Successfully parsed a group of options.
Opening an input file: Comentaris_prova_%05d.png.
[image2 @ 000001742817d100] Could find no file with path 'Comentaris_prova_%05d.png' and index in the range -24--20
Comentaris_prova_%05d.png: No such file or directory
Sergio Acereda Feb. 10, 2022, 8:50 p.m. UTC | #3
By the way, is there any problem with the patch itself? Not sure why it says 'Failed to apply patch'.

Did my email client break it somehow?

>
Sergio Acereda Feb. 11, 2022, 4:45 p.m. UTC | #4
Not sure what I'm doing wrong here. This is what I'm doing:

$ git pull
$ git co master
...apply changes...
$ git add libavformat/img2.h
$ git add libavformat/img2dec.c
$ git commit -s -m"[PATCH] avformat/img2dec: Option to play sequence backwards"
$ git format-patch -s -o "outputfolder" --add-header "X-Unsent: 1" --suffix .eml --to ffmpeg-devel@ffmpeg.org -1 6b36bb6

Then I open the .eml on Apple Mail client, select 'Message / Send Again', and add some explanation before the 'signed off' line.

Just wondering what is wrong here, in order to not repeating the same mistake again.

Thanks,
 Sergio


> On 10 Feb 2022, at 21:50, Sergio Acereda <sergio.acereda@gmail.com> wrote:
> 
> By the way, is there any problem with the patch itself? Not sure why it says 'Failed to apply patch'.
> 
> Did my email client break it somehow?
Marvin Scholz Feb. 11, 2022, 5:19 p.m. UTC | #5
On 11 Feb 2022, at 17:45, Sergio Acereda wrote:

> Not sure what I'm doing wrong here. This is what I'm doing:
>
> $ git pull
> $ git co master
> ...apply changes...
> $ git add libavformat/img2.h
> $ git add libavformat/img2dec.c
> $ git commit -s -m"[PATCH] avformat/img2dec: Option to play sequence 
> backwards"
> $ git format-patch -s -o "outputfolder" --add-header "X-Unsent: 1" 
> --suffix .eml --to ffmpeg-devel@ffmpeg.org -1 6b36bb6
>
> Then I open the .eml on Apple Mail client, select 'Message / Send 
> Again', and add some explanation before the 'signed off' line.
>
> Just wondering what is wrong here, in order to not repeating the same 
> mistake again.
>

I think Apple Mail wraps the lines in the mail or somehow else alters it 
breaking
the patch.

I would recommend to use git send-email or try it with a different mail 
client
like MailMate maybe.

> Thanks,
>  Sergio
>
>
>> On 10 Feb 2022, at 21:50, Sergio Acereda <sergio.acereda@gmail.com> 
>> wrote:
>>
>> By the way, is there any problem with the patch itself? Not sure why 
>> it says 'Failed to apply patch'.
>>
>> Did my email client break it somehow?
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
Sergio Acereda Feb. 11, 2022, 7:39 p.m. UTC | #6
> I think Apple Mail wraps the lines in the mail or somehow else alters it 
> breaking
> the patch.
> 
> I would recommend to use git send-email or try it with a different mail 
> client
> like MailMate maybe.

I see... I'll try with git send-email then, not sure if it will open a new thread or continue here.

Thanks,
diff mbox series

Patch

diff --git a/libavformat/img2.h b/libavformat/img2.h
index 5fd8ff77fc..3d01c00537 100644
--- a/libavformat/img2.h
+++ b/libavformat/img2.h
@@ -59,6 +59,7 @@  typedef struct VideoDemuxData {
#endif
    int start_number;
    int start_number_range;
+    int reverse;
    int frame_size;
    int ts_from_file;
    int export_path_metadata; /**< enabled when set to 1. */
diff --git a/libavformat/img2dec.c b/libavformat/img2dec.c
index 8608252d83..90465441f1 100644
--- a/libavformat/img2dec.c
+++ b/libavformat/img2dec.c
@@ -105,10 +105,12 @@  static int is_glob(const char *path)
 * @param plast_index  pointer to index updated with the last number in the range
 * @param path         path which has to be matched by the image files in the range
 * @param start_index  minimum accepted value for the first index in the range
+ * @param start_index_range range for looking at the first sequence number
+ * @param reverse      play backwards
 * @return -1 if no image file could be found
 */
static int find_image_range(AVIOContext *pb, int *pfirst_index, int *plast_index,
-                            const char *path, int start_index, int start_index_range)
+                            const char *path, int start_index, int start_index_range, int reverse)
{
    char buf[1024];
    int range, last_index, range1, first_index;
@@ -152,8 +154,14 @@  static int find_image_range(AVIOContext *pb, int *pfirst_index, int *plast_index
            break;
        last_index += range;
    }
-    *pfirst_index = first_index;
-    *plast_index  = last_index;
+    if (reverse) {
+        *pfirst_index = last_index;
+        *plast_index  = first_index;
+    }
+    else {
+        *pfirst_index = first_index;
+        *plast_index  = last_index;
+    }
    return 0;

fail:
@@ -274,7 +282,7 @@  int ff_img_read_header(AVFormatContext *s1)
        }
        if ((s->pattern_type == PT_GLOB_SEQUENCE && !s->use_glob) || s->pattern_type == PT_SEQUENCE) {
            if (find_image_range(s1->pb, &first_index, &last_index, s->path,
-                                 s->start_number, s->start_number_range) < 0) {
+                                 s->start_number, s->start_number_range, s->reverse) < 0) {
                av_log(s1, AV_LOG_ERROR,
                       "Could find no file with path '%s' and index in the range %d-%d\n",
                       s->path, s->start_number, s->start_number + s->start_number_range - 1);
@@ -307,7 +315,7 @@  int ff_img_read_header(AVFormatContext *s1)
        /* compute duration */
        if (!s->ts_from_file) {
            st->start_time = 0;
-            st->duration   = last_index - first_index + 1;
+            st->duration   = abs(last_index - first_index) + 1;
        }
    }

@@ -413,11 +421,12 @@  int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt)
    AVCodecParameters *par = s1->streams[0]->codecpar;

    if (!s->is_pipe) {
+        int bad = s->reverse? (s->img_number < s->img_last) : (s->img_number > s->img_last);
        /* loop over input */
-        if (s->loop && s->img_number > s->img_last) {
+        if (s->loop && bad) {
            s->img_number = s->img_first;
        }
-        if (s->img_number > s->img_last)
+        if (bad)
            return AVERROR_EOF;
        if (s->pattern_type == PT_NONE) {
            av_strlcpy(filename_bytes, s->path, sizeof(filename_bytes));
@@ -554,8 +563,9 @@  int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt)
        }
        goto fail;
    } else {
+        int step = s->reverse? -1 : 1;
        s->img_count++;
-        s->img_number++;
+        s->img_number += step;
        s->pts++;
        return 0;
    }
@@ -594,9 +604,10 @@  static int img_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
        return 0;
    }

-    if (timestamp < 0 || !s1->loop && timestamp > s1->img_last - s1->img_first)
+    int bad = s1->reverse? (timestamp < s1->img_last) : (timestamp > s1->img_last);
+    if (timestamp < 0 || !s1->loop && bad)
        return -1;
-    s1->img_number = timestamp%(s1->img_last - s1->img_first + 1) + s1->img_first;
+    s1->img_number = timestamp%abs(s1->img_last - s1->img_first + 1) + s1->img_first;
    s1->pts = timestamp;
    return 0;
}
@@ -619,6 +630,7 @@  const AVOption ff_img_options[] = {
    { "none",         "disable pattern matching",            0, AV_OPT_TYPE_CONST,  {.i64=PT_NONE         }, INT_MIN, INT_MAX, DEC, "pattern_type" },
    { "start_number", "set first number in the sequence",    OFFSET(start_number), AV_OPT_TYPE_INT,    {.i64 = 0   }, INT_MIN, INT_MAX, DEC },
    { "start_number_range", "set range for looking at the first sequence number", OFFSET(start_number_range), AV_OPT_TYPE_INT, {.i64 = 5}, 1, INT_MAX, DEC },
+    { "reverse",      "reverse direction",                   OFFSET(reverse),      AV_OPT_TYPE_INT,    {.i64 = 0   }, 0, 1, DEC },
    { "ts_from_file", "set frame timestamp from file's one", OFFSET(ts_from_file), AV_OPT_TYPE_INT,    {.i64 = 0   }, 0, 2,       DEC, "ts_type" },
    { "none", "none",                   0, AV_OPT_TYPE_CONST,    {.i64 = 0   }, 0, 2,       DEC, "ts_type" },
    { "sec",  "second precision",       0, AV_OPT_TYPE_CONST,    {.i64 = 1   }, 0, 2,       DEC, "ts_type" },