movtextdec: 3GPP TS 26.245 Timed Text Decoder.
This change introduces a basic decoder for 3GPP Timed Text subtitles, also known as TX3G, Quicktime subtitles, or "movtext" in the existing code. This initial change doesn't attempt to parse styling information, and just reads the plain text of the subtitles. I intend to add support for styles eventually, but it's challenging due to a lack of existing players that support them. Signed-off-by: Philip Langdale <philipl@overt.org>
This commit is contained in:
parent
57d5a224ce
commit
2c501ae82b
@ -27,6 +27,7 @@ version next:
|
|||||||
- iec61883 device
|
- iec61883 device
|
||||||
- asettb filter
|
- asettb filter
|
||||||
- new option: -progress
|
- new option: -progress
|
||||||
|
- 3GPP Timed Text decoder
|
||||||
|
|
||||||
|
|
||||||
version 0.11:
|
version 0.11:
|
||||||
|
@ -876,16 +876,17 @@ performance on systems without hardware floating point support).
|
|||||||
|
|
||||||
@multitable @columnfractions .4 .1 .1 .1 .1
|
@multitable @columnfractions .4 .1 .1 .1 .1
|
||||||
@item Name @tab Muxing @tab Demuxing @tab Encoding @tab Decoding
|
@item Name @tab Muxing @tab Demuxing @tab Encoding @tab Decoding
|
||||||
@item SSA/ASS @tab X @tab X @tab X @tab X
|
@item SSA/ASS @tab X @tab X @tab X @tab X
|
||||||
@item DVB @tab X @tab X @tab X @tab X
|
@item DVB @tab X @tab X @tab X @tab X
|
||||||
@item DVD @tab X @tab X @tab X @tab X
|
@item DVD @tab X @tab X @tab X @tab X
|
||||||
@item JACOsub @tab X @tab X @tab @tab X
|
@item JACOsub @tab X @tab X @tab @tab X
|
||||||
@item MicroDVD @tab X @tab X @tab @tab X
|
@item MicroDVD @tab X @tab X @tab @tab X
|
||||||
@item PGS @tab @tab @tab @tab X
|
@item PGS @tab @tab @tab @tab X
|
||||||
@item RealText @tab @tab X @tab @tab X
|
@item RealText @tab @tab X @tab @tab X
|
||||||
@item SAMI @tab @tab X @tab @tab X
|
@item SAMI @tab @tab X @tab @tab X
|
||||||
@item SubRip (SRT) @tab X @tab X @tab X @tab X
|
@item SubRip (SRT) @tab X @tab X @tab X @tab X
|
||||||
@item XSUB @tab @tab @tab X @tab X
|
@item 3GPP Timed Text @tab @tab @tab @tab X
|
||||||
|
@item XSUB @tab @tab @tab X @tab X
|
||||||
@end multitable
|
@end multitable
|
||||||
|
|
||||||
@code{X} means that the feature is supported.
|
@code{X} means that the feature is supported.
|
||||||
|
@ -265,6 +265,7 @@ OBJS-$(CONFIG_MJPEGB_DECODER) += mjpegbdec.o mjpegdec.o mjpeg.o
|
|||||||
OBJS-$(CONFIG_MLP_DECODER) += mlpdec.o mlpdsp.o
|
OBJS-$(CONFIG_MLP_DECODER) += mlpdec.o mlpdsp.o
|
||||||
OBJS-$(CONFIG_MMVIDEO_DECODER) += mmvideo.o
|
OBJS-$(CONFIG_MMVIDEO_DECODER) += mmvideo.o
|
||||||
OBJS-$(CONFIG_MOTIONPIXELS_DECODER) += motionpixels.o
|
OBJS-$(CONFIG_MOTIONPIXELS_DECODER) += motionpixels.o
|
||||||
|
OBJS-$(CONFIG_MOVTEXT_DECODER) += movtextdec.o ass.o
|
||||||
OBJS-$(CONFIG_MP1_DECODER) += mpegaudiodec.o mpegaudiodecheader.o \
|
OBJS-$(CONFIG_MP1_DECODER) += mpegaudiodec.o mpegaudiodecheader.o \
|
||||||
mpegaudio.o mpegaudiodata.o
|
mpegaudio.o mpegaudiodata.o
|
||||||
OBJS-$(CONFIG_MP1FLOAT_DECODER) += mpegaudiodec_float.o mpegaudiodecheader.o \
|
OBJS-$(CONFIG_MP1FLOAT_DECODER) += mpegaudiodec_float.o mpegaudiodecheader.o \
|
||||||
|
@ -409,6 +409,7 @@ void avcodec_register_all(void)
|
|||||||
REGISTER_ENCDEC (DVDSUB, dvdsub);
|
REGISTER_ENCDEC (DVDSUB, dvdsub);
|
||||||
REGISTER_DECODER (JACOSUB, jacosub);
|
REGISTER_DECODER (JACOSUB, jacosub);
|
||||||
REGISTER_DECODER (MICRODVD, microdvd);
|
REGISTER_DECODER (MICRODVD, microdvd);
|
||||||
|
REGISTER_DECODER (MOVTEXT, movtext);
|
||||||
REGISTER_DECODER (PGSSUB, pgssub);
|
REGISTER_DECODER (PGSSUB, pgssub);
|
||||||
REGISTER_DECODER (REALTEXT, realtext);
|
REGISTER_DECODER (REALTEXT, realtext);
|
||||||
REGISTER_DECODER (SAMI, sami);
|
REGISTER_DECODER (SAMI, sami);
|
||||||
|
106
libavcodec/movtextdec.c
Normal file
106
libavcodec/movtextdec.c
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* 3GPP TS 26.245 Timed Text decoder
|
||||||
|
* Copyright (c) 2012 Philip Langdale <philipl@overt.org>
|
||||||
|
*
|
||||||
|
* This file is part of FFmpeg.
|
||||||
|
*
|
||||||
|
* FFmpeg is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FFmpeg is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with FFmpeg; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "avcodec.h"
|
||||||
|
#include "ass.h"
|
||||||
|
#include "libavutil/avstring.h"
|
||||||
|
#include "libavutil/common.h"
|
||||||
|
#include "libavutil/bprint.h"
|
||||||
|
#include "libavutil/intreadwrite.h"
|
||||||
|
|
||||||
|
static int text_to_ass(AVBPrint *buf, const char *text, const char *text_end)
|
||||||
|
{
|
||||||
|
while (text < text_end) {
|
||||||
|
switch (*text) {
|
||||||
|
case '\r':
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
av_bprintf(buf, "\\N");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
av_bprint_chars(buf, *text, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
text++;
|
||||||
|
}
|
||||||
|
|
||||||
|
av_bprintf(buf, "\r\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mov_text_init(AVCodecContext *avctx) {
|
||||||
|
/*
|
||||||
|
* TODO: Handle the default text style.
|
||||||
|
* NB: Most players ignore styles completely, with the result that
|
||||||
|
* it's very common to find files where the default style is broken
|
||||||
|
* and respecting it results in a worse experience than ignoring it.
|
||||||
|
*/
|
||||||
|
return ff_ass_subtitle_header_default(avctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mov_text_decode_frame(AVCodecContext *avctx,
|
||||||
|
void *data, int *got_sub_ptr, AVPacket *avpkt)
|
||||||
|
{
|
||||||
|
AVSubtitle *sub = data;
|
||||||
|
int ts_start, ts_end;
|
||||||
|
AVBPrint buf;
|
||||||
|
const char *ptr = avpkt->data;
|
||||||
|
const char *end;
|
||||||
|
|
||||||
|
if (!ptr || avpkt->size <= 2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The first two bytes of the packet are the length of the text string
|
||||||
|
* In complex cases, there are style descriptors appended to the string
|
||||||
|
* so we can't just assume the packet size is the string size.
|
||||||
|
*/
|
||||||
|
end = ptr + FFMAX(2 + AV_RB16(ptr), avpkt->size);
|
||||||
|
ptr += 2;
|
||||||
|
|
||||||
|
ts_start = av_rescale_q(avpkt->pts,
|
||||||
|
avctx->time_base,
|
||||||
|
(AVRational){1,100});
|
||||||
|
ts_end = av_rescale_q(avpkt->pts + avpkt->duration,
|
||||||
|
avctx->time_base,
|
||||||
|
(AVRational){1,100});
|
||||||
|
|
||||||
|
// Note that the spec recommends lines be no longer than 2048 characters.
|
||||||
|
av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
|
||||||
|
text_to_ass(&buf, ptr, end);
|
||||||
|
|
||||||
|
if (!av_bprint_is_complete(&buf))
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
|
ff_ass_add_rect(sub, buf.str, ts_start, ts_end-ts_start, 0);
|
||||||
|
*got_sub_ptr = sub->num_rects > 0;
|
||||||
|
av_bprint_finalize(&buf, NULL);
|
||||||
|
return avpkt->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
AVCodec ff_movtext_decoder = {
|
||||||
|
.name = "mov_text",
|
||||||
|
.long_name = NULL_IF_CONFIG_SMALL("3GPP Timed Text subtitle"),
|
||||||
|
.type = AVMEDIA_TYPE_SUBTITLE,
|
||||||
|
.id = CODEC_ID_MOV_TEXT,
|
||||||
|
.init = mov_text_init,
|
||||||
|
.decode = mov_text_decode_frame,
|
||||||
|
};
|
@ -27,7 +27,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define LIBAVCODEC_VERSION_MAJOR 54
|
#define LIBAVCODEC_VERSION_MAJOR 54
|
||||||
#define LIBAVCODEC_VERSION_MINOR 38
|
#define LIBAVCODEC_VERSION_MINOR 39
|
||||||
#define LIBAVCODEC_VERSION_MICRO 101
|
#define LIBAVCODEC_VERSION_MICRO 101
|
||||||
|
|
||||||
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
||||||
|
@ -13,5 +13,8 @@ fate-sub-srt: CMD = md5 -i $(SAMPLES)/sub/SubRip_capability_tester.srt -f ass
|
|||||||
FATE_SUBTITLES += fate-sub-realtext
|
FATE_SUBTITLES += fate-sub-realtext
|
||||||
fate-sub-realtext: CMD = md5 -i $(SAMPLES)/sub/RealText_capability_tester.rt -f ass
|
fate-sub-realtext: CMD = md5 -i $(SAMPLES)/sub/RealText_capability_tester.rt -f ass
|
||||||
|
|
||||||
|
FATE_SUBTITLES += fate-sub-movtext
|
||||||
|
fate-sub-movtext: CMD = md5 -i $(SAMPLES)/sub/MovText_capability_tester.mp4 -f ass
|
||||||
|
|
||||||
FATE_SAMPLES_FFMPEG += $(FATE_SUBTITLES)
|
FATE_SAMPLES_FFMPEG += $(FATE_SUBTITLES)
|
||||||
fate-subtitles: $(FATE_SUBTITLES)
|
fate-subtitles: $(FATE_SUBTITLES)
|
||||||
|
1
tests/ref/fate/sub-movtext
Normal file
1
tests/ref/fate/sub-movtext
Normal file
@ -0,0 +1 @@
|
|||||||
|
21453e8ddbbe35d1368a99fe563c969d
|
Loading…
Reference in New Issue
Block a user