diff mbox series

[FFmpeg-devel,3/3] avcodec/xbmenc: Allow for making UW images

Message ID 202101182143.13808.digital@joescat.com
State Accepted
Commit c31a7d07f6f22a94b7f44dcb73c025b2d78cfc66
Headers show
Series [FFmpeg-devel,1/3] avcodec/xbmenc: Do not add last comma into output | expand

Checks

Context Check Description
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished
andriy/PPC64_make success Make finished
andriy/PPC64_make_fate success Make fate finished

Commit Message

Jose Da Silva Jan. 19, 2021, 5:43 a.m. UTC
I've run into some bugs where I was downloading a bunch of data and began 
seeing weird hiccups. For example, javascript promises to allow you to push 
some very long lines of data, but the hiccups I saw was with data larger 
than 2k in length (windows) pushed out of a child process stdout piped into 
the stdin of the calling parent program.
Soo much for smooth promises, this was broken and would run into similar 
problems on a linux PC with 32k line limits.
The solution was to break the data into smaller chunks than 2k - and then 
these data hiccups disappeared (windows PC).

It would be expected to be similar for linux PCs (32k I think) and other 
OSes with different sizes.

If the ANSI required minimum needs to be 509 chars or larger (assuming 
509+<CR>+<LF>+<0>=512), then 509 was chosen as the shortest worst-case 
scenario) in this patch.
Most small pictures will go output looking pretty much the same data out 
until you get to about 84bytes (672 pixels wide), where lines out begin to 
be split. For example a UW 4K will exceed a 2k readln and a UW 10K picture 
approaches an 8k readln

The purpose for this patch is to ensure that data remains below the 
readline limits (of 509 chars), so that programs (like javascript) can push 
data in large chunks without breaking into hiccups because the data length 
is too long to be pushed cleanly in one go.
Subject: [PATCH 3/3] avcodec/xbmenc: Allow for making UW images

Worst-case ANSI must allow for 509 chars, while Windows allows for 2048
and Linux for 32K line length. This allows an OS with a small readline
access limitation to fetch very wide images (created from ffmpeg).
---
 libavcodec/xbmenc.c | 30 +++++++++++++++++++++++-------
 1 file changed, 23 insertions(+), 7 deletions(-)

Comments

Paul B Mahol Jan. 28, 2021, 10:22 a.m. UTC | #1
Gonna apply this set soon.
Jose Da Silva Jan. 28, 2021, 3:41 p.m. UTC | #2
This is an incredibly busy dev list.
 - pretty easy to miss a message in the noise.

Thanks for the FYI.
diff mbox series

Patch

diff --git a/libavcodec/xbmenc.c b/libavcodec/xbmenc.c
index 193ced652a..1cf13f6f0b 100644
--- a/libavcodec/xbmenc.c
+++ b/libavcodec/xbmenc.c
@@ -24,15 +24,25 @@ 
 #include "internal.h"
 #include "mathops.h"
 
+#define ANSI_MIN_READLINE 509
+
 static int xbm_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                             const AVFrame *p, int *got_packet)
 {
-    int i, j, commas, ret, size, linesize;
+    int i, j, l, commas, ret, size, linesize, lineout, rowsout;
     uint8_t *ptr, *buf;
 
-    linesize = (avctx->width + 7) / 8;
+    linesize = lineout = (avctx->width + 7) / 8;
     commas   = avctx->height * linesize;
-    size     = avctx->height * (linesize * 6 + 1) + 106;
+
+    /* ANSI worst case minimum readline is 509 chars. */
+    rowsout  = avctx->height;
+    if (lineout > (ANSI_MIN_READLINE / 6)) {
+        lineout = ANSI_MIN_READLINE / 6;
+        rowsout = (commas + lineout - 1) / lineout;
+    }
+
+    size     = rowsout * (lineout * 6 + 1) + 106;
     if ((ret = ff_alloc_packet2(avctx, pkt, size, 0)) < 0)
         return ret;
 
@@ -42,14 +52,20 @@  static int xbm_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     buf += snprintf(buf, 32, "#define image_width %u\n", avctx->width);
     buf += snprintf(buf, 33, "#define image_height %u\n", avctx->height);
     buf += snprintf(buf, 39, "static unsigned char image_bits[] = {\n");
-    for (i = 0; i < avctx->height; i++) {
+    for (i = 0, l = lineout; i < avctx->height; i++) {
         for (j = 0; j < linesize; j++) {
             buf += snprintf(buf, 6, " 0x%02X", ff_reverse[*ptr++]);
-            if (--commas > 0)
-                buf += snprintf(buf, 2, ",");
+            if (--commas <= 0) {
+                buf += snprintf(buf, 2, "\n");
+                break;
+            }
+            buf += snprintf(buf, 2, ",");
+            if (--l <= 0) {
+                buf += snprintf(buf, 2, "\n");
+                l = lineout;
+            }
         }
         ptr += p->linesize[0] - linesize;
-        buf += snprintf(buf, 2, "\n");
     }
     buf += snprintf(buf, 5, " };\n");