[FFmpeg-devel,18/20] avformat/lrcenc: Avoid allocations for writing packet data

Message ID AM7PR03MB666074F67B8CE96DFB508EA98FAB9@AM7PR03MB6660.eurprd03.prod.outlook.com
State Accepted
Commit e110076d8c1611a1b1c20edf1d0e8dea8be7ea15
Headers
Series [FFmpeg-devel,01/20] libpostproc/postprocess_template: Don't reimplement FFSWAP |

Checks

Context Check Description
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished
andriy/make_ppc success Make finished
andriy/make_fate_ppc success Make fate finished

Commit Message

Andreas Rheinhardt Oct. 1, 2021, 9:08 p.m. UTC
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavformat/lrcenc.c | 44 ++++++++++++++++++--------------------------
 1 file changed, 18 insertions(+), 26 deletions(-)
  

Comments

Paul B Mahol Oct. 2, 2021, 3:04 p.m. UTC | #1
lgtm
  

Patch

diff --git a/libavformat/lrcenc.c b/libavformat/lrcenc.c
index 0de0bb18f4..21cb3860ab 100644
--- a/libavformat/lrcenc.c
+++ b/libavformat/lrcenc.c
@@ -86,33 +86,25 @@  static int lrc_write_header(AVFormatContext *s)
 static int lrc_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
     if(pkt->pts != AV_NOPTS_VALUE) {
-        char *data = av_malloc(pkt->size + 1);
-        char *line;
-        char *delim;
+        const uint8_t *line = pkt->data;
+        const uint8_t *end  = pkt->data + pkt->size;
 
-        if(!data) {
-            return AVERROR(ENOMEM);
-        }
-        memcpy(data, pkt->data, pkt->size);
-        data[pkt->size] = '\0';
-
-        for(delim = data + pkt->size - 1;
-            delim >= data && (delim[0] == '\n' || delim[0] == '\r'); delim--) {
-            delim[0] = '\0'; // Strip last empty lines
-        }
-        line = data;
-        while(line[0] == '\n' || line[0] == '\r') {
-            line++; // Skip first empty lines
+        while (end > line && (end[-1] == '\n' || end[-1] == '\r'))
+            end--;
+        if (line != end) {
+            while (line[0] == '\n' || line[0] == '\r')
+                line++; // Skip first empty lines
         }
 
         while(line) {
-            delim = strchr(line, '\n');
-            if(delim) {
-                if(delim > line && delim[-1] == '\r') {
-                    delim[-1] = '\0';
-                }
-                delim[0] = '\0';
-                delim++;
+            const uint8_t *next_line = memchr(line, '\n', end - line);
+            size_t size = end - line;
+
+            if (next_line) {
+                size = next_line - line;
+                if (next_line > line && next_line[-1] == '\r')
+                    size--;
+                next_line++;
             }
             if(line[0] == '[') {
                 av_log(s, AV_LOG_WARNING,
@@ -132,10 +124,10 @@  static int lrc_write_packet(AVFormatContext *s, AVPacket *pkt)
                             ((-pkt->pts) / 100) % 60,
                             (-pkt->pts) % 100);
             }
-            avio_printf(s->pb, "%s\n", line);
-            line = delim;
+            avio_write(s->pb, line, size);
+            avio_w8(s->pb, '\n');
+            line = next_line;
         }
-        av_free(data);
     }
     return 0;
 }