Kill timed SRT

pull/86/merge
Clément Bœsch 10 years ago
parent d5ddcb5f8e
commit 55180b3299
  1. 33
      libavcodec/srtdec.c
  2. 45
      libavcodec/srtenc.c
  3. 2
      libavcodec/version.h
  4. 1
      libavformat/matroska.c
  5. 45
      libavformat/matroskaenc.c
  6. 11
      libavformat/srtenc.c
  7. 2
      libavformat/version.h

@ -193,28 +193,6 @@ static const char *srt_to_ass(AVCodecContext *avctx, char *out, char *out_end,
return in; return in;
} }
static const char *read_ts(const char *buf, int *ts_start, int *ts_end,
int *x1, int *y1, int *x2, int *y2)
{
int i, hs, ms, ss, he, me, se;
for (i=0; i<2; i++) {
/* try to read timestamps in either the first or second line */
int c = sscanf(buf, "%d:%2d:%2d%*1[,.]%3d --> %d:%2d:%2d%*1[,.]%3d"
"%*[ ]X1:%u X2:%u Y1:%u Y2:%u",
&hs, &ms, &ss, ts_start, &he, &me, &se, ts_end,
x1, x2, y1, y2);
buf += strcspn(buf, "\n");
buf += !!*buf;
if (c >= 8) {
*ts_start = 100*(ss + 60*(ms + 60*hs)) + *ts_start/10;
*ts_end = 100*(se + 60*(me + 60*he)) + *ts_end /10;
return buf;
}
}
return NULL;
}
static int srt_decode_frame(AVCodecContext *avctx, static int srt_decode_frame(AVCodecContext *avctx,
void *data, int *got_sub_ptr, AVPacket *avpkt) void *data, int *got_sub_ptr, AVPacket *avpkt)
{ {
@ -237,11 +215,7 @@ static int srt_decode_frame(AVCodecContext *avctx,
return avpkt->size; return avpkt->size;
while (ptr < end && *ptr) { while (ptr < end && *ptr) {
if (avctx->codec->id == AV_CODEC_ID_SRT) { // TODO: reindent
ptr = read_ts(ptr, &ts_start, &ts_end, &x1, &y1, &x2, &y2);
if (!ptr)
break;
} else {
// Do final divide-by-10 outside rescale to force rounding down. // Do final divide-by-10 outside rescale to force rounding down.
ts_start = av_rescale_q(avpkt->pts, ts_start = av_rescale_q(avpkt->pts,
avctx->time_base, avctx->time_base,
@ -249,7 +223,6 @@ static int srt_decode_frame(AVCodecContext *avctx,
ts_end = av_rescale_q(avpkt->pts + avpkt->duration, ts_end = av_rescale_q(avpkt->pts + avpkt->duration,
avctx->time_base, avctx->time_base,
(AVRational){1,100}); (AVRational){1,100});
}
ptr = srt_to_ass(avctx, buffer, buffer+sizeof(buffer), ptr, ptr = srt_to_ass(avctx, buffer, buffer+sizeof(buffer), ptr,
x1, y1, x2, y2); x1, y1, x2, y2);
ret = ff_ass_add_rect(sub, buffer, ts_start, ts_end-ts_start, 0); ret = ff_ass_add_rect(sub, buffer, ts_start, ts_end-ts_start, 0);
@ -265,9 +238,9 @@ static int srt_decode_frame(AVCodecContext *avctx,
/* deprecated decoder */ /* deprecated decoder */
AVCodec ff_srt_decoder = { AVCodec ff_srt_decoder = {
.name = "srt", .name = "srt",
.long_name = NULL_IF_CONFIG_SMALL("SubRip subtitle with embedded timing"), .long_name = NULL_IF_CONFIG_SMALL("SubRip subtitle"),
.type = AVMEDIA_TYPE_SUBTITLE, .type = AVMEDIA_TYPE_SUBTITLE,
.id = AV_CODEC_ID_SRT, .id = AV_CODEC_ID_SUBRIP,
.init = ff_ass_subtitle_header_default, .init = ff_ass_subtitle_header_default,
.decode = srt_decode_frame, .decode = srt_decode_frame,
}; };

@ -33,8 +33,6 @@ typedef struct {
AVCodecContext *avctx; AVCodecContext *avctx;
ASSSplitContext *ass_ctx; ASSSplitContext *ass_ctx;
AVBPrint buffer; AVBPrint buffer;
unsigned timestamp_end;
int count;
char stack[SRT_STACK_SIZE]; char stack[SRT_STACK_SIZE];
int stack_ptr; int stack_ptr;
int alignment_applied; int alignment_applied;
@ -201,35 +199,13 @@ static void srt_cancel_overrides_cb(void *priv, const char *style)
static void srt_move_cb(void *priv, int x1, int y1, int x2, int y2, static void srt_move_cb(void *priv, int x1, int y1, int x2, int y2,
int t1, int t2) int t1, int t2)
{ {
SRTContext *s = priv; // TODO: add a AV_PKT_DATA_SUBTITLE_POSITION side data when a new subtitles
// encoding API passing the AVPacket is available.
if (s->avctx->codec->id == AV_CODEC_ID_SRT) {
char buffer[32];
int len = snprintf(buffer, sizeof(buffer),
" X1:%03u X2:%03u Y1:%03u Y2:%03u", x1, x2, y1, y2);
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;
}
} }
static void srt_end_cb(void *priv) static void srt_end_cb(void *priv)
{ {
SRTContext *s = priv;
srt_stack_push_pop(priv, 0, 1); srt_stack_push_pop(priv, 0, 1);
if (s->avctx->codec->id == AV_CODEC_ID_SRT)
srt_print(priv, "\r\n\r\n");
} }
static const ASSCodesCallbacks srt_callbacks = { static const ASSCodesCallbacks srt_callbacks = {
@ -263,19 +239,6 @@ static int srt_encode_frame(AVCodecContext *avctx,
dialog = ff_ass_split_dialog(s->ass_ctx, sub->rects[i]->ass, 0, &num); dialog = ff_ass_split_dialog(s->ass_ctx, sub->rects[i]->ass, 0, &num);
for (; dialog && num--; dialog++) { for (; dialog && num--; dialog++) {
if (avctx->codec->id == AV_CODEC_ID_SRT) {
int sh, sm, ss, sc = 10 * dialog->start;
int eh, em, es, ec = 10 * dialog->end;
sh = sc/3600000; sc -= 3600000*sh;
sm = sc/ 60000; sc -= 60000*sm;
ss = sc/ 1000; sc -= 1000*ss;
eh = ec/3600000; ec -= 3600000*eh;
em = ec/ 60000; ec -= 60000*em;
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->timestamp_end = s->buffer.len - 2;
}
s->alignment_applied = 0; s->alignment_applied = 0;
srt_style_apply(s, dialog->style); srt_style_apply(s, dialog->style);
ff_ass_split_override_codes(&srt_callbacks, s, dialog->text); ff_ass_split_override_codes(&srt_callbacks, s, dialog->text);
@ -308,9 +271,9 @@ static int srt_encode_close(AVCodecContext *avctx)
/* deprecated encoder */ /* deprecated encoder */
AVCodec ff_srt_encoder = { AVCodec ff_srt_encoder = {
.name = "srt", .name = "srt",
.long_name = NULL_IF_CONFIG_SMALL("SubRip subtitle with embedded timing"), .long_name = NULL_IF_CONFIG_SMALL("SubRip subtitle"),
.type = AVMEDIA_TYPE_SUBTITLE, .type = AVMEDIA_TYPE_SUBTITLE,
.id = AV_CODEC_ID_SRT, .id = AV_CODEC_ID_SUBRIP,
.priv_data_size = sizeof(SRTContext), .priv_data_size = sizeof(SRTContext),
.init = srt_encode_init, .init = srt_encode_init,
.encode_sub = srt_encode_frame, .encode_sub = srt_encode_frame,

@ -30,7 +30,7 @@
#define LIBAVCODEC_VERSION_MAJOR 56 #define LIBAVCODEC_VERSION_MAJOR 56
#define LIBAVCODEC_VERSION_MINOR 1 #define LIBAVCODEC_VERSION_MINOR 1
#define LIBAVCODEC_VERSION_MICRO 101 #define LIBAVCODEC_VERSION_MICRO 102
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \ LIBAVCODEC_VERSION_MINOR, \

@ -66,7 +66,6 @@ const CodecTags ff_mkv_codec_tags[]={
{"S_TEXT/UTF8" , AV_CODEC_ID_SUBRIP}, {"S_TEXT/UTF8" , AV_CODEC_ID_SUBRIP},
{"S_TEXT/UTF8" , AV_CODEC_ID_TEXT}, {"S_TEXT/UTF8" , AV_CODEC_ID_TEXT},
{"S_TEXT/UTF8" , AV_CODEC_ID_SRT},
{"S_TEXT/ASCII" , AV_CODEC_ID_TEXT}, {"S_TEXT/ASCII" , AV_CODEC_ID_TEXT},
{"S_TEXT/ASS" , AV_CODEC_ID_ASS}, {"S_TEXT/ASS" , AV_CODEC_ID_ASS},
{"S_TEXT/SSA" , AV_CODEC_ID_ASS}, {"S_TEXT/SSA" , AV_CODEC_ID_ASS},

@ -1589,47 +1589,6 @@ static void mkv_write_block(AVFormatContext *s, AVIOContext *pb,
} }
} }
static int srt_get_duration(uint8_t **buf)
{
int i, duration = 0;
for (i = 0; i < 2 && !duration; i++) {
int s_hour, s_min, s_sec, s_hsec, e_hour, e_min, e_sec, e_hsec;
if (sscanf(*buf, "%d:%2d:%2d%*1[,.]%3d --> %d:%2d:%2d%*1[,.]%3d",
&s_hour, &s_min, &s_sec, &s_hsec,
&e_hour, &e_min, &e_sec, &e_hsec) == 8) {
s_min += 60 * s_hour;
e_min += 60 * e_hour;
s_sec += 60 * s_min;
e_sec += 60 * e_min;
s_hsec += 1000 * s_sec;
e_hsec += 1000 * e_sec;
duration = e_hsec - s_hsec;
}
*buf += ff_subtitles_next_line(*buf);
}
return duration;
}
static int mkv_write_srt_blocks(AVFormatContext *s, AVIOContext *pb,
AVPacket *pkt)
{
ebml_master blockgroup;
AVPacket pkt2 = *pkt;
int64_t duration = srt_get_duration(&pkt2.data);
pkt2.size -= pkt2.data - pkt->data;
blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP,
mkv_blockgroup_size(pkt2.size));
mkv_write_block(s, pb, MATROSKA_ID_BLOCK, &pkt2, 0);
put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, duration);
end_ebml_master(pb, blockgroup);
return duration;
}
static int mkv_write_vtt_blocks(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt) static int mkv_write_vtt_blocks(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt)
{ {
MatroskaMuxContext *mkv = s->priv_data; MatroskaMuxContext *mkv = s->priv_data;
@ -1757,9 +1716,7 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt, int add_
if (ret < 0) return ret; if (ret < 0) return ret;
} }
} else { } else {
if (codec->codec_id == AV_CODEC_ID_SRT) { if (codec->codec_id == AV_CODEC_ID_WEBVTT) {
duration = mkv_write_srt_blocks(s, pb, pkt);
} else if (codec->codec_id == AV_CODEC_ID_WEBVTT) {
duration = mkv_write_vtt_blocks(s, pb, pkt); duration = mkv_write_vtt_blocks(s, pb, pkt);
} else { } else {
ebml_master blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP, ebml_master blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP,

@ -45,8 +45,7 @@ static int srt_write_header(AVFormatContext *avf)
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
if (avf->streams[0]->codec->codec_id != AV_CODEC_ID_TEXT && if (avf->streams[0]->codec->codec_id != AV_CODEC_ID_TEXT &&
avf->streams[0]->codec->codec_id != AV_CODEC_ID_SUBRIP && avf->streams[0]->codec->codec_id != AV_CODEC_ID_SUBRIP) {
avf->streams[0]->codec->codec_id != AV_CODEC_ID_SRT) {
av_log(avf, AV_LOG_ERROR, av_log(avf, AV_LOG_ERROR,
"Unsupported subtitles codec: %s\n", "Unsupported subtitles codec: %s\n",
avcodec_get_name(avf->streams[0]->codec->codec_id)); avcodec_get_name(avf->streams[0]->codec->codec_id));
@ -60,9 +59,8 @@ static int srt_write_header(AVFormatContext *avf)
static int srt_write_packet(AVFormatContext *avf, AVPacket *pkt) static int srt_write_packet(AVFormatContext *avf, AVPacket *pkt)
{ {
SRTContext *srt = avf->priv_data; SRTContext *srt = avf->priv_data;
int write_ts = avf->streams[0]->codec->codec_id != AV_CODEC_ID_SRT;
if (write_ts) { // TODO: reindent
int64_t s = pkt->pts, e, d = pkt->duration; int64_t s = pkt->pts, e, d = pkt->duration;
int size, x1 = -1, y1 = -1, x2 = -1, y2 = -1; int size, x1 = -1, y1 = -1, x2 = -1, y2 = -1;
const uint8_t *p; const uint8_t *p;
@ -94,10 +92,9 @@ static int srt_write_packet(AVFormatContext *avf, AVPacket *pkt)
avio_printf(avf->pb, " X1:%03d X2:%03d Y1:%03d Y2:%03d", avio_printf(avf->pb, " X1:%03d X2:%03d Y1:%03d Y2:%03d",
x1, x2, y1, y2); x1, x2, y1, y2);
avio_printf(avf->pb, "\n"); avio_printf(avf->pb, "\n");
}
avio_write(avf->pb, pkt->data, pkt->size); avio_write(avf->pb, pkt->data, pkt->size);
if (write_ts) avio_write(avf->pb, "\n\n", 2);
avio_write(avf->pb, "\n\n", 2);
srt->index++; srt->index++;
return 0; return 0;
} }

@ -31,7 +31,7 @@
#define LIBAVFORMAT_VERSION_MAJOR 56 #define LIBAVFORMAT_VERSION_MAJOR 56
#define LIBAVFORMAT_VERSION_MINOR 7 #define LIBAVFORMAT_VERSION_MINOR 7
#define LIBAVFORMAT_VERSION_MICRO 101 #define LIBAVFORMAT_VERSION_MICRO 102
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
LIBAVFORMAT_VERSION_MINOR, \ LIBAVFORMAT_VERSION_MINOR, \

Loading…
Cancel
Save