From 25d3f96db7d7b4a30acd4373ebf5469821789366 Mon Sep 17 00:00:00 2001 From: Tristan Matthews Date: Fri, 15 Apr 2022 07:53:01 -0400 Subject: librtmp: use AVBPrint instead of char * MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This avoids having to do one pass to calculate the full length to allocate followed by a second pass to actually append values. Signed-off-by: Martin Storsjö --- libavformat/librtmp.c | 124 ++++++++++++++------------------------------------ 1 file changed, 33 insertions(+), 91 deletions(-) (limited to 'libavformat') diff --git a/libavformat/librtmp.c b/libavformat/librtmp.c index 43013e46e0..b7e9fc81cf 100644 --- a/libavformat/librtmp.c +++ b/libavformat/librtmp.c @@ -25,6 +25,7 @@ */ #include "libavutil/avstring.h" +#include "libavutil/bprint.h" #include "libavutil/mathematics.h" #include "libavutil/opt.h" #include "avformat.h" @@ -38,6 +39,7 @@ typedef struct LibRTMPContext { const AVClass *class; + AVBPrint filename; RTMP rtmp; char *app; char *conn; @@ -50,7 +52,6 @@ typedef struct LibRTMPContext { char *pageurl; char *client_buffer_time; int live; - char *temp_filename; int buffer_size; } LibRTMPContext; @@ -76,7 +77,7 @@ static int rtmp_close(URLContext *s) RTMP *r = &ctx->rtmp; RTMP_Close(r); - av_freep(&ctx->temp_filename); + av_bprint_finalize(&ctx->filename, NULL); return 0; } @@ -97,8 +98,8 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) LibRTMPContext *ctx = s->priv_data; RTMP *r = &ctx->rtmp; int rc = 0, level; - char *filename = s->filename; - int len = strlen(s->filename) + 1; + /* This needs to stay allocated for as long as the RTMP context exists. */ + av_bprint_init(&ctx->filename, 0, AV_BPRINT_SIZE_UNLIMITED); switch (av_log_get_level()) { default: @@ -112,118 +113,58 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) RTMP_LogSetLevel(level); RTMP_LogSetCallback(rtmp_log); - if (ctx->app) len += strlen(ctx->app) + sizeof(" app="); - if (ctx->tcurl) len += strlen(ctx->tcurl) + sizeof(" tcUrl="); - if (ctx->pageurl) len += strlen(ctx->pageurl) + sizeof(" pageUrl="); - if (ctx->flashver) len += strlen(ctx->flashver) + sizeof(" flashver="); - + av_bprintf(&ctx->filename, "%s", s->filename); + if (ctx->app) + av_bprintf(&ctx->filename, " app=%s", ctx->app); + if (ctx->tcurl) + av_bprintf(&ctx->filename, " tcUrl=%s", ctx->tcurl); + if (ctx->pageurl) + av_bprintf(&ctx->filename, " pageUrl=%s", ctx->pageurl); + if (ctx->swfurl) + av_bprintf(&ctx->filename, " swfUrl=%s", ctx->swfurl); + if (ctx->flashver) + av_bprintf(&ctx->filename, " flashVer=%s", ctx->flashver); if (ctx->conn) { char *sep, *p = ctx->conn; - int options = 0; - while (p) { - options++; + av_bprintf(&ctx->filename, " conn="); p += strspn(p, " "); if (!*p) break; sep = strchr(p, ' '); + if (sep) + *sep = '\0'; + av_bprintf(&ctx->filename, "%s", p); + if (sep) p = sep + 1; else break; } - len += options * sizeof(" conn="); - len += strlen(ctx->conn); } - if (ctx->playpath) - len += strlen(ctx->playpath) + sizeof(" playpath="); + av_bprintf(&ctx->filename, " playpath=%s", ctx->playpath); if (ctx->live) - len += sizeof(" live=1"); + av_bprintf(&ctx->filename, " live=1"); if (ctx->subscribe) - len += strlen(ctx->subscribe) + sizeof(" subscribe="); - + av_bprintf(&ctx->filename, " subscribe=%s", ctx->subscribe); if (ctx->client_buffer_time) - len += strlen(ctx->client_buffer_time) + sizeof(" buffer="); - + av_bprintf(&ctx->filename, " buffer=%s", ctx->client_buffer_time); if (ctx->swfurl || ctx->swfverify) { - len += sizeof(" swfUrl="); - if (ctx->swfverify) - len += strlen(ctx->swfverify) + sizeof(" swfVfy=1"); + av_bprintf(&ctx->filename, " swfUrl=%s swfVfy=1", ctx->swfverify); else - len += strlen(ctx->swfurl); + av_bprintf(&ctx->filename, " swfUrl=%s", ctx->swfurl); } - if (!(ctx->temp_filename = filename = av_malloc(len))) + if (!av_bprint_is_complete(&ctx->filename)) { + av_bprint_finalize(&ctx->filename, NULL); return AVERROR(ENOMEM); - - av_strlcpy(filename, s->filename, len); - if (ctx->app) { - av_strlcat(filename, " app=", len); - av_strlcat(filename, ctx->app, len); - } - if (ctx->tcurl) { - av_strlcat(filename, " tcUrl=", len); - av_strlcat(filename, ctx->tcurl, len); - } - if (ctx->pageurl) { - av_strlcat(filename, " pageUrl=", len); - av_strlcat(filename, ctx->pageurl, len); - } - if (ctx->swfurl) { - av_strlcat(filename, " swfUrl=", len); - av_strlcat(filename, ctx->swfurl, len); - } - if (ctx->flashver) { - av_strlcat(filename, " flashVer=", len); - av_strlcat(filename, ctx->flashver, len); - } - if (ctx->conn) { - char *sep, *p = ctx->conn; - while (p) { - av_strlcat(filename, " conn=", len); - p += strspn(p, " "); - if (!*p) - break; - sep = strchr(p, ' '); - if (sep) - *sep = '\0'; - av_strlcat(filename, p, len); - - if (sep) - p = sep + 1; - else - break; - } - } - if (ctx->playpath) { - av_strlcat(filename, " playpath=", len); - av_strlcat(filename, ctx->playpath, len); - } - if (ctx->live) - av_strlcat(filename, " live=1", len); - if (ctx->subscribe) { - av_strlcat(filename, " subscribe=", len); - av_strlcat(filename, ctx->subscribe, len); - } - if (ctx->client_buffer_time) { - av_strlcat(filename, " buffer=", len); - av_strlcat(filename, ctx->client_buffer_time, len); - } - if (ctx->swfurl || ctx->swfverify) { - av_strlcat(filename, " swfUrl=", len); - - if (ctx->swfverify) { - av_strlcat(filename, ctx->swfverify, len); - av_strlcat(filename, " swfVfy=1", len); - } else { - av_strlcat(filename, ctx->swfurl, len); - } } RTMP_Init(r); - if (!RTMP_SetupURL(r, filename)) { + /* This will modify filename by null terminating the URL portion */ + if (!RTMP_SetupURL(r, ctx->filename.str)) { rc = AVERROR_UNKNOWN; goto fail; } @@ -249,9 +190,10 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) s->is_streamed = 1; return 0; fail: - av_freep(&ctx->temp_filename); + if (rc) RTMP_Close(r); + av_bprint_finalize(&ctx->filename, NULL); return rc; } -- cgit v1.2.3