From patchwork Tue Jan 31 14:22:17 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul B Mahol X-Patchwork-Id: 2379 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.89.21 with SMTP id n21csp1962287vsb; Tue, 31 Jan 2017 06:22:39 -0800 (PST) X-Received: by 10.223.162.205 with SMTP id t13mr26875767wra.155.1485872559378; Tue, 31 Jan 2017 06:22:39 -0800 (PST) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id e71si17427002wmc.105.2017.01.31.06.22.39; Tue, 31 Jan 2017 06:22:39 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 1DA2A68A171; Tue, 31 Jan 2017 16:22:34 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm0-f67.google.com (mail-wm0-f67.google.com [74.125.82.67]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id E6FD668A099 for ; Tue, 31 Jan 2017 16:22:27 +0200 (EET) Received: by mail-wm0-f67.google.com with SMTP id v77so23139955wmv.0 for ; Tue, 31 Jan 2017 06:22:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id; bh=FVft87H9KWdq6f7tbjHTq0g6o3N1n0/1bJbmgnR/5eE=; b=TMGktIud3pOLMhCM6xYWk8XPpM4U+c+5DimxWZzJQegMA83nTOw6mSxGebt6NTCO1j mgmd7tEIag3wctc50K9KnkFqyklh6YLtcwEY+UyMLchV7itP4VkHdPiRttoBU4hZrVsY pXi9V61e0EmHk9SCYntVHIdMsnq0aS99OXVKCMcGF1xuPSytB0N8rkV72waKyG8cPjVH JabQ6Jx721PSQrPPRiUBXexI6/EMlUSeBCIAWRaSuEYNtZw2RGux9NNpASkFLtMEXTIY SnXZ8vmjbeylfwEQEaLdEtOooJqhGQorzwrbYzMzLpILkd6ej8suG80SCnlRXTtcVwB7 mkTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id; bh=FVft87H9KWdq6f7tbjHTq0g6o3N1n0/1bJbmgnR/5eE=; b=atRn9gg26MxTNDTNbnz0L36RlHoHlp37mk3iQYynS+2EEOqUq0iQpPKuaGGuKApYNT XZBUxE6+cij4p+zmsyfy0kicy3pg+nCTJXIWMzHnsewyj+wUx4hYwfOoOY2fw0vlVZ9g 37ugA2fWBVJDtflFCByyuVW9am8bHjRTwmU03N3Aa6DyS7XYy1hndkS5e4RpMqBkEMQD +/mSFSdCYmg75IRP3Qwbblc4CL0jwdAsMl+XyKvoPe8uVm5dXUQn0XYFjndZNb3DvpP9 t0U/Fr1ZalaeqZhMkB9CT44AfuxHNOLPlVSzvBUjDetscpakSLo2Iyu7Tv7TXn+MIWh0 4x5g== X-Gm-Message-State: AIkVDXJsT88BFSiNbT+ObFVRYEw0T3L7Pv9Wd/pdtp+EGNA4QnJRbfudMrmpHslT3MuE9Q== X-Received: by 10.28.230.91 with SMTP id d88mr17947003wmh.129.1485872549875; Tue, 31 Jan 2017 06:22:29 -0800 (PST) Received: from localhost.localdomain ([94.250.174.60]) by smtp.gmail.com with ESMTPSA id b51sm28698787wrd.39.2017.01.31.06.22.28 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 31 Jan 2017 06:22:28 -0800 (PST) From: Paul B Mahol To: ffmpeg-devel@ffmpeg.org Date: Tue, 31 Jan 2017 15:22:17 +0100 Message-Id: <20170131142217.23731-1-onemda@gmail.com> X-Mailer: git-send-email 2.9.3 Subject: [FFmpeg-devel] [PATCH] avcodec: add HDMV Text Subtitle decoder X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Signed-off-by: Paul B Mahol --- libavcodec/Makefile | 2 + libavcodec/allcodecs.c | 2 + libavcodec/textst_parser.c | 49 ++++++++++++++++++++ libavcodec/textstdec.c | 108 +++++++++++++++++++++++++++++++++++++++++++++ libavformat/utils.c | 1 + 5 files changed, 162 insertions(+) create mode 100644 libavcodec/textst_parser.c create mode 100644 libavcodec/textstdec.c diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 43a6add..edadb0f 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -539,6 +539,7 @@ OBJS-$(CONFIG_SVQ1_ENCODER) += svq1enc.o svq1.o h263data.o \ OBJS-$(CONFIG_SVQ3_DECODER) += svq3.o svq13.o mpegutils.o h264data.o OBJS-$(CONFIG_TEXT_DECODER) += textdec.o ass.o OBJS-$(CONFIG_TEXT_ENCODER) += srtenc.o ass_split.o +OBJS-$(CONFIG_TEXTST_DECODER) += textstdec.o ass.o OBJS-$(CONFIG_TAK_DECODER) += takdec.o tak.o takdsp.o OBJS-$(CONFIG_TARGA_DECODER) += targa.o OBJS-$(CONFIG_TARGA_ENCODER) += targaenc.o rle.o @@ -945,6 +946,7 @@ OBJS-$(CONFIG_RV30_PARSER) += rv34_parser.o OBJS-$(CONFIG_RV40_PARSER) += rv34_parser.o OBJS-$(CONFIG_SIPR_PARSER) += sipr_parser.o OBJS-$(CONFIG_TAK_PARSER) += tak_parser.o tak.o +OBJS-$(CONFIG_TEXTST_PARSER) += textst_parser.o OBJS-$(CONFIG_VC1_PARSER) += vc1_parser.o vc1.o vc1data.o \ simple_idct.o wmv2data.o OBJS-$(CONFIG_VP3_PARSER) += vp3_parser.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index f92b2b7..9a90533 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -581,6 +581,7 @@ void avcodec_register_all(void) REGISTER_DECODER(SUBVIEWER, subviewer); REGISTER_DECODER(SUBVIEWER1, subviewer1); REGISTER_ENCDEC (TEXT, text); + REGISTER_DECODER(TEXTST, textst); REGISTER_DECODER(VPLAYER, vplayer); REGISTER_ENCDEC (WEBVTT, webvtt); REGISTER_ENCDEC (XSUB, xsub); @@ -704,6 +705,7 @@ void avcodec_register_all(void) REGISTER_PARSER(RV40, rv40); REGISTER_PARSER(SIPR, sipr); REGISTER_PARSER(TAK, tak); + REGISTER_PARSER(TEXTST, textst); REGISTER_PARSER(VC1, vc1); REGISTER_PARSER(VORBIS, vorbis); REGISTER_PARSER(VP3, vp3); diff --git a/libavcodec/textst_parser.c b/libavcodec/textst_parser.c new file mode 100644 index 0000000..5079a96 --- /dev/null +++ b/libavcodec/textst_parser.c @@ -0,0 +1,49 @@ +/* + * 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 + */ + +/** + * @file + * HDMV TextST subtitle parser + */ + +#include "libavutil/intreadwrite.h" +#include "parser.h" + +static int textst_parse(AVCodecParserContext *s1, AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + if (buf_size > 13) { + int64_t end; + + s1->pts = ((int64_t)(buf[3] & 1) << 32) | AV_RB32(&buf[4]); + end = ((int64_t)(buf[8] & 1) << 32) | AV_RB32(&buf[9]); + s1->duration = (end - s1->pts); + } + + /* always return the full packet. this parser isn't doing any splitting or + combining, only packet analysis */ + *poutbuf = buf; + *poutbuf_size = buf_size; + return buf_size; +} + +AVCodecParser ff_textst_parser = { + .codec_ids = { AV_CODEC_ID_HDMV_TEXT_SUBTITLE }, + .parser_parse = textst_parse, +}; diff --git a/libavcodec/textstdec.c b/libavcodec/textstdec.c new file mode 100644 index 0000000..a259d2d --- /dev/null +++ b/libavcodec/textstdec.c @@ -0,0 +1,108 @@ +/* + * HDMV TextST decoder + * Copyright (c) 2017 Paul B Mahol + * + * 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 + +#include "libavutil/bprint.h" +#include "avcodec.h" +#include "ass.h" +#include "bytestream.h" + +static int textst_event_to_ass(AVBPrint *buf, const char *p, int size) +{ + GetByteContext gb; + int i, count; + + bytestream2_init(&gb, p, size); + count = bytestream2_get_byte(&gb); + + if (count > 127) { + int size = bytestream2_get_be16(&gb); + bytestream2_skip(&gb, size); + } + if (bytestream2_get_bytes_left(&gb) > 2) { + count = bytestream2_get_byte(&gb); + + for (i = 0; i < count; i++) { + int dlength; + + bytestream2_skip(&gb, 2); + dlength = bytestream2_get_be16(&gb); + + while (dlength > 3) { + int type, length; + int code = bytestream2_get_byte(&gb); + + dlength--; + if (code != 0x1b) + continue; + + type = bytestream2_get_byte(&gb); + length = bytestream2_get_byte(&gb); + dlength -= (2 + length); + + switch (type) { + case 1: + av_bprint_append_data(buf, gb.buffer, FFMIN(length, bytestream2_get_bytes_left(&gb))); + bytestream2_skip(&gb, length); + break; + case 0x0a: + av_bprintf(buf, "\n"); + default: + bytestream2_skip(&gb, length); + break; + } + } + } + } + + return 0; +} + +static int textst_decode_frame(AVCodecContext *avctx, + void *data, int *got_sub_ptr, AVPacket *avpkt) +{ + FFASSDecoderContext *s = avctx->priv_data; + const char *ptr = avpkt->data; + AVSubtitle *sub = data; + AVBPrint buf; + int ret = 0; + + av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED); + if (ptr && avpkt->size > 13 && !textst_event_to_ass(&buf, ptr + 13, avpkt->size - 13)) + ret = ff_ass_add_rect(sub, buf.str, s->readorder++, 0, NULL, NULL); + av_bprint_finalize(&buf, NULL); + if (ret < 0) + return ret; + *got_sub_ptr = sub->num_rects > 0; + return avpkt->size; +} + +AVCodec ff_textst_decoder = { + .name = "textst", + .long_name = NULL_IF_CONFIG_SMALL("HDMV TextST subtitle"), + .type = AVMEDIA_TYPE_SUBTITLE, + .id = AV_CODEC_ID_HDMV_TEXT_SUBTITLE, + .decode = textst_decode_frame, + .init = ff_ass_subtitle_header_default, + .flush = ff_ass_decoder_flush, + .priv_data_size = sizeof(FFASSDecoderContext), +}; diff --git a/libavformat/utils.c b/libavformat/utils.c index 0711310..74f808f 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -1445,6 +1445,7 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, int stream_index) out_pkt.stream_index = st->index; out_pkt.pts = st->parser->pts; + out_pkt.duration = st->parser->duration; out_pkt.dts = st->parser->dts; out_pkt.pos = st->parser->pos;