mirror of
https://github.com/librempeg/librempeg
synced 2024-11-23 11:39:47 +00:00
lavf/srtdec: trim line break event separators from packet.
The muxer add them automatically, so this avoid having a bunch of line breaks all over the output files. One '\n' is still kept/added because the lavc subrip decoder seems to have trouble with line ending abruptly (it doesn't flush correctly the tags). This bug is harmless but should be fixed; though, this doesn't look like a trivial change. When this bug gets fixed, we can consider removing the '\n' at the end of the packet. The 2048B buffer limit was also removed while moving to AVBPrint API. Note that this doesn't really matter since the decoder is limited as well.
This commit is contained in:
parent
d513fb1c75
commit
cc88734c3c
@ -21,6 +21,7 @@
|
||||
|
||||
#include "avformat.h"
|
||||
#include "internal.h"
|
||||
#include "libavutil/bprint.h"
|
||||
#include "libavutil/intreadwrite.h"
|
||||
|
||||
static int srt_probe(AVProbeData *p)
|
||||
@ -52,7 +53,7 @@ static int srt_read_header(AVFormatContext *s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int64_t get_pts(char **buf, int *duration,
|
||||
static int64_t get_pts(const char **buf, int *duration,
|
||||
int32_t *x1, int32_t *y1, int32_t *x2, int32_t *y2)
|
||||
{
|
||||
int i;
|
||||
@ -81,27 +82,69 @@ static inline int is_eol(char c)
|
||||
return c == '\r' || c == '\n';
|
||||
}
|
||||
|
||||
static void read_chunk(AVIOContext *pb, AVBPrint *buf)
|
||||
{
|
||||
char eol_buf[5];
|
||||
int n = 0, i = 0, nb_eol = 0;
|
||||
|
||||
for (;;) {
|
||||
char c = avio_r8(pb);
|
||||
|
||||
if (!c)
|
||||
break;
|
||||
|
||||
/* ignore all initial line breaks */
|
||||
if (n == 0 && is_eol(c))
|
||||
continue;
|
||||
|
||||
/* line break buffering: we don't want to add the trailing \r\n */
|
||||
if (is_eol(c)) {
|
||||
nb_eol += c == '\n';
|
||||
if (nb_eol == 2)
|
||||
break;
|
||||
eol_buf[i++] = c;
|
||||
if (i == sizeof(eol_buf) - 1)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* only one line break followed by data: we flush the line breaks
|
||||
* buffer */
|
||||
if (i) {
|
||||
eol_buf[i] = 0;
|
||||
av_bprintf(buf, "%s", eol_buf);
|
||||
i = nb_eol = 0;
|
||||
}
|
||||
|
||||
av_bprint_chars(buf, c, 1);
|
||||
n++;
|
||||
}
|
||||
|
||||
/* FIXME: remove the following when the lavc SubRip decoder is fixed
|
||||
* (trailing tags are not correctly flushed, see what happens to FATE when
|
||||
* you disable this code) */
|
||||
if (buf->len)
|
||||
av_bprintf(buf, "\n");
|
||||
}
|
||||
|
||||
static int srt_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
{
|
||||
char buffer[2048], *ptr = buffer, *ptr2;
|
||||
AVBPrint buf;
|
||||
int64_t pos = avio_tell(s->pb);
|
||||
int res = AVERROR_EOF;
|
||||
|
||||
do {
|
||||
ptr2 = ptr;
|
||||
ptr += ff_get_line(s->pb, ptr, sizeof(buffer)+buffer-ptr);
|
||||
} while (!is_eol(*ptr2) && !url_feof(s->pb) && ptr-buffer<sizeof(buffer)-1);
|
||||
av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
|
||||
read_chunk(s->pb, &buf);
|
||||
|
||||
if (buffer[0]) {
|
||||
if (buf.len) {
|
||||
int64_t pts;
|
||||
int duration;
|
||||
const char *end = ptr;
|
||||
int duration, pkt_size;
|
||||
const char *ptr = buf.str;
|
||||
int32_t x1 = -1, y1 = -1, x2 = -1, y2 = -1;
|
||||
|
||||
ptr = buffer;
|
||||
pts = get_pts(&ptr, &duration, &x1, &y1, &x2, &y2);
|
||||
if (pts != AV_NOPTS_VALUE &&
|
||||
!(res = av_new_packet(pkt, end - ptr))) {
|
||||
pkt_size = buf.len - (ptr - buf.str);
|
||||
if (pts != AV_NOPTS_VALUE && !(res = av_new_packet(pkt, pkt_size))) {
|
||||
memcpy(pkt->data, ptr, pkt->size);
|
||||
pkt->flags |= AV_PKT_FLAG_KEY;
|
||||
pkt->pos = pos;
|
||||
@ -118,6 +161,7 @@ static int srt_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
}
|
||||
}
|
||||
}
|
||||
av_bprint_finalize(&buf, NULL);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user