Problem after applying a patch for random name generation in ffmpeg

1

I applied the following patch below, it works as expected, but occasionally transcoding to and in other cases ( rare cases depending on the version of compiled ffmpeg ) continues to run but instead of creating multiple segments with random names, it gets all of them stored in a single thread file.

That is, looking at the patch, is there any inconsistency in it? If so, how could I resolve?

diff --git a/libavformat/utils.c b/libavformat/utils.c
index 17ae300..7ff8c22 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -3809,6 +3809,36 @@ uint64_t ff_ntp_time(void)
     return (av_gettime() / 1000) * 1000 + NTP_OFFSET_US;
 }

+static char *randstring(size_t length) {
+
+    static char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+    char *randomString;
+
+    if (length) {
+        randomString = malloc(sizeof(char) * (length +1));
+
+        if (randomString) {
+            for (int n = 0;n < length;n++) {
+                int key = rand() % (int)(sizeof(charset) -1);
+                randomString[n] = charset[key];
+            }
+
+            randomString[length] = '
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 17ae300..7ff8c22 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -3809,6 +3809,36 @@ uint64_t ff_ntp_time(void)
     return (av_gettime() / 1000) * 1000 + NTP_OFFSET_US;
 }

+static char *randstring(size_t length) {
+
+    static char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+    char *randomString;
+
+    if (length) {
+        randomString = malloc(sizeof(char) * (length +1));
+
+        if (randomString) {
+            for (int n = 0;n < length;n++) {
+                int key = rand() % (int)(sizeof(charset) -1);
+                randomString[n] = charset[key];
+            }
+
+            randomString[length] = '%pre%';
+        }
+    }
+
+    return randomString;
+}
+
+/**
+ * Random filename usage
+ *
+ * use "%<size>r" at -segment_format. <size> is the length of random string generated, for example: "%20r"
+ *
+ * command example:
+ * ffmpeg -i $1 -r 25 -c:a libfaac -ab:a 128k -ac:a 2 -c:v mpeg2video -s:v 640x360 -aspect:v 16:9 -map 0 -f segment -segment_time 120 -segment_list $2.m3u8 -segment_format mpegts "$2-%20r.ts"
+ */
+
 int av_get_frame_filename(char *buf, int buf_size, const char *path, int number)
 {
     const char *p;
@@ -3829,7 +3859,6 @@ int av_get_frame_filename(char *buf, int buf_size, const char *path, int number)
                     nd = nd * 10 + *p++ - '0';
                 c = *p++;
             } while (av_isdigit(c));
-
             switch (c) {
             case '%':
                 goto addchar;
@@ -3846,6 +3875,17 @@ int av_get_frame_filename(char *buf, int buf_size, const char *path, int number)
                 memcpy(q, buf1, len);
                 q += len;
                 break;
+            case 'r':
+                percentd_found = 1;
+                if (number < 0)
+                    nd += 1;
+                snprintf(buf1, sizeof(buf1), "%s", randstring(nd));
+                len = strlen(buf1);
+                if ((q - buf + len) > buf_size - 1)
+                    goto fail;
+                memcpy(q, buf1, len);
+                q += len;
+                goto addchar;
             default:
                 goto fail;
             }
'; + } + } + + return randomString; +} + +/** + * Random filename usage + * + * use "%<size>r" at -segment_format. <size> is the length of random string generated, for example: "%20r" + * + * command example: + * ffmpeg -i $1 -r 25 -c:a libfaac -ab:a 128k -ac:a 2 -c:v mpeg2video -s:v 640x360 -aspect:v 16:9 -map 0 -f segment -segment_time 120 -segment_list $2.m3u8 -segment_format mpegts "$2-%20r.ts" + */ + int av_get_frame_filename(char *buf, int buf_size, const char *path, int number) { const char *p; @@ -3829,7 +3859,6 @@ int av_get_frame_filename(char *buf, int buf_size, const char *path, int number) nd = nd * 10 + *p++ - '0'; c = *p++; } while (av_isdigit(c)); - switch (c) { case '%': goto addchar; @@ -3846,6 +3875,17 @@ int av_get_frame_filename(char *buf, int buf_size, const char *path, int number) memcpy(q, buf1, len); q += len; break; + case 'r': + percentd_found = 1; + if (number < 0) + nd += 1; + snprintf(buf1, sizeof(buf1), "%s", randstring(nd)); + len = strlen(buf1); + if ((q - buf + len) > buf_size - 1) + goto fail; + memcpy(q, buf1, len); + q += len; + goto addchar; default: goto fail; }
    
asked by anonymous 21.11.2016 / 15:28

1 answer

1

I do not know if this answers the question, but it was too big for a comment.

On the face, I notice that randstring(0) returns an uninitialized pointer, which is dangerous. I think, but I'm not sure, that this could happen if path contains %0r .

However, there is a serious memory leak problem with randstring . This function allocates memory in the heap, returns a pointer to av_get_frame_filename , and the av_get_frame_filename function does not call free anywhere.

So, I suggest that the randstring function is as follows:

static char *randstring(char *target, size_t length) {

    static char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

    for (int n = 0; n < length - 1; n++) {
        int key = rand() % (int)(sizeof(charset) - 1);
        target[n] = charset[key];
    }

    if (length) target[length - 1] = '
snprintf(buf1, sizeof(buf1), "%s", randstring(nd));
len = strlen(buf1);
'; return target; }

Note that length is now the number of characters to be written including malloc , and no longer excluding av_get_frame_filename . And we no longer need to use av_get_frame_filename in this function.

And then, in its function %code% instead:

len = sizeof(buf1);
if (len > nd + 1) len = nd + 1;
randstring(buf1, len);

You put this:

static char *randstring(char *target, size_t length) {

    static char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

    for (int n = 0; n < length - 1; n++) {
        int key = rand() % (int)(sizeof(charset) - 1);
        target[n] = charset[key];
    }

    if (length) target[length - 1] = '
snprintf(buf1, sizeof(buf1), "%s", randstring(nd));
len = strlen(buf1);
'; return target; }

As for the rest of the %code% function, I do not know, because I did not fully understand it yet, although I understood more or less what it does.

    
21.11.2016 / 16:54