aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas George <george@nsup.org>2013-11-25 16:27:41 +0100
committerCarl Eugen Hoyos <cehoyos@ag.or.at>2013-11-30 19:22:07 +0100
commit12c2d2ed464cc5e8868f176a17eb89eb212b831a (patch)
tree376e4b0623c79622ec2de55eddb4a6eb80fb0e84
parent88e368d5a7ab9a97dc7fb7a5b11b47e864c2621b (diff)
downloadffmpeg-12c2d2ed464cc5e8868f176a17eb89eb212b831a.tar.gz
lavc/srtenc: use bprint for text buffers.
Fix trac ticket #3120. (cherry picked from commit 4b1c9b720e11d200ca7090210b34c409f43fafeb)
-rw-r--r--libavcodec/srtenc.c48
1 files changed, 28 insertions, 20 deletions
diff --git a/libavcodec/srtenc.c b/libavcodec/srtenc.c
index 3036a7fb0c..89c26dcbf0 100644
--- a/libavcodec/srtenc.c
+++ b/libavcodec/srtenc.c
@@ -22,6 +22,7 @@
#include <stdarg.h>
#include "avcodec.h"
#include "libavutil/avstring.h"
+#include "libavutil/bprint.h"
#include "ass_split.h"
#include "ass.h"
@@ -31,10 +32,8 @@
typedef struct {
AVCodecContext *avctx;
ASSSplitContext *ass_ctx;
- char buffer[2048];
- char *ptr;
- char *end;
- char *dialog_start;
+ AVBPrint buffer;
+ unsigned timestamp_end;
int count;
char stack[SRT_STACK_SIZE];
int stack_ptr;
@@ -49,7 +48,7 @@ static void srt_print(SRTContext *s, const char *str, ...)
{
va_list vargs;
va_start(vargs, str);
- s->ptr += vsnprintf(s->ptr, s->end - s->ptr, str, vargs);
+ av_vbprintf(&s->buffer, str, vargs);
va_end(vargs);
}
@@ -138,14 +137,14 @@ static av_cold int srt_encode_init(AVCodecContext *avctx)
SRTContext *s = avctx->priv_data;
s->avctx = avctx;
s->ass_ctx = ff_ass_split(avctx->subtitle_header);
+ av_bprint_init(&s->buffer, 0, AV_BPRINT_SIZE_UNLIMITED);
return s->ass_ctx ? 0 : AVERROR_INVALIDDATA;
}
static void srt_text_cb(void *priv, const char *text, int len)
{
SRTContext *s = priv;
- av_strlcpy(s->ptr, text, FFMIN(s->end-s->ptr, len+1));
- s->ptr += len;
+ av_bprint_append_data(&s->buffer, text, len);
}
static void srt_new_line_cb(void *priv, int forced)
@@ -208,11 +207,19 @@ static void srt_move_cb(void *priv, int x1, int y1, int x2, int y2,
char buffer[32];
int len = snprintf(buffer, sizeof(buffer),
" X1:%03u X2:%03u Y1:%03u Y2:%03u", x1, x2, y1, y2);
- if (s->end - s->ptr > len) {
- memmove(s->dialog_start+len, s->dialog_start, s->ptr-s->dialog_start+1);
- memcpy(s->dialog_start, buffer, len);
- s->ptr += len;
+ unsigned char *dummy;
+ unsigned room;
+
+ av_bprint_get_buffer(&s->buffer, len, &dummy, &room);
+ if (room >= len) {
+ memmove(s->buffer.str + s->timestamp_end + len,
+ s->buffer.str + s->timestamp_end,
+ s->buffer.len - s->timestamp_end + 1);
+ memcpy(s->buffer.str + s->timestamp_end, buffer, len);
}
+ /* Increment even if av_bprint_get_buffer() did not return enough room:
+ the bprint structure will be treated as truncated. */
+ s->buffer.len += len;
}
}
@@ -243,10 +250,9 @@ static int srt_encode_frame(AVCodecContext *avctx,
{
SRTContext *s = avctx->priv_data;
ASSDialog *dialog;
- int i, len, num;
+ int i, num;
- s->ptr = s->buffer;
- s->end = s->ptr + sizeof(s->buffer);
+ av_bprint_clear(&s->buffer);
for (i=0; i<sub->num_rects; i++) {
@@ -268,7 +274,7 @@ static int srt_encode_frame(AVCodecContext *avctx,
es = ec/ 1000; ec -= 1000*es;
srt_print(s,"%d\r\n%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\r\n",
++s->count, sh, sm, ss, sc, eh, em, es, ec);
- s->dialog_start = s->ptr - 2;
+ s->timestamp_end = s->buffer.len - 2;
}
s->alignment_applied = 0;
srt_style_apply(s, dialog->style);
@@ -276,23 +282,25 @@ static int srt_encode_frame(AVCodecContext *avctx,
}
}
- if (s->ptr == s->buffer)
+ if (!av_bprint_is_complete(&s->buffer))
+ return AVERROR(ENOMEM);
+ if (!s->buffer.len)
return 0;
- len = av_strlcpy(buf, s->buffer, bufsize);
-
- if (len > bufsize-1) {
+ if (s->buffer.len > bufsize) {
av_log(avctx, AV_LOG_ERROR, "Buffer too small for ASS event.\n");
return -1;
}
+ memcpy(buf, s->buffer.str, s->buffer.len);
- return len;
+ return s->buffer.len;
}
static int srt_encode_close(AVCodecContext *avctx)
{
SRTContext *s = avctx->priv_data;
ff_ass_split_free(s->ass_ctx);
+ av_bprint_finalize(&s->buffer, NULL);
return 0;
}