From patchwork Sun Sep 12 03:21:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Soft Works X-Patchwork-Id: 30180 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6602:2a4a:0:0:0:0 with SMTP id k10csp2862893iov; Sat, 11 Sep 2021 20:22:08 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwI3k6a+RIMcb2Vvt9OIf0oCN7QpydlzdAalWk8C0AQZpcMs7QFKjR0QyCIk4RaMNkMLBN7 X-Received: by 2002:a05:6402:14c3:: with SMTP id f3mr6102012edx.312.1631416928171; Sat, 11 Sep 2021 20:22:08 -0700 (PDT) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id nd33si3747401ejc.139.2021.09.11.20.22.07; Sat, 11 Sep 2021 20:22:08 -0700 (PDT) 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=@hotmail.com header.s=selector1 header.b=QXVb11g9; arc=fail (body hash mismatch); 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=hotmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 4A8F268A92E; Sun, 12 Sep 2021 06:21:50 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from NAM10-DM6-obe.outbound.protection.outlook.com (mail-dm6nam10olkn2062.outbound.protection.outlook.com [40.92.41.62]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 2777868A901 for ; Sun, 12 Sep 2021 06:21:43 +0300 (EEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=SZ2JTuK4CsQcNw2pp0/RrhBhhU/wbo+z1U8TC99CcRmiFnBUoL47ybqaADxyWKpQe947NhnnOr1I81svbrEU2+RkUGL5bJtoYr0jGaa1xFmRLwCcVkdwiU0nvkdqdNr2CvgV6dcD7V/QM2b2XYHg4udhdDyWXr4jFE0BHKhrVACn9OBdrlg8nDbGL7Dw8JiFg4gE+h/X0OOxAOTAx8kZvw0ol58V2ca8UDK8GHG+L2Wx7+/zl5b2jr+U0k3WX7oJm0DIhpQowvzLI2gi0zTeUJUZBJIFbmSVj32tC0F0Lf/j035p5N5kpnh1nBMeSFAEOyXiY2rNY3dcYiHcByk1iw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=30HhpAwTBICc00bf6R5JOaDGhVKCHBCOJAjPBRh+Swo=; b=LR8LgYKz2BwRBribPMWZKjIDPyX0JBANltSFn63AKHa33RWt5uRdO/Ie9GOaSXLeyURo2XFbhO1Af3/GoikXRrYKK68ljHHPBspz8EhYS4Vxg/SmVWV0PP0mYbgBm5aLSJroo/xl417FmolGgWiMOMm8AJ9nsqRnBgxm4wWpJ6RkyH4bEz405lIyHP1s2xex9KGxizCs/m0ZAZsE2qALPbzCf4OdzpNhZdBeOCyOTRGQNR+EBcl1WkTEUBkDSUShgjC/TLsQwrQZxGRtNtYZ7tV+dp5ORD2scbqpWcCt7e7EMyqcg3FInjYVfhrLRPq7L+skwZkFN4Lbp7vYS2P+Tw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; dkim=none; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hotmail.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=30HhpAwTBICc00bf6R5JOaDGhVKCHBCOJAjPBRh+Swo=; b=QXVb11g9eaXpxWzPDTfBnvrOBHmTea9YlHyDVbW30KBbUGwVnMuIGj8R6B0Nx0tWGFLD5G3chISj07CjYymkl2zLM7bfmdUiht6ojze9AeH2nU3xix+EEFTUFeDvAnfs1qiNPpTo6Pzkrt4ldl39xOxsNBFN1J4LNisU7V0EjVYDjRHabnldAycAqw3xGmLGKsNNpGxfRcYXOvjMDUCXPVP43pm3tAQr/fNnWkRaix+E/F62hNBHzJ7h5+V95Fjeeqog1+9/tF2VQKcmuXWLqNF3QMpbui+e82Ou7HGRwwP4aEFOzBCv3mxKICDNXtJPBvcFiUbWsCK+VHICv8pKug== Received: from MN2PR04MB5981.namprd04.prod.outlook.com (2603:10b6:208:da::10) by MN2PR04MB5728.namprd04.prod.outlook.com (2603:10b6:208:3d::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4500.14; Sun, 12 Sep 2021 03:21:37 +0000 Received: from MN2PR04MB5981.namprd04.prod.outlook.com ([fe80::ecfe:2528:2012:22cb]) by MN2PR04MB5981.namprd04.prod.outlook.com ([fe80::ecfe:2528:2012:22cb%5]) with mapi id 15.20.4500.018; Sun, 12 Sep 2021 03:21:37 +0000 From: Soft Works To: "ffmpeg-devel@ffmpeg.org" Thread-Topic: [PATCH v5 02/12] global: Merge AVSubtitle into AVFrame Thread-Index: AQHXp4VLULMa9R3Fu0+u6pWXhWgwtQ== Date: Sun, 12 Sep 2021 03:21:37 +0000 Message-ID: References: In-Reply-To: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-messagesentrepresentingtype: 1 x-tmn: [VkPo2LeIzaiGenofx/C+BgeyNLdmlDr7AM/QbghRfGk=] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 118a5889-de4f-49a1-54ed-08d9759c6e37 x-ms-traffictypediagnostic: MN2PR04MB5728: x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: IWarwvCtfYCKIitvOy8YQYVGPxAGfBw9xF3wohrQzEEQFMkmjmaJoE6eE85lGLSIFKFn58lOH7wS4YfZo3Q4jJHjIyUSpo/sELsrL7cslUY1YMaCU2bi9pTfPlbTmugDgq/9OHg8/oFSiorUe/Mh5h/27YJ5qcuYQmZgYSkp7riLy/Ng4qAA15jnFsXmlfGo66DfKqA+Jvaxeje6aJf30+fOn6gqnPibya2ScDz1BX7f5njpcRjpYkyOdKrgCw5gX1KGA5T2ZyAsfkb0oHCHrc2rCykPEor84XK2AUMkhKTnwBL8Fc2Fuw9f+VZ7Sab/7UImj3W0PGWT9nEvo5Tg8QILw+/MXE4spKDZdS8MpHj+MZEiNOkCqp2bQ/1wEfDUhQ/bZVW84yyI7VuNbSV7LWScBvKBuxYSQqUDY/qLr1aIf/Fsz1l7iKUmenrm6/xF x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: EeqgE+Ba1+sT032ll9IX3aFYj9lEwQ2w3fnzIp7Za6d04ed3fT1ePk66sshvszsp2d6xjk1GA4L0bsCPgF+TbmneBMRERLFed0sICWBTemMJsKhGjdfYvZ4mcq9qXR5L3ErxG9SM1csuEv5L5g3hgg== x-ms-exchange-transport-forked: True MIME-Version: 1.0 X-OriginatorOrg: sct-15-20-3174-20-msonline-outlook-529c7.templateTenant X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: MN2PR04MB5981.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-CrossTenant-Network-Message-Id: 118a5889-de4f-49a1-54ed-08d9759c6e37 X-MS-Exchange-CrossTenant-originalarrivaltime: 12 Sep 2021 03:21:37.2574 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-rms-persistedconsumerorg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR04MB5728 Subject: [FFmpeg-devel] [PATCH v5 02/12] global: Merge AVSubtitle into AVFrame X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: K4Zc23B9pDEL Signed-off-by: softworkz --- libavcodec/ass.c | 16 ++-- libavcodec/ass.h | 8 +- libavcodec/assdec.c | 18 ++--- libavcodec/assenc.c | 10 +-- libavcodec/avcodec.c | 19 ----- libavcodec/avcodec.h | 81 ++++---------------- libavcodec/ccaption_dec.c | 28 +++---- libavcodec/codec.h | 4 +- libavcodec/codec_desc.h | 4 +- libavcodec/decode.c | 23 +++--- libavcodec/dvbsubdec.c | 48 ++++++------ libavcodec/dvbsubenc.c | 72 +++++++++--------- libavcodec/dvdsubdec.c | 122 +++++++++++++++---------------- libavcodec/dvdsubenc.c | 40 +++++----- libavcodec/encode.c | 6 +- libavcodec/jacosubdec.c | 4 +- libavcodec/libzvbi-teletextdec.c | 16 ++-- libavcodec/microdvddec.c | 4 +- libavcodec/movtextdec.c | 4 +- libavcodec/movtextenc.c | 10 +-- libavcodec/mpl2dec.c | 4 +- libavcodec/pgssubdec.c | 68 ++++++++--------- libavcodec/realtextdec.c | 4 +- libavcodec/samidec.c | 4 +- libavcodec/srtdec.c | 4 +- libavcodec/srtenc.c | 14 ++-- libavcodec/subviewerdec.c | 4 +- libavcodec/textdec.c | 4 +- libavcodec/ttmlenc.c | 10 +-- libavcodec/utils.c | 11 +++ libavcodec/webvttdec.c | 4 +- libavcodec/webvttenc.c | 10 +-- libavcodec/xsubdec.c | 58 +++++++-------- libavcodec/xsubenc.c | 48 ++++++------ libavfilter/vf_subtitles.c | 28 +++---- libavformat/utils.c | 5 +- libavutil/Makefile | 2 + libavutil/frame.c | 41 ++++++++++- libavutil/frame.h | 12 +++ libavutil/subfmt.c | 52 +++++++++++++ libavutil/subfmt.h | 94 ++++++++++++++++++++++++ 41 files changed, 576 insertions(+), 442 deletions(-) create mode 100644 libavutil/subfmt.c create mode 100644 libavutil/subfmt.h diff --git a/libavcodec/ass.c b/libavcodec/ass.c index 907e2d7b88..415ef12911 100644 --- a/libavcodec/ass.c +++ b/libavcodec/ass.c @@ -114,26 +114,26 @@ char *ff_ass_get_dialog(int readorder, int layer, const char *style, speaker ? speaker : "", text); } -int ff_ass_add_rect(AVSubtitle *sub, const char *dialog, +int ff_ass_add_rect(AVFrame *sub, const char *dialog, int readorder, int layer, const char *style, const char *speaker) { char *ass_str; AVSubtitleRect **rects; - rects = av_realloc_array(sub->rects, sub->num_rects+1, sizeof(*sub->rects)); + rects = av_realloc_array(sub->subtitle_rects, sub->num_subtitle_rects+1, sizeof(*sub->subtitle_rects)); if (!rects) return AVERROR(ENOMEM); - sub->rects = rects; - rects[sub->num_rects] = av_mallocz(sizeof(*rects[0])); - if (!rects[sub->num_rects]) + sub->subtitle_rects = rects; + rects[sub->num_subtitle_rects] = av_mallocz(sizeof(*rects[0])); + if (!rects[sub->num_subtitle_rects]) return AVERROR(ENOMEM); - rects[sub->num_rects]->type = SUBTITLE_ASS; + rects[sub->num_subtitle_rects]->type = AV_SUBTITLE_FMT_ASS; ass_str = ff_ass_get_dialog(readorder, layer, style, speaker, dialog); if (!ass_str) return AVERROR(ENOMEM); - rects[sub->num_rects]->ass = ass_str; - sub->num_rects++; + rects[sub->num_subtitle_rects]->ass = ass_str; + sub->num_subtitle_rects++; return 0; } diff --git a/libavcodec/ass.h b/libavcodec/ass.h index 2c260e4e78..de31f35c8a 100644 --- a/libavcodec/ass.h +++ b/libavcodec/ass.h @@ -48,7 +48,7 @@ typedef struct FFASSDecoderContext { } FFASSDecoderContext; /** - * Generate a suitable AVCodecContext.subtitle_header for SUBTITLE_ASS. + * Generate a suitable AVCodecContext.subtitle_header for AV_SUBTITLE_FMT_ASS. * Can specify all fields explicitly * * @param avctx pointer to the AVCodecContext @@ -76,7 +76,7 @@ int ff_ass_subtitle_header_full(AVCodecContext *avctx, int bold, int italic, int underline, int border_style, int alignment); /** - * Generate a suitable AVCodecContext.subtitle_header for SUBTITLE_ASS. + * Generate a suitable AVCodecContext.subtitle_header for AV_SUBTITLE_FMT_ASS. * * @param avctx pointer to the AVCodecContext * @param font name of the default font face to use @@ -97,7 +97,7 @@ int ff_ass_subtitle_header(AVCodecContext *avctx, int border_style, int alignment); /** - * Generate a suitable AVCodecContext.subtitle_header for SUBTITLE_ASS + * Generate a suitable AVCodecContext.subtitle_header for AV_SUBTITLE_FMT_ASS * with default style. * * @param avctx pointer to the AVCodecContext @@ -114,7 +114,7 @@ char *ff_ass_get_dialog(int readorder, int layer, const char *style, /** * Add an ASS dialog to a subtitle. */ -int ff_ass_add_rect(AVSubtitle *sub, const char *dialog, +int ff_ass_add_rect(AVFrame *sub, const char *dialog, int readorder, int layer, const char *style, const char *speaker); diff --git a/libavcodec/assdec.c b/libavcodec/assdec.c index 319279490c..0df08ba756 100644 --- a/libavcodec/assdec.c +++ b/libavcodec/assdec.c @@ -42,21 +42,21 @@ static av_cold int ass_decode_init(AVCodecContext *avctx) static int ass_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, AVPacket *avpkt) { - AVSubtitle *sub = data; + AVFrame *sub = data; if (avpkt->size <= 0) return avpkt->size; - sub->rects = av_malloc(sizeof(*sub->rects)); - if (!sub->rects) + sub->subtitle_rects = av_malloc(sizeof(*sub->subtitle_rects)); + if (!sub->subtitle_rects) return AVERROR(ENOMEM); - sub->rects[0] = av_mallocz(sizeof(*sub->rects[0])); - if (!sub->rects[0]) + sub->subtitle_rects[0] = av_mallocz(sizeof(*sub->subtitle_rects[0])); + if (!sub->subtitle_rects[0]) return AVERROR(ENOMEM); - sub->num_rects = 1; - sub->rects[0]->type = SUBTITLE_ASS; - sub->rects[0]->ass = av_strdup(avpkt->data); - if (!sub->rects[0]->ass) + sub->num_subtitle_rects = 1; + sub->subtitle_rects[0]->type = AV_SUBTITLE_FMT_ASS; + sub->subtitle_rects[0]->ass = av_strdup(avpkt->data); + if (!sub->subtitle_rects[0]->ass) return AVERROR(ENOMEM); *got_sub_ptr = 1; return avpkt->size; diff --git a/libavcodec/assenc.c b/libavcodec/assenc.c index a6d107ded2..84745a4487 100644 --- a/libavcodec/assenc.c +++ b/libavcodec/assenc.c @@ -41,15 +41,15 @@ static av_cold int ass_encode_init(AVCodecContext *avctx) static int ass_encode_frame(AVCodecContext *avctx, unsigned char *buf, int bufsize, - const AVSubtitle *sub) + const AVFrame *sub) { int i, len, total_len = 0; - for (i=0; inum_rects; i++) { - const char *ass = sub->rects[i]->ass; + for (i=0; inum_subtitle_rects; i++) { + const char *ass = sub->subtitle_rects[i]->ass; - if (sub->rects[i]->type != SUBTITLE_ASS) { - av_log(avctx, AV_LOG_ERROR, "Only SUBTITLE_ASS type supported.\n"); + if (sub->subtitle_rects[i]->type != AV_SUBTITLE_FMT_ASS) { + av_log(avctx, AV_LOG_ERROR, "Only AV_SUBTITLE_FMT_ASS type supported.\n"); return AVERROR(EINVAL); } diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c index 2dd7dd84e0..963f52c4bd 100644 --- a/libavcodec/avcodec.c +++ b/libavcodec/avcodec.c @@ -426,25 +426,6 @@ void avcodec_flush_buffers(AVCodecContext *avctx) av_bsf_flush(avci->bsf); } -void avsubtitle_free(AVSubtitle *sub) -{ - int i; - - for (i = 0; i < sub->num_rects; i++) { - av_freep(&sub->rects[i]->data[0]); - av_freep(&sub->rects[i]->data[1]); - av_freep(&sub->rects[i]->data[2]); - av_freep(&sub->rects[i]->data[3]); - av_freep(&sub->rects[i]->text); - av_freep(&sub->rects[i]->ass); - av_freep(&sub->rects[i]); - } - - av_freep(&sub->rects); - - memset(sub, 0, sizeof(*sub)); -} - av_cold int avcodec_close(AVCodecContext *avctx) { int i; diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index ffd58c333f..a7a2df8cf4 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -35,6 +35,7 @@ #include "libavutil/frame.h" #include "libavutil/log.h" #include "libavutil/pixfmt.h" +#include "libavutil/subfmt.h" #include "libavutil/rational.h" #include "codec.h" @@ -1670,7 +1671,7 @@ typedef struct AVCodecContext { /** * Header containing style information for text subtitles. - * For SUBTITLE_ASS subtitle type, it should contain the whole ASS + * For AV_SUBTITLE_FMT_ASS subtitle type, it should contain the whole ASS * [Script Info] and [V4+ Styles] section, plus the [Events] line and * the Format line following. It shouldn't include any Dialogue line. * - encoding: Set/allocated/freed by user (before avcodec_open2()) @@ -2233,63 +2234,8 @@ typedef struct AVHWAccel { * @} */ -enum AVSubtitleType { - SUBTITLE_NONE, - - SUBTITLE_BITMAP, ///< A bitmap, pict will be set - - /** - * Plain text, the text field must be set by the decoder and is - * authoritative. ass and pict fields may contain approximations. - */ - SUBTITLE_TEXT, - - /** - * Formatted text, the ass field must be set by the decoder and is - * authoritative. pict and text fields may contain approximations. - */ - SUBTITLE_ASS, -}; - #define AV_SUBTITLE_FLAG_FORCED 0x00000001 -typedef struct AVSubtitleRect { - int x; ///< top left corner of pict, undefined when pict is not set - int y; ///< top left corner of pict, undefined when pict is not set - int w; ///< width of pict, undefined when pict is not set - int h; ///< height of pict, undefined when pict is not set - int nb_colors; ///< number of colors in pict, undefined when pict is not set - - /** - * data+linesize for the bitmap of this subtitle. - * Can be set for text/ass as well once they are rendered. - */ - uint8_t *data[4]; - int linesize[4]; - - enum AVSubtitleType type; - - char *text; ///< 0 terminated plain UTF-8 text - - /** - * 0 terminated ASS/SSA compatible event line. - * The presentation of this is unaffected by the other values in this - * struct. - */ - char *ass; - - int flags; -} AVSubtitleRect; - -typedef struct AVSubtitle { - uint16_t format; /* 0 = graphics */ - uint32_t start_display_time; /* relative to packet pts, in ms */ - uint32_t end_display_time; /* relative to packet pts, in ms */ - unsigned num_rects; - AVSubtitleRect **rects; - int64_t pts; ///< Same as packet pts, in AV_TIME_BASE -} AVSubtitle; - /** * Return the LIBAVCODEC_VERSION_INT constant. */ @@ -2425,13 +2371,6 @@ int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **op */ int avcodec_close(AVCodecContext *avctx); -/** - * Free all allocated data in the given subtitle struct. - * - * @param sub AVSubtitle to free. - */ -void avsubtitle_free(AVSubtitle *sub); - /** * @} */ @@ -2518,12 +2457,12 @@ enum AVChromaLocation avcodec_chroma_pos_to_enum(int xpos, int ypos); * before packets may be fed to the decoder. * * @param avctx the codec context - * @param[out] sub The preallocated AVSubtitle in which the decoded subtitle will be stored, - * must be freed with avsubtitle_free if *got_sub_ptr is set. + * @param[out] sub The preallocated AVFrame in which the decoded subtitle will be stored, + * must be freed with av_frame_free if *got_sub_ptr is set. * @param[in,out] got_sub_ptr Zero if no subtitle could be decompressed, otherwise, it is nonzero. * @param[in] avpkt The input AVPacket containing the input buffer. */ -int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, +int avcodec_decode_subtitle2(AVCodecContext *avctx, AVFrame *sub, int *got_sub_ptr, AVPacket *avpkt); @@ -3004,7 +2943,7 @@ void av_parser_close(AVCodecParserContext *s); */ int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, - const AVSubtitle *sub); + const AVFrame *sub); /** @@ -3120,6 +3059,14 @@ void avcodec_flush_buffers(AVCodecContext *avctx); */ int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes); +/** + * Return subtitle format from a codec descriptor + * + * @param codec_descriptor codec descriptor + * @return the subtitle type (e.g. bitmap, text) + */ +enum AVSubtitleType av_get_subtitle_format_from_codecdesc(const AVCodecDescriptor *codec_descriptor); + /* memory */ /** diff --git a/libavcodec/ccaption_dec.c b/libavcodec/ccaption_dec.c index 27c61527f6..33cc88f705 100644 --- a/libavcodec/ccaption_dec.c +++ b/libavcodec/ccaption_dec.c @@ -841,8 +841,8 @@ static int process_cc608(CCaptionSubContext *ctx, uint8_t hi, uint8_t lo) static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avpkt) { CCaptionSubContext *ctx = avctx->priv_data; - AVSubtitle *sub = data; - int64_t in_time = sub->pts; + AVFrame *sub = data; + int64_t in_time = sub->subtitle_pts; int64_t start_time; int64_t end_time; int bidx = ctx->buffer_index; @@ -879,17 +879,17 @@ static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avp if (ctx->buffer[bidx].str[0] || ctx->real_time) { ff_dlog(ctx, "cdp writing data (%s)\n", ctx->buffer[bidx].str); start_time = ctx->buffer_time[0]; - sub->pts = start_time; + sub->subtitle_pts = start_time; end_time = ctx->buffer_time[1]; if (!ctx->real_time) - sub->end_display_time = av_rescale_q(end_time - start_time, + sub->subtitle_end_time = av_rescale_q(end_time - start_time, AV_TIME_BASE_Q, ms_tb); else - sub->end_display_time = -1; + sub->subtitle_end_time = -1; ret = ff_ass_add_rect(sub, ctx->buffer[bidx].str, ctx->readorder++, 0, NULL, NULL); if (ret < 0) return ret; - ctx->last_real_time = sub->pts; + ctx->last_real_time = sub->subtitle_pts; ctx->screen_touched = 0; } } @@ -899,16 +899,16 @@ static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avp ret = ff_ass_add_rect(sub, ctx->buffer[bidx].str, ctx->readorder++, 0, NULL, NULL); if (ret < 0) return ret; - sub->pts = ctx->buffer_time[1]; - sub->end_display_time = av_rescale_q(ctx->buffer_time[1] - ctx->buffer_time[0], + sub->subtitle_pts = ctx->buffer_time[1]; + sub->subtitle_end_time = av_rescale_q(ctx->buffer_time[1] - ctx->buffer_time[0], AV_TIME_BASE_Q, ms_tb); - if (sub->end_display_time == 0) - sub->end_display_time = ctx->buffer[bidx].len * 20; + if (sub->subtitle_end_time == 0) + sub->subtitle_end_time = ctx->buffer[bidx].len * 20; } if (ctx->real_time && ctx->screen_touched && - sub->pts >= ctx->last_real_time + av_rescale_q(ctx->real_time_latency_msec, ms_tb, AV_TIME_BASE_Q)) { - ctx->last_real_time = sub->pts; + sub->subtitle_pts >= ctx->last_real_time + av_rescale_q(ctx->real_time_latency_msec, ms_tb, AV_TIME_BASE_Q)) { + ctx->last_real_time = sub->subtitle_pts; ctx->screen_touched = 0; capture_screen(ctx); @@ -917,10 +917,10 @@ static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avp ret = ff_ass_add_rect(sub, ctx->buffer[bidx].str, ctx->readorder++, 0, NULL, NULL); if (ret < 0) return ret; - sub->end_display_time = -1; + sub->subtitle_end_time = -1; } - *got_sub = sub->num_rects > 0; + *got_sub = sub->num_subtitle_rects > 0; return ret; } diff --git a/libavcodec/codec.h b/libavcodec/codec.h index 8f12705066..785a6bf27e 100644 --- a/libavcodec/codec.h +++ b/libavcodec/codec.h @@ -188,7 +188,7 @@ typedef struct AVProfile { typedef struct AVCodecDefault AVCodecDefault; struct AVCodecContext; -struct AVSubtitle; +struct AVFrame; struct AVPacket; /** @@ -283,7 +283,7 @@ typedef struct AVCodec { int (*init)(struct AVCodecContext *); int (*encode_sub)(struct AVCodecContext *, uint8_t *buf, int buf_size, - const struct AVSubtitle *sub); + const struct AVFrame *sub); /** * Encode data to an AVPacket. * diff --git a/libavcodec/codec_desc.h b/libavcodec/codec_desc.h index 126b52df47..387863a041 100644 --- a/libavcodec/codec_desc.h +++ b/libavcodec/codec_desc.h @@ -92,12 +92,12 @@ typedef struct AVCodecDescriptor { #define AV_CODEC_PROP_REORDER (1 << 3) /** * Subtitle codec is bitmap based - * Decoded AVSubtitle data can be read from the AVSubtitleRect->pict field. + * Decoded AVFrame data can be read from the AVSubtitleRect->pict field. */ #define AV_CODEC_PROP_BITMAP_SUB (1 << 16) /** * Subtitle codec is text based. - * Decoded AVSubtitle data can be read from the AVSubtitleRect->ass field. + * Decoded AVFrame data can be read from the AVSubtitleRect->ass field. */ #define AV_CODEC_PROP_TEXT_SUB (1 << 17) diff --git a/libavcodec/decode.c b/libavcodec/decode.c index 643f9d6a30..37dd69070e 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -712,10 +712,10 @@ int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *fr return 0; } -static void get_subtitle_defaults(AVSubtitle *sub) +static void get_subtitle_defaults(AVFrame *sub) { memset(sub, 0, sizeof(*sub)); - sub->pts = AV_NOPTS_VALUE; + sub->subtitle_pts = AV_NOPTS_VALUE; } #define UTF8_MAX_BYTES 4 /* 5 and 6 bytes sequences should not be used */ @@ -799,7 +799,7 @@ static int utf8_check(const uint8_t *str) return 1; } -int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, +int avcodec_decode_subtitle2(AVCodecContext *avctx, AVFrame *sub, int *got_sub_ptr, AVPacket *avpkt) { @@ -828,31 +828,28 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, return ret; if (avctx->pkt_timebase.num && avpkt->pts != AV_NOPTS_VALUE) - sub->pts = av_rescale_q(avpkt->pts, + sub->subtitle_pts = av_rescale_q(avpkt->pts, avctx->pkt_timebase, AV_TIME_BASE_Q); ret = avctx->codec->decode(avctx, sub, got_sub_ptr, pkt); av_assert1((ret >= 0) >= !!*got_sub_ptr && !!*got_sub_ptr >= !!sub->num_rects); - if (sub->num_rects && !sub->end_display_time && avpkt->duration && + if (sub->num_subtitle_rects && !sub->subtitle_end_time && avpkt->duration && avctx->pkt_timebase.num) { AVRational ms = { 1, 1000 }; - sub->end_display_time = av_rescale_q(avpkt->duration, + sub->subtitle_end_time = av_rescale_q(avpkt->duration, avctx->pkt_timebase, ms); } - if (avctx->codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB) - sub->format = 0; - else if (avctx->codec_descriptor->props & AV_CODEC_PROP_TEXT_SUB) - sub->format = 1; + sub->format = av_get_subtitle_format_from_codecdesc(avctx->codec_descriptor); - for (unsigned i = 0; i < sub->num_rects; i++) { + for (unsigned i = 0; i < sub->num_subtitle_rects; i++) { if (avctx->sub_charenc_mode != FF_SUB_CHARENC_MODE_IGNORE && - sub->rects[i]->ass && !utf8_check(sub->rects[i]->ass)) { + sub->subtitle_rects[i]->ass && !utf8_check(sub->subtitle_rects[i]->ass)) { av_log(avctx, AV_LOG_ERROR, "Invalid UTF-8 in decoded subtitles text; " "maybe missing -sub_charenc option\n"); - avsubtitle_free(sub); + av_frame_free(&sub); ret = AVERROR_INVALIDDATA; break; } diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c index e45c14e878..aeb88df06f 100644 --- a/libavcodec/dvbsubdec.c +++ b/libavcodec/dvbsubdec.c @@ -725,7 +725,7 @@ static void compute_default_clut(DVBSubContext *ctx, uint8_t *clut, AVSubtitleRe } -static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_output) +static int save_subtitle_set(AVCodecContext *avctx, AVFrame *sub, int *got_output) { DVBSubContext *ctx = avctx->priv_data; DVBSubRegionDisplay *display; @@ -745,34 +745,34 @@ static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_ou } /* Not touching AVSubtitles again*/ - if (sub->num_rects) { + if (sub->num_subtitle_rects) { avpriv_request_sample(ctx, "Different Version of Segment asked Twice"); return AVERROR_PATCHWELCOME; } for (display = ctx->display_list; display; display = display->next) { region = get_region(ctx, display->region_id); if (region && region->dirty) - sub->num_rects++; + sub->num_subtitle_rects++; } if (ctx->compute_edt == 0) { - sub->end_display_time = ctx->time_out * 1000; + sub->subtitle_end_time = ctx->time_out * 1000; *got_output = 1; } else if (ctx->prev_start != AV_NOPTS_VALUE) { - sub->end_display_time = av_rescale_q((sub->pts - ctx->prev_start ), AV_TIME_BASE_Q, (AVRational){ 1, 1000 }) - 1; + sub->subtitle_end_time = av_rescale_q((sub->subtitle_pts - ctx->prev_start ), AV_TIME_BASE_Q, (AVRational){ 1, 1000 }) - 1; *got_output = 1; } - if (sub->num_rects > 0) { + if (sub->num_subtitle_rects > 0) { - sub->rects = av_mallocz_array(sizeof(*sub->rects), sub->num_rects); - if (!sub->rects) { + sub->subtitle_rects = av_mallocz_array(sizeof(*sub->subtitle_rects), sub->num_subtitle_rects); + if (!sub->subtitle_rects) { ret = AVERROR(ENOMEM); goto fail; } - for (i = 0; i < sub->num_rects; i++) { - sub->rects[i] = av_mallocz(sizeof(*sub->rects[i])); - if (!sub->rects[i]) { + for (i = 0; i < sub->num_subtitle_rects; i++) { + sub->subtitle_rects[i] = av_mallocz(sizeof(*sub->subtitle_rects[i])); + if (!sub->subtitle_rects[i]) { ret = AVERROR(ENOMEM); goto fail; } @@ -789,13 +789,13 @@ static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_ou if (!region->dirty) continue; - rect = sub->rects[i]; + rect = sub->subtitle_rects[i]; rect->x = display->x_pos + offset_x; rect->y = display->y_pos + offset_y; rect->w = region->width; rect->h = region->height; rect->nb_colors = (1 << region->depth); - rect->type = SUBTITLE_BITMAP; + rect->type = AV_SUBTITLE_FMT_BITMAP; rect->linesize[0] = region->width; clut = get_clut(ctx, region->clut); @@ -846,18 +846,18 @@ static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_ou return 0; fail: - if (sub->rects) { - for (i=0; i < sub->num_rects; i++) { - rect = sub->rects[i]; + if (sub->subtitle_rects) { + for (i=0; i < sub->num_subtitle_rects; i++) { + rect = sub->subtitle_rects[i]; if (rect) { av_freep(&rect->data[0]); av_freep(&rect->data[1]); } - av_freep(&sub->rects[i]); + av_freep(&sub->subtitle_rects[i]); } - av_freep(&sub->rects); + av_freep(&sub->subtitle_rects); } - sub->num_rects = 0; + sub->num_subtitle_rects = 0; return ret; } @@ -1291,7 +1291,7 @@ static int dvbsub_parse_region_segment(AVCodecContext *avctx, } static int dvbsub_parse_page_segment(AVCodecContext *avctx, - const uint8_t *buf, int buf_size, AVSubtitle *sub, int *got_output) + const uint8_t *buf, int buf_size, AVFrame *sub, int *got_output) { DVBSubContext *ctx = avctx->priv_data; DVBSubRegionDisplay *display; @@ -1598,7 +1598,7 @@ static int dvbsub_parse_display_definition_segment(AVCodecContext *avctx, } static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf, - int buf_size, AVSubtitle *sub,int *got_output) + int buf_size, AVFrame *sub,int *got_output) { DVBSubContext *ctx = avctx->priv_data; @@ -1617,7 +1617,7 @@ static int dvbsub_decode(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; DVBSubContext *ctx = avctx->priv_data; - AVSubtitle *sub = data; + AVFrame *sub = data; const uint8_t *p, *p_end; int segment_type; int page_id; @@ -1720,11 +1720,11 @@ static int dvbsub_decode(AVCodecContext *avctx, end: if (ret < 0) { *got_sub_ptr = 0; - avsubtitle_free(sub); + av_frame_free(&sub); return ret; } else { if (ctx->compute_edt == 1) - FFSWAP(int64_t, ctx->prev_start, sub->pts); + FFSWAP(int64_t, ctx->prev_start, sub->subtitle_pts); } return p - buf; diff --git a/libavcodec/dvbsubenc.c b/libavcodec/dvbsubenc.c index 322fc27cb4..480092867e 100644 --- a/libavcodec/dvbsubenc.c +++ b/libavcodec/dvbsubenc.c @@ -269,7 +269,7 @@ static int dvb_encode_rle8(uint8_t **pq, int buf_size, } static int dvbsub_encode(AVCodecContext *avctx, uint8_t *outbuf, int buf_size, - const AVSubtitle *h) + const AVFrame *h) { DVBSubtitleContext *s = avctx->priv_data; uint8_t *q, *pseg_len; @@ -280,7 +280,7 @@ static int dvbsub_encode(AVCodecContext *avctx, uint8_t *outbuf, int buf_size, page_id = 1; - if (h->num_rects && !h->rects) + if (h->num_subtitle_rects && !h->subtitle_rects) return AVERROR(EINVAL); if (avctx->width > 0 && avctx->height > 0) { @@ -301,7 +301,7 @@ static int dvbsub_encode(AVCodecContext *avctx, uint8_t *outbuf, int buf_size, /* page composition segment */ - if (buf_size < 8 + h->num_rects * 6) + if (buf_size < 8 + h->num_subtitle_rects * 6) return AVERROR_BUFFER_TOO_SMALL; *q++ = 0x0f; /* sync_byte */ *q++ = 0x10; /* segment_type */ @@ -313,30 +313,30 @@ static int dvbsub_encode(AVCodecContext *avctx, uint8_t *outbuf, int buf_size, /* page_version = 0 + page_state */ *q++ = (s->object_version << 4) | (page_state << 2) | 3; - for (region_id = 0; region_id < h->num_rects; region_id++) { + for (region_id = 0; region_id < h->num_subtitle_rects; region_id++) { *q++ = region_id; *q++ = 0xff; /* reserved */ - bytestream_put_be16(&q, h->rects[region_id]->x); /* left pos */ - bytestream_put_be16(&q, h->rects[region_id]->y); /* top pos */ + bytestream_put_be16(&q, h->subtitle_rects[region_id]->x); /* left pos */ + bytestream_put_be16(&q, h->subtitle_rects[region_id]->y); /* top pos */ } bytestream_put_be16(&pseg_len, q - pseg_len - 2); - buf_size -= 8 + h->num_rects * 6; + buf_size -= 8 + h->num_subtitle_rects * 6; - if (h->num_rects) { - for (clut_id = 0; clut_id < h->num_rects; clut_id++) { - if (buf_size < 6 + h->rects[clut_id]->nb_colors * 6) + if (h->num_subtitle_rects) { + for (clut_id = 0; clut_id < h->num_subtitle_rects; clut_id++) { + if (buf_size < 6 + h->subtitle_rects[clut_id]->nb_colors * 6) return AVERROR_BUFFER_TOO_SMALL; /* CLUT segment */ - if (h->rects[clut_id]->nb_colors <= 4) { + if (h->subtitle_rects[clut_id]->nb_colors <= 4) { /* 2 bpp, some decoders do not support it correctly */ bpp_index = 0; - } else if (h->rects[clut_id]->nb_colors <= 16) { + } else if (h->subtitle_rects[clut_id]->nb_colors <= 16) { /* 4 bpp, standard encoding */ bpp_index = 1; - } else if (h->rects[clut_id]->nb_colors <= 256) { + } else if (h->subtitle_rects[clut_id]->nb_colors <= 256) { /* 8 bpp, standard encoding */ bpp_index = 2; } else { @@ -353,12 +353,12 @@ static int dvbsub_encode(AVCodecContext *avctx, uint8_t *outbuf, int buf_size, *q++ = clut_id; *q++ = (0 << 4) | 0xf; /* version = 0 */ - for(i = 0; i < h->rects[clut_id]->nb_colors; i++) { + for(i = 0; i < h->subtitle_rects[clut_id]->nb_colors; i++) { *q++ = i; /* clut_entry_id */ *q++ = (1 << (7 - bpp_index)) | (0xf << 1) | 1; /* 2 bits/pixel full range */ { int a, r, g, b; - uint32_t x= ((uint32_t*)h->rects[clut_id]->data[1])[i]; + uint32_t x= ((uint32_t*)h->subtitle_rects[clut_id]->data[1])[i]; a = (x >> 24) & 0xff; r = (x >> 16) & 0xff; g = (x >> 8) & 0xff; @@ -372,22 +372,22 @@ static int dvbsub_encode(AVCodecContext *avctx, uint8_t *outbuf, int buf_size, } bytestream_put_be16(&pseg_len, q - pseg_len - 2); - buf_size -= 6 + h->rects[clut_id]->nb_colors * 6; + buf_size -= 6 + h->subtitle_rects[clut_id]->nb_colors * 6; } - if (buf_size < h->num_rects * 22) + if (buf_size < h->num_subtitle_rects * 22) return AVERROR_BUFFER_TOO_SMALL; - for (region_id = 0; region_id < h->num_rects; region_id++) { + for (region_id = 0; region_id < h->num_subtitle_rects; region_id++) { /* region composition segment */ - if (h->rects[region_id]->nb_colors <= 4) { + if (h->subtitle_rects[region_id]->nb_colors <= 4) { /* 2 bpp, some decoders do not support it correctly */ bpp_index = 0; - } else if (h->rects[region_id]->nb_colors <= 16) { + } else if (h->subtitle_rects[region_id]->nb_colors <= 16) { /* 4 bpp, standard encoding */ bpp_index = 1; - } else if (h->rects[region_id]->nb_colors <= 256) { + } else if (h->subtitle_rects[region_id]->nb_colors <= 256) { /* 8 bpp, standard encoding */ bpp_index = 2; } else { @@ -401,8 +401,8 @@ static int dvbsub_encode(AVCodecContext *avctx, uint8_t *outbuf, int buf_size, q += 2; /* segment length */ *q++ = region_id; *q++ = (s->object_version << 4) | (0 << 3) | 0x07; /* version , no fill */ - bytestream_put_be16(&q, h->rects[region_id]->w); /* region width */ - bytestream_put_be16(&q, h->rects[region_id]->h); /* region height */ + bytestream_put_be16(&q, h->subtitle_rects[region_id]->w); /* region width */ + bytestream_put_be16(&q, h->subtitle_rects[region_id]->h); /* region height */ *q++ = ((1 + bpp_index) << 5) | ((1 + bpp_index) << 2) | 0x03; *q++ = region_id; /* clut_id == region_id */ *q++ = 0; /* 8 bit fill colors */ @@ -416,9 +416,9 @@ static int dvbsub_encode(AVCodecContext *avctx, uint8_t *outbuf, int buf_size, bytestream_put_be16(&pseg_len, q - pseg_len - 2); } - buf_size -= h->num_rects * 22; + buf_size -= h->num_subtitle_rects * 22; - for (object_id = 0; object_id < h->num_rects; object_id++) { + for (object_id = 0; object_id < h->num_subtitle_rects; object_id++) { int (*dvb_encode_rle)(uint8_t **pq, int buf_size, const uint8_t *bitmap, int linesize, int w, int h); @@ -427,13 +427,13 @@ static int dvbsub_encode(AVCodecContext *avctx, uint8_t *outbuf, int buf_size, return AVERROR_BUFFER_TOO_SMALL; /* bpp_index maths */ - if (h->rects[object_id]->nb_colors <= 4) { + if (h->subtitle_rects[object_id]->nb_colors <= 4) { /* 2 bpp, some decoders do not support it correctly */ dvb_encode_rle = dvb_encode_rle2; - } else if (h->rects[object_id]->nb_colors <= 16) { + } else if (h->subtitle_rects[object_id]->nb_colors <= 16) { /* 4 bpp, standard encoding */ dvb_encode_rle = dvb_encode_rle4; - } else if (h->rects[object_id]->nb_colors <= 256) { + } else if (h->subtitle_rects[object_id]->nb_colors <= 256) { /* 8 bpp, standard encoding */ dvb_encode_rle = dvb_encode_rle8; } else { @@ -463,19 +463,19 @@ static int dvbsub_encode(AVCodecContext *avctx, uint8_t *outbuf, int buf_size, top_ptr = q; ret = dvb_encode_rle(&q, buf_size, - h->rects[object_id]->data[0], - h->rects[object_id]->w * 2, - h->rects[object_id]->w, - h->rects[object_id]->h >> 1); + h->subtitle_rects[object_id]->data[0], + h->subtitle_rects[object_id]->w * 2, + h->subtitle_rects[object_id]->w, + h->subtitle_rects[object_id]->h >> 1); if (ret < 0) return ret; buf_size -= ret; bottom_ptr = q; ret = dvb_encode_rle(&q, buf_size, - h->rects[object_id]->data[0] + h->rects[object_id]->w, - h->rects[object_id]->w * 2, - h->rects[object_id]->w, - h->rects[object_id]->h >> 1); + h->subtitle_rects[object_id]->data[0] + h->subtitle_rects[object_id]->w, + h->subtitle_rects[object_id]->w * 2, + h->subtitle_rects[object_id]->w, + h->subtitle_rects[object_id]->h >> 1); if (ret < 0) return ret; buf_size -= ret; diff --git a/libavcodec/dvdsubdec.c b/libavcodec/dvdsubdec.c index 52259f0730..6c7b315026 100644 --- a/libavcodec/dvdsubdec.c +++ b/libavcodec/dvdsubdec.c @@ -200,24 +200,24 @@ static void guess_palette(DVDSubContext* ctx, } } -static void reset_rects(AVSubtitle *sub_header) +static void reset_rects(AVFrame *sub_header) { int i; - if (sub_header->rects) { - for (i = 0; i < sub_header->num_rects; i++) { - av_freep(&sub_header->rects[i]->data[0]); - av_freep(&sub_header->rects[i]->data[1]); - av_freep(&sub_header->rects[i]); + if (sub_header->subtitle_rects) { + for (i = 0; i < sub_header->num_subtitle_rects; i++) { + av_freep(&sub_header->subtitle_rects[i]->data[0]); + av_freep(&sub_header->subtitle_rects[i]->data[1]); + av_freep(&sub_header->subtitle_rects[i]); } - av_freep(&sub_header->rects); - sub_header->num_rects = 0; + av_freep(&sub_header->subtitle_rects); + sub_header->num_subtitle_rects = 0; } } #define READ_OFFSET(a) (big_offsets ? AV_RB32(a) : AV_RB16(a)) -static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header, +static int decode_dvd_subtitles(DVDSubContext *ctx, AVFrame *sub_header, const uint8_t *buf, int buf_size) { int cmd_pos, pos, cmd, x1, y1, x2, y2, next_cmd_pos; @@ -273,11 +273,11 @@ static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header, break; case 0x01: /* set start date */ - sub_header->start_display_time = (date << 10) / 90; + sub_header->subtitle_start_time = (date << 10) / 90; break; case 0x02: /* set end date */ - sub_header->end_display_time = (date << 10) / 90; + sub_header->subtitle_end_time = (date << 10) / 90; break; case 0x03: /* set colormap */ @@ -371,14 +371,14 @@ static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header, if (w > 0 && h > 1) { reset_rects(sub_header); memset(ctx->used_color, 0, sizeof(ctx->used_color)); - sub_header->rects = av_mallocz(sizeof(*sub_header->rects)); - if (!sub_header->rects) + sub_header->subtitle_rects = av_mallocz(sizeof(*sub_header->subtitle_rects)); + if (!sub_header->subtitle_rects) goto fail; - sub_header->rects[0] = av_mallocz(sizeof(AVSubtitleRect)); - if (!sub_header->rects[0]) + sub_header->subtitle_rects[0] = av_mallocz(sizeof(AVSubtitleRect)); + if (!sub_header->subtitle_rects[0]) goto fail; - sub_header->num_rects = 1; - bitmap = sub_header->rects[0]->data[0] = av_malloc(w * h); + sub_header->num_subtitle_rects = 1; + bitmap = sub_header->subtitle_rects[0]->data[0] = av_malloc(w * h); if (!bitmap) goto fail; if (decode_rle(bitmap, w * 2, w, (h + 1) / 2, ctx->used_color, @@ -387,28 +387,28 @@ static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header, if (decode_rle(bitmap + w, w * 2, w, h / 2, ctx->used_color, buf, offset2, buf_size, is_8bit) < 0) goto fail; - sub_header->rects[0]->data[1] = av_mallocz(AVPALETTE_SIZE); - if (!sub_header->rects[0]->data[1]) + sub_header->subtitle_rects[0]->data[1] = av_mallocz(AVPALETTE_SIZE); + if (!sub_header->subtitle_rects[0]->data[1]) goto fail; if (is_8bit) { if (!yuv_palette) goto fail; - sub_header->rects[0]->nb_colors = 256; + sub_header->subtitle_rects[0]->nb_colors = 256; yuv_a_to_rgba(yuv_palette, alpha, - (uint32_t *)sub_header->rects[0]->data[1], + (uint32_t *)sub_header->subtitle_rects[0]->data[1], 256); } else { - sub_header->rects[0]->nb_colors = 4; - guess_palette(ctx, (uint32_t*)sub_header->rects[0]->data[1], + sub_header->subtitle_rects[0]->nb_colors = 4; + guess_palette(ctx, (uint32_t*)sub_header->subtitle_rects[0]->data[1], 0xffff00); } - sub_header->rects[0]->x = x1; - sub_header->rects[0]->y = y1; - sub_header->rects[0]->w = w; - sub_header->rects[0]->h = h; - sub_header->rects[0]->type = SUBTITLE_BITMAP; - sub_header->rects[0]->linesize[0] = w; - sub_header->rects[0]->flags = is_menu ? AV_SUBTITLE_FLAG_FORCED : 0; + sub_header->subtitle_rects[0]->x = x1; + sub_header->subtitle_rects[0]->y = y1; + sub_header->subtitle_rects[0]->w = w; + sub_header->subtitle_rects[0]->h = h; + sub_header->subtitle_rects[0]->type = AV_SUBTITLE_FMT_BITMAP; + sub_header->subtitle_rects[0]->linesize[0] = w; + sub_header->subtitle_rects[0]->flags = is_menu ? AV_SUBTITLE_FLAG_FORCED : 0; } } if (next_cmd_pos < cmd_pos) { @@ -419,7 +419,7 @@ static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header, break; cmd_pos = next_cmd_pos; } - if (sub_header->num_rects > 0) + if (sub_header->num_subtitle_rects > 0) return is_menu; fail: reset_rects(sub_header); @@ -439,18 +439,18 @@ static int is_transp(const uint8_t *buf, int pitch, int n, } /* return 0 if empty rectangle, 1 if non empty */ -static int find_smallest_bounding_rectangle(DVDSubContext *ctx, AVSubtitle *s) +static int find_smallest_bounding_rectangle(DVDSubContext *ctx, AVFrame *s) { uint8_t transp_color[256] = { 0 }; int y1, y2, x1, x2, y, w, h, i; uint8_t *bitmap; int transparent = 1; - if (s->num_rects == 0 || !s->rects || s->rects[0]->w <= 0 || s->rects[0]->h <= 0) + if (s->num_subtitle_rects == 0 || !s->subtitle_rects || s->subtitle_rects[0]->w <= 0 || s->subtitle_rects[0]->h <= 0) return 0; - for(i = 0; i < s->rects[0]->nb_colors; i++) { - if ((((uint32_t *)s->rects[0]->data[1])[i] >> 24) == 0) { + for(i = 0; i < s->subtitle_rects[0]->nb_colors; i++) { + if ((((uint32_t *)s->subtitle_rects[0]->data[1])[i] >> 24) == 0) { transp_color[i] = 1; } else if (ctx->used_color[i]) transparent = 0; @@ -458,25 +458,25 @@ static int find_smallest_bounding_rectangle(DVDSubContext *ctx, AVSubtitle *s) if (transparent) return 0; y1 = 0; - while (y1 < s->rects[0]->h && is_transp(s->rects[0]->data[0] + y1 * s->rects[0]->linesize[0], - 1, s->rects[0]->w, transp_color)) + while (y1 < s->subtitle_rects[0]->h && is_transp(s->subtitle_rects[0]->data[0] + y1 * s->subtitle_rects[0]->linesize[0], + 1, s->subtitle_rects[0]->w, transp_color)) y1++; - if (y1 == s->rects[0]->h) { - av_freep(&s->rects[0]->data[0]); - s->rects[0]->w = s->rects[0]->h = 0; + if (y1 == s->subtitle_rects[0]->h) { + av_freep(&s->subtitle_rects[0]->data[0]); + s->subtitle_rects[0]->w = s->subtitle_rects[0]->h = 0; return 0; } - y2 = s->rects[0]->h - 1; - while (y2 > 0 && is_transp(s->rects[0]->data[0] + y2 * s->rects[0]->linesize[0], 1, - s->rects[0]->w, transp_color)) + y2 = s->subtitle_rects[0]->h - 1; + while (y2 > 0 && is_transp(s->subtitle_rects[0]->data[0] + y2 * s->subtitle_rects[0]->linesize[0], 1, + s->subtitle_rects[0]->w, transp_color)) y2--; x1 = 0; - while (x1 < (s->rects[0]->w - 1) && is_transp(s->rects[0]->data[0] + x1, s->rects[0]->linesize[0], - s->rects[0]->h, transp_color)) + while (x1 < (s->subtitle_rects[0]->w - 1) && is_transp(s->subtitle_rects[0]->data[0] + x1, s->subtitle_rects[0]->linesize[0], + s->subtitle_rects[0]->h, transp_color)) x1++; - x2 = s->rects[0]->w - 1; - while (x2 > 0 && is_transp(s->rects[0]->data[0] + x2, s->rects[0]->linesize[0], s->rects[0]->h, + x2 = s->subtitle_rects[0]->w - 1; + while (x2 > 0 && is_transp(s->subtitle_rects[0]->data[0] + x2, s->subtitle_rects[0]->linesize[0], s->subtitle_rects[0]->h, transp_color)) x2--; w = x2 - x1 + 1; @@ -485,15 +485,15 @@ static int find_smallest_bounding_rectangle(DVDSubContext *ctx, AVSubtitle *s) if (!bitmap) return 1; for(y = 0; y < h; y++) { - memcpy(bitmap + w * y, s->rects[0]->data[0] + x1 + (y1 + y) * s->rects[0]->linesize[0], w); + memcpy(bitmap + w * y, s->subtitle_rects[0]->data[0] + x1 + (y1 + y) * s->subtitle_rects[0]->linesize[0], w); } - av_freep(&s->rects[0]->data[0]); - s->rects[0]->data[0] = bitmap; - s->rects[0]->linesize[0] = w; - s->rects[0]->w = w; - s->rects[0]->h = h; - s->rects[0]->x += x1; - s->rects[0]->y += y1; + av_freep(&s->subtitle_rects[0]->data[0]); + s->subtitle_rects[0]->data[0] = bitmap; + s->subtitle_rects[0]->linesize[0] = w; + s->subtitle_rects[0]->w = w; + s->subtitle_rects[0]->h = h; + s->subtitle_rects[0]->x += x1; + s->subtitle_rects[0]->y += y1; return 1; } @@ -554,7 +554,7 @@ static int dvdsub_decode(AVCodecContext *avctx, DVDSubContext *ctx = avctx->priv_data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; - AVSubtitle *sub = data; + AVFrame *sub = data; int appended = 0; int is_menu; @@ -586,7 +586,7 @@ static int dvdsub_decode(AVCodecContext *avctx, if (!is_menu && find_smallest_bounding_rectangle(ctx, sub) == 0) goto no_subtitle; - if (ctx->forced_subs_only && !(sub->rects[0]->flags & AV_SUBTITLE_FLAG_FORCED)) + if (ctx->forced_subs_only && !(sub->subtitle_rects[0]->flags & AV_SUBTITLE_FLAG_FORCED)) goto no_subtitle; #if defined(DEBUG) @@ -595,10 +595,10 @@ static int dvdsub_decode(AVCodecContext *avctx, snprintf(ppm_name, sizeof(ppm_name), "/tmp/%05d.ppm", ctx->sub_id++); ff_dlog(NULL, "start=%d ms end =%d ms\n", - sub->start_display_time, - sub->end_display_time); - ppm_save(ppm_name, sub->rects[0]->data[0], - sub->rects[0]->w, sub->rects[0]->h, (uint32_t*) sub->rects[0]->data[1]); + sub->subtitle_start_time, + sub->subtitle_end_time); + ppm_save(ppm_name, sub->subtitle_rects[0]->data[0], + sub->subtitle_rects[0]->w, sub->subtitle_rects[0]->h, (uint32_t*) sub->subtitle_rects[0]->data[1]); } #endif diff --git a/libavcodec/dvdsubenc.c b/libavcodec/dvdsubenc.c index ff4fbed39d..53df1251ed 100644 --- a/libavcodec/dvdsubenc.c +++ b/libavcodec/dvdsubenc.c @@ -250,12 +250,12 @@ static void copy_rectangle(AVSubtitleRect *dst, AVSubtitleRect *src, int cmap[]) static int encode_dvd_subtitles(AVCodecContext *avctx, uint8_t *outbuf, int outbuf_size, - const AVSubtitle *h) + const AVFrame *h) { DVDSubtitleContext *dvdc = avctx->priv_data; uint8_t *q, *qq; int offset1, offset2; - int i, rects = h->num_rects, ret; + int i, rects = h->num_subtitle_rects, ret; unsigned global_palette_hits[33] = { 0 }; int cmap[256]; int out_palette[4]; @@ -265,34 +265,34 @@ static int encode_dvd_subtitles(AVCodecContext *avctx, int x2, y2; int forced = 0; - if (rects == 0 || !h->rects) + if (rects == 0 || !h->subtitle_rects) return AVERROR(EINVAL); for (i = 0; i < rects; i++) - if (h->rects[i]->type != SUBTITLE_BITMAP) { + if (h->subtitle_rects[i]->type != AV_SUBTITLE_FMT_BITMAP) { av_log(avctx, AV_LOG_ERROR, "Bitmap subtitle required\n"); return AVERROR(EINVAL); } /* Mark this subtitle forced if any of the rectangles is forced. */ for (i = 0; i < rects; i++) - if ((h->rects[i]->flags & AV_SUBTITLE_FLAG_FORCED) != 0) { + if ((h->subtitle_rects[i]->flags & AV_SUBTITLE_FLAG_FORCED) != 0) { forced = 1; break; } - vrect = *h->rects[0]; + vrect = *h->subtitle_rects[0]; if (rects > 1) { /* DVD subtitles can have only one rectangle: build a virtual rectangle containing all actual rectangles. The data of the rectangles will be copied later, when the palette is decided, because the rectangles may have different palettes. */ - int xmin = h->rects[0]->x, xmax = xmin + h->rects[0]->w; - int ymin = h->rects[0]->y, ymax = ymin + h->rects[0]->h; + int xmin = h->subtitle_rects[0]->x, xmax = xmin + h->subtitle_rects[0]->w; + int ymin = h->subtitle_rects[0]->y, ymax = ymin + h->subtitle_rects[0]->h; for (i = 1; i < rects; i++) { - xmin = FFMIN(xmin, h->rects[i]->x); - ymin = FFMIN(ymin, h->rects[i]->y); - xmax = FFMAX(xmax, h->rects[i]->x + h->rects[i]->w); - ymax = FFMAX(ymax, h->rects[i]->y + h->rects[i]->h); + xmin = FFMIN(xmin, h->subtitle_rects[i]->x); + ymin = FFMIN(ymin, h->subtitle_rects[i]->y); + xmax = FFMAX(xmax, h->subtitle_rects[i]->x + h->subtitle_rects[i]->w); + ymax = FFMAX(ymax, h->subtitle_rects[i]->y + h->subtitle_rects[i]->h); } vrect.x = xmin; vrect.y = ymin; @@ -304,11 +304,11 @@ static int encode_dvd_subtitles(AVCodecContext *avctx, /* Count pixels outside the virtual rectangle as transparent */ global_palette_hits[0] = vrect.w * vrect.h; for (i = 0; i < rects; i++) - global_palette_hits[0] -= h->rects[i]->w * h->rects[i]->h; + global_palette_hits[0] -= h->subtitle_rects[i]->w * h->subtitle_rects[i]->h; } for (i = 0; i < rects; i++) - count_colors(avctx, global_palette_hits, h->rects[i]); + count_colors(avctx, global_palette_hits, h->subtitle_rects[i]); select_palette(avctx, out_palette, out_alpha, global_palette_hits); if (rects > 1) { @@ -317,14 +317,14 @@ static int encode_dvd_subtitles(AVCodecContext *avctx, vrect.data [0] = vrect_data; vrect.linesize[0] = vrect.w; for (i = 0; i < rects; i++) { - build_color_map(avctx, cmap, (uint32_t *)h->rects[i]->data[1], + build_color_map(avctx, cmap, (uint32_t *)h->subtitle_rects[i]->data[1], out_palette, out_alpha); - copy_rectangle(&vrect, h->rects[i], cmap); + copy_rectangle(&vrect, h->subtitle_rects[i], cmap); } for (i = 0; i < 4; i++) cmap[i] = i; } else { - build_color_map(avctx, cmap, (uint32_t *)h->rects[0]->data[1], + build_color_map(avctx, cmap, (uint32_t *)h->subtitle_rects[0]->data[1], out_palette, out_alpha); } @@ -362,7 +362,7 @@ static int encode_dvd_subtitles(AVCodecContext *avctx, bytestream_put_be16(&qq, q - outbuf); // send start display command - bytestream_put_be16(&q, (h->start_display_time*90) >> 10); + bytestream_put_be16(&q, (h->subtitle_start_time*90) >> 10); bytestream_put_be16(&q, (q - outbuf) /*- 2 */ + 8 + 12 + 2); *q++ = 0x03; // palette - 4 nibbles *q++ = (out_palette[3] << 4) | out_palette[2]; @@ -394,7 +394,7 @@ static int encode_dvd_subtitles(AVCodecContext *avctx, *q++ = 0xff; // terminating command // send stop display command last - bytestream_put_be16(&q, (h->end_display_time*90) >> 10); + bytestream_put_be16(&q, (h->subtitle_end_time*90) >> 10); bytestream_put_be16(&q, (q - outbuf) - 2 /*+ 4*/); *q++ = 0x02; // set end *q++ = 0xff; // terminating command @@ -469,7 +469,7 @@ static int dvdsub_init(AVCodecContext *avctx) static int dvdsub_encode(AVCodecContext *avctx, unsigned char *buf, int buf_size, - const AVSubtitle *sub) + const AVFrame *sub) { //DVDSubtitleContext *s = avctx->priv_data; int ret; diff --git a/libavcodec/encode.c b/libavcodec/encode.c index 98dfbfdff3..289f6e88f1 100644 --- a/libavcodec/encode.c +++ b/libavcodec/encode.c @@ -141,11 +141,11 @@ fail: } int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, - const AVSubtitle *sub) + const AVFrame *sub) { int ret; - if (sub->start_display_time) { - av_log(avctx, AV_LOG_ERROR, "start_display_time must be 0.\n"); + if (sub->subtitle_start_time) { + av_log(avctx, AV_LOG_ERROR, "subtitle_start_time must be 0.\n"); return -1; } diff --git a/libavcodec/jacosubdec.c b/libavcodec/jacosubdec.c index 698895a86b..4c87d0f06d 100644 --- a/libavcodec/jacosubdec.c +++ b/libavcodec/jacosubdec.c @@ -166,7 +166,7 @@ static int jacosub_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, AVPacket *avpkt) { int ret; - AVSubtitle *sub = data; + AVFrame *sub = data; const char *ptr = avpkt->data; FFASSDecoderContext *s = avctx->priv_data; @@ -190,7 +190,7 @@ static int jacosub_decode_frame(AVCodecContext *avctx, } end: - *got_sub_ptr = sub->num_rects > 0; + *got_sub_ptr = sub->num_subtitle_rects > 0; return avpkt->size; } diff --git a/libavcodec/libzvbi-teletextdec.c b/libavcodec/libzvbi-teletextdec.c index 1073d6a0bd..b597042c52 100644 --- a/libavcodec/libzvbi-teletextdec.c +++ b/libavcodec/libzvbi-teletextdec.c @@ -215,7 +215,7 @@ static int gen_sub_text(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_page } if (buf.len) { - sub_rect->type = SUBTITLE_ASS; + sub_rect->type = AV_SUBTITLE_FMT_ASS; sub_rect->ass = create_ass_text(ctx, buf.str); if (!sub_rect->ass) { @@ -224,7 +224,7 @@ static int gen_sub_text(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_page } av_log(ctx, AV_LOG_DEBUG, "subtext:%s:txetbus\n", sub_rect->ass); } else { - sub_rect->type = SUBTITLE_NONE; + sub_rect->type = AV_SUBTITLE_FMT_NONE; } av_bprint_finalize(&buf, NULL); return 0; @@ -393,7 +393,7 @@ static int gen_sub_ass(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_page } if (buf.len) { - sub_rect->type = SUBTITLE_ASS; + sub_rect->type = AV_SUBTITLE_FMT_ASS; sub_rect->ass = ff_ass_get_dialog(ctx->readorder++, 0, is_subtitle_page ? "Subtitle" : "Teletext", NULL, buf.str); if (!sub_rect->ass) { @@ -402,7 +402,7 @@ static int gen_sub_ass(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_page } av_log(ctx, AV_LOG_DEBUG, "subtext:%s:txetbus\n", sub_rect->ass); } else { - sub_rect->type = SUBTITLE_NONE; + sub_rect->type = AV_SUBTITLE_FMT_NONE; } av_bprint_finalize(&buf, NULL); return 0; @@ -462,7 +462,7 @@ static int gen_sub_bitmap(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_pa if (vc >= vcend) { av_log(ctx, AV_LOG_DEBUG, "dropping empty page %3x\n", page->pgno); - sub_rect->type = SUBTITLE_NONE; + sub_rect->type = AV_SUBTITLE_FMT_NONE; return 0; } @@ -500,7 +500,7 @@ static int gen_sub_bitmap(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_pa } ((uint32_t *)sub_rect->data[1])[VBI_TRANSPARENT_BLACK] = RGBA(0, 0, 0, 0); ((uint32_t *)sub_rect->data[1])[VBI_TRANSPARENT_BLACK + VBI_NB_COLORS] = RGBA(0, 0, 0, 0); - sub_rect->type = SUBTITLE_BITMAP; + sub_rect->type = AV_SUBTITLE_FMT_BITMAP; return 0; } @@ -639,7 +639,7 @@ static int slice_to_vbi_lines(TeletextContext *ctx, uint8_t* buf, int size) static int teletext_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, AVPacket *pkt) { TeletextContext *ctx = avctx->priv_data; - AVSubtitle *sub = data; + AVFrame *sub = data; int ret = 0; if (!ctx->vbi) { @@ -695,7 +695,7 @@ static int teletext_decode_frame(AVCodecContext *avctx, void *data, int *got_sub sub->num_rects = 0; sub->pts = ctx->pages->pts; - if (ctx->pages->sub_rect->type != SUBTITLE_NONE) { + if (ctx->pages->sub_rect->type != AV_SUBTITLE_FMT_NONE) { sub->rects = av_malloc(sizeof(*sub->rects)); if (sub->rects) { sub->num_rects = 1; diff --git a/libavcodec/microdvddec.c b/libavcodec/microdvddec.c index c45fe043bf..8618c94bf2 100644 --- a/libavcodec/microdvddec.c +++ b/libavcodec/microdvddec.c @@ -277,7 +277,7 @@ static void microdvd_close_no_persistent_tags(AVBPrint *new_line, static int microdvd_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, AVPacket *avpkt) { - AVSubtitle *sub = data; + AVFrame *sub = data; AVBPrint new_line; char *line = avpkt->data; char *end = avpkt->data + avpkt->size; @@ -316,7 +316,7 @@ static int microdvd_decode_frame(AVCodecContext *avctx, return ret; } - *got_sub_ptr = sub->num_rects > 0; + *got_sub_ptr = sub->num_subtitle_rects > 0; return avpkt->size; } diff --git a/libavcodec/movtextdec.c b/libavcodec/movtextdec.c index 4e14ae5900..55fc1db69d 100644 --- a/libavcodec/movtextdec.c +++ b/libavcodec/movtextdec.c @@ -461,7 +461,7 @@ static int mov_text_init(AVCodecContext *avctx) { static int mov_text_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, AVPacket *avpkt) { - AVSubtitle *sub = data; + AVFrame *sub = data; MovTextContext *m = avctx->priv_data; int ret; AVBPrint buf; @@ -549,7 +549,7 @@ static int mov_text_decode_frame(AVCodecContext *avctx, av_bprint_finalize(&buf, NULL); if (ret < 0) return ret; - *got_sub_ptr = sub->num_rects > 0; + *got_sub_ptr = sub->num_subtitle_rects > 0; return avpkt->size; } diff --git a/libavcodec/movtextenc.c b/libavcodec/movtextenc.c index 2ae5a9bf0b..315fb9732a 100644 --- a/libavcodec/movtextenc.c +++ b/libavcodec/movtextenc.c @@ -635,7 +635,7 @@ static const ASSCodesCallbacks mov_text_callbacks = { }; static int mov_text_encode_frame(AVCodecContext *avctx, unsigned char *buf, - int bufsize, const AVSubtitle *sub) + int bufsize, const AVFrame *sub) { MovTextContext *s = avctx->priv_data; ASSDialog *dialog; @@ -646,11 +646,11 @@ static int mov_text_encode_frame(AVCodecContext *avctx, unsigned char *buf, s->text_pos = 0; s->count = 0; s->box_flags = 0; - for (i = 0; i < sub->num_rects; i++) { - const char *ass = sub->rects[i]->ass; + for (i = 0; i < sub->num_subtitle_rects; i++) { + const char *ass = sub->subtitle_rects[i]->ass; - if (sub->rects[i]->type != SUBTITLE_ASS) { - av_log(avctx, AV_LOG_ERROR, "Only SUBTITLE_ASS type supported.\n"); + if (sub->subtitle_rects[i]->type != AV_SUBTITLE_FMT_ASS) { + av_log(avctx, AV_LOG_ERROR, "Only AV_SUBTITLE_FMT_ASS type supported.\n"); return AVERROR(EINVAL); } diff --git a/libavcodec/mpl2dec.c b/libavcodec/mpl2dec.c index 61e47050ec..76efc0ce4f 100644 --- a/libavcodec/mpl2dec.c +++ b/libavcodec/mpl2dec.c @@ -68,7 +68,7 @@ static int mpl2_decode_frame(AVCodecContext *avctx, void *data, { int ret = 0; AVBPrint buf; - AVSubtitle *sub = data; + AVFrame *sub = data; const char *ptr = avpkt->data; FFASSDecoderContext *s = avctx->priv_data; @@ -78,7 +78,7 @@ static int mpl2_decode_frame(AVCodecContext *avctx, void *data, av_bprint_finalize(&buf, NULL); if (ret < 0) return ret; - *got_sub_ptr = sub->num_rects > 0; + *got_sub_ptr = sub->num_subtitle_rects > 0; return avpkt->size; } diff --git a/libavcodec/pgssubdec.c b/libavcodec/pgssubdec.c index 55eda4c2a9..1e4557ed42 100644 --- a/libavcodec/pgssubdec.c +++ b/libavcodec/pgssubdec.c @@ -498,28 +498,28 @@ static int parse_presentation_segment(AVCodecContext *avctx, static int display_end_segment(AVCodecContext *avctx, void *data, const uint8_t *buf, int buf_size) { - AVSubtitle *sub = data; + AVFrame *sub = data; PGSSubContext *ctx = avctx->priv_data; int64_t pts; PGSSubPalette *palette; int i, ret; - pts = ctx->presentation.pts != AV_NOPTS_VALUE ? ctx->presentation.pts : sub->pts; + pts = ctx->presentation.pts != AV_NOPTS_VALUE ? ctx->presentation.pts : sub->subtitle_pts; memset(sub, 0, sizeof(*sub)); - sub->pts = pts; + sub->subtitle_pts = pts; ctx->presentation.pts = AV_NOPTS_VALUE; - sub->start_display_time = 0; + sub->subtitle_start_time = 0; // There is no explicit end time for PGS subtitles. The end time // is defined by the start of the next sub which may contain no // objects (i.e. clears the previous sub) - sub->end_display_time = UINT32_MAX; - sub->format = 0; + sub->subtitle_end_time = UINT32_MAX; + sub->format = AV_SUBTITLE_FMT_BITMAP; // Blank if last object_count was 0. if (!ctx->presentation.object_count) return 1; - sub->rects = av_mallocz_array(ctx->presentation.object_count, sizeof(*sub->rects)); - if (!sub->rects) { + sub->subtitle_rects = av_mallocz_array(ctx->presentation.object_count, sizeof(*sub->subtitle_rects)); + if (!sub->subtitle_rects) { return AVERROR(ENOMEM); } palette = find_palette(ctx->presentation.palette_id, &ctx->palettes); @@ -527,19 +527,19 @@ static int display_end_segment(AVCodecContext *avctx, void *data, // Missing palette. Should only happen with damaged streams. av_log(avctx, AV_LOG_ERROR, "Invalid palette id %d\n", ctx->presentation.palette_id); - avsubtitle_free(sub); + av_frame_free(&sub); return AVERROR_INVALIDDATA; } for (i = 0; i < ctx->presentation.object_count; i++) { PGSSubObject *object; - sub->rects[i] = av_mallocz(sizeof(*sub->rects[0])); - if (!sub->rects[i]) { - avsubtitle_free(sub); + sub->subtitle_rects[i] = av_mallocz(sizeof(*sub->subtitle_rects[0])); + if (!sub->subtitle_rects[i]) { + av_frame_free(&sub); return AVERROR(ENOMEM); } - sub->num_rects++; - sub->rects[i]->type = SUBTITLE_BITMAP; + sub->num_subtitle_rects++; + sub->subtitle_rects[i]->type = AV_SUBTITLE_FMT_BITMAP; /* Process bitmap */ object = find_object(ctx->presentation.objects[i].id, &ctx->objects); @@ -548,54 +548,54 @@ static int display_end_segment(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_ERROR, "Invalid object id %d\n", ctx->presentation.objects[i].id); if (avctx->err_recognition & AV_EF_EXPLODE) { - avsubtitle_free(sub); + av_frame_free(&sub); return AVERROR_INVALIDDATA; } // Leaves rect empty with 0 width and height. continue; } if (ctx->presentation.objects[i].composition_flag & 0x40) - sub->rects[i]->flags |= AV_SUBTITLE_FLAG_FORCED; + sub->subtitle_rects[i]->flags |= AV_SUBTITLE_FLAG_FORCED; - sub->rects[i]->x = ctx->presentation.objects[i].x; - sub->rects[i]->y = ctx->presentation.objects[i].y; + sub->subtitle_rects[i]->x = ctx->presentation.objects[i].x; + sub->subtitle_rects[i]->y = ctx->presentation.objects[i].y; if (object->rle) { - sub->rects[i]->w = object->w; - sub->rects[i]->h = object->h; + sub->subtitle_rects[i]->w = object->w; + sub->subtitle_rects[i]->h = object->h; - sub->rects[i]->linesize[0] = object->w; + sub->subtitle_rects[i]->linesize[0] = object->w; if (object->rle_remaining_len) { av_log(avctx, AV_LOG_ERROR, "RLE data length %u is %u bytes shorter than expected\n", object->rle_data_len, object->rle_remaining_len); if (avctx->err_recognition & AV_EF_EXPLODE) { - avsubtitle_free(sub); + av_frame_free(&sub); return AVERROR_INVALIDDATA; } } - ret = decode_rle(avctx, sub->rects[i], object->rle, object->rle_data_len); + ret = decode_rle(avctx, sub->subtitle_rects[i], object->rle, object->rle_data_len); if (ret < 0) { if ((avctx->err_recognition & AV_EF_EXPLODE) || ret == AVERROR(ENOMEM)) { - avsubtitle_free(sub); + av_frame_free(&sub); return ret; } - sub->rects[i]->w = 0; - sub->rects[i]->h = 0; + sub->subtitle_rects[i]->w = 0; + sub->subtitle_rects[i]->h = 0; continue; } } /* Allocate memory for colors */ - sub->rects[i]->nb_colors = 256; - sub->rects[i]->data[1] = av_mallocz(AVPALETTE_SIZE); - if (!sub->rects[i]->data[1]) { - avsubtitle_free(sub); + sub->subtitle_rects[i]->nb_colors = 256; + sub->subtitle_rects[i]->data[1] = av_mallocz(AVPALETTE_SIZE); + if (!sub->subtitle_rects[i]->data[1]) { + av_frame_free(&sub); return AVERROR(ENOMEM); } if (!ctx->forced_subs_only || ctx->presentation.objects[i].composition_flag & 0x40) - memcpy(sub->rects[i]->data[1], palette->clut, sub->rects[i]->nb_colors * sizeof(uint32_t)); + memcpy(sub->subtitle_rects[i]->data[1], palette->clut, sub->subtitle_rects[i]->nb_colors * sizeof(uint32_t)); } return 1; } @@ -605,7 +605,7 @@ static int decode(AVCodecContext *avctx, void *data, int *got_sub_ptr, { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; - + AVFrame *sub = data; const uint8_t *buf_end; uint8_t segment_type; int segment_length; @@ -649,7 +649,7 @@ static int decode(AVCodecContext *avctx, void *data, int *got_sub_ptr, ret = parse_object_segment(avctx, buf, segment_length); break; case PRESENTATION_SEGMENT: - ret = parse_presentation_segment(avctx, buf, segment_length, ((AVSubtitle*)(data))->pts); + ret = parse_presentation_segment(avctx, buf, segment_length, sub->subtitle_pts); break; case WINDOW_SEGMENT: /* @@ -678,7 +678,7 @@ static int decode(AVCodecContext *avctx, void *data, int *got_sub_ptr, break; } if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) { - avsubtitle_free(data); + av_frame_free(&sub); *got_sub_ptr = 0; return ret; } diff --git a/libavcodec/realtextdec.c b/libavcodec/realtextdec.c index 11b586d493..8ce24e0bcc 100644 --- a/libavcodec/realtextdec.c +++ b/libavcodec/realtextdec.c @@ -60,7 +60,7 @@ static int realtext_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, AVPacket *avpkt) { int ret = 0; - AVSubtitle *sub = data; + AVFrame *sub = data; const char *ptr = avpkt->data; FFASSDecoderContext *s = avctx->priv_data; AVBPrint buf; @@ -71,7 +71,7 @@ static int realtext_decode_frame(AVCodecContext *avctx, av_bprint_finalize(&buf, NULL); if (ret < 0) return ret; - *got_sub_ptr = sub->num_rects > 0; + *got_sub_ptr = sub->num_subtitle_rects > 0; return avpkt->size; } diff --git a/libavcodec/samidec.c b/libavcodec/samidec.c index 32d07447b4..2c25edefea 100644 --- a/libavcodec/samidec.c +++ b/libavcodec/samidec.c @@ -135,7 +135,7 @@ end: static int sami_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, AVPacket *avpkt) { - AVSubtitle *sub = data; + AVFrame *sub = data; const char *ptr = avpkt->data; SAMIContext *sami = avctx->priv_data; @@ -148,7 +148,7 @@ static int sami_decode_frame(AVCodecContext *avctx, if (ret < 0) return ret; } - *got_sub_ptr = sub->num_rects > 0; + *got_sub_ptr = sub->num_subtitle_rects > 0; return avpkt->size; } diff --git a/libavcodec/srtdec.c b/libavcodec/srtdec.c index 4f16226b83..557ffab45e 100644 --- a/libavcodec/srtdec.c +++ b/libavcodec/srtdec.c @@ -56,7 +56,7 @@ static int srt_to_ass(AVCodecContext *avctx, AVBPrint *dst, static int srt_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, AVPacket *avpkt) { - AVSubtitle *sub = data; + AVFrame *sub = data; AVBPrint buffer; int x1 = -1, y1 = -1, x2 = -1, y2 = -1; int ret; @@ -83,7 +83,7 @@ static int srt_decode_frame(AVCodecContext *avctx, if (ret < 0) return ret; - *got_sub_ptr = sub->num_rects > 0; + *got_sub_ptr = sub->num_subtitle_rects > 0; return avpkt->size; } diff --git a/libavcodec/srtenc.c b/libavcodec/srtenc.c index 2e3ac55770..f4a9de1e70 100644 --- a/libavcodec/srtenc.c +++ b/libavcodec/srtenc.c @@ -228,7 +228,7 @@ static const ASSCodesCallbacks text_callbacks = { }; static int encode_frame(AVCodecContext *avctx, - unsigned char *buf, int bufsize, const AVSubtitle *sub, + unsigned char *buf, int bufsize, const AVFrame *sub, const ASSCodesCallbacks *cb) { SRTContext *s = avctx->priv_data; @@ -237,11 +237,11 @@ static int encode_frame(AVCodecContext *avctx, av_bprint_clear(&s->buffer); - for (i=0; inum_rects; i++) { - const char *ass = sub->rects[i]->ass; + for (i=0; inum_subtitle_rects; i++) { + const char *ass = sub->subtitle_rects[i]->ass; - if (sub->rects[i]->type != SUBTITLE_ASS) { - av_log(avctx, AV_LOG_ERROR, "Only SUBTITLE_ASS type supported.\n"); + if (sub->subtitle_rects[i]->type != AV_SUBTITLE_FMT_ASS) { + av_log(avctx, AV_LOG_ERROR, "Only AV_SUBTITLE_FMT_ASS type supported.\n"); return AVERROR(EINVAL); } @@ -270,13 +270,13 @@ static int encode_frame(AVCodecContext *avctx, } static int srt_encode_frame(AVCodecContext *avctx, - unsigned char *buf, int bufsize, const AVSubtitle *sub) + unsigned char *buf, int bufsize, const AVFrame *sub) { return encode_frame(avctx, buf, bufsize, sub, &srt_callbacks); } static int text_encode_frame(AVCodecContext *avctx, - unsigned char *buf, int bufsize, const AVSubtitle *sub) + unsigned char *buf, int bufsize, const AVFrame *sub) { return encode_frame(avctx, buf, bufsize, sub, &text_callbacks); } diff --git a/libavcodec/subviewerdec.c b/libavcodec/subviewerdec.c index 5c650d0cde..e4eff51d33 100644 --- a/libavcodec/subviewerdec.c +++ b/libavcodec/subviewerdec.c @@ -51,7 +51,7 @@ static int subviewer_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, AVPacket *avpkt) { int ret = 0; - AVSubtitle *sub = data; + AVFrame *sub = data; const char *ptr = avpkt->data; FFASSDecoderContext *s = avctx->priv_data; AVBPrint buf; @@ -62,7 +62,7 @@ static int subviewer_decode_frame(AVCodecContext *avctx, av_bprint_finalize(&buf, NULL); if (ret < 0) return ret; - *got_sub_ptr = sub->num_rects > 0; + *got_sub_ptr = sub->num_subtitle_rects > 0; return avpkt->size; } diff --git a/libavcodec/textdec.c b/libavcodec/textdec.c index 308553660a..274b53f74d 100644 --- a/libavcodec/textdec.c +++ b/libavcodec/textdec.c @@ -48,7 +48,7 @@ static int text_decode_frame(AVCodecContext *avctx, void *data, { int ret = 0; AVBPrint buf; - AVSubtitle *sub = data; + AVFrame *sub = data; const char *ptr = avpkt->data; TextContext *text = avctx->priv_data; @@ -60,7 +60,7 @@ static int text_decode_frame(AVCodecContext *avctx, void *data, av_bprint_finalize(&buf, NULL); if (ret < 0) return ret; - *got_sub_ptr = sub->num_rects > 0; + *got_sub_ptr = sub->num_subtitle_rects > 0; return avpkt->size; } diff --git a/libavcodec/ttmlenc.c b/libavcodec/ttmlenc.c index ad2eddfdd5..3a439db98e 100644 --- a/libavcodec/ttmlenc.c +++ b/libavcodec/ttmlenc.c @@ -78,7 +78,7 @@ static const ASSCodesCallbacks ttml_callbacks = { }; static int ttml_encode_frame(AVCodecContext *avctx, uint8_t *buf, - int bufsize, const AVSubtitle *sub) + int bufsize, const AVFrame *sub) { TTMLContext *s = avctx->priv_data; ASSDialog *dialog; @@ -86,12 +86,12 @@ static int ttml_encode_frame(AVCodecContext *avctx, uint8_t *buf, av_bprint_clear(&s->buffer); - for (i=0; inum_rects; i++) { - const char *ass = sub->rects[i]->ass; + for (i=0; inum_subtitle_rects; i++) { + const char *ass = sub->subtitle_rects[i]->ass; int ret; - if (sub->rects[i]->type != SUBTITLE_ASS) { - av_log(avctx, AV_LOG_ERROR, "Only SUBTITLE_ASS type supported.\n"); + if (sub->subtitle_rects[i]->type != AV_SUBTITLE_FMT_ASS) { + av_log(avctx, AV_LOG_ERROR, "Only AV_SUBTITLE_FMT_ASS type supported.\n"); return AVERROR(EINVAL); } diff --git a/libavcodec/utils.c b/libavcodec/utils.c index cfc07cbcb8..767dfabd1e 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -818,6 +818,17 @@ int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes) return FFMAX(0, duration); } +enum AVSubtitleType av_get_subtitle_format_from_codecdesc(const AVCodecDescriptor *codec_descriptor) +{ + if(codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB) + return AV_SUBTITLE_FMT_BITMAP; + + if(codec_descriptor->props & AV_CODEC_PROP_TEXT_SUB) + return AV_SUBTITLE_FMT_ASS; + + return AV_SUBTITLE_FMT_UNKNOWN; +} + int av_get_audio_frame_duration2(AVCodecParameters *par, int frame_bytes) { int duration = get_audio_frame_duration(par->codec_id, par->sample_rate, diff --git a/libavcodec/webvttdec.c b/libavcodec/webvttdec.c index 0093f328fa..23b0c5245c 100644 --- a/libavcodec/webvttdec.c +++ b/libavcodec/webvttdec.c @@ -84,7 +84,7 @@ static int webvtt_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, AVPacket *avpkt) { int ret = 0; - AVSubtitle *sub = data; + AVFrame *sub = data; const char *ptr = avpkt->data; FFASSDecoderContext *s = avctx->priv_data; AVBPrint buf; @@ -95,7 +95,7 @@ static int webvtt_decode_frame(AVCodecContext *avctx, av_bprint_finalize(&buf, NULL); if (ret < 0) return ret; - *got_sub_ptr = sub->num_rects > 0; + *got_sub_ptr = sub->num_subtitle_rects > 0; return avpkt->size; } diff --git a/libavcodec/webvttenc.c b/libavcodec/webvttenc.c index 89b49e42bf..287a246156 100644 --- a/libavcodec/webvttenc.c +++ b/libavcodec/webvttenc.c @@ -156,7 +156,7 @@ static const ASSCodesCallbacks webvtt_callbacks = { }; static int webvtt_encode_frame(AVCodecContext *avctx, - unsigned char *buf, int bufsize, const AVSubtitle *sub) + unsigned char *buf, int bufsize, const AVFrame *sub) { WebVTTContext *s = avctx->priv_data; ASSDialog *dialog; @@ -164,11 +164,11 @@ static int webvtt_encode_frame(AVCodecContext *avctx, av_bprint_clear(&s->buffer); - for (i=0; inum_rects; i++) { - const char *ass = sub->rects[i]->ass; + for (i=0; inum_subtitle_rects; i++) { + const char *ass = sub->subtitle_rects[i]->ass; - if (sub->rects[i]->type != SUBTITLE_ASS) { - av_log(avctx, AV_LOG_ERROR, "Only SUBTITLE_ASS type supported.\n"); + if (sub->subtitle_rects[i]->type != AV_SUBTITLE_FMT_ASS) { + av_log(avctx, AV_LOG_ERROR, "Only AV_SUBTITLE_FMT_ASS type supported.\n"); return AVERROR(EINVAL); } diff --git a/libavcodec/xsubdec.c b/libavcodec/xsubdec.c index 979399bae6..f45edcc0ca 100644 --- a/libavcodec/xsubdec.c +++ b/libavcodec/xsubdec.c @@ -51,7 +51,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; - AVSubtitle *sub = data; + AVFrame *sub = data; const uint8_t *buf_end = buf + buf_size; uint8_t *bitmap; int w, h, x, y, i, ret; @@ -72,8 +72,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, } if (avpkt->pts != AV_NOPTS_VALUE) packet_time = av_rescale_q(avpkt->pts, AV_TIME_BASE_Q, (AVRational){1, 1000}); - sub->start_display_time = parse_timecode(buf + 1, packet_time); - sub->end_display_time = parse_timecode(buf + 14, packet_time); + sub->subtitle_start_time = parse_timecode(buf + 1, packet_time); + sub->subtitle_end_time = parse_timecode(buf + 14, packet_time); buf += 27; // read header @@ -96,51 +96,51 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, return AVERROR_INVALIDDATA; // allocate sub and set values - sub->rects = av_mallocz(sizeof(*sub->rects)); - if (!sub->rects) + sub->subtitle_rects = av_mallocz(sizeof(*sub->subtitle_rects)); + if (!sub->subtitle_rects) return AVERROR(ENOMEM); - sub->rects[0] = av_mallocz(sizeof(*sub->rects[0])); - if (!sub->rects[0]) { - av_freep(&sub->rects); + sub->subtitle_rects[0] = av_mallocz(sizeof(*sub->subtitle_rects[0])); + if (!sub->subtitle_rects[0]) { + av_freep(&sub->subtitle_rects); return AVERROR(ENOMEM); } - sub->rects[0]->x = x; sub->rects[0]->y = y; - sub->rects[0]->w = w; sub->rects[0]->h = h; - sub->rects[0]->type = SUBTITLE_BITMAP; - sub->rects[0]->linesize[0] = w; - sub->rects[0]->data[0] = av_malloc(w * h); - sub->rects[0]->nb_colors = 4; - sub->rects[0]->data[1] = av_mallocz(AVPALETTE_SIZE); - if (!sub->rects[0]->data[0] || !sub->rects[0]->data[1]) { - av_freep(&sub->rects[0]->data[1]); - av_freep(&sub->rects[0]->data[0]); - av_freep(&sub->rects[0]); - av_freep(&sub->rects); + sub->subtitle_rects[0]->x = x; sub->subtitle_rects[0]->y = y; + sub->subtitle_rects[0]->w = w; sub->subtitle_rects[0]->h = h; + sub->subtitle_rects[0]->type = AV_SUBTITLE_FMT_BITMAP; + sub->subtitle_rects[0]->linesize[0] = w; + sub->subtitle_rects[0]->data[0] = av_malloc(w * h); + sub->subtitle_rects[0]->nb_colors = 4; + sub->subtitle_rects[0]->data[1] = av_mallocz(AVPALETTE_SIZE); + if (!sub->subtitle_rects[0]->data[0] || !sub->subtitle_rects[0]->data[1]) { + av_freep(&sub->subtitle_rects[0]->data[1]); + av_freep(&sub->subtitle_rects[0]->data[0]); + av_freep(&sub->subtitle_rects[0]); + av_freep(&sub->subtitle_rects); return AVERROR(ENOMEM); } - sub->num_rects = 1; + sub->num_subtitle_rects = 1; // read palette - for (i = 0; i < sub->rects[0]->nb_colors; i++) - ((uint32_t*)sub->rects[0]->data[1])[i] = bytestream_get_be24(&buf); + for (i = 0; i < sub->subtitle_rects[0]->nb_colors; i++) + ((uint32_t*)sub->subtitle_rects[0]->data[1])[i] = bytestream_get_be24(&buf); if (!has_alpha) { // make all except background (first entry) non-transparent - for (i = 1; i < sub->rects[0]->nb_colors; i++) - ((uint32_t *)sub->rects[0]->data[1])[i] |= 0xff000000; + for (i = 1; i < sub->subtitle_rects[0]->nb_colors; i++) + ((uint32_t *)sub->subtitle_rects[0]->data[1])[i] |= 0xff000000; } else { - for (i = 0; i < sub->rects[0]->nb_colors; i++) - ((uint32_t *)sub->rects[0]->data[1])[i] |= (unsigned)*buf++ << 24; + for (i = 0; i < sub->subtitle_rects[0]->nb_colors; i++) + ((uint32_t *)sub->subtitle_rects[0]->data[1])[i] |= (unsigned)*buf++ << 24; } // process RLE-compressed data if ((ret = init_get_bits8(&gb, buf, buf_end - buf)) < 0) return ret; - bitmap = sub->rects[0]->data[0]; + bitmap = sub->subtitle_rects[0]->data[0]; for (y = 0; y < h; y++) { // interlaced: do odd lines - if (y == (h + 1) / 2) bitmap = sub->rects[0]->data[0] + w; + if (y == (h + 1) / 2) bitmap = sub->subtitle_rects[0]->data[0] + w; for (x = 0; x < w; ) { int log2 = ff_log2_tab[show_bits(&gb, 8)]; int run = get_bits(&gb, 14 - 4 * (log2 >> 1)); diff --git a/libavcodec/xsubenc.c b/libavcodec/xsubenc.c index 03d0dc2d86..6508af9a73 100644 --- a/libavcodec/xsubenc.c +++ b/libavcodec/xsubenc.c @@ -112,10 +112,10 @@ static int make_tc(uint64_t ms, int *tc) } static int xsub_encode(AVCodecContext *avctx, unsigned char *buf, - int bufsize, const AVSubtitle *h) + int bufsize, const AVFrame *h) { - uint64_t startTime = h->pts / 1000; // FIXME: need better solution... - uint64_t endTime = startTime + h->end_display_time - h->start_display_time; + uint64_t startTime = h->subtitle_pts / 1000; // FIXME: need better solution... + uint64_t endTime = startTime + h->subtitle_end_time - h->subtitle_start_time; int start_tc[4], end_tc[4]; uint8_t *hdr = buf + 27; // Point behind the timestamp uint8_t *rlelenptr; @@ -129,21 +129,21 @@ static int xsub_encode(AVCodecContext *avctx, unsigned char *buf, } // TODO: support multiple rects - if (h->num_rects != 1) - av_log(avctx, AV_LOG_WARNING, "Only single rects supported (%d in subtitle.)\n", h->num_rects); + if (h->num_subtitle_rects != 1) + av_log(avctx, AV_LOG_WARNING, "Only single rects supported (%d in subtitle.)\n", h->num_subtitle_rects); // TODO: render text-based subtitles into bitmaps - if (!h->rects[0]->data[0] || !h->rects[0]->data[1]) { + if (!h->subtitle_rects[0]->data[0] || !h->subtitle_rects[0]->data[1]) { av_log(avctx, AV_LOG_WARNING, "No subtitle bitmap available.\n"); return AVERROR(EINVAL); } // TODO: color reduction, similar to dvdsub encoder - if (h->rects[0]->nb_colors > 4) - av_log(avctx, AV_LOG_WARNING, "No more than 4 subtitle colors supported (%d found.)\n", h->rects[0]->nb_colors); + if (h->subtitle_rects[0]->nb_colors > 4) + av_log(avctx, AV_LOG_WARNING, "No more than 4 subtitle colors supported (%d found.)\n", h->subtitle_rects[0]->nb_colors); // TODO: Palette swapping if color zero is not transparent - if (((uint32_t *)h->rects[0]->data[1])[0] & 0xff000000) + if (((uint32_t *)h->subtitle_rects[0]->data[1])[0] & 0xff000000) av_log(avctx, AV_LOG_WARNING, "Color index 0 is not transparent. Transparency will be messed up.\n"); if (make_tc(startTime, start_tc) || make_tc(endTime, end_tc)) { @@ -160,40 +160,40 @@ static int xsub_encode(AVCodecContext *avctx, unsigned char *buf, // 2 pixels required on either side of subtitle. // Possibly due to limitations of hardware renderers. // TODO: check if the bitmap is already padded - width = FFALIGN(h->rects[0]->w, 2) + PADDING * 2; - height = FFALIGN(h->rects[0]->h, 2); + width = FFALIGN(h->subtitle_rects[0]->w, 2) + PADDING * 2; + height = FFALIGN(h->subtitle_rects[0]->h, 2); bytestream_put_le16(&hdr, width); bytestream_put_le16(&hdr, height); - bytestream_put_le16(&hdr, h->rects[0]->x); - bytestream_put_le16(&hdr, h->rects[0]->y); - bytestream_put_le16(&hdr, h->rects[0]->x + width -1); - bytestream_put_le16(&hdr, h->rects[0]->y + height -1); + bytestream_put_le16(&hdr, h->subtitle_rects[0]->x); + bytestream_put_le16(&hdr, h->subtitle_rects[0]->y); + bytestream_put_le16(&hdr, h->subtitle_rects[0]->x + width -1); + bytestream_put_le16(&hdr, h->subtitle_rects[0]->y + height -1); rlelenptr = hdr; // Will store length of first field here later. hdr+=2; // Palette for (i=0; i<4; i++) - bytestream_put_be24(&hdr, ((uint32_t *)h->rects[0]->data[1])[i]); + bytestream_put_be24(&hdr, ((uint32_t *)h->subtitle_rects[0]->data[1])[i]); // Bitmap // RLE buffer. Reserve 2 bytes for possible padding after the last row. init_put_bits(&pb, hdr, bufsize - (hdr - buf) - 2); - if (xsub_encode_rle(&pb, h->rects[0]->data[0], - h->rects[0]->linesize[0] * 2, - h->rects[0]->w, (h->rects[0]->h + 1) >> 1)) + if (xsub_encode_rle(&pb, h->subtitle_rects[0]->data[0], + h->subtitle_rects[0]->linesize[0] * 2, + h->subtitle_rects[0]->w, (h->subtitle_rects[0]->h + 1) >> 1)) return AVERROR_BUFFER_TOO_SMALL; bytestream_put_le16(&rlelenptr, put_bytes_count(&pb, 0)); // Length of first field - if (xsub_encode_rle(&pb, h->rects[0]->data[0] + h->rects[0]->linesize[0], - h->rects[0]->linesize[0] * 2, - h->rects[0]->w, h->rects[0]->h >> 1)) + if (xsub_encode_rle(&pb, h->subtitle_rects[0]->data[0] + h->subtitle_rects[0]->linesize[0], + h->subtitle_rects[0]->linesize[0] * 2, + h->subtitle_rects[0]->w, h->subtitle_rects[0]->h >> 1)) return AVERROR_BUFFER_TOO_SMALL; // Enforce total height to be a multiple of 2 - if (h->rects[0]->h & 1) { - put_xsub_rle(&pb, h->rects[0]->w, PADDING_COLOR); + if (h->subtitle_rects[0]->h & 1) { + put_xsub_rle(&pb, h->subtitle_rects[0]->w, PADDING_COLOR); } flush_put_bits(&pb); diff --git a/libavfilter/vf_subtitles.c b/libavfilter/vf_subtitles.c index d0bafcd3cf..c536854c45 100644 --- a/libavfilter/vf_subtitles.c +++ b/libavfilter/vf_subtitles.c @@ -35,14 +35,12 @@ # include "libavformat/avformat.h" #endif #include "libavutil/avstring.h" -#include "libavutil/imgutils.h" #include "libavutil/opt.h" #include "libavutil/parseutils.h" #include "drawutils.h" #include "avfilter.h" #include "internal.h" #include "formats.h" -#include "video.h" typedef struct AssContext { const AVClass *class; @@ -306,6 +304,7 @@ static av_cold int init_subtitles(AVFilterContext *ctx) AVStream *st; AVPacket pkt; AssContext *ass = ctx->priv; + enum AVSubtitleType subtitle_format; /* Init libass */ ret = init(ctx); @@ -386,16 +385,19 @@ static av_cold int init_subtitles(AVFilterContext *ctx) ret = AVERROR_DECODER_NOT_FOUND; goto end; } + dec_desc = avcodec_descriptor_get(st->codecpar->codec_id); - if (dec_desc && !(dec_desc->props & AV_CODEC_PROP_TEXT_SUB)) { + subtitle_format = av_get_subtitle_format_from_codecdesc(dec_desc); + + if (subtitle_format != AV_SUBTITLE_FMT_ASS) { av_log(ctx, AV_LOG_ERROR, - "Only text based subtitles are currently supported\n"); - ret = AVERROR_PATCHWELCOME; + "Only text based subtitles are supported by this filter\n"); + ret = AVERROR_INVALIDDATA; goto end; } + if (ass->charenc) av_dict_set(&codec_opts, "sub_charenc", ass->charenc, 0); - av_dict_set(&codec_opts, "sub_text_format", "ass", 0); dec_ctx = avcodec_alloc_context3(dec); if (!dec_ctx) { @@ -449,18 +451,18 @@ static av_cold int init_subtitles(AVFilterContext *ctx) dec_ctx->subtitle_header_size); while (av_read_frame(fmt, &pkt) >= 0) { int i, got_subtitle; - AVSubtitle sub = {0}; + AVFrame *sub = av_frame_alloc(); if (pkt.stream_index == sid) { - ret = avcodec_decode_subtitle2(dec_ctx, &sub, &got_subtitle, &pkt); + ret = avcodec_decode_subtitle2(dec_ctx, sub, &got_subtitle, &pkt); if (ret < 0) { av_log(ctx, AV_LOG_WARNING, "Error decoding: %s (ignored)\n", av_err2str(ret)); } else if (got_subtitle) { - const int64_t start_time = av_rescale_q(sub.pts, AV_TIME_BASE_Q, av_make_q(1, 1000)); - const int64_t duration = sub.end_display_time; - for (i = 0; i < sub.num_rects; i++) { - char *ass_line = sub.rects[i]->ass; + const int64_t start_time = av_rescale_q(sub->subtitle_pts, AV_TIME_BASE_Q, av_make_q(1, 1000)); + const int64_t duration = sub->subtitle_end_time; + for (i = 0; i < sub->num_subtitle_rects; i++) { + char *ass_line = sub->subtitle_rects[i]->ass; if (!ass_line) break; ass_process_chunk(ass->track, ass_line, strlen(ass_line), @@ -469,7 +471,7 @@ static av_cold int init_subtitles(AVFilterContext *ctx) } } av_packet_unref(&pkt); - avsubtitle_free(&sub); + av_frame_free(&sub); } end: diff --git a/libavformat/utils.c b/libavformat/utils.c index b56190d2da..f83dadd477 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -2949,7 +2949,6 @@ static int try_decode_frame(AVFormatContext *s, AVStream *st, const AVCodec *codec; int got_picture = 1, ret = 0; AVFrame *frame = av_frame_alloc(); - AVSubtitle subtitle; AVPacket pkt = *avpkt; int do_skip_frame = 0; enum AVDiscard skip_frame; @@ -3020,10 +3019,8 @@ static int try_decode_frame(AVFormatContext *s, AVStream *st, if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) ret = 0; } else if (avctx->codec_type == AVMEDIA_TYPE_SUBTITLE) { - ret = avcodec_decode_subtitle2(avctx, &subtitle, + ret = avcodec_decode_subtitle2(avctx, frame, &got_picture, &pkt); - if (got_picture) - avsubtitle_free(&subtitle); if (ret >= 0) pkt.size = 0; } diff --git a/libavutil/Makefile b/libavutil/Makefile index 410ac636f7..04e1101bf3 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -74,6 +74,7 @@ HEADERS = adler32.h \ sha512.h \ spherical.h \ stereo3d.h \ + subfmt.h \ threadmessage.h \ time.h \ timecode.h \ @@ -159,6 +160,7 @@ OBJS = adler32.o \ slicethread.o \ spherical.o \ stereo3d.o \ + subfmt.o \ threadmessage.o \ time.o \ timecode.o \ diff --git a/libavutil/frame.c b/libavutil/frame.c index ef2867d318..1855de9b3d 100644 --- a/libavutil/frame.c +++ b/libavutil/frame.c @@ -72,7 +72,12 @@ static void get_frame_defaults(AVFrame *frame) frame->colorspace = AVCOL_SPC_UNSPECIFIED; frame->color_range = AVCOL_RANGE_UNSPECIFIED; frame->chroma_location = AVCHROMA_LOC_UNSPECIFIED; - frame->flags = 0; + frame->subtitle_start_time = 0; + frame->subtitle_end_time = 0; + frame->num_subtitle_rects = 0; + frame->subtitle_rects = NULL; + frame->subtitle_pts = 0; + frame->subtitle_header = NULL; } static void free_side_data(AVFrameSideData **ptr_sd) @@ -306,6 +311,9 @@ static int frame_copy_props(AVFrame *dst, const AVFrame *src, int force_copy) dst->colorspace = src->colorspace; dst->color_range = src->color_range; dst->chroma_location = src->chroma_location; + dst->subtitle_start_time = src->subtitle_start_time; + dst->subtitle_end_time = src->subtitle_end_time; + dst->subtitle_pts = src->subtitle_pts; av_dict_copy(&dst->metadata, src->metadata, 0); @@ -359,6 +367,19 @@ int av_frame_ref(AVFrame *dst, const AVFrame *src) if (ret < 0) goto fail; + /* duplicate subtitle rects */ + dst->num_subtitle_rects = src->num_subtitle_rects; + + if (src->num_subtitle_rects) { + dst->subtitle_rects = av_malloc_array(src->num_subtitle_rects, sizeof(AVSubtitleRect *)); + + for (i = 0; i < src->num_subtitle_rects; i++) { + AVSubtitleRect *rect = src->subtitle_rects[i]; + rect->nb_refs++; + dst->subtitle_rects[i] = rect; + } + } + /* duplicate the frame data if it's not refcounted */ if (!src->buf[0]) { ret = av_frame_get_buffer2(dst, 0); @@ -472,6 +493,24 @@ void av_frame_unref(AVFrame *frame) av_buffer_unref(&frame->opaque_ref); av_buffer_unref(&frame->private_ref); + for (i = 0; i < frame->num_subtitle_rects; i++) { + AVSubtitleRect *rect = frame->subtitle_rects[i]; + + if (rect && rect->nb_refs > 0) + rect->nb_refs--; + else { + av_freep(&rect->data[0]); + av_freep(&rect->data[1]); + av_freep(&rect->data[2]); + av_freep(&rect->data[3]); + av_freep(&rect->text); + av_freep(&rect->ass); + av_freep(&rect); + } + } + + av_freep(&frame->subtitle_rects); + get_frame_defaults(frame); } diff --git a/libavutil/frame.h b/libavutil/frame.h index 005eed9d18..4e2cfe19b3 100644 --- a/libavutil/frame.h +++ b/libavutil/frame.h @@ -34,6 +34,7 @@ #include "rational.h" #include "samplefmt.h" #include "pixfmt.h" +#include "subfmt.h" #include "version.h" @@ -469,6 +470,17 @@ typedef struct AVFrame { */ uint64_t channel_layout; + uint32_t subtitle_start_time; /* display start time, relative to packet pts, in ms */ + uint32_t subtitle_end_time; /* display end time, relative to packet pts, in ms */ + unsigned num_subtitle_rects; + AVSubtitleRect **subtitle_rects; + int64_t subtitle_pts; ///< Same as packet pts, in AV_TIME_BASE + + /** + * Header containing style information for text subtitles. + */ + char *subtitle_header; + /** * AVBuffer references backing the data for this frame. If all elements of * this array are NULL, then this frame is not reference counted. This array diff --git a/libavutil/subfmt.c b/libavutil/subfmt.c new file mode 100644 index 0000000000..9a19d01aa3 --- /dev/null +++ b/libavutil/subfmt.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2021 softworkz + * + * 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 "common.h" +#include "subfmt.h" + +typedef struct SubtitleFmtInfo { + enum AVSubtitleType fmt; + char* name; +} SubtitleFmtInfo; + +static SubtitleFmtInfo sub_fmt_info[AV_SUBTITLE_FMT_NB] = { + {.fmt = AV_SUBTITLE_FMT_UNKNOWN, .name = "Unknown subtitle format", }, + {.fmt = AV_SUBTITLE_FMT_BITMAP, .name = "Graphical subtitles", }, + {.fmt = AV_SUBTITLE_FMT_TEXT, .name = "Text subtitles (plain)", }, + {.fmt = AV_SUBTITLE_FMT_ASS, .name = "Text subtitles (ass)", }, +}; + +const char *av_get_subtitle_fmt_name(enum AVSubtitleType sub_fmt) +{ + if (sub_fmt < 0 || sub_fmt >= AV_SUBTITLE_FMT_NB) + return NULL; + return sub_fmt_info[sub_fmt].name; +} + +enum AVSubtitleType av_get_subtitle_fmt(const char *name) +{ + int i; + + for (i = 0; i < AV_SUBTITLE_FMT_NB; i++) + if (!strcmp(sub_fmt_info[i].name, name)) + return i; + return AV_SUBTITLE_FMT_NONE; +} diff --git a/libavutil/subfmt.h b/libavutil/subfmt.h new file mode 100644 index 0000000000..31dabc957c --- /dev/null +++ b/libavutil/subfmt.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2021 softworkz + * + * 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 + */ + +#ifndef AVUTIL_SUBFMT_H +#define AVUTIL_SUBFMT_H + +#include + +enum AVSubtitleType { + + /** + * Subtitle format unknown. + */ + AV_SUBTITLE_FMT_NONE = -1, + + /** + * Subtitle format unknown. + */ + AV_SUBTITLE_FMT_UNKNOWN = 0, + + /** + * Bitmap area in AVSubtitleRect.data, pixfmt AV_PIX_FMT_PAL8. + */ + AV_SUBTITLE_FMT_BITMAP = 1, + + /** + * Plain text in AVSubtitleRect.text. + */ + AV_SUBTITLE_FMT_TEXT = 2, + + /** + * Text Formatted as per ASS specification, contained AVSubtitleRect.ass. + */ + AV_SUBTITLE_FMT_ASS = 3, + + AV_SUBTITLE_FMT_NB, +}; + +typedef struct AVSubtitleRect { + unsigned nb_refs; + int x; ///< top left corner of pict, undefined when pict is not set + int y; ///< top left corner of pict, undefined when pict is not set + int w; ///< width of pict, undefined when pict is not set + int h; ///< height of pict, undefined when pict is not set + int nb_colors; ///< number of colors in pict, undefined when pict is not set + + /** + * data+linesize for the bitmap of this subtitle. + */ + uint8_t *data[4]; + int linesize[4]; + + enum AVSubtitleType type; + + char *text; ///< 0 terminated plain UTF-8 text + + /** + * 0-terminated ASS/SSA compatible event line. + */ + char *ass; + + int flags; +} AVSubtitleRect; + +/** + * Return the name of sub_fmt, or NULL if sub_fmt is not + * recognized. + */ +const char *av_get_subtitle_fmt_name(enum AVSubtitleType sub_fmt); + +/** + * Return a subtitle format corresponding to name, or AV_SUBTITLE_FMT_NONE + * on error. + */ +enum AVSubtitleType av_get_subtitle_fmt(const char *name); + +#endif /* AVUTIL_SUBFMT_H */