From patchwork Thu Aug 19 07:43:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Soft Works X-Patchwork-Id: 29605 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6602:2a4a:0:0:0:0 with SMTP id k10csp64236iov; Thu, 19 Aug 2021 00:43:30 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz1eA5Hx3I/oLFKqJpeBL81auB78zJauikvFaVnuE0ibokhNL5lLzZX1RI8/qL3WzrA5C8g X-Received: by 2002:a17:906:3947:: with SMTP id g7mr9543494eje.87.1629359010482; Thu, 19 Aug 2021 00:43:30 -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 z19si2371921edc.428.2021.08.19.00.43.30; Thu, 19 Aug 2021 00:43:30 -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=cnBa+0No; 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 18C8868A03B; Thu, 19 Aug 2021 10:43:22 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from NAM11-DM6-obe.outbound.protection.outlook.com (mail-dm6nam11olkn2099.outbound.protection.outlook.com [40.92.19.99]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 730CF68020A for ; Thu, 19 Aug 2021 10:43:15 +0300 (EEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=abaFbtF3Wi/TqE00EasXJc+YTRHvzMGNF0HMGPU9oZIDn0bZ8EuSKWX0oyehKE9jKnf22tY14FQQDVb8OCBgmALUOHVt2mJgt1UprTiawNm4H0ViFIorUXr+WLzlVaMU0p6sf4btKVFyXnQZ409s8PxACyPjZ1IfhAPyZInazHB0n3NW/b+ccT6hPY6lxwc76okPFvuWKX1It8H1t4JB5p9jK2pFfQkPjAKbRITY7N0o4Wl3lq84BdqrVN3nSUjYNZj053ZWRhmnecxP0qG0HnnruyC6xb1FyHv4ZEGs8LxmLsEtR/8vvwJh96C6tFD/ICYJ/T++iqHOoeqidVngog== 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:X-MS-Exchange-SenderADCheck; bh=96bcPrLEZBrHmXfa900MRbR69huK0v4B70YT2cfCm00=; b=LLMKyqNuEnpwnBxqiSF/dldfHOYChr9cVbJnxvFsFo+oAYNgBPp9OtevOQO/67az+SWysLxmTqktNr2oTDWLC43JzpxQTBPcF628g+2upcljYA3RTO6R5EVsMkjgkH2uqGDod41V7hoJr0whlGYwQMd7aEn1OZgMsSwwgZRKXFfyKHuxel4vJ/ZBCH0vtmK+/aztEqG4KJl+Q9SjX/G7Tng74y2ziUQ0W9AyYsWoFF+PjEE+CJLJ1ZeZMiK4BWLE0J3eESvCOKrOMPS2r5g+wcocWq9dTIxiZ005g8HTMotyn40JKVu54RYjJC8BOBhBTfG+LQlssdvPMZsgs1/bWQ== 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=96bcPrLEZBrHmXfa900MRbR69huK0v4B70YT2cfCm00=; b=cnBa+0NolEcLzSR+zw4wUaaabfOKNSoHUEzsfUM5lC/I+nUH9NLR3273r4HlN2PtbJIXXlLMh7m8EM5XWTRKqwYUWc6PjYJF5GgjWtQPyUms324cDPrODQqhXZrTDlt+bUMHwJXHLS2TyuRzUQ7kbNVNs6xZazBwdLheDXNpkBXiGVoDBRWzkz0/EfbEUHoJWkM07EM+aTZwnScUYJin7zGU7NrCO8xCIfYe6OYPyM76xsUeICHE/RJY5PkoDL0Dny/mutfNpWwSByb6DYkB0aMB7gQhGWkC040bzS5agaqnrqFnjnGHEVq0ctgeXyPITg120P2moBxTafhZaQJR9g== Received: from MN2PR04MB5981.namprd04.prod.outlook.com (2603:10b6:208:da::10) by MN2PR04MB6255.namprd04.prod.outlook.com (2603:10b6:208:d5::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4415.22; Thu, 19 Aug 2021 07:43:09 +0000 Received: from MN2PR04MB5981.namprd04.prod.outlook.com ([fe80::5d83:1c26:c2b1:3a30]) by MN2PR04MB5981.namprd04.prod.outlook.com ([fe80::5d83:1c26:c2b1:3a30%6]) with mapi id 15.20.4415.024; Thu, 19 Aug 2021 07:43:09 +0000 From: Soft Works To: "ffmpeg-devel@ffmpeg.org" Thread-Topic: [PATCH 1/9] lavu/frame: avframe add type property Thread-Index: AdeUhtWMG2LoKHM6QwCJ7VzhSu+5wg== Date: Thu, 19 Aug 2021 07:43:09 +0000 Message-ID: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-messagesentrepresentingtype: 1 x-tmn: [+yTljXQAD8PwWo34JrnsP1J51xVqCIGA] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 38c0d72e-df4c-4ad5-7fa3-08d962e4fd6f x-ms-traffictypediagnostic: MN2PR04MB6255: x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: Rm2Q+x7mtRD1Buy+N8NjJcdRqPVpv1jPnoiSG2R/OKytwbOuyDcxkoyNJaK97BH9DTo4P8sUQIAfaxIsaMZmvum7pynkZJekMihqoi+2vMGrAlIo5bym4NqMWuDjVkHBthGLkqO8H2ZhzfzTjFEU/Kq5glS9reFiKkX/91NiDkI5s3x98pWV31OpPsDmtM9g5bpacubJKskMncj5j8o2a2G6CrJTyeNhwMYFua3s0+phvp5eAOp2xDvD/5YxSMwd9s2f3eboj8Qd6aXdeJ/NPljgYRNgj55liknB7heZRA+beDn9Lp5tusbjvgy46JYqH7W8OR1KV26kUSFfQr3xB8A2smvCi0/39MXSCJ1Bb6nMM1GGP7n1iUxoC0oCB/NmZa99bBtg8zIzL4IZMfMQnU/oF255RujErCkLKUJNUb2vUqKIFk4r3EPLg8FgQzwT x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: FUJeK6OF6yMhnTFGaf8CO3Gw+CHGS9E7xHf6JVTYoyjFq/b8a8sIajii9aBkDUpWuDcTrXtXtAbjFrTmexCLvRtMH0u3/5IvMXu02sXWBuJMCi5sqZPYvC8G+tYJgoCrrmbyI97kxKj2RDgGUzCy4g== 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: 38c0d72e-df4c-4ad5-7fa3-08d962e4fd6f X-MS-Exchange-CrossTenant-originalarrivaltime: 19 Aug 2021 07:43:09.2534 (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: MN2PR04MB6255 Subject: [FFmpeg-devel] [PATCH 1/9] lavu/frame: avframe add type property 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: NJHdb/ULST2w Signed-off-by: softworkz --- libavutil/frame.c | 74 ++++++++++++++++++++++++++++++++++++--------- libavutil/frame.h | 39 ++++++++++++++++++++++-- libavutil/version.h | 2 +- 3 files changed, 97 insertions(+), 18 deletions(-) diff --git a/libavutil/frame.c b/libavutil/frame.c index b0ceaf7145..7d95849cef 100644 --- a/libavutil/frame.c +++ b/libavutil/frame.c @@ -244,22 +244,39 @@ static int get_audio_buffer(AVFrame *frame, int align) } int av_frame_get_buffer(AVFrame *frame, int align) +{ + if (frame->width > 0 && frame->height > 0) + return av_frame_get_buffer2(frame, AVMEDIA_TYPE_VIDEO, align); + else if (frame->nb_samples > 0 && (frame->channel_layout || frame->channels > 0)) + return av_frame_get_buffer2(frame, AVMEDIA_TYPE_AUDIO, align); + + return AVERROR(EINVAL); +} + +int av_frame_get_buffer2(AVFrame *frame, enum AVMediaType type, int align) { if (frame->format < 0) return AVERROR(EINVAL); - if (frame->width > 0 && frame->height > 0) + frame->type = type; + + switch(frame->type) { + case AVMEDIA_TYPE_VIDEO: return get_video_buffer(frame, align); - else if (frame->nb_samples > 0 && (frame->channel_layout || frame->channels > 0)) + case AVMEDIA_TYPE_AUDIO: return get_audio_buffer(frame, align); - - return AVERROR(EINVAL); + case AVMEDIA_TYPE_SUBTITLE: + return 0; + default: + return AVERROR(EINVAL); + } } static int frame_copy_props(AVFrame *dst, const AVFrame *src, int force_copy) { int ret, i; + dst->type = src->type; dst->key_frame = src->key_frame; dst->pict_type = src->pict_type; dst->sample_aspect_ratio = src->sample_aspect_ratio; @@ -331,6 +348,7 @@ int av_frame_ref(AVFrame *dst, const AVFrame *src) av_assert1(dst->width == 0 && dst->height == 0); av_assert1(dst->channels == 0); + dst->type = src->type; dst->format = src->format; dst->width = src->width; dst->height = src->height; @@ -499,6 +517,7 @@ int av_frame_make_writable(AVFrame *frame) return 0; memset(&tmp, 0, sizeof(tmp)); + tmp.type = frame->type; tmp.format = frame->format; tmp.width = frame->width; tmp.height = frame->height; @@ -544,14 +563,22 @@ AVBufferRef *av_frame_get_plane_buffer(AVFrame *frame, int plane) uint8_t *data; int planes, i; - if (frame->nb_samples) { - int channels = frame->channels; - if (!channels) - return NULL; - CHECK_CHANNELS_CONSISTENCY(frame); - planes = av_sample_fmt_is_planar(frame->format) ? channels : 1; - } else + switch(frame->type) { + case AVMEDIA_TYPE_VIDEO: planes = 4; + break; + case AVMEDIA_TYPE_AUDIO: + { + int channels = frame->channels; + if (!channels) + return NULL; + CHECK_CHANNELS_CONSISTENCY(frame); + planes = av_sample_fmt_is_planar(frame->format) ? channels : 1; + break; + } + default: + return NULL; + } if (plane < 0 || plane >= planes || !frame->extended_data[plane]) return NULL; @@ -675,17 +702,34 @@ static int frame_copy_audio(AVFrame *dst, const AVFrame *src) return 0; } +static int frame_copy_subtitles(AVFrame *dst, const AVFrame *src) +{ + dst->type = AVMEDIA_TYPE_SUBTITLE; + dst->format = src->format; + + if (src->buf[0]) { + dst->buf[0] = av_buffer_ref(src->buf[0]); + dst->data[0] = src->data[0]; + } + + return 0; +} + int av_frame_copy(AVFrame *dst, const AVFrame *src) { if (dst->format != src->format || dst->format < 0) return AVERROR(EINVAL); - if (dst->width > 0 && dst->height > 0) + switch(dst->type) { + case AVMEDIA_TYPE_VIDEO: return frame_copy_video(dst, src); - else if (dst->nb_samples > 0 && dst->channels > 0) + case AVMEDIA_TYPE_AUDIO: return frame_copy_audio(dst, src); - - return AVERROR(EINVAL); + case AVMEDIA_TYPE_SUBTITLE: + return frame_copy_subtitles(dst, src); + default: + return AVERROR(EINVAL); + } } void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type) diff --git a/libavutil/frame.h b/libavutil/frame.h index ff2540a20f..c104815df9 100644 --- a/libavutil/frame.h +++ b/libavutil/frame.h @@ -271,7 +271,7 @@ typedef struct AVRegionOfInterest { } AVRegionOfInterest; /** - * This structure describes decoded (raw) audio or video data. + * This structure describes decoded (raw) audio, video or subtitle data. * * AVFrame must be allocated using av_frame_alloc(). Note that this only * allocates the AVFrame itself, the buffers for the data must be managed @@ -302,6 +302,13 @@ typedef struct AVRegionOfInterest { */ typedef struct AVFrame { #define AV_NUM_DATA_POINTERS 8 + /** + * Media type of the frame (audio, video, subtitles..) + * + * See AVMEDIA_TYPE_xxx + */ + enum AVMediaType type; + /** * pointer to the picture/channel planes. * This might be different from the first allocated byte @@ -371,7 +378,7 @@ typedef struct AVFrame { /** * format of the frame, -1 if unknown or unset * Values correspond to enum AVPixelFormat for video frames, - * enum AVSampleFormat for audio) + * enum AVSampleFormat for audio, AVSubtitleType for subtitles) */ int format; @@ -721,6 +728,8 @@ void av_frame_move_ref(AVFrame *dst, AVFrame *src); /** * Allocate new buffer(s) for audio or video data. * + * Note: For subtitle data, use av_frame_get_buffer2 + * * The following fields must be set on frame before calling this function: * - format (pixel format for video, sample format for audio) * - width and height for video @@ -743,6 +752,32 @@ void av_frame_move_ref(AVFrame *dst, AVFrame *src); */ int av_frame_get_buffer(AVFrame *frame, int align); +/** + * Allocate new buffer(s) for audio, video or subtitle data. + * + * The following fields must be set on frame before calling this function: + * - format (pixel format for video, sample format for audio) + * - width and height for video + * - nb_samples and channel_layout for audio + * + * This function will fill AVFrame.data and AVFrame.buf arrays and, if + * necessary, allocate and fill AVFrame.extended_data and AVFrame.extended_buf. + * For planar formats, one buffer will be allocated for each plane. + * + * @warning: if frame already has been allocated, calling this function will + * leak memory. In addition, undefined behavior can occur in certain + * cases. + * + * @param frame frame in which to store the new buffers. + * @param type media type to set for the frame. + * @param align Required buffer size alignment. If equal to 0, alignment will be + * chosen automatically for the current CPU. It is highly + * recommended to pass 0 here unless you know what you are doing. + * + * @return 0 on success, a negative AVERROR on error. + */ +int av_frame_get_buffer2(AVFrame *frame, enum AVMediaType type, int align); + /** * Check if the frame data is writable. * diff --git a/libavutil/version.h b/libavutil/version.h index 4b77387b08..1e6a80f86e 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,7 +79,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 57 -#define LIBAVUTIL_VERSION_MINOR 4 +#define LIBAVUTIL_VERSION_MINOR 5 #define LIBAVUTIL_VERSION_MICRO 101 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ From patchwork Thu Aug 19 07:43:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Soft Works X-Patchwork-Id: 29606 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6602:2a4a:0:0:0:0 with SMTP id k10csp64324iov; Thu, 19 Aug 2021 00:43:41 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxR/MgHDKZlu7YSeoee2zKQR7iiqY1qZ9LcwADMGWxNG8lOG8KDSC1mfQ7VrlFAF1J7AXaF X-Received: by 2002:a17:906:b18e:: with SMTP id w14mr14402910ejy.63.1629359021303; Thu, 19 Aug 2021 00:43:41 -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 ne31si3033465ejc.157.2021.08.19.00.43.40; Thu, 19 Aug 2021 00:43:41 -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=OkDdVjnO; 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 2643B6806E4; Thu, 19 Aug 2021 10:43:27 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from NAM11-DM6-obe.outbound.protection.outlook.com (mail-dm6nam11olkn2099.outbound.protection.outlook.com [40.92.19.99]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C8E396806E4 for ; Thu, 19 Aug 2021 10:43:20 +0300 (EEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=lPTRN9cN6uL7zq6aeygdW0n+7AiVQ1zxFD0HHcq8ePnuSR9WDzdUrer+7rEFC45Kt+/wKLsUK6Uj/fVR+nH6qx0f6WlLLj43MM/eT24zuATjGTvQhIh7/W/4md7qE0BnDgHhiDZ4TxUZhnyVF/hhLV7CTSwFKX6tCJlEcnreBW82ciT09uDOtuxxh9/ZiXDUY0Uk9a1xej4/wiKxyTK5Vu9sq8+FmLz/ZciDOAnzJKon/UqW90FVazY+KetkTKXvQBOR3p4LKtuNiAhZQ89MPPs7HZiv9QILrUWeValaobaduxDtGICfgvbDR+RLjC6Kl6LSRgcRtH8fcCZq9JecEg== 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:X-MS-Exchange-SenderADCheck; bh=aStZ7U0TdMMw6ABbS0cNG7BM0ubvGM3ndz0EMcIthtE=; b=dcy4132t2CjhZnMgOkSyyWIEberuOo1AEfgMzJwxXHFzAu9ajBRulzUWm4DSeAgxzvDthtWFxbg9nBd4CQgDBm5GKTZgkLY0MHHJVgq/O05TNmbCeILVZ7hnkUZXdvMHNVHQvSdcUAcuQrjyByXYXj9QQ8g5vMmKOYnZPvzI7k+1pS2Lft/piv9XbC5fWwEOtxc+NlUmH0Iz89kLrey/6yHjonD/MnuuRvF6CxYwZpCaZh/Jh1vjkf/CHyLUS/BNpzZcr60OIZrtezOxB19fGjTiWHDIxymz9b1cyg6O7bDOg6aK3s3xcBtee43VdAafOPyu6YB48evPofoF1GV5qg== 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=aStZ7U0TdMMw6ABbS0cNG7BM0ubvGM3ndz0EMcIthtE=; b=OkDdVjnOziSYJIpRytAKcpqj+tp+3/dsprF15ld+XbI7O3AUoVoRm60uhK3IoUTHIKWdWe4MKGU2XlblV9rj2VlKU7rapfyPlyk63c2Xav5ZD1Jkc7aO3k2rZGgxFTvLUPwR2b9LDzoUDue49MCBDuIah9YnRimkOd8oyfLmpvUTagiMDqq+gwxH/8vKOA6b+8E9ziQqqh+8z7+Jzg5zeg5EGQCRY3t6NFsJKsrLpW+Q7cG88QzpaoWEjLKitVgCRYerx6fnximS805rbG+9IPjsXys34IbiBAuMNXLfPGAi/OfX4sfEDZVwxAxTkfDc6iQZJWmRITP/R0s4fM9TJw== Received: from MN2PR04MB5981.namprd04.prod.outlook.com (2603:10b6:208:da::10) by MN2PR04MB6255.namprd04.prod.outlook.com (2603:10b6:208:d5::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4415.22; Thu, 19 Aug 2021 07:43:13 +0000 Received: from MN2PR04MB5981.namprd04.prod.outlook.com ([fe80::5d83:1c26:c2b1:3a30]) by MN2PR04MB5981.namprd04.prod.outlook.com ([fe80::5d83:1c26:c2b1:3a30%6]) with mapi id 15.20.4415.024; Thu, 19 Aug 2021 07:43:13 +0000 From: Soft Works To: "ffmpeg-devel@ffmpeg.org" Thread-Topic: [PATCH 2/9] avfilter/subtitles: Add subtitles.c Thread-Index: AdeUdgfh9/D5ComkTyS1ia3MCgrGOA== Date: Thu, 19 Aug 2021 07:43:13 +0000 Message-ID: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-messagesentrepresentingtype: 1 x-tmn: [wwHBVQcwWY+fkz8lt+r6jOL6ybeYiqgh] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: cf2669e4-7dea-4e4a-a5fd-08d962e4fff5 x-ms-traffictypediagnostic: MN2PR04MB6255: x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: kGt6zlUgn3WWaLbzA834uPUIlf98bfLRiXmGPAhsdi7bR+lRlImEDbUArM81LMgQ7T04lQbEVBdpmFwuEjMwjJJggcRhpVvzb4ha0TrNtkQhXatstUvj+xbVpAZNXzrnRyJDlrMyP+K8ptguZ9PHRO2OLsV1rjA61OnyZVwFtv7d8L48OrS4X7FTrmglQj7zT9z+AAr3cUQKIj9q38BAnq9G/h8DryQISnCd8bOubLYnDB+gCvQu2COuIYu4T2hBU5v8Ehnf6WEjQeJC2V9SZb0QMgpEhS/jxx/WVIlQOtHLaOrhPudO168SKmhTO0GRl4YbIhNt1CiRQF/Xlpt/cKYedz2aSdLMoKmnQIdOEF6wlvT0YywFxLLe3JO3D2nHchaN+JZAD/rod6wRQj6ChvbPI/e6EilRnSThYKex7arZJHZi+DdNZ0SOoAAxvq69 x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: 8P8pr0Zz7sEV/fcYawhhZQAOVzHYkig7++lu76DfeGlJR94OpAzlouTt26O6NJY0KObXME5hsD7a2O48UHDm+IRsBSIeY6Pb/b3S0MKHJesWROAS+0aaLK00t//fIM2d0tMM+RaH4kqThjHB/GP+pA== 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: cf2669e4-7dea-4e4a-a5fd-08d962e4fff5 X-MS-Exchange-CrossTenant-originalarrivaltime: 19 Aug 2021 07:43:13.5320 (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: MN2PR04MB6255 Subject: [FFmpeg-devel] [PATCH 2/9] avfilter/subtitles: Add subtitles.c 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: ayYmfkcJzhpW Signed-off-by: softworkz --- libavfilter/Makefile | 1 + libavfilter/internal.h | 8 ++++++ libavfilter/subtitles.c | 61 +++++++++++++++++++++++++++++++++++++++++ libavfilter/subtitles.h | 42 ++++++++++++++++++++++++++++ 4 files changed, 112 insertions(+) create mode 100644 libavfilter/subtitles.c create mode 100644 libavfilter/subtitles.h diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 102ce7beff..db32cf1265 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -19,6 +19,7 @@ OBJS = allfilters.o \ framequeue.o \ graphdump.o \ graphparser.o \ + subtitles.o \ video.o \ OBJS-$(HAVE_THREADS) += pthread.o diff --git a/libavfilter/internal.h b/libavfilter/internal.h index a0aa32af4d..4f9aedf151 100644 --- a/libavfilter/internal.h +++ b/libavfilter/internal.h @@ -87,6 +87,14 @@ struct AVFilterPad { AVFrame *(*audio)(AVFilterLink *link, int nb_samples); } get_buffer; + /** + * Callback function to get a subtitle buffer. If NULL, the filter system will + * use ff_default_get_subtitle_buffer(). + * + * Input subtitle pads only. + */ + AVFrame *(*get_subtitle_buffer)(AVFilterLink *link, int format); + /** * Filtering callback. This is where a filter receives a frame with * audio/video data and should do its processing. diff --git a/libavfilter/subtitles.c b/libavfilter/subtitles.c new file mode 100644 index 0000000000..188ff1289c --- /dev/null +++ b/libavfilter/subtitles.c @@ -0,0 +1,61 @@ +/* + * 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 "libavutil/common.h" + +#include "subtitles.h" +#include "avfilter.h" +#include "internal.h" + + +AVFrame *ff_null_get_subtitles_buffer(AVFilterLink *link, int format) +{ + return ff_get_subtitles_buffer(link->dst->outputs[0], format); +} + +AVFrame *ff_default_get_subtitles_buffer(AVFilterLink *link, int format) +{ + AVFrame *frame = NULL; + + // TODO: + //frame = ff_frame_pool_get(link->frame_pool); + + frame = av_frame_alloc(); + if (!frame) + return NULL; + + frame->format = format; + frame->type = AVMEDIA_TYPE_SUBTITLE; + + return frame; +} + +AVFrame *ff_get_subtitles_buffer(AVFilterLink *link, int format) +{ + AVFrame *ret = NULL; + + if (link->dstpad->get_subtitle_buffer) + ret = link->dstpad->get_subtitle_buffer(link, format); + + if (!ret) + ret = ff_default_get_subtitles_buffer(link, format); + + return ret; +} diff --git a/libavfilter/subtitles.h b/libavfilter/subtitles.h new file mode 100644 index 0000000000..b964b61c37 --- /dev/null +++ b/libavfilter/subtitles.h @@ -0,0 +1,42 @@ +/* + * 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 AVFILTER_SUBTITLES_H +#define AVFILTER_SUBTITLES_H + +#include "avfilter.h" +#include "internal.h" + +/** default handler for get_subtitles_buffer() for subtitle inputs */ +AVFrame *ff_default_get_subtitles_buffer(AVFilterLink *link, int format); + +/** get_subtitles_buffer() handler for filters which simply pass subtitles along */ +AVFrame *ff_null_get_subtitles_buffer(AVFilterLink *link, int format); + +/** + * Request a subtitles buffer with a specific set of permissions. + * + * @param link the output link to the filter from which the buffer will + * be requested + * @return The subtitles format. + */ +AVFrame *ff_get_subtitles_buffer(AVFilterLink *link, int format); + +#endif /* AVFILTER_SUBTITLES_H */ From patchwork Thu Aug 19 07:43:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Soft Works X-Patchwork-Id: 29601 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6602:2a4a:0:0:0:0 with SMTP id k10csp64394iov; Thu, 19 Aug 2021 00:43:50 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxlx9/8GSAQLywdnca+c5MnJyfL5bvaU40f5ccZ7UEUmQptgnZ2pPXTI1oUWwtXIxF2Q5mr X-Received: by 2002:aa7:d4d3:: with SMTP id t19mr14662045edr.131.1629359030137; Thu, 19 Aug 2021 00:43:50 -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 r16si2408810edq.576.2021.08.19.00.43.49; Thu, 19 Aug 2021 00:43:50 -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="UryPXNQ/"; 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 4A19E68A2B9; Thu, 19 Aug 2021 10:43:33 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from NAM11-DM6-obe.outbound.protection.outlook.com (mail-dm6nam11olkn2099.outbound.protection.outlook.com [40.92.19.99]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 3CB756880AF for ; Thu, 19 Aug 2021 10:43:26 +0300 (EEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=IYyenVBw9JU4boW2KFLWdkU5XtX57PHhABHJRnaNS4/yhgxFikyOxnNQR0bQawtR+bBdc42evHrR4vCDWmc0GNVULiyd0fyeQ1ZwyPsYSAzzELMJZz8O0DmAAqoMe3E6HzthbD7rc+K5tfDBRUBEsN/+nLVCL4hxYImdFg6vxu+YeyMsOV25aaQ4qSPR3inIC7ivQaYF8Qp8HuJa7GaTRs+wOtoAwR39asNeiwV87k04JJEfDSGLa5uSZGftL9zbZm0SsvInTbvXclzncQKeh6Nlhgm0/CuoUTutWzRc7C+KLdJ4URKcodqBQeoRDQRkACM9xBCkRRmT+POVDuUWKQ== 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:X-MS-Exchange-SenderADCheck; bh=0+7uPs/TpEzsqHfmNCYSYYwUDSKVe5PUcxeDCxkmWEs=; b=HPzg1ft4xXx4rP62L+KHaUmgprwkIq2BSO37mpRGx+iTRltNI+XJszuUnTslj7aUwmB3AEvlME9NrDXcui8JfSqdi00wQVPXgqeUmrP5Tab43KLVp12Bqb4XNijFV3TZFPU8DXcdgzYTC7mAHTYHu3ZbpIMnUu7lP5+njF/HvKA1jH4rDK4e1i8DWUSEZJeRw5OHIrIi8EzM5wrb4/2YFzikh94PZcvGnC8ilhBGIqiwiBK2RXmfb1f6WpRmZjWZR+UlagkSRa8ZQfS2An7vdCLGUm25vHCRPaSLH0Otuc1OqjOqQM/H3XybeCxDzTUU7rdlPN/CseAhW4rzgr43yw== 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=0+7uPs/TpEzsqHfmNCYSYYwUDSKVe5PUcxeDCxkmWEs=; b=UryPXNQ/lmt2lu4FK1asaL3L4JKwf6+upQ3Q341poTzpz16SNLqMo6n5suYqfzBeq1QaXyfPeSC3SFixX8+M+9nd6on14lSm5hVRRw+UuvTkzbgUvP1lz8Lt+QwZT5FgPzchupav3rbW5gwQVWnLokqOcKyrmga5oDur/UDNFHQUtQdni2OMVewJ5YxokVk8a6CpIxEC0ew2tmAcc9Ffpp5CVbVtUiJWIoDAJelbcfMr09BJcoYAZcWW7TBCrgQgDEkllY6BJP5SuOxPXM3TJ1cHmytkwqT6TTloc1xr4kxVRxjYtPylP9ZARxnKqcMK9Qo56oL6Zr+dQDYSEU30hQ== Received: from MN2PR04MB5981.namprd04.prod.outlook.com (2603:10b6:208:da::10) by MN2PR04MB6255.namprd04.prod.outlook.com (2603:10b6:208:d5::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4415.22; Thu, 19 Aug 2021 07:43:16 +0000 Received: from MN2PR04MB5981.namprd04.prod.outlook.com ([fe80::5d83:1c26:c2b1:3a30]) by MN2PR04MB5981.namprd04.prod.outlook.com ([fe80::5d83:1c26:c2b1:3a30%6]) with mapi id 15.20.4415.024; Thu, 19 Aug 2021 07:43:16 +0000 From: Soft Works To: "ffmpeg-devel@ffmpeg.org" Thread-Topic: [PATCH 3/9] avfilter/avfilter: Handle subtitle frames Thread-Index: AdeUdjgpzWhLa5/+TnKpj/TXwsxYhg== Date: Thu, 19 Aug 2021 07:43:16 +0000 Message-ID: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-messagesentrepresentingtype: 1 x-tmn: [q3+pKiOY2lLZWg1OAZPWWUV9h3GZyBnz] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 3310b30b-5d74-4434-1881-08d962e5019a x-ms-traffictypediagnostic: MN2PR04MB6255: x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: AeGTE/K6OSKwxjbLn5LaGauXaHm/SmYXINNsr5MyOrreKkuzK6nsWC97wZM+eXjgoLE7JfB02StcHLUVWF1dku2Lbpp/YFRz9SGZtuUYwQGCIal6oIDvtF6fk19GT0fi/xTGExxZFcsegLUfPLoDjV4hHxyDwLgygF7maGVlZiNrKRIj1UD7BhodAkL1IIAAgWnh3Lb5kRMa/yBIZO882yHNWLx9BaQZTDwP/t/zuMHgD6UTulsVc40D9lN0Ik4LfAw+CyYUb0Af9Vd70wo1Sn9cTuVNw23V1VvbDCcZ7l6ty824p54Ar4Ds0s71h0Lo6S2rNS5O3O3ubwT6ZDsyO7Nlbrx8sldNxgMLFushOsnmuE2rqS4Nvb0CAJ8e/td+JVK/Y1yRCyh3L/QLBqd6JIbdXyDoZoo4gw9qNks/HEKJHZaVM7kkHx3PPt4h2KeO x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: nV3co6FT2S0A6disFmKIh52/i2XdWP3q82p+y2fDKXZwIvefpQJ/aOG9D4Gk9o8mUxa+AnVmloKrnNL19qvoGekHBroVKGAd3aVu73Ho0+iNMr5mWo9iTeyOYz6ThYl5X0C/dPT3/qFjX1Ev0QiMvg== 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: 3310b30b-5d74-4434-1881-08d962e5019a X-MS-Exchange-CrossTenant-originalarrivaltime: 19 Aug 2021 07:43:16.3174 (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: MN2PR04MB6255 Subject: [FFmpeg-devel] [PATCH 3/9] avfilter/avfilter: Handle subtitle frames 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: X++UVu4uyZl/ Signed-off-by: softworkz --- libavfilter/avfilter.c | 8 +++++--- libavfilter/avfiltergraph.c | 5 +++++ libavfilter/formats.c | 11 +++++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index ea22b247de..5505c34678 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -56,7 +56,8 @@ void ff_tlog_ref(void *ctx, AVFrame *ref, int end) ref->linesize[0], ref->linesize[1], ref->linesize[2], ref->linesize[3], ref->pts, ref->pkt_pos); - if (ref->width) { + switch(ref->type) { + case AVMEDIA_TYPE_VIDEO: ff_tlog(ctx, " a:%d/%d s:%dx%d i:%c iskey:%d type:%c", ref->sample_aspect_ratio.num, ref->sample_aspect_ratio.den, ref->width, ref->height, @@ -64,12 +65,13 @@ void ff_tlog_ref(void *ctx, AVFrame *ref, int end) ref->top_field_first ? 'T' : 'B', /* Top / Bottom */ ref->key_frame, av_get_picture_type_char(ref->pict_type)); - } - if (ref->nb_samples) { + break; + case AVMEDIA_TYPE_AUDIO: ff_tlog(ctx, " cl:%"PRId64"d n:%d r:%d", ref->channel_layout, ref->nb_samples, ref->sample_rate); + break; } ff_tlog(ctx, "]%s", end ? "\n" : ""); diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index 41a91a9bda..4f581bc7a6 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -328,6 +328,8 @@ static int filter_link_check_formats(void *log, AVFilterLink *link, AVFilterForm return ret; break; + case AVMEDIA_TYPE_SUBTITLE: + return 0; default: av_assert0(!"reached"); } @@ -463,6 +465,9 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) if (!link) continue; + if (link->type == AVMEDIA_TYPE_SUBTITLE) + continue; + neg = ff_filter_get_negotiation(link); av_assert0(neg); for (neg_step = 1; neg_step < neg->nb; neg_step++) { diff --git a/libavfilter/formats.c b/libavfilter/formats.c index 9e39d65a3c..26d8e45263 100644 --- a/libavfilter/formats.c +++ b/libavfilter/formats.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavcodec/avcodec.h" #include "libavutil/avassert.h" #include "libavutil/channel_layout.h" #include "libavutil/common.h" @@ -430,6 +431,12 @@ int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout) return 0; } +static int ff_add_subtitle_type(AVFilterFormats **avff, int64_t fmt) +{ + ADD_FORMAT(avff, fmt, ff_formats_unref, int, formats, nb_formats); + return 0; +} + AVFilterFormats *ff_all_formats(enum AVMediaType type) { AVFilterFormats *ret = NULL; @@ -447,6 +454,10 @@ AVFilterFormats *ff_all_formats(enum AVMediaType type) return NULL; fmt++; } + } else if (type == AVMEDIA_TYPE_SUBTITLE) { + ff_add_subtitle_type(&ret, SUBTITLE_BITMAP); + ff_add_subtitle_type(&ret, SUBTITLE_ASS); + ff_add_subtitle_type(&ret, SUBTITLE_TEXT); } return ret; From patchwork Thu Aug 19 07:43:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Soft Works X-Patchwork-Id: 29604 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6602:2a4a:0:0:0:0 with SMTP id k10csp64508iov; Thu, 19 Aug 2021 00:44:01 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzKnJziIAIQGgv8sHQdTEVOp2w/ostz3nL9G6IWdBjC0CwglOzj7DTRLGuJ/kriOIme2ol/ X-Received: by 2002:aa7:dc56:: with SMTP id g22mr15108385edu.129.1629359041235; Thu, 19 Aug 2021 00:44:01 -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 z23si2497546edx.139.2021.08.19.00.44.00; Thu, 19 Aug 2021 00:44:01 -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=FVY+R9xD; 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 6E6D068A255; Thu, 19 Aug 2021 10:43:34 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from NAM11-DM6-obe.outbound.protection.outlook.com (mail-dm6nam11olkn2099.outbound.protection.outlook.com [40.92.19.99]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 9F3FF6880AF for ; Thu, 19 Aug 2021 10:43:31 +0300 (EEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=dy9RhQGW7x75oww1G6UUB9mdxouYDP8FyPGoIO5HTpsyeaurCw+pHdKJ+Owh3oQiyQXiBFl6iAAspmnRKDuZzoE+kr9TR37GaGcZvWfAfzn8X5KsOic/q5xIrHQfhqa2cbZ8Wh66RWN9R7OOwLsCFwtMZRlNaYYmqao0y3XDpq1HI3mNCPv5qfS7b4QMeE2sA4MtFgvp0BtPVboIru7YsiDJcgiW5G2wtwm6J/XPS9TwuPDA80H+gsdo9fYaQscNQaDRnJlrj3EeRAXA5Y313YXX5V0fLkp4Vcxdvql4fVCe68faM8RJhWzX+ExXkR9lT//SCJt7zmgtpvuzIiPcFg== 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:X-MS-Exchange-SenderADCheck; bh=z+OpYj+J57LSFUVoO5NmEWaJHsci7RKHUkHZOBoSnjM=; b=ZH/k8nacVkIqlGCVIiMuIjlc639xAJaI6SZEZiJmBE0m6fxy8e9Fskl5pIOJXbWmSdtZlmLiBpX7dO8nUCVWCjsGDNsXJFTcC8x6qcqpyj2pMnQi/hVynVOd1wj6AehmhbQm/5fnpVTM/fAUdbPpUfP2ArFvocy09c+9Anag0Z9fyDo/LO/NjcR54XDLmRrImoSQSYTct8D5Z278++h5JNRwoCARb6tyJSZ8+vMsbJZURyU34uWZMgJNspUmfIRdIPw0Pg1tVYw1X0NVh1jyhXdg7Zx6PhF+faNYJC1qGN1U5eA/dR8Fog16vLk3z84GMCwg3lY6pkmKA83CToaoXA== 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=z+OpYj+J57LSFUVoO5NmEWaJHsci7RKHUkHZOBoSnjM=; b=FVY+R9xD0FYFYVEr3B6R27S2zKu22AthSF8oZh6x7JlnBn1ThEI1IcZnslgqhyb2uyLxD+Mmbf91YGrpPkD0DVGA1XREFuEGNDPzt2ptRm/SEGjS6+jL1N+pPicKE4WVh8GsCppXVc3tsA9EcP+oGb+s3ypYCAQ5M4MegrjD8tp9DZBQiusBfvlQ1Y1pFtj13JDFnTzHyqCUkqwdJSNAoqNOJWexLghN6iuzPM2fZXxI2FvOjOSyemyY/PjscJt9srl5Ldsh592+fVOhyRcBuoQSJfgqtT5coryMPM9rbWV1b+8nLX5cU9V7nxcrDG0ssMqOeiy1G3DsIJRQHp9X4g== Received: from MN2PR04MB5981.namprd04.prod.outlook.com (2603:10b6:208:da::10) by MN2PR04MB6255.namprd04.prod.outlook.com (2603:10b6:208:d5::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4415.22; Thu, 19 Aug 2021 07:43:19 +0000 Received: from MN2PR04MB5981.namprd04.prod.outlook.com ([fe80::5d83:1c26:c2b1:3a30]) by MN2PR04MB5981.namprd04.prod.outlook.com ([fe80::5d83:1c26:c2b1:3a30%6]) with mapi id 15.20.4415.024; Thu, 19 Aug 2021 07:43:19 +0000 From: Soft Works To: "ffmpeg-devel@ffmpeg.org" Thread-Topic: [PATCH 4/9] avfilter/overlay_subs: Add overlay_subs filter Thread-Index: AdeUg3cRVq0PefFKThChNYVeZezOUQ== Date: Thu, 19 Aug 2021 07:43:19 +0000 Message-ID: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-messagesentrepresentingtype: 1 x-tmn: [Qig25QeWgO76XbmCT7KJM9Gl9IrjHNMJ] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 5ae5edab-8626-4e80-7d21-08d962e5038a x-ms-traffictypediagnostic: MN2PR04MB6255: x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: WRjOUZ4V0R2LkaEkR4wjeCLvlh0E2kWDoTforRYtge7XH1ayK9D1KRaWrz+bq04AOrnku8gqtpnpEujmQhOG7hGiX3SLRNsyG/jyQHHEnAeMXS20udKxvbY6wGsX2238rAgE5rLTdeIibRR1UIZDwL0dBfXClrb7OhWMDYpUtM3GQ173GTE/k4KYAnIxF9MIMx9hm8WHqa9QoiE8nNG/x2rdDf8oDMcUxBLAVGDaMfQlYAj6Z83wJa6H+4Rgey3U33Ny/bqZZrbK4qL0u2L5ys/W9snWHFTSEvD6ypreIQX1DZiH6aDZpmUe3ImovVpnhgiBogZeS9E314cwLzqjynEDQS+kJ1S/+rNwUH1xH7ngL4/hoVtgR+kdgp96KLIThIU+2bNVUrjHGZsyM70avWCS4Y7Qz/RzRP5N6IxZrH2hJ6PWsVKnqcSbp4ssC5Hm x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: qxN3TSKTUjaf+Cn+UUDlLjDZ7m9A6hRYVMvo5XrvG7rHwiCWMz5VlFSFre+1hFDMxVKdSD5a6obuqIfBaUjJ3XQ80xnJMMMniHyiWYKC/UkHemY5A4gZXdWWburg6bUQ0uZriEs6vciTUs8Y+2bPyw== 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: 5ae5edab-8626-4e80-7d21-08d962e5038a X-MS-Exchange-CrossTenant-originalarrivaltime: 19 Aug 2021 07:43:19.5206 (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: MN2PR04MB6255 Subject: [FFmpeg-devel] [PATCH 4/9] avfilter/overlay_subs: Add overlay_subs filter 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: lXoCmYxS9Lfv Signed-off-by: softworkz --- libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/vf_overlay_subs.c | 1173 +++++++++++++++++++++++++++++++++ libavfilter/vf_overlay_subs.h | 88 +++ 4 files changed, 1263 insertions(+) create mode 100644 libavfilter/vf_overlay_subs.c create mode 100644 libavfilter/vf_overlay_subs.h diff --git a/libavfilter/Makefile b/libavfilter/Makefile index db32cf1265..68a7f5cb88 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -357,6 +357,7 @@ OBJS-$(CONFIG_OVERLAY_CUDA_FILTER) += vf_overlay_cuda.o framesync.o vf OBJS-$(CONFIG_OVERLAY_OPENCL_FILTER) += vf_overlay_opencl.o opencl.o \ opencl/overlay.o framesync.o OBJS-$(CONFIG_OVERLAY_QSV_FILTER) += vf_overlay_qsv.o framesync.o +OBJS-$(CONFIG_OVERLAY_SUBS_FILTER) += vf_overlay_subs.o framesync.o OBJS-$(CONFIG_OVERLAY_VULKAN_FILTER) += vf_overlay_vulkan.o vulkan.o OBJS-$(CONFIG_OWDENOISE_FILTER) += vf_owdenoise.o OBJS-$(CONFIG_PAD_FILTER) += vf_pad.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 73040d2824..abd0a47750 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -339,6 +339,7 @@ extern const AVFilter ff_vf_oscilloscope; extern const AVFilter ff_vf_overlay; extern const AVFilter ff_vf_overlay_opencl; extern const AVFilter ff_vf_overlay_qsv; +extern const AVFilter ff_vf_overlay_subs; extern const AVFilter ff_vf_overlay_vulkan; extern const AVFilter ff_vf_overlay_cuda; extern const AVFilter ff_vf_owdenoise; diff --git a/libavfilter/vf_overlay_subs.c b/libavfilter/vf_overlay_subs.c new file mode 100644 index 0000000000..02659300a9 --- /dev/null +++ b/libavfilter/vf_overlay_subs.c @@ -0,0 +1,1173 @@ +/* + * Copyright (c) 2010 Stefano Sabatini + * Copyright (c) 2010 Baptiste Coudurier + * Copyright (c) 2007 Bobby Bingham + * + * 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 + * overlay one video on top of another + */ + +#include "avfilter.h" +#include "formats.h" +#include "libavutil/common.h" +#include "libavutil/eval.h" +#include "libavutil/avstring.h" +#include "libavutil/pixdesc.h" +#include "libavutil/imgutils.h" +#include "libavutil/mathematics.h" +#include "libavutil/opt.h" +#include "libavutil/timestamp.h" +#include "internal.h" +#include "drawutils.h" +#include "framesync.h" +#include "video.h" +#include "vf_overlay_subs.h" + +#include "libavcodec/avcodec.h" + +typedef struct ThreadData { + AVFrame *dst; + AVSubtitleRect *src; +} ThreadData; + +static const char *const var_names[] = { + "main_w", "W", ///< width of the main video + "main_h", "H", ///< height of the main video + "overlay_w", "w", ///< width of the overlay video + "overlay_h", "h", ///< height of the overlay video + "hsub", + "vsub", + "x", + "y", + "n", ///< number of frame + "pos", ///< position in the file + "t", ///< timestamp expressed in seconds + NULL +}; + +#define MAIN 0 +#define OVERLAY 1 + +#define R 0 +#define G 1 +#define B 2 +#define A 3 + +#define Y 0 +#define U 1 +#define V 2 + +enum EvalMode { + EVAL_MODE_INIT, + EVAL_MODE_FRAME, + EVAL_MODE_NB +}; + +static av_cold void uninit(AVFilterContext *ctx) +{ + OverlaySubsContext *s = ctx->priv; + + ff_framesync_uninit(&s->fs); + av_expr_free(s->x_pexpr); s->x_pexpr = NULL; + av_expr_free(s->y_pexpr); s->y_pexpr = NULL; +} + +static inline int normalize_xy(double d, int chroma_sub) +{ + if (isnan(d)) + return INT_MAX; + return (int)d & ~((1 << chroma_sub) - 1); +} + +static void eval_expr(AVFilterContext *ctx) +{ + OverlaySubsContext *s = ctx->priv; + + s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, NULL); + s->var_values[VAR_Y] = av_expr_eval(s->y_pexpr, s->var_values, NULL); + /* It is necessary if x is expressed from y */ + s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, NULL); + s->x = normalize_xy(s->var_values[VAR_X], s->hsub); + s->y = normalize_xy(s->var_values[VAR_Y], s->vsub); +} + +static int set_expr(AVExpr **pexpr, const char *expr, const char *option, void *log_ctx) +{ + int ret; + AVExpr *old = NULL; + + if (*pexpr) + old = *pexpr; + ret = av_expr_parse(pexpr, expr, var_names, + NULL, NULL, NULL, NULL, 0, log_ctx); + if (ret < 0) { + av_log(log_ctx, AV_LOG_ERROR, + "Error when evaluating the expression '%s' for %s\n", + expr, option); + *pexpr = old; + return ret; + } + + av_expr_free(old); + return 0; +} + +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, + char *res, int res_len, int flags) +{ + OverlaySubsContext *s = ctx->priv; + int ret; + + if (!strcmp(cmd, "x")) + ret = set_expr(&s->x_pexpr, args, cmd, ctx); + else if (!strcmp(cmd, "y")) + ret = set_expr(&s->y_pexpr, args, cmd, ctx); + else + ret = AVERROR(ENOSYS); + + if (ret < 0) + return ret; + + if (s->eval_mode == EVAL_MODE_INIT) { + eval_expr(ctx); + av_log(ctx, AV_LOG_VERBOSE, "x:%f xi:%d y:%f yi:%d\n", + s->var_values[VAR_X], s->x, + s->var_values[VAR_Y], s->y); + } + return ret; +} + +static const enum AVPixelFormat alpha_pix_fmts[] = { + AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, + AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA422P10, + AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, AV_PIX_FMT_RGBA, + AV_PIX_FMT_BGRA, AV_PIX_FMT_GBRAP, AV_PIX_FMT_NONE +}; + +static int query_formats(AVFilterContext *ctx) +{ + OverlaySubsContext *s = ctx->priv; + + /* overlay formats contains alpha, for avoiding conversion with alpha information loss */ + static const enum AVPixelFormat main_pix_fmts_yuv420[] = { + AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVA420P, + AV_PIX_FMT_NV12, AV_PIX_FMT_NV21, + AV_PIX_FMT_NONE + }; + + static const enum AVPixelFormat main_pix_fmts_yuv420p10[] = { + AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUVA420P10, + AV_PIX_FMT_NONE + }; + + static const enum AVPixelFormat main_pix_fmts_yuv422[] = { + AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_NONE + }; + + static const enum AVPixelFormat main_pix_fmts_yuv422p10[] = { + AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_NONE + }; + + static const enum AVPixelFormat main_pix_fmts_yuv444[] = { + AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVA444P, AV_PIX_FMT_NONE + }; + + static const enum AVPixelFormat main_pix_fmts_gbrp[] = { + AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, AV_PIX_FMT_NONE + }; + + static const enum AVPixelFormat main_pix_fmts_rgb[] = { + AV_PIX_FMT_ARGB, AV_PIX_FMT_RGBA, + AV_PIX_FMT_ABGR, AV_PIX_FMT_BGRA, + AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24, + AV_PIX_FMT_NONE + }; + + const enum AVPixelFormat *main_formats, *overlay_formats; + AVFilterFormats *formats; + int ret; + + switch (s->format) { + case OVERLAY_FORMAT_YUV420: + main_formats = main_pix_fmts_yuv420; + break; + case OVERLAY_FORMAT_YUV420P10: + main_formats = main_pix_fmts_yuv420p10; + break; + case OVERLAY_FORMAT_YUV422: + main_formats = main_pix_fmts_yuv422; + break; + case OVERLAY_FORMAT_YUV422P10: + main_formats = main_pix_fmts_yuv422p10; + break; + case OVERLAY_FORMAT_YUV444: + main_formats = main_pix_fmts_yuv444; + break; + case OVERLAY_FORMAT_RGB: + main_formats = main_pix_fmts_rgb; + break; + case OVERLAY_FORMAT_GBRP: + main_formats = main_pix_fmts_gbrp; + break; + case OVERLAY_FORMAT_AUTO: + return ff_set_common_formats(ctx, ff_make_format_list(alpha_pix_fmts)); + default: + av_assert0(0); + } + + formats = ff_make_format_list(main_formats); + if ((ret = ff_formats_ref(formats, &ctx->inputs[MAIN]->outcfg.formats)) < 0 || + (ret = ff_formats_ref(formats, &ctx->outputs[MAIN]->incfg.formats)) < 0) + return ret; + + return ff_formats_ref(ff_make_format_list(overlay_formats), + &ctx->inputs[OVERLAY]->outcfg.formats); +} + +static int config_input_overlay(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + OverlaySubsContext *s = inlink->dst->priv; + int ret; + const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(AV_PIX_FMT_BGRA); + + av_image_fill_max_pixsteps(s->overlay_pix_step, NULL, pix_desc); + + /* Finish the configuration by evaluating the expressions + now when both inputs are configured. */ + s->var_values[VAR_MAIN_W ] = s->var_values[VAR_MW] = ctx->inputs[MAIN ]->w; + s->var_values[VAR_MAIN_H ] = s->var_values[VAR_MH] = ctx->inputs[MAIN ]->h; + s->var_values[VAR_OVERLAY_W] = s->var_values[VAR_OW] = ctx->inputs[OVERLAY]->w; + s->var_values[VAR_OVERLAY_H] = s->var_values[VAR_OH] = ctx->inputs[OVERLAY]->h; + s->var_values[VAR_HSUB] = 1<log2_chroma_w; + s->var_values[VAR_VSUB] = 1<log2_chroma_h; + s->var_values[VAR_X] = NAN; + s->var_values[VAR_Y] = NAN; + s->var_values[VAR_N] = 0; + s->var_values[VAR_T] = NAN; + s->var_values[VAR_POS] = NAN; + + if ((ret = set_expr(&s->x_pexpr, s->x_expr, "x", ctx)) < 0 || + (ret = set_expr(&s->y_pexpr, s->y_expr, "y", ctx)) < 0) + return ret; + + s->overlay_is_packed_rgb = + ff_fill_rgba_map(s->overlay_rgba_map, AV_PIX_FMT_BGRA) >= 0; + s->overlay_has_alpha = ff_fmt_is_in(AV_PIX_FMT_BGRA, alpha_pix_fmts); + + if (s->eval_mode == EVAL_MODE_INIT) { + eval_expr(ctx); + av_log(ctx, AV_LOG_VERBOSE, "x:%f xi:%d y:%f yi:%d\n", + s->var_values[VAR_X], s->x, + s->var_values[VAR_Y], s->y); + } + + av_log(ctx, AV_LOG_VERBOSE, + "main w:%d h:%d fmt:%s overlay w:%d h:%d fmt:%s\n", + ctx->inputs[MAIN]->w, ctx->inputs[MAIN]->h, + av_get_pix_fmt_name(ctx->inputs[MAIN]->format), + ctx->inputs[OVERLAY]->w, ctx->inputs[OVERLAY]->h, + av_get_pix_fmt_name(ctx->inputs[OVERLAY]->format)); + return 0; +} + +static int config_output(AVFilterLink *outlink) +{ + AVFilterContext *ctx = outlink->src; + OverlaySubsContext *s = ctx->priv; + int ret; + + if ((ret = ff_framesync_init_dualinput(&s->fs, ctx)) < 0) + return ret; + + outlink->w = ctx->inputs[MAIN]->w; + outlink->h = ctx->inputs[MAIN]->h; + outlink->time_base = ctx->inputs[MAIN]->time_base; + + return ff_framesync_configure(&s->fs); +} + +// divide by 255 and round to nearest +// apply a fast variant: (X+127)/255 = ((X+127)*257+257)>>16 = ((X+128)*257)>>16 +#define FAST_DIV255(x) ((((x) + 128) * 257) >> 16) + +// calculate the unpremultiplied alpha, applying the general equation: +// alpha = alpha_overlay / ( (alpha_main + alpha_overlay) - (alpha_main * alpha_overlay) ) +// (((x) << 16) - ((x) << 9) + (x)) is a faster version of: 255 * 255 * x +// ((((x) + (y)) << 8) - ((x) + (y)) - (y) * (x)) is a faster version of: 255 * (x + y) +#define UNPREMULTIPLY_ALPHA(x, y) ((((x) << 16) - ((x) << 9) + (x)) / ((((x) + (y)) << 8) - ((x) + (y)) - (y) * (x))) + +/** + * Blend image in src to destination buffer dst at position (x, y). + */ + +static av_always_inline void blend_slice_packed_rgb(AVFilterContext *ctx, + AVFrame *dst, const AVSubtitleRect *src, + int main_has_alpha, int x, int y, + int is_straight, int jobnr, int nb_jobs) +{ + OverlaySubsContext *s = ctx->priv; + int i, imax, j, jmax; + const int src_w = src->w; + const int src_h = src->h; + const int dst_w = dst->width; + const int dst_h = dst->height; + uint8_t alpha; ///< the amount of overlay to blend on to main + const int dr = s->main_rgba_map[R]; + const int dg = s->main_rgba_map[G]; + const int db = s->main_rgba_map[B]; + const int da = s->main_rgba_map[A]; + const int dstep = s->main_pix_step[0]; + const int sr = s->overlay_rgba_map[R]; + const int sg = s->overlay_rgba_map[G]; + const int sb = s->overlay_rgba_map[B]; + const int sa = s->overlay_rgba_map[A]; + const int sstep = s->overlay_pix_step[0]; + int slice_start, slice_end; + uint8_t *S, *sp, *d, *dp; + + i = FFMAX(-y, 0); + imax = FFMIN3(-y + dst_h, FFMIN(src_h, dst_h), y + src_h); + + slice_start = i + (imax * jobnr) / nb_jobs; + slice_end = i + (imax * (jobnr+1)) / nb_jobs; + + sp = src->data[0] + (slice_start) * src->linesize[0]; + dp = dst->data[0] + (y + slice_start) * dst->linesize[0]; + + for (i = slice_start; i < slice_end; i++) { + j = FFMAX(-x, 0); + S = sp + j * sstep; + d = dp + (x+j) * dstep; + + for (jmax = FFMIN(-x + dst_w, src_w); j < jmax; j++) { + alpha = S[sa]; + + // if the main channel has an alpha channel, alpha has to be calculated + // to create an un-premultiplied (straight) alpha value + if (main_has_alpha && alpha != 0 && alpha != 255) { + uint8_t alpha_d = d[da]; + alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d); + } + + switch (alpha) { + case 0: + break; + case 255: + d[dr] = S[sr]; + d[dg] = S[sg]; + d[db] = S[sb]; + break; + default: + // main_value = main_value * (1 - alpha) + overlay_value * alpha + // since alpha is in the range 0-255, the result must divided by 255 + d[dr] = is_straight ? FAST_DIV255(d[dr] * (255 - alpha) + S[sr] * alpha) : + FFMIN(FAST_DIV255(d[dr] * (255 - alpha)) + S[sr], 255); + d[dg] = is_straight ? FAST_DIV255(d[dg] * (255 - alpha) + S[sg] * alpha) : + FFMIN(FAST_DIV255(d[dg] * (255 - alpha)) + S[sg], 255); + d[db] = is_straight ? FAST_DIV255(d[db] * (255 - alpha) + S[sb] * alpha) : + FFMIN(FAST_DIV255(d[db] * (255 - alpha)) + S[sb], 255); + } + if (main_has_alpha) { + switch (alpha) { + case 0: + break; + case 255: + d[da] = S[sa]; + break; + default: + // apply alpha compositing: main_alpha += (1-main_alpha) * overlay_alpha + d[da] += FAST_DIV255((255 - d[da]) * S[sa]); + } + } + d += dstep; + S += sstep; + } + dp += dst->linesize[0]; + sp += src->linesize[0]; + } +} + +#define DEFINE_BLEND_PLANE(depth, nbits) \ +static av_always_inline void blend_plane_##depth##_##nbits##bits(AVFilterContext *ctx, \ + AVFrame *dst, const AVFrame *src, \ + int src_w, int src_h, \ + int dst_w, int dst_h, \ + int i, int hsub, int vsub, \ + int x, int y, \ + int main_has_alpha, \ + int dst_plane, \ + int dst_offset, \ + int dst_step, \ + int straight, \ + int yuv, \ + int jobnr, \ + int nb_jobs) \ +{ \ + OverlaySubsContext *octx = ctx->priv; \ + int src_wp = AV_CEIL_RSHIFT(src_w, hsub); \ + int src_hp = AV_CEIL_RSHIFT(src_h, vsub); \ + int dst_wp = AV_CEIL_RSHIFT(dst_w, hsub); \ + int dst_hp = AV_CEIL_RSHIFT(dst_h, vsub); \ + int yp = y>>vsub; \ + int xp = x>>hsub; \ + uint##depth##_t *s, *sp, *d, *dp, *dap, *a, *da, *ap; \ + int jmax, j, k, kmax; \ + int slice_start, slice_end; \ + const uint##depth##_t max = (1 << nbits) - 1; \ + const uint##depth##_t mid = (1 << (nbits -1)) ; \ + int bytes = depth / 8; \ + \ + dst_step /= bytes; \ + j = FFMAX(-yp, 0); \ + jmax = FFMIN3(-yp + dst_hp, FFMIN(src_hp, dst_hp), yp + src_hp); \ + \ + slice_start = j + (jmax * jobnr) / nb_jobs; \ + slice_end = j + (jmax * (jobnr+1)) / nb_jobs; \ + \ + sp = (uint##depth##_t *)(src->data[i] + (slice_start) * src->linesize[i]); \ + dp = (uint##depth##_t *)(dst->data[dst_plane] \ + + (yp + slice_start) * dst->linesize[dst_plane] \ + + dst_offset); \ + ap = (uint##depth##_t *)(src->data[3] + (slice_start << vsub) * src->linesize[3]); \ + dap = (uint##depth##_t *)(dst->data[3] + ((yp + slice_start) << vsub) * dst->linesize[3]); \ + \ + for (j = slice_start; j < slice_end; j++) { \ + k = FFMAX(-xp, 0); \ + d = dp + (xp+k) * dst_step; \ + s = sp + k; \ + a = ap + (k<blend_row[i]) { \ + int c = octx->blend_row[i]((uint8_t*)d, (uint8_t*)da, (uint8_t*)s, \ + (uint8_t*)a, kmax - k, src->linesize[3]); \ + \ + s += c; \ + d += dst_step * c; \ + da += (1 << hsub) * c; \ + a += (1 << hsub) * c; \ + k += c; \ + } \ + for (; k < kmax; k++) { \ + int alpha_v, alpha_h, alpha; \ + \ + /* average alpha for color components, improve quality */ \ + if (hsub && vsub && j+1 < src_hp && k+1 < src_wp) { \ + alpha = (a[0] + a[src->linesize[3]] + \ + a[1] + a[src->linesize[3]+1]) >> 2; \ + } else if (hsub || vsub) { \ + alpha_h = hsub && k+1 < src_wp ? \ + (a[0] + a[1]) >> 1 : a[0]; \ + alpha_v = vsub && j+1 < src_hp ? \ + (a[0] + a[src->linesize[3]]) >> 1 : a[0]; \ + alpha = (alpha_v + alpha_h) >> 1; \ + } else \ + alpha = a[0]; \ + /* if the main channel has an alpha channel, alpha has to be calculated */ \ + /* to create an un-premultiplied (straight) alpha value */ \ + if (main_has_alpha && alpha != 0 && alpha != max) { \ + /* average alpha for color components, improve quality */ \ + uint8_t alpha_d; \ + if (hsub && vsub && j+1 < src_hp && k+1 < src_wp) { \ + alpha_d = (da[0] + da[dst->linesize[3]] + \ + da[1] + da[dst->linesize[3]+1]) >> 2; \ + } else if (hsub || vsub) { \ + alpha_h = hsub && k+1 < src_wp ? \ + (da[0] + da[1]) >> 1 : da[0]; \ + alpha_v = vsub && j+1 < src_hp ? \ + (da[0] + da[dst->linesize[3]]) >> 1 : da[0]; \ + alpha_d = (alpha_v + alpha_h) >> 1; \ + } else \ + alpha_d = da[0]; \ + alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d); \ + } \ + if (straight) { \ + if (nbits > 8) \ + *d = (*d * (max - alpha) + *s * alpha) / max; \ + else \ + *d = FAST_DIV255(*d * (255 - alpha) + *s * alpha); \ + } else { \ + if (nbits > 8) { \ + if (i && yuv) \ + *d = av_clip((*d * (max - alpha) + *s * alpha) / max + *s - mid, -mid, mid) + mid; \ + else \ + *d = FFMIN((*d * (max - alpha) + *s * alpha) / max + *s, max); \ + } else { \ + if (i && yuv) \ + *d = av_clip(FAST_DIV255((*d - mid) * (max - alpha)) + *s - mid, -mid, mid) + mid; \ + else \ + *d = FFMIN(FAST_DIV255(*d * (max - alpha)) + *s, max); \ + } \ + } \ + s++; \ + d += dst_step; \ + da += 1 << hsub; \ + a += 1 << hsub; \ + } \ + dp += dst->linesize[dst_plane] / bytes; \ + sp += src->linesize[i] / bytes; \ + ap += (1 << vsub) * src->linesize[3] / bytes; \ + dap += (1 << vsub) * dst->linesize[3] / bytes; \ + } \ +} +DEFINE_BLEND_PLANE(8, 8) +DEFINE_BLEND_PLANE(16, 10) + +#define DEFINE_ALPHA_COMPOSITE(depth, nbits) \ +static inline void alpha_composite_##depth##_##nbits##bits(const AVFrame *src, const AVFrame *dst, \ + int src_w, int src_h, \ + int dst_w, int dst_h, \ + int x, int y, \ + int jobnr, int nb_jobs) \ +{ \ + uint##depth##_t alpha; /* the amount of overlay to blend on to main */ \ + uint##depth##_t *s, *sa, *d, *da; \ + int i, imax, j, jmax; \ + int slice_start, slice_end; \ + const uint##depth##_t max = (1 << nbits) - 1; \ + int bytes = depth / 8; \ + \ + imax = FFMIN(-y + dst_h, src_h); \ + slice_start = (imax * jobnr) / nb_jobs; \ + slice_end = ((imax * (jobnr+1)) / nb_jobs); \ + \ + i = FFMAX(-y, 0); \ + sa = (uint##depth##_t *)(src->data[3] + (i + slice_start) * src->linesize[3]); \ + da = (uint##depth##_t *)(dst->data[3] + (y + i + slice_start) * dst->linesize[3]); \ + \ + for (i = i + slice_start; i < slice_end; i++) { \ + j = FFMAX(-x, 0); \ + s = sa + j; \ + d = da + x+j; \ + \ + for (jmax = FFMIN(-x + dst_w, src_w); j < jmax; j++) { \ + alpha = *s; \ + if (alpha != 0 && alpha != max) { \ + uint8_t alpha_d = *d; \ + alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d); \ + } \ + if (alpha == max) \ + *d = *s; \ + else if (alpha > 0) { \ + /* apply alpha compositing: main_alpha += (1-main_alpha) * overlay_alpha */ \ + if (nbits > 8) \ + *d += (max - *d) * *s / max; \ + else \ + *d += FAST_DIV255((max - *d) * *s); \ + } \ + d += 1; \ + s += 1; \ + } \ + da += dst->linesize[3] / bytes; \ + sa += src->linesize[3] / bytes; \ + } \ +} +DEFINE_ALPHA_COMPOSITE(8, 8) +DEFINE_ALPHA_COMPOSITE(16, 10) + +#define DEFINE_BLEND_SLICE_YUV(depth, nbits) \ +static av_always_inline void blend_slice_yuv_##depth##_##nbits##bits(AVFilterContext *ctx, \ + AVFrame *dst, const AVSubtitleRect *src, \ + int hsub, int vsub, \ + int main_has_alpha, \ + int x, int y, \ + int is_straight, \ + int jobnr, int nb_jobs) \ +{ \ + OverlaySubsContext *s = ctx->priv; \ + const int src_w = src->w; \ + const int src_h = src->h; \ + const int dst_w = dst->width; \ + const int dst_h = dst->height; \ + \ + blend_plane_##depth##_##nbits##bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0, 0, \ + x, y, main_has_alpha, s->main_desc->comp[0].plane, s->main_desc->comp[0].offset, \ + s->main_desc->comp[0].step, is_straight, 1, jobnr, nb_jobs); \ + blend_plane_##depth##_##nbits##bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 1, hsub, vsub, \ + x, y, main_has_alpha, s->main_desc->comp[1].plane, s->main_desc->comp[1].offset, \ + s->main_desc->comp[1].step, is_straight, 1, jobnr, nb_jobs); \ + blend_plane_##depth##_##nbits##bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 2, hsub, vsub, \ + x, y, main_has_alpha, s->main_desc->comp[2].plane, s->main_desc->comp[2].offset, \ + s->main_desc->comp[2].step, is_straight, 1, jobnr, nb_jobs); \ + \ + if (main_has_alpha) \ + alpha_composite_##depth##_##nbits##bits(src, dst, src_w, src_h, dst_w, dst_h, x, y, \ + jobnr, nb_jobs); \ +} +DEFINE_BLEND_SLICE_YUV(8, 8) +DEFINE_BLEND_SLICE_YUV(16, 10) + +static av_always_inline void blend_slice_planar_rgb(AVFilterContext *ctx, + AVFrame *dst, const AVFrame *src, + int hsub, int vsub, + int main_has_alpha, + int x, int y, + int is_straight, + int jobnr, + int nb_jobs) +{ + OverlaySubsContext *s = ctx->priv; + const int src_w = src->width; + const int src_h = src->height; + const int dst_w = dst->width; + const int dst_h = dst->height; + + blend_plane_8_8bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0, 0, x, y, main_has_alpha, + s->main_desc->comp[1].plane, s->main_desc->comp[1].offset, s->main_desc->comp[1].step, is_straight, 0, + jobnr, nb_jobs); + blend_plane_8_8bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 1, hsub, vsub, x, y, main_has_alpha, + s->main_desc->comp[2].plane, s->main_desc->comp[2].offset, s->main_desc->comp[2].step, is_straight, 0, + jobnr, nb_jobs); + blend_plane_8_8bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 2, hsub, vsub, x, y, main_has_alpha, + s->main_desc->comp[0].plane, s->main_desc->comp[0].offset, s->main_desc->comp[0].step, is_straight, 0, + jobnr, nb_jobs); + + if (main_has_alpha) + alpha_composite_8_8bits(src, dst, src_w, src_h, dst_w, dst_h, x, y, jobnr, nb_jobs); +} + +static int blend_slice_yuv420(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlaySubsContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 1, 0, s->x, s->y, 1, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_yuva420(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlaySubsContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 1, 1, s->x, s->y, 1, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_yuv420p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlaySubsContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_yuv_16_10bits(ctx, td->dst, td->src, 1, 1, 0, s->x, s->y, 1, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_yuva420p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlaySubsContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_yuv_16_10bits(ctx, td->dst, td->src, 1, 1, 1, s->x, s->y, 1, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_yuv422p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlaySubsContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_yuv_16_10bits(ctx, td->dst, td->src, 1, 0, 0, s->x, s->y, 1, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_yuva422p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlaySubsContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_yuv_16_10bits(ctx, td->dst, td->src, 1, 0, 1, s->x, s->y, 1, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_yuv422(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlaySubsContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 0, 0, s->x, s->y, 1, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_yuva422(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlaySubsContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 0, 1, s->x, s->y, 1, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_yuv444(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlaySubsContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 1, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_yuva444(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlaySubsContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 1, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_gbrp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlaySubsContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_planar_rgb(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 1, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_gbrap(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlaySubsContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_planar_rgb(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 1, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_yuv420_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlaySubsContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 1, 0, s->x, s->y, 0, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_yuva420_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlaySubsContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 1, 1, s->x, s->y, 0, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_yuv422_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlaySubsContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 0, 0, s->x, s->y, 0, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_yuva422_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlaySubsContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 0, 1, s->x, s->y, 0, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_yuv444_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlaySubsContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 0, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_yuva444_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlaySubsContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 0, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_gbrp_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlaySubsContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_planar_rgb(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 0, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_gbrap_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlaySubsContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_planar_rgb(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 0, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_rgb(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlaySubsContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_packed_rgb(ctx, td->dst, td->src, 0, s->x, s->y, 1, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_rgba(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlaySubsContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_packed_rgb(ctx, td->dst, td->src, 1, s->x, s->y, 1, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_rgb_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlaySubsContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_packed_rgb(ctx, td->dst, td->src, 0, s->x, s->y, 0, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_rgba_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlaySubsContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_packed_rgb(ctx, td->dst, td->src, 1, s->x, s->y, 0, jobnr, nb_jobs); + return 0; +} + +static int config_input_main(AVFilterLink *inlink) +{ + OverlaySubsContext *s = inlink->dst->priv; + const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format); + + av_image_fill_max_pixsteps(s->main_pix_step, NULL, pix_desc); + + s->hsub = pix_desc->log2_chroma_w; + s->vsub = pix_desc->log2_chroma_h; + + s->main_desc = pix_desc; + + s->main_is_packed_rgb = + ff_fill_rgba_map(s->main_rgba_map, inlink->format) >= 0; + s->main_has_alpha = ff_fmt_is_in(inlink->format, alpha_pix_fmts); + + switch (s->format) { + case OVERLAY_FORMAT_YUV420: + s->blend_slice = s->main_has_alpha ? blend_slice_yuva420 : blend_slice_yuv420; + break; + case OVERLAY_FORMAT_YUV420P10: + s->blend_slice = s->main_has_alpha ? blend_slice_yuva420p10 : blend_slice_yuv420p10; + break; + case OVERLAY_FORMAT_YUV422: + s->blend_slice = s->main_has_alpha ? blend_slice_yuva422 : blend_slice_yuv422; + break; + case OVERLAY_FORMAT_YUV422P10: + s->blend_slice = s->main_has_alpha ? blend_slice_yuva422p10 : blend_slice_yuv422p10; + break; + case OVERLAY_FORMAT_YUV444: + s->blend_slice = s->main_has_alpha ? blend_slice_yuva444 : blend_slice_yuv444; + break; + case OVERLAY_FORMAT_RGB: + s->blend_slice = s->main_has_alpha ? blend_slice_rgba : blend_slice_rgb; + break; + case OVERLAY_FORMAT_GBRP: + s->blend_slice = s->main_has_alpha ? blend_slice_gbrap : blend_slice_gbrp; + break; + case OVERLAY_FORMAT_AUTO: + switch (inlink->format) { + case AV_PIX_FMT_YUVA420P: + s->blend_slice = blend_slice_yuva420; + break; + case AV_PIX_FMT_YUVA420P10: + s->blend_slice = blend_slice_yuva420p10; + break; + case AV_PIX_FMT_YUVA422P: + s->blend_slice = blend_slice_yuva422; + break; + case AV_PIX_FMT_YUVA422P10: + s->blend_slice = blend_slice_yuva422p10; + break; + case AV_PIX_FMT_YUVA444P: + s->blend_slice = blend_slice_yuva444; + break; + case AV_PIX_FMT_ARGB: + case AV_PIX_FMT_RGBA: + case AV_PIX_FMT_BGRA: + case AV_PIX_FMT_ABGR: + s->blend_slice = blend_slice_rgba; + break; + case AV_PIX_FMT_GBRAP: + s->blend_slice = blend_slice_gbrap; + break; + default: + av_assert0(0); + break; + } + break; + } + + if (!s->alpha_format) + goto end; + + switch (s->format) { + case OVERLAY_FORMAT_YUV420: + s->blend_slice = s->main_has_alpha ? blend_slice_yuva420_pm : blend_slice_yuv420_pm; + break; + case OVERLAY_FORMAT_YUV422: + s->blend_slice = s->main_has_alpha ? blend_slice_yuva422_pm : blend_slice_yuv422_pm; + break; + case OVERLAY_FORMAT_YUV444: + s->blend_slice = s->main_has_alpha ? blend_slice_yuva444_pm : blend_slice_yuv444_pm; + break; + case OVERLAY_FORMAT_RGB: + s->blend_slice = s->main_has_alpha ? blend_slice_rgba_pm : blend_slice_rgb_pm; + break; + case OVERLAY_FORMAT_GBRP: + s->blend_slice = s->main_has_alpha ? blend_slice_gbrap_pm : blend_slice_gbrp_pm; + break; + case OVERLAY_FORMAT_AUTO: + switch (inlink->format) { + case AV_PIX_FMT_YUVA420P: + s->blend_slice = blend_slice_yuva420_pm; + break; + case AV_PIX_FMT_YUVA422P: + s->blend_slice = blend_slice_yuva422_pm; + break; + case AV_PIX_FMT_YUVA444P: + s->blend_slice = blend_slice_yuva444_pm; + break; + case AV_PIX_FMT_ARGB: + case AV_PIX_FMT_RGBA: + case AV_PIX_FMT_BGRA: + case AV_PIX_FMT_ABGR: + s->blend_slice = blend_slice_rgba_pm; + break; + case AV_PIX_FMT_GBRAP: + s->blend_slice = blend_slice_gbrap_pm; + break; + default: + av_assert0(0); + break; + } + break; + } + +end: + if (ARCH_X86) + ff_overlay_init_x86(s, s->format, inlink->format, + s->alpha_format, s->main_has_alpha); + + return 0; +} + +static void sub2video_copy_rect(uint8_t *dst, int dst_linesize, int w, int h, + AVSubtitleRect *r) +{ + uint32_t *pal, *dst2; + uint8_t *src, *src2; + int x, y; + + // hack: + ////if (r->y > 600) + //// r->y = r->y - 300; + + if (r->type != SUBTITLE_BITMAP) { + av_log(NULL, AV_LOG_WARNING, "sub2video: non-bitmap subtitle\n"); + return; + } + if (r->x < 0 || r->x + r->w > w || r->y < 0 || r->y + r->h > h) { + av_log(NULL, AV_LOG_WARNING, "sub2video: rectangle (%d %d %d %d) overflowing %d %d\n", + r->x, r->y, r->w, r->h, w, h + ); + return; + } + + dst += r->y * dst_linesize + r->x * 4; + src = r->data[0]; + pal = (uint32_t *)r->data[1]; + for (y = 0; y < r->h; y++) { + dst2 = (uint32_t *)dst; + src2 = src; + for (x = 0; x < r->w; x++) + *(dst2++) = pal[*(src2++)]; + dst += dst_linesize; + src += r->linesize[0]; + } +} + +static int do_blend(FFFrameSync *fs) +{ + AVFilterContext *ctx = fs->parent; + AVFrame *mainpic, *second; + OverlaySubsContext *s = ctx->priv; + AVFilterLink *inlink = ctx->inputs[0]; + int ret; + + ret = ff_framesync_dualinput_get_writable(fs, &mainpic, &second); + if (ret < 0) + return ret; + if (!second) + return ff_filter_frame(ctx->outputs[0], mainpic); + + if (s->eval_mode == EVAL_MODE_FRAME) { + int64_t pos = mainpic->pkt_pos; + + s->var_values[VAR_N] = inlink->frame_count_out; + s->var_values[VAR_T] = mainpic->pts == AV_NOPTS_VALUE ? + NAN : mainpic->pts * av_q2d(inlink->time_base); + s->var_values[VAR_POS] = pos == -1 ? NAN : pos; + + s->var_values[VAR_OVERLAY_W] = s->var_values[VAR_OW] = second->width; + s->var_values[VAR_OVERLAY_H] = s->var_values[VAR_OH] = second->height; + s->var_values[VAR_MAIN_W ] = s->var_values[VAR_MW] = mainpic->width; + s->var_values[VAR_MAIN_H ] = s->var_values[VAR_MH] = mainpic->height; + + eval_expr(ctx); + av_log(ctx, AV_LOG_DEBUG, "n:%f t:%f pos:%f x:%f xi:%d y:%f yi:%d\n", + s->var_values[VAR_N], s->var_values[VAR_T], s->var_values[VAR_POS], + s->var_values[VAR_X], s->x, + s->var_values[VAR_Y], s->y); + } + + if (second->buf[0] && second->buf[0]->data) { + + AVSubtitle *sub = (AVSubtitle *)second->buf[0]->data; + uint8_t *dst; + int dst_linesize; + int num_rects, i; + + num_rects = sub->num_rects; + dst = mainpic->data[0]; + dst_linesize = mainpic->linesize[0]; + + for (i = 0; i < num_rects; i++) { + AVSubtitleRect *sub_rect = sub->rects[i]; + + sub_rect->y += s->y; + sub_rect->x += s->x; + + sub2video_copy_rect(dst, dst_linesize, mainpic->width, mainpic->height, sub_rect); + + sub_rect->y -= s->y; + sub_rect->x -= s->x; + continue; + + if (sub_rect->x < 0 || sub_rect->x + sub_rect->w > mainpic->width || sub_rect->y < 0 || sub_rect->y + sub_rect->h > mainpic->height) { + av_log(NULL, AV_LOG_WARNING, "sub2video: rectangle (%d %d %d %d) overflowing %d %d\n", + sub_rect->x, sub_rect->y, sub_rect->w, sub_rect->h, mainpic->width, mainpic->height + ); + + sub_rect->y -= s->y; + sub_rect->x -= s->x; + + continue; + } + + if (sub_rect->x < mainpic->width && sub_rect->x + sub_rect->w >= 0 && + sub_rect->y < mainpic->height && sub_rect->y + sub_rect->h >= 0) { + ThreadData td; + + td.dst = mainpic; + td.src = sub_rect; + ctx->internal->execute(ctx, s->blend_slice, &td, NULL, FFMIN(FFMAX(1, FFMIN3(sub_rect->y + sub_rect->h, FFMIN(sub_rect->h, mainpic->height), mainpic->height - sub_rect->y)), + ff_filter_get_nb_threads(ctx))); + } + + sub_rect->y -= s->y; + sub_rect->x -= s->x; + } + } + + return ff_filter_frame(ctx->outputs[0], mainpic); +} + +static av_cold int init(AVFilterContext *ctx) +{ + OverlaySubsContext *s = ctx->priv; + + s->fs.on_event = do_blend; + return 0; +} + +static int activate(AVFilterContext *ctx) +{ + OverlaySubsContext *s = ctx->priv; + return ff_framesync_activate(&s->fs); +} + +#define OFFSET(x) offsetof(OverlaySubsContext, x) +#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM + +static const AVOption overlay_subs_options[] = { + { "x", "set the x expression", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str = "0"}, 0, 0, FLAGS }, + { "y", "set the y expression", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str = "0"}, 0, 0, FLAGS }, + { "eof_action", "Action to take when encountering EOF from secondary input ", + OFFSET(fs.opt_eof_action), AV_OPT_TYPE_INT, { .i64 = EOF_ACTION_REPEAT }, + EOF_ACTION_REPEAT, EOF_ACTION_PASS, .flags = FLAGS, "eof_action" }, + { "repeat", "Repeat the previous frame.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_REPEAT }, .flags = FLAGS, "eof_action" }, + { "endall", "End both streams.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_ENDALL }, .flags = FLAGS, "eof_action" }, + { "pass", "Pass through the main input.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_PASS }, .flags = FLAGS, "eof_action" }, + { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_FRAME}, 0, EVAL_MODE_NB-1, FLAGS, "eval" }, + { "init", "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT}, .flags = FLAGS, .unit = "eval" }, + { "frame", "eval expressions per-frame", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = FLAGS, .unit = "eval" }, + { "shortest", "force termination when the shortest input terminates", OFFSET(fs.opt_shortest), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, + { "format", "set output format", OFFSET(format), AV_OPT_TYPE_INT, {.i64=OVERLAY_FORMAT_YUV420}, 0, OVERLAY_FORMAT_NB-1, FLAGS, "format" }, + { "yuv420", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV420}, .flags = FLAGS, .unit = "format" }, + { "yuv420p10", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV420P10}, .flags = FLAGS, .unit = "format" }, + { "yuv422", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV422}, .flags = FLAGS, .unit = "format" }, + { "yuv422p10", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV422P10}, .flags = FLAGS, .unit = "format" }, + { "yuv444", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV444}, .flags = FLAGS, .unit = "format" }, + { "rgb", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_RGB}, .flags = FLAGS, .unit = "format" }, + { "gbrp", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_GBRP}, .flags = FLAGS, .unit = "format" }, + { "auto", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_AUTO}, .flags = FLAGS, .unit = "format" }, + { "repeatlast", "repeat overlay of the last overlay frame", OFFSET(fs.opt_repeatlast), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS }, + { "alpha", "alpha format", OFFSET(alpha_format), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "alpha_format" }, + { "straight", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, .flags = FLAGS, .unit = "alpha_format" }, + { "premultiplied", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, .flags = FLAGS, .unit = "alpha_format" }, + { NULL } +}; + +FRAMESYNC_DEFINE_CLASS(overlay_subs, OverlaySubsContext, fs); + +static const AVFilterPad avfilter_vf_overlay_inputs[] = { + { + .name = "main", + .type = AVMEDIA_TYPE_VIDEO, + .config_props = config_input_main, + }, + { + .name = "overlay", + .type = AVMEDIA_TYPE_SUBTITLE, + .config_props = config_input_overlay, + }, + { NULL } +}; + +static const AVFilterPad avfilter_vf_overlay_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .config_props = config_output, + }, + { NULL } +}; + +const AVFilter ff_vf_overlay_subs = { + .name = "overlay_subs", + .description = NULL_IF_CONFIG_SMALL("Overlay graphical subtitles on top of the input."), + .preinit = overlay_subs_framesync_preinit, + .init = init, + .uninit = uninit, + .priv_size = sizeof(OverlaySubsContext), + .priv_class = &overlay_subs_class, + .query_formats = query_formats, + .activate = activate, + .process_command = process_command, + .inputs = avfilter_vf_overlay_inputs, + .outputs = avfilter_vf_overlay_outputs, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | + AVFILTER_FLAG_SLICE_THREADS, +}; diff --git a/libavfilter/vf_overlay_subs.h b/libavfilter/vf_overlay_subs.h new file mode 100644 index 0000000000..f3d0e0353b --- /dev/null +++ b/libavfilter/vf_overlay_subs.h @@ -0,0 +1,88 @@ +/* + * 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 AVFILTER_OVERLAY_SUBS_H +#define AVFILTER_OVERLAY_SUBS_H + +#include "libavutil/eval.h" +#include "libavutil/pixdesc.h" +#include "framesync.h" +#include "avfilter.h" + +enum var_name { + VAR_MAIN_W, VAR_MW, + VAR_MAIN_H, VAR_MH, + VAR_OVERLAY_W, VAR_OW, + VAR_OVERLAY_H, VAR_OH, + VAR_HSUB, + VAR_VSUB, + VAR_X, + VAR_Y, + VAR_N, + VAR_POS, + VAR_T, + VAR_VARS_NB +}; + +enum OverlayFormat { + OVERLAY_FORMAT_YUV420, + OVERLAY_FORMAT_YUV420P10, + OVERLAY_FORMAT_YUV422, + OVERLAY_FORMAT_YUV422P10, + OVERLAY_FORMAT_YUV444, + OVERLAY_FORMAT_RGB, + OVERLAY_FORMAT_GBRP, + OVERLAY_FORMAT_AUTO, + OVERLAY_FORMAT_NB +}; + +typedef struct OverlaySubsContext { + const AVClass *class; + int x, y; ///< position of overlaid picture + + uint8_t main_is_packed_rgb; + uint8_t main_rgba_map[4]; + uint8_t main_has_alpha; + uint8_t overlay_is_packed_rgb; + uint8_t overlay_rgba_map[4]; + uint8_t overlay_has_alpha; + int format; ///< OverlayFormat + int alpha_format; + int eval_mode; ///< EvalMode + + FFFrameSync fs; + + int main_pix_step[4]; ///< steps per pixel for each plane of the main output + int overlay_pix_step[4]; ///< steps per pixel for each plane of the overlay + int hsub, vsub; ///< chroma subsampling values + const AVPixFmtDescriptor *main_desc; ///< format descriptor for main input + + double var_values[VAR_VARS_NB]; + char *x_expr, *y_expr; + + AVExpr *x_pexpr, *y_pexpr; + + int (*blend_row[4])(uint8_t *d, uint8_t *da, uint8_t *s, uint8_t *a, int w, + ptrdiff_t alinesize); + int (*blend_slice)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs); +} OverlaySubsContext; + +void ff_overlay_init_x86(OverlaySubsContext *s, int format, int pix_format, + int alpha_format, int main_has_alpha); + +#endif /* AVFILTER_OVERLAY_SUBS_H */ From patchwork Thu Aug 19 07:43:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Soft Works X-Patchwork-Id: 29603 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6602:2a4a:0:0:0:0 with SMTP id k10csp64623iov; Thu, 19 Aug 2021 00:44:11 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxyjTEofVpbvjOehrMRYuSwWlxRDlUfWrxe+F+t+ofzSWCBg2xl/fshCaz4SSuijAmqhYql X-Received: by 2002:a17:906:87d0:: with SMTP id zb16mr14668651ejb.143.1629359051818; Thu, 19 Aug 2021 00:44:11 -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 j24si2455414edp.316.2021.08.19.00.44.11; Thu, 19 Aug 2021 00:44:11 -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=gDVo9Exl; 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 864F668A3E8; Thu, 19 Aug 2021 10:43:35 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from NAM11-DM6-obe.outbound.protection.outlook.com (mail-dm6nam11olkn2099.outbound.protection.outlook.com [40.92.19.99]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 4655F68A134 for ; Thu, 19 Aug 2021 10:43:32 +0300 (EEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=MEIe/F4tN7YIaXXs4wB5oug35wKMm1J2PZB4WJaewbGEd0r8ySRr5jRCPlUWFsQUfH5VXwP67uraYPSNLyDXx09T0E41oRVW2TaHsRhf8lQlAAJLHV5CvO/GkJdplLtwz+J9M4co5aDtfvvapvxaeT63LVxSz/tYlCidne9fCOEP+ZuOsRP0V3BDR45yvHGOVv8Ew/8GTLrAHjssZko0MCbhkeKP5BtbbF1kvQUUz/S3Hqc0rOSEth5tPjLdy/UVCWrAW1l7xuQ0frpiH/+IPDXqw4PsdW/qeff7DeO4uSMSwjc55Fr6+AHv5859rMrFjfyVz5RjDlZUrM1qqsbhGQ== 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:X-MS-Exchange-SenderADCheck; bh=p7o7qQaou596UfzFoL/6IBpzMvjcuDhL+IoQnt0LfmM=; b=GKWAsiKsMHRR8wJTMXIBJ7CVRt4Bir+X5cXeqRkhMTdzMEaWNoApN3E+zMqk3RBrd42rMgaFAFyG3puVfJPIPvV3Yof7s1IDWlDW9/MGP6bQblcvupZ/rp/9cmpr2tsv+YvD6Jp4hrMJCkKQ9IIm3tB6LhYDej7NRclNndwcemmIPisAkE8UQb3RUq1Q7TmQRAllP/hieJv3e0z2CfgmHMQfOSUpRX3m9zcYYgOrYShzz5mskKnFtbFre8nn6viC7dlQFm7LSi/uP1ttriD5dF4lJKeI7RJrA2AnpetFQJ/V2OxGBYSUYVGffd4YotCqqMFpxq+nhBS5G8m0HdZWpQ== 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=p7o7qQaou596UfzFoL/6IBpzMvjcuDhL+IoQnt0LfmM=; b=gDVo9Exld0wBynR1UFXrEHXly36Mjkr6U/bxxV/EOAZMZGzZRVfJvXA2WZJeQ78VJoAqmM2Bymzt6sK3+ilYhyHchYSM0TzyAcD7F+DRI87rx6+HQtBP0x0ZX1vgbWVQPTWgwidiSuS+OgCxmf9YI7lNNyy7goRhcnOyzSI2DDIlzfVFQaa3XCal48zW3eBa9uvp65Tdax16WWHnGtXuiP3zSym5XeFM2X5NqDCM3oM/jew/t24v0PjeVc6lWuM7YPCIJOzMFGH3znahw1Nb1oYk5Y5NJwE6O40H72HBfDRhYH53YtzHtXaNAbmDdh5LFUwQxfYw3m8LSupZ28/Ixg== Received: from MN2PR04MB5981.namprd04.prod.outlook.com (2603:10b6:208:da::10) by MN2PR04MB6255.namprd04.prod.outlook.com (2603:10b6:208:d5::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4415.22; Thu, 19 Aug 2021 07:43:22 +0000 Received: from MN2PR04MB5981.namprd04.prod.outlook.com ([fe80::5d83:1c26:c2b1:3a30]) by MN2PR04MB5981.namprd04.prod.outlook.com ([fe80::5d83:1c26:c2b1:3a30%6]) with mapi id 15.20.4415.024; Thu, 19 Aug 2021 07:43:22 +0000 From: Soft Works To: "ffmpeg-devel@ffmpeg.org" Thread-Topic: [PATCH 5/9] avfilter/sub2video: Add sub2video filter Thread-Index: AdeUd97Cd6dyxG8DT0WgDBENch+JsA== Date: Thu, 19 Aug 2021 07:43:22 +0000 Message-ID: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-messagesentrepresentingtype: 1 x-tmn: [VC7RmsEuKB8TFl7JLAncDo16kOSk/Eff] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 43e51aa5-abbc-4f90-bfa3-08d962e50532 x-ms-traffictypediagnostic: MN2PR04MB6255: x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: XcQh9TCvl6meU3yH4drLZbzX3cCWVO1vmuc3Hj7vn1kou2ErEUEbBjbty7LHiXn7CyNVf+0v5ex2grbPvsRRF7/IVVczWTJEqY1it3DqH+CmWtU93WVJCs91CeqJFoRUXPMvjUzXBMZiWv8AwUGhxR6OdCmC9mSVdC9TST9Zv737yNOpjnC0kokTZew+P2toQay4aBG5v2rmr8Arq2GrSlpcjJ2YkDH4ctVU/CvklH+uSXW1SeFyCBzqTR7CrtTmdBDuGnl3WAhFAJbJSA3L+U/uvm4KqDAUOsKjYh4hJhOaB4kowfsliNpde3JrcCWyzE+3jT8Mj4gj+pLghvegzvkk4gm5p04Jof++r8E77M4zYIswBh9WOOPNsCBMi81ThEJdwsnyVsNtpNBmD0KZKd7kFIfHEZxFf2h2C9aWOAklsrVxMiIlNEc5UKRr9bJH x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: u2I84fSc6WkU/tqO41zWDX4wBCxhsyhcUHApWN2snxGWKf5m740Q9qrjJoIAeWMRABrd2gzRm/7Ndt1QWQHX23ZQdq0ZH/e8bz1B9yX8z63P8zEDiPuCdfBs3tiXZ91c/HHFMj744rzkZrDc9dW/qw== 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: 43e51aa5-abbc-4f90-bfa3-08d962e50532 X-MS-Exchange-CrossTenant-originalarrivaltime: 19 Aug 2021 07:43:22.2601 (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: MN2PR04MB6255 Subject: [FFmpeg-devel] [PATCH 5/9] avfilter/sub2video: Add sub2video filter 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: e++ytyXkPC4k Signed-off-by: softworkz --- libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/svf_sub2video.c | 260 ++++++++++++++++++++++++++++++++++++ 3 files changed, 262 insertions(+) create mode 100644 libavfilter/svf_sub2video.c diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 68a7f5cb88..5f63ec0123 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -542,6 +542,7 @@ OBJS-$(CONFIG_SHOWSPECTRUMPIC_FILTER) += avf_showspectrum.o OBJS-$(CONFIG_SHOWVOLUME_FILTER) += avf_showvolume.o OBJS-$(CONFIG_SHOWWAVES_FILTER) += avf_showwaves.o OBJS-$(CONFIG_SHOWWAVESPIC_FILTER) += avf_showwaves.o +OBJS-$(CONFIG_SUB2VIDEO_FILTER) += svf_sub2video.o OBJS-$(CONFIG_SPECTRUMSYNTH_FILTER) += vaf_spectrumsynth.o # multimedia sources diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index abd0a47750..5b631b3617 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -518,6 +518,7 @@ extern const AVFilter ff_avf_showvolume; extern const AVFilter ff_avf_showwaves; extern const AVFilter ff_avf_showwavespic; extern const AVFilter ff_vaf_spectrumsynth; +extern const AVFilter ff_svf_sub2video; /* multimedia sources */ extern const AVFilter ff_avsrc_amovie; diff --git a/libavfilter/svf_sub2video.c b/libavfilter/svf_sub2video.c new file mode 100644 index 0000000000..689c2a565c --- /dev/null +++ b/libavfilter/svf_sub2video.c @@ -0,0 +1,260 @@ +/* + * 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 + */ + +/** + * @file + * graphical subtitles to video conversion, based on previous sub2video + * implementation. + */ + +#include + +#include "libavutil/audio_fifo.h" +#include "libavutil/avassert.h" +#include "libavutil/avstring.h" +#include "libavutil/channel_layout.h" +#include "libavutil/opt.h" +#include "libavutil/parseutils.h" +#include "libavutil/xga_font_data.h" +#include "avfilter.h" +#include "blend.h" +#include "filters.h" +#include "internal.h" +#include "libavcodec/avcodec.h" +typedef struct Sub2VideoContext { + const AVClass *class; + int w, h; + AVFrame *outpicref; + int pixstep; +} Sub2VideoContext; + +#define OFFSET(x) offsetof(Sub2VideoContext, x) +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM + +////static int alloc_out_frame(Sub2VideoContext *s2v_ctx, const int16_t *p, +//// const AVFilterLink *inlink, AVFilterLink *outlink, +//// const AVFrame *in) +////{ +//// if (!s2v_ctx->outpicref) { +//// int j; +//// AVFrame *out = s2v_ctx->outpicref = +//// ff_get_video_buffer(outlink, outlink->w, outlink->h); +//// if (!out) +//// return AVERROR(ENOMEM); +//// out->width = outlink->w; +//// out->height = outlink->h; +//// out->pts = in->pts + av_rescale_q((p - (int16_t *)in->data[0]) / inlink->channels, +//// av_make_q(1, inlink->sample_rate), +//// outlink->time_base); +//// for (j = 0; j < outlink->h; j++) +//// memset(out->data[0] + j*out->linesize[0], 0, outlink->w * s2v_ctx->pixstep); +//// } +//// return 0; +////} + + +static const AVOption sub2video_options[] = { + { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "640x512"}, 0, 0, FLAGS }, + { "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "640x512"}, 0, 0, FLAGS }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(sub2video); + +static int query_formats(AVFilterContext *ctx) +{ + AVFilterFormats *formats = NULL; + AVFilterLink *inlink = ctx->inputs[0]; + AVFilterLink *outlink = ctx->outputs[0]; + static const enum AVSubtitleType subtitle_fmts[] = { SUBTITLE_BITMAP, SUBTITLE_NONE }; + static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE }; + int ret; + + /* set input subtitle format */ + formats = ff_make_format_list(subtitle_fmts); + if ((ret = ff_formats_ref(formats, &inlink->outcfg.formats)) < 0) + return ret; + + /* set output video format */ + formats = ff_make_format_list(pix_fmts); + if ((ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0) + return ret; + + return 0; +} + +static int config_input(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + Sub2VideoContext *s = ctx->priv; + + s->w = 1920; // inlink->w; + s->h = 1080; // inlink->h; + return 0; +} + +static int config_output(AVFilterLink *outlink) +{ + Sub2VideoContext *s = outlink->src->priv; + float overlap; + + outlink->w = s->w; + outlink->h = s->h; + outlink->sample_aspect_ratio = (AVRational){1,1}; + + return 0; +} + +static void sub2video_copy_rect(uint8_t *dst, int dst_linesize, int w, int h, + AVSubtitleRect *r) +{ + uint32_t *pal, *dst2; + uint8_t *src, *src2; + int x, y; + + if (r->type != SUBTITLE_BITMAP) { + av_log(NULL, AV_LOG_WARNING, "sub2video: non-bitmap subtitle\n"); + return; + } + if (r->x < 0 || r->x + r->w > w || r->y < 0 || r->y + r->h > h) { + av_log(NULL, AV_LOG_WARNING, "sub2video: rectangle (%d %d %d %d) overflowing %d %d\n", + r->x, r->y, r->w, r->h, w, h + ); + return; + } + + dst += r->y * dst_linesize + r->x * 4; + src = r->data[0]; + pal = (uint32_t *)r->data[1]; + for (y = 0; y < r->h; y++) { + dst2 = (uint32_t *)dst; + src2 = src; + for (x = 0; x < r->w; x++) + *(dst2++) = pal[*(src2++)]; + dst += dst_linesize; + src += r->linesize[0]; + } +} + +static int filter_frame(AVFilterLink *inlink, AVFrame *src_frame) +{ + Sub2VideoContext *s = inlink->dst->priv; + AVFilterLink *outlink = inlink->dst->outputs[0]; + AVSubtitle *sub; + int ret; + int dst_linesize; + AVFrame *out; + unsigned int num_rects, i; + uint8_t *dst; + + outlink->w = 1920; + outlink->h = 1080; + + out = av_frame_alloc(); + if (!out) { + av_frame_free(&src_frame); + return AVERROR(ENOMEM); + } + + out->width = outlink->w; + out->height = outlink->h; + out->format = AV_PIX_FMT_RGB32; + + if ((ret = av_frame_get_buffer(out, 0)) < 0) + return ret; + + memset(out->data[0], 0, out->height * out->linesize[0]); + + ////out = ff_get_video_buffer(outlink, outlink->w, outlink->h); + ////if (!out) { + //// av_frame_free(&src_frame); + //// return AVERROR(ENOMEM); + ////} + ////memset(out->data[0], 0, out->linesize[0] * out->height ); + + out->pts = src_frame->pts; + out->repeat_pict = src_frame->repeat_pict; + out->pkt_dts = src_frame->pkt_dts; + out->pkt_pos = src_frame->pkt_pos; + out->pkt_size = src_frame->pkt_size; + out->pkt_duration = src_frame->pkt_duration; + out->reordered_opaque = src_frame->reordered_opaque; + out->best_effort_timestamp = src_frame->best_effort_timestamp; + out->flags = src_frame->flags; + + sub = (AVSubtitle *)src_frame->data[0]; + + if (sub) { + num_rects = sub->num_rects; + dst = out->data [0]; + dst_linesize = out->linesize[0]; + for (i = 0; i < num_rects; i++) + sub2video_copy_rect(dst, dst_linesize, out->width, out->height, sub->rects[i]); + } + + av_frame_free(&src_frame); + return ff_filter_frame(outlink, out); +} + +////static int activate(AVFilterContext *ctx) +////{ +//// AVFilterLink *inlink = ctx->inputs[0]; +//// AVFilterLink *outlink = ctx->outputs[0]; +//// Sub2VideoContext *s = ctx->priv; +//// +//// do { +//// int ret = ff_outlink_get_status(outlink); +//// if (ret) { +//// ff_inlink_set_status(inlink, ret); +//// return 0; +//// } +//// } while (0); +//// +//// return FFERROR_NOT_READY; +////} + +static const AVFilterPad sub2video_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_SUBTITLE, + .filter_frame = filter_frame, + .config_props = config_input, + }, + { NULL } +}; + +static const AVFilterPad sub2video_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .config_props = config_output, + }, + { NULL } +}; + +AVFilter ff_svf_sub2video = { + .name = "sub2video", + .description = NULL_IF_CONFIG_SMALL("Convert graphical subtitles to video"), + .query_formats = query_formats, + .priv_size = sizeof(Sub2VideoContext), + .priv_class = &sub2video_class, + .inputs = sub2video_inputs, + .outputs = sub2video_outputs, +}; From patchwork Thu Aug 19 07:43:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Soft Works X-Patchwork-Id: 29607 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6602:2a4a:0:0:0:0 with SMTP id k10csp64736iov; Thu, 19 Aug 2021 00:44:22 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyyG5vWmmJ64QHOepFWFOWQroJUc6Tn/TyqkmAPvWFDYWruDRki1cJx0WGQQcXjzOJETVRi X-Received: by 2002:a05:6402:3193:: with SMTP id di19mr15015223edb.183.1629359062213; Thu, 19 Aug 2021 00:44:22 -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 h20si2411471edw.295.2021.08.19.00.44.21; Thu, 19 Aug 2021 00:44:22 -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=dnEn4U+g; 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 5A35668A408; Thu, 19 Aug 2021 10:43:36 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from NAM11-DM6-obe.outbound.protection.outlook.com (mail-dm6nam11olkn2099.outbound.protection.outlook.com [40.92.19.99]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 9C94268A134 for ; Thu, 19 Aug 2021 10:43:32 +0300 (EEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Ou1Q/6X3Ib6pUPO7ghHCUFukckHD2NBcHgT7V8tito99w03h8bnkCHUA9dzpflgVEegzpEyyBbNiT+bVZxQWWuxjCEFWfXxvSBBvp3Cxbwnw/+POeGc0svWz2rhBbEkQ1ErUyFt/SELcPUUCZs0cBgjGowx3E1PB4klUFB/n12LT+TJ1VmeZeY8AlQWZ10zpE6ChOdiN2JhxkoZ1mTL54ZjmEFeAjvO3tMo4lstXcIgYHD0xWYbuS1Skl804zmDp568TlEC1/yUbp2buJ8nje45eda81qLUEt5u99xx7CwI38orkSylcPRcplvsr7EEYWsnIpAbYq7asPBLkPmbq4Q== 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:X-MS-Exchange-SenderADCheck; bh=gfs/FR4G/eyIbOvxJfWy7dy9ZHpQOsRBAV9DHMzqrlM=; b=HeyyAyEynCr2b4IyeEH362A8RE1y8P3CHGfgICogax4GMfib5YIsLx5Vxqn7Z31VqleUnZfB+6bNDBNfZQl+tiR4qrFbouBvGqkh6dTNuI5VbVjmdIO7uIzJUELpAp8LaIlJ4u6iT7qsPrsZpg5tLCi/+OHsfglBc85GEri7h7GavL9FIH+647uzg5dRJLM2bGVhXzxlB0pnL3cTnBaoc83kb1eZjes7RumIYwKWkelMUDl2dkWejiQmuh2IRdh7z/QvPJwls1dhdhz7UyZTyCf5qONxMsXOtkhLj+m5YKyWOzybMFUKqPEN2lNiE1QUp+Cj8nPh97JWz/dj94xx4g== 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=gfs/FR4G/eyIbOvxJfWy7dy9ZHpQOsRBAV9DHMzqrlM=; b=dnEn4U+gYv6JKiYwTFSlvK/HfZSQ78xjTllLeR6flEawxJuaC0xsCO34qXQvOcrNL007ZCtW4r6uh2skgWs+Ibd9nwwGbsMYghgjgF+WJWxTgoqi2Q57972WVzoaLkUd+3fkhCIoZXL707ygBQV7bQCHLXSoWhOWbnevfg7F+5Hm4N15i2ahTsSzp/25u1h9NA3jM+rVCY2OqeOFIw/tZbbsnlweXP3332mQ5maJJzOHDC7RNwemWVIDFCc8bUjtL0wuAHPw4L6s+6ue/pG0MJ7AB7YDgRcgZ1hAwjteRDgw1b6EwASOiPUJf3c8lq9vRfGuaTNvYyiWTNyKzX4Mug== Received: from MN2PR04MB5981.namprd04.prod.outlook.com (2603:10b6:208:da::10) by MN2PR04MB6255.namprd04.prod.outlook.com (2603:10b6:208:d5::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4415.22; Thu, 19 Aug 2021 07:43:25 +0000 Received: from MN2PR04MB5981.namprd04.prod.outlook.com ([fe80::5d83:1c26:c2b1:3a30]) by MN2PR04MB5981.namprd04.prod.outlook.com ([fe80::5d83:1c26:c2b1:3a30%6]) with mapi id 15.20.4415.024; Thu, 19 Aug 2021 07:43:25 +0000 From: Soft Works To: "ffmpeg-devel@ffmpeg.org" Thread-Topic: [PATCH 6/9] avfilter/sbuffer: Add sbuffersrv and sbuffersink filters Thread-Index: AdeUpHY9z/WEsBfGRySjwSpB6GG1ng== Date: Thu, 19 Aug 2021 07:43:25 +0000 Message-ID: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-messagesentrepresentingtype: 1 x-tmn: [fjEflTM1V07q1XdlhSjPr+jBlOv96K44] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 85ac0039-fc6b-4c9a-11ca-08d962e50734 x-ms-traffictypediagnostic: MN2PR04MB6255: x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: 2ZSiqqMI+IUvV/Q1wOrGvMdCejvuM9OzBIU8+mknWxu5WLjRJmuTGQpzeo3sxf1q7zDHlHogpDgeudJKBGtLcnbKvxXu1VRx2goCDRMPbWZ/MhjgD+Obwb51jZthpmYozNWxxbvh0Fm9hNCWgINfax7GKzxSj6kcfAcREmv4oxiVpxnO/wHaBQNAz8+2XQdQN5FXKBuPRigWAuTqFrEn/krYFrMbBuis+LxaZ65H/lrPnFly+KM8+hYoMwx7qwGakgUWh9IMBcFaH+TXXVTu8AeK+UWCzMN9AOMuWMvl1xnH9VYsgheXPgYulEBI/xQyUCqWWYtd4QC0ufnpClqpSbC0yoG5eWe9KHwzgjeD5Hv9c03+LwqngUE4+3FGskew3KNvswyh67ImgXlDGCnV/7pjWSFMEzlywo2gsFDDmZpzraS44/nwNlv0pGCsSoPv x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: Xn3/GhNH4qfbGikZvzOTp9oV5IUX+n2FZ1dPKpa72/+cIw0ykLkX4+74aS2TGhmbWgY7UW3eC/uuSV6/Yd+3YHTdQeEzVU0hTD417VI78fOa2w/oH3skj7sFesrT19YqnI3mcPJU8nQnbK3jxEhseA== 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: 85ac0039-fc6b-4c9a-11ca-08d962e50734 X-MS-Exchange-CrossTenant-originalarrivaltime: 19 Aug 2021 07:43:25.6352 (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: MN2PR04MB6255 Subject: [FFmpeg-devel] [PATCH 6/9] avfilter/sbuffer: Add sbuffersrv and sbuffersink filters 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: mkx4dozoG1wK Signed-off-by: softworkz --- configure | 2 +- libavfilter/allfilters.c | 10 ++++--- libavfilter/buffersink.c | 65 ++++++++++++++++++++++++++++++++++++++++ libavfilter/buffersink.h | 15 ++++++++++ libavfilter/buffersrc.c | 65 ++++++++++++++++++++++++++++++++++++++++ libavfilter/buffersrc.h | 1 + 6 files changed, 153 insertions(+), 5 deletions(-) diff --git a/configure b/configure index 9249254b70..fdb3bf1714 100755 --- a/configure +++ b/configure @@ -7715,7 +7715,7 @@ print_enabled_components(){ fi done if [ "$name" = "filter_list" ]; then - for c in asrc_abuffer vsrc_buffer asink_abuffer vsink_buffer; do + for c in asrc_abuffer vsrc_buffer ssrc_sbuffer asink_abuffer vsink_buffer ssink_sbuffer; do printf " &ff_%s,\n" $c >> $TMPH done fi diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 5b631b3617..5bd54db2c8 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -528,10 +528,12 @@ extern const AVFilter ff_avsrc_movie; * they are formatted to not be found by the grep * as they are manually added again (due to their 'names' * being the same while having different 'types'). */ -extern const AVFilter ff_asrc_abuffer; -extern const AVFilter ff_vsrc_buffer; -extern const AVFilter ff_asink_abuffer; -extern const AVFilter ff_vsink_buffer; +extern const AVFilter ff_asrc_abuffer; +extern const AVFilter ff_vsrc_buffer; +extern const AVFilter ff_ssrc_sbuffer; +extern const AVFilter ff_asink_abuffer; +extern const AVFilter ff_vsink_buffer; +extern const AVFilter ff_ssink_sbuffer; extern const AVFilter ff_af_afifo; extern const AVFilter ff_vf_fifo; diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c index 07c4812f29..20845eb10f 100644 --- a/libavfilter/buffersink.c +++ b/libavfilter/buffersink.c @@ -57,6 +57,10 @@ typedef struct BufferSinkContext { int *sample_rates; ///< list of accepted sample rates, terminated by -1 int sample_rates_size; + /* only used for subtitles */ + enum AVSubtitleType *subtitle_types; ///< list of accepted subtitle types, must be terminated with -1 + int subtitle_types_size; + AVFrame *peeked_frame; } BufferSinkContext; @@ -168,6 +172,15 @@ AVABufferSinkParams *av_abuffersink_params_alloc(void) return NULL; return params; } + +AVSBufferSinkParams *av_sbuffersink_params_alloc(void) +{ + AVSBufferSinkParams *params = av_mallocz(sizeof(AVSBufferSinkParams)); + + if (!params) + return NULL; + return params; +} #endif static av_cold int common_init(AVFilterContext *ctx) @@ -305,6 +318,31 @@ static int asink_query_formats(AVFilterContext *ctx) return 0; } +static int ssink_query_formats(AVFilterContext *ctx) +{ + BufferSinkContext *buf = ctx->priv; + AVFilterFormats *formats = NULL; + unsigned i; + int ret; + + if ((ret = ff_default_query_formats(ctx)) < 0) + return ret; + + ////CHECK_LIST_SIZE(pixel_fmts) + ////if (buf->pixel_fmts_size) { + //// for (i = 0; i < NB_ITEMS(buf->pixel_fmts); i++) + //// if ((ret = ff_add_format(&formats, buf->pixel_fmts[i])) < 0) + //// return ret; + //// if ((ret = ff_set_common_formats(ctx, formats)) < 0) + //// return ret; + ////} else { + //// if ((ret = ff_default_query_formats(ctx)) < 0) + //// return ret; + ////} + + return 0; +} + #define OFFSET(x) offsetof(BufferSinkContext, x) #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM static const AVOption buffersink_options[] = { @@ -322,9 +360,16 @@ static const AVOption abuffersink_options[] = { { NULL }, }; #undef FLAGS +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_SUBTITLE_PARAM +static const AVOption sbuffersink_options[] = { + { "subtitle_types", "set the supported subtitle formats", OFFSET(subtitle_types), AV_OPT_TYPE_BINARY, .flags = FLAGS }, + { NULL }, +}; +#undef FLAGS AVFILTER_DEFINE_CLASS(buffersink); AVFILTER_DEFINE_CLASS(abuffersink); +AVFILTER_DEFINE_CLASS(sbuffersink); static const AVFilterPad avfilter_vsink_buffer_inputs[] = { { @@ -365,3 +410,23 @@ const AVFilter ff_asink_abuffer = { .inputs = avfilter_asink_abuffer_inputs, .outputs = NULL, }; + +static const AVFilterPad avfilter_ssink_sbuffer_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_SUBTITLE, + }, + { NULL } +}; + +AVFilter ff_ssink_sbuffer = { + .name = "sbuffersink", + .description = NULL_IF_CONFIG_SMALL("Buffer subtitle frames, and make them available to the end of the filter graph."), + .priv_class = &sbuffersink_class, + .priv_size = sizeof(BufferSinkContext), + .init = common_init, + .query_formats = ssink_query_formats, + .activate = activate, + .inputs = avfilter_ssink_sbuffer_inputs, + .outputs = NULL, +}; diff --git a/libavfilter/buffersink.h b/libavfilter/buffersink.h index 69ed0f29a8..b439b586c5 100644 --- a/libavfilter/buffersink.h +++ b/libavfilter/buffersink.h @@ -129,6 +129,21 @@ typedef struct AVABufferSinkParams { */ attribute_deprecated AVABufferSinkParams *av_abuffersink_params_alloc(void); + +/** + * Deprecated and unused struct to use for initializing an sbuffersink context. + */ +typedef struct AVSBufferSinkParams { + const int *subtitle_type; +} AVSBufferSinkParams; + +/** + * Create an AVSBufferSinkParams structure. + * + * Must be freed with av_free(). + */ +attribute_deprecated +AVSBufferSinkParams *av_sbuffersink_params_alloc(void); #endif /** diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c index 4d0bb4f91d..eeef3e2390 100644 --- a/libavfilter/buffersrc.c +++ b/libavfilter/buffersrc.c @@ -39,6 +39,7 @@ #include "formats.h" #include "internal.h" #include "video.h" +#include "libavcodec/avcodec.h" typedef struct BufferSourceContext { const AVClass *class; @@ -63,6 +64,9 @@ typedef struct BufferSourceContext { uint64_t channel_layout; char *channel_layout_str; + /* subtitle only */ + enum AVSubtitleType subtitle_type; + int eof; } BufferSourceContext; @@ -130,6 +134,9 @@ int av_buffersrc_parameters_set(AVFilterContext *ctx, AVBufferSrcParameters *par if (param->channel_layout) s->channel_layout = param->channel_layout; break; + case AVMEDIA_TYPE_SUBTITLE: + s->subtitle_type = param->format; + break; default: return AVERROR_BUG; } @@ -197,6 +204,8 @@ int attribute_align_arg av_buffersrc_add_frame_flags(AVFilterContext *ctx, AVFra CHECK_AUDIO_PARAM_CHANGE(ctx, s, frame->sample_rate, frame->channel_layout, frame->channels, frame->format, frame->pts); break; + case AVMEDIA_TYPE_SUBTITLE: + break; default: return AVERROR(EINVAL); } @@ -269,6 +278,7 @@ unsigned av_buffersrc_get_nb_failed_requests(AVFilterContext *buffer_src) #define OFFSET(x) offsetof(BufferSourceContext, x) #define A AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_AUDIO_PARAM #define V AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM +#define S AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_SUBTITLE_PARAM static const AVOption buffer_options[] = { { "width", NULL, OFFSET(w), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, V }, @@ -298,6 +308,14 @@ static const AVOption abuffer_options[] = { AVFILTER_DEFINE_CLASS(abuffer); +static const AVOption sbuffer_options[] = { + { "time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, INT_MAX, S }, + { "subtitle_type", NULL, OFFSET(subtitle_type), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, S }, + { NULL }, +}; + +AVFILTER_DEFINE_CLASS(sbuffer); + static av_cold int init_audio(AVFilterContext *ctx) { BufferSourceContext *s = ctx->priv; @@ -347,6 +365,21 @@ static av_cold int init_audio(AVFilterContext *ctx) return ret; } +static av_cold int init_subtitle(AVFilterContext *ctx) +{ + BufferSourceContext *c = ctx->priv; + + if (c->subtitle_type == SUBTITLE_BITMAP) + av_log(ctx, AV_LOG_VERBOSE, "graphical subtitles - w:%d h:%d tb:%d/%d\n", + c->w, c->h, c->time_base.num, c->time_base.den); + else + av_log(ctx, AV_LOG_VERBOSE, "text subtitles - tb:%d/%d\n", + c->time_base.num, c->time_base.den); + + return 0; +} + + static av_cold void uninit(AVFilterContext *ctx) { BufferSourceContext *s = ctx->priv; @@ -381,6 +414,11 @@ static int query_formats(AVFilterContext *ctx) if ((ret = ff_set_common_channel_layouts(ctx, channel_layouts)) < 0) return ret; break; + case AVMEDIA_TYPE_SUBTITLE: + if ((ret = ff_add_format (&formats, c->subtitle_type)) < 0 || + (ret = ff_set_common_formats (ctx , formats )) < 0) + return ret; + break; default: return AVERROR(EINVAL); } @@ -408,6 +446,9 @@ static int config_props(AVFilterLink *link) if (!c->channel_layout) c->channel_layout = link->channel_layout; break; + case AVMEDIA_TYPE_SUBTITLE: + link->format = c->subtitle_type; + break; default: return AVERROR(EINVAL); } @@ -474,3 +515,27 @@ const AVFilter ff_asrc_abuffer = { .outputs = avfilter_asrc_abuffer_outputs, .priv_class = &abuffer_class, }; + +static const AVFilterPad avfilter_ssrc_sbuffer_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_SUBTITLE, + .request_frame = request_frame, + .config_props = config_props, + }, + { NULL } +}; + +const AVFilter ff_ssrc_sbuffer = { + .name = "sbuffer", + .description = NULL_IF_CONFIG_SMALL("Buffer subtitle frames, and make them accessible to the filterchain."), + .priv_size = sizeof(BufferSourceContext), + .query_formats = query_formats, + + .init = init_subtitle, + .uninit = uninit, + + .inputs = NULL, + .outputs = avfilter_ssrc_sbuffer_outputs, + .priv_class = &sbuffer_class, +}; diff --git a/libavfilter/buffersrc.h b/libavfilter/buffersrc.h index 08fbd18a47..929a2fa249 100644 --- a/libavfilter/buffersrc.h +++ b/libavfilter/buffersrc.h @@ -74,6 +74,7 @@ typedef struct AVBufferSrcParameters { /** * video: the pixel format, value corresponds to enum AVPixelFormat * audio: the sample format, value corresponds to enum AVSampleFormat + * subtitles: the subtitle format, value corresponds to enum AVSubtitleType */ int format; /** From patchwork Thu Aug 19 07:43:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Soft Works X-Patchwork-Id: 29610 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6602:2a4a:0:0:0:0 with SMTP id k10csp64971iov; Thu, 19 Aug 2021 00:44:33 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxqFK7EM3Pbg1taAbpTDtpuWs8YClh2NE6Jf3ksvga6C7exKAJJqrJd5vdi0AFgF4VIo1Vw X-Received: by 2002:a17:907:7291:: with SMTP id dt17mr14646689ejc.162.1629359073211; Thu, 19 Aug 2021 00:44:33 -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 p26si2767053edu.78.2021.08.19.00.44.32; Thu, 19 Aug 2021 00:44:33 -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=J8X002up; 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 1C36068A1EF; Thu, 19 Aug 2021 10:43:38 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from NAM11-DM6-obe.outbound.protection.outlook.com (mail-dm6nam11olkn2099.outbound.protection.outlook.com [40.92.19.99]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id F282468A2B9 for ; Thu, 19 Aug 2021 10:43:32 +0300 (EEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=JX1sosEjg8679eztM97otoNSPM0Si0K3rMtcudh7w8vBrhcegIdWYyAyiQc3ROaxALl4F5wnNs1sa/f/znE2cp9CHIy393BGr1X1zFbKgm6ebW2RMK6AxaraMFoYkN/5RhH//qOyrIjNQH9TsxF2Do/r/KC+jyZjR/h1h5X82SgGqhYMO9jCLe5+s0RKKWsT9DukZTYKj8e7n+gTZcDDo3DeQpxIWKJDHliE6doD2kINr6/2wJNxdpQe+5xuzok7ocxPdM9JJZ76ybMP+HjoJ0W4XmmBw/P9gLn4C905uh+Ar0FbIDVpXW0NaqcwKHAbKJ0oTzOcugGiHESqpntXtQ== 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:X-MS-Exchange-SenderADCheck; bh=m9cFQF3DyshM2NlNiXkO9uLCnE9BIHlC36nWiD4RcG8=; b=H13UalhukSoX5M3t7EZ4uhqGokwe/i8FfbQ/lJ8qw1UlOQxfDNsFPU4HLpuEE1ddaewhkhBOWWOegcpqYuymsUiFXJ+cBku2rYUcYU8m15Cf8ApxDnLbFFS7zfZ2LcOovhClOxfEehHMTLL5X2wxC91KA+N7tVHkpc3hzREnVf1XUj53ridk4XmKGZ7d4TeDnyM+npZ+/rz3l/+DST8SNw69vwuAIpgKQ3N/f6LSJEfGbwk6K3uAbS9IW5bGY7S+V7ZXoZKlXAyu+jtg0QXYpzI0pq5svBeUd2KTfWDZCeQyhtQZIfjI2sgwewjUO+pv4hAAIRzmbzbiW9kB8KDcjA== 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=m9cFQF3DyshM2NlNiXkO9uLCnE9BIHlC36nWiD4RcG8=; b=J8X002up8vkuEWM3ccd6wW6EanJ8UIqfP7XbSm2glurpjLiXrkjPs0N6G77Lzv8pbWr2ljSiuWyRD29dVYbRUqcoaFrAm6j02aTqVE3mVTw2nVhkdOtSiiCTX3WlWmxmOBLYDU2H1OsHCmDpc5jZscr58e8+IO6fbtMJZZfw7QvEBswBj+t9mw/tXNKak1eCRAljpwxwAyBUmA9OidqRDlVZkARJMNTP+bfH3r5FwzNTSP0/q4SIAWthmoK7IZxzAqYoQOGAO5VGtGmoc9DLv6VYLWSTsfyNl5p0KgU0s8r4VpZjowPk0ytspefoiH5aYWL7uHkrfcMI5SBMyZjLHA== Received: from MN2PR04MB5981.namprd04.prod.outlook.com (2603:10b6:208:da::10) by MN2PR04MB6255.namprd04.prod.outlook.com (2603:10b6:208:d5::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4415.22; Thu, 19 Aug 2021 07:43:31 +0000 Received: from MN2PR04MB5981.namprd04.prod.outlook.com ([fe80::5d83:1c26:c2b1:3a30]) by MN2PR04MB5981.namprd04.prod.outlook.com ([fe80::5d83:1c26:c2b1:3a30%6]) with mapi id 15.20.4415.024; Thu, 19 Aug 2021 07:43:31 +0000 From: Soft Works To: "ffmpeg-devel@ffmpeg.org" Thread-Topic: [PATCH 7/9] avfilter/sleet: Add sleet filter Thread-Index: AdeUeEEb3DbCQDzPTau6u4BdhirUZA== Date: Thu, 19 Aug 2021 07:43:31 +0000 Message-ID: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-messagesentrepresentingtype: 1 x-tmn: [24CuWBNJcLgi1wd6ZO77MP//ZmPzkNr+] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: cd237a83-0cf4-4ee6-d63d-08d962e50a9c x-ms-traffictypediagnostic: MN2PR04MB6255: x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: gjaZT4st+EEgTn9KfgpHUA7MqZtZRM/LGfU4VGTv6z2nqO6RTSHnlr6YFmFJiC2YDgV8mZpbX3aurGkBxe+YKaUWowBAk4sDsc2TXX6itkEsp40XPkviXZn84mwL9fgOJUuQom3KjpTA/gzC4elb08mRZrBs4PaPByaCFCsyd4Wquto6PUagxDQTtwqPPOryqcCBsIhK/Q0Aqz/zkb0jln17G/Zw7O/kzehHdhrYf9G8ptDkmBPjOwhrycDlhinhq2LMZQ7f9+NdP3ytHXc9reJViZhLUPZF635qAlEW6qM5DFq4Opq9cr0Ly29lGSGZXOeavlcjkyN7p+mdba4QVkvg8qZwJZ9iRYwXWn8ocjDN7gpfimo3SxJFATBiw/DLdqznWJuqPXT7sroAW34AuoCf9PZds99c8KRK0q9uO1d09ybIdHOAxwa32GhOrPJY x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: LoJvnMXPFRubt8U92TJGSj7cRcjPPuKcKdKelsOzz99sAStTYXTZVYko6meGLtTC5HkNmYp6ZsVKCsmQSez3m7Kcz3t1M+gFr/FtekHini76F9Z9g1AojN7YLpjCNmMlFsGZxNTSJEwECowDUIK2qQ== 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: cd237a83-0cf4-4ee6-d63d-08d962e50a9c X-MS-Exchange-CrossTenant-originalarrivaltime: 19 Aug 2021 07:43:31.3499 (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: MN2PR04MB6255 Subject: [FFmpeg-devel] [PATCH 7/9] avfilter/sleet: Add sleet filter 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: c5au9MeEiMER Signed-off-by: softworkz --- libavfilter/Makefile | 3 + libavfilter/allfilters.c | 1 + libavfilter/sf_sleet.c | 209 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 213 insertions(+) create mode 100644 libavfilter/sf_sleet.c diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 5f63ec0123..2a321a7f50 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -526,6 +526,9 @@ OBJS-$(CONFIG_YUVTESTSRC_FILTER) += vsrc_testsrc.o OBJS-$(CONFIG_NULLSINK_FILTER) += vsink_nullsink.o +# subtitle filters +OBJS-$(CONFIG_SLEET_FILTER) += sf_sleet.o + # multimedia filters OBJS-$(CONFIG_ABITSCOPE_FILTER) += avf_abitscope.o OBJS-$(CONFIG_ADRAWGRAPH_FILTER) += f_drawgraph.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 5bd54db2c8..efe16b8e1b 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -519,6 +519,7 @@ extern const AVFilter ff_avf_showwaves; extern const AVFilter ff_avf_showwavespic; extern const AVFilter ff_vaf_spectrumsynth; extern const AVFilter ff_svf_sub2video; +extern const AVFilter ff_sf_sleet; /* multimedia sources */ extern const AVFilter ff_avsrc_amovie; diff --git a/libavfilter/sf_sleet.c b/libavfilter/sf_sleet.c new file mode 100644 index 0000000000..cf7701c01f --- /dev/null +++ b/libavfilter/sf_sleet.c @@ -0,0 +1,209 @@ +/* + * 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 + */ + +/** + * @file + * text subtitle filter which translates to 'leet speak' + */ + +#include "libavutil/avassert.h" +#include "libavutil/avstring.h" +#include "libavutil/opt.h" +#include "avfilter.h" +#include "internal.h" +#include "libavcodec/avcodec.h" + +static const char* alphabet_src = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; +static const char* alphabet_dst = "abcd3f6#1jklmn0pq257uvwxyzAB(D3F6#1JKLMN0PQ257UVWXYZ"; + + +typedef struct LeetContext { + const AVClass *class; + enum AVSubtitleType format; +} LeetContext; + +static const AVOption sleet_options[] = { + { NULL } +}; + +AVFILTER_DEFINE_CLASS(sleet); + +static int query_formats(AVFilterContext *ctx) +{ + AVFilterFormats *formats = NULL; + AVFilterLink *inlink = ctx->inputs[0]; + AVFilterLink *outlink = ctx->outputs[0]; + static const enum AVSubtitleType subtitle_fmts[] = { SUBTITLE_ASS, SUBTITLE_NONE }; + static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE }; + int ret; + + /* set input subtitle format */ + formats = ff_make_format_list(subtitle_fmts); + if ((ret = ff_formats_ref(formats, &inlink->outcfg.formats)) < 0) + return ret; + + /* set output video format */ + formats = ff_make_format_list(pix_fmts); + if ((ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0) + return ret; + + return 0; +} + +static int config_input(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + LeetContext *s = ctx->priv; + + s->format = inlink->format; + return 0; +} + +static int config_output(AVFilterLink *outlink) +{ + LeetContext *s = outlink->src->priv; + + outlink->format = s->format; + + return 0; +} + +static void avsubtitle_free_ref(void *opaque, uint8_t *data) +{ + avsubtitle_free((AVSubtitle *)data); +} + +static int filter_frame(AVFilterLink *inlink, AVFrame *src_frame) +{ + LeetContext *s = inlink->dst->priv; + AVFilterLink *outlink = inlink->dst->outputs[0]; + AVSubtitle *sub; + int ret; + AVFrame *out; + unsigned int num_rects; + uint8_t *dst; + + outlink->format = inlink->format; + + out = av_frame_alloc(); + if (!out) { + av_frame_free(&src_frame); + return AVERROR(ENOMEM); + } + + out->format = outlink->format; + + if ((ret = av_frame_get_buffer2(out, AVMEDIA_TYPE_SUBTITLE, 0)) < 0) + return ret; + + out->pts = src_frame->pts; + out->repeat_pict = src_frame->repeat_pict; + out->pkt_dts = src_frame->pkt_dts; + out->pkt_pos = src_frame->pkt_pos; + out->pkt_size = src_frame->pkt_size; + out->pkt_duration = src_frame->pkt_duration; + out->reordered_opaque = src_frame->reordered_opaque; + out->best_effort_timestamp = src_frame->best_effort_timestamp; + out->flags = src_frame->flags; + + sub = (AVSubtitle *)src_frame->data[0]; + + if (sub) { + AVSubtitle *out_sub = av_memdup(sub, sizeof(*out_sub)); + if (!out_sub) + return AVERROR(ENOMEM); + + out->buf[0] = av_buffer_create((uint8_t*)out_sub, sizeof(*out_sub), avsubtitle_free_ref, NULL, AV_BUFFER_FLAG_READONLY); + out->data[0] = (uint8_t*)out_sub; + + if (sub->num_rects) { + out_sub->rects = av_malloc_array(sub->num_rects, sizeof(AVSubtitleRect *)); + } + + for (unsigned i = 0; i < sub->num_rects; i++) { + + AVSubtitleRect *src_rect = sub->rects[i]; + AVSubtitleRect *dst_rect = av_memdup(src_rect, sizeof(*dst_rect)); + out_sub->rects[i] = dst_rect; + + if (src_rect->text) { + dst_rect->text = av_strdup(src_rect->text); + if (!dst_rect->text) + return AVERROR(ENOMEM); + + for (size_t n = 0; n < strlen(dst_rect->text); n++) { + for (size_t t = 0; t < FF_ARRAY_ELEMS(alphabet_src); t++) { + if (dst_rect->text[n] == alphabet_src[t]) { + dst_rect->text[n] = alphabet_dst[t]; + break; + } + } + } + } + + if (src_rect->ass) { + dst_rect->ass = av_strdup(src_rect->ass); + if (!dst_rect->ass) + return AVERROR(ENOMEM); + + for (size_t n = 0; n < strlen(dst_rect->ass); n++) { + for (size_t t = 0; t < FF_ARRAY_ELEMS(alphabet_src); t++) { + if (dst_rect->ass[n] == alphabet_src[t]) { + dst_rect->ass[n] = alphabet_dst[t]; + break; + } + } + } + } + } + } + + av_frame_free(&src_frame); + return ff_filter_frame(outlink, out); +} + +static const AVFilterPad sleet_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_SUBTITLE, + .filter_frame = filter_frame, + .config_props = config_input, + }, + { NULL } +}; + +static const AVFilterPad sleet_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_SUBTITLE, + .config_props = config_output, + }, + { NULL } +}; + +const AVFilter ff_sf_sleet = { + .name = "sleet", + .description = NULL_IF_CONFIG_SMALL("Translate text subtitles to 'leet speak'"), + .query_formats = query_formats, + .priv_size = sizeof(LeetContext), + .priv_class = &sleet_class, + .inputs = sleet_inputs, + .outputs = sleet_outputs, +}; From patchwork Thu Aug 19 07:43: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: 29608 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6602:2a4a:0:0:0:0 with SMTP id k10csp65108iov; Thu, 19 Aug 2021 00:44:46 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwD4JauZ7Y/0A/LgPd2MhI+14T3zoQkHTJtOdBPX4rO4C9yOFCchmlAQxkgJ0B02j+ua5pJ X-Received: by 2002:a17:906:9155:: with SMTP id y21mr14387956ejw.104.1629359086035; Thu, 19 Aug 2021 00:44:46 -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 b23si2710475edv.199.2021.08.19.00.44.44; Thu, 19 Aug 2021 00:44:46 -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=NHn985If; 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 D3B8F68A450; Thu, 19 Aug 2021 10:43:43 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from NAM11-DM6-obe.outbound.protection.outlook.com (mail-dm6nam11olkn2031.outbound.protection.outlook.com [40.92.19.31]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 89C9D6801C5 for ; Thu, 19 Aug 2021 10:43:41 +0300 (EEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=cFWZL2x6lXVLEzT2UHl55UiBi2+fNS7uZk8tOLaU1unWoxQAqcV5MnmfhgYlv1KGy1GidXMVu07XBUWinYWmLRBG2pwPVZ7FTQd65h9NMyZm7Iy+CM7sVJpH+llUe+qWlj9jLhKovb/uvzn3Np3jfN6SfcTQZ2kc/j4Ds+jmIwqbKq1xaZHW7e/ANBUUp6k6Qf4bYsxrfDRsHy9i0LwLcrI/Yh/Zf0c+Bz1/UYMq7gS1/TVt+SrzPjbZggRuRFvkq5D3/qUdQH3dZBZHkaF/0Nty5qBmyl5SKoLhbn/xh8uszQHdU2G44rAfm01IwML8xGmeH8+e1Swi7B8/ukiUNQ== 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:X-MS-Exchange-SenderADCheck; bh=1HiuoiTzF2Gt5JrOQT/p0aQLXmjwp5/c1vbRIL/JQvA=; b=HXMl2IQWTgbVlLle7/jci6kLOz+a0IhupxxJ+eHOhwYucOxm63oDGCd3s6b5m6o6mkgNjov6dOjMwdPNUXVkXbV4jO17ay/mInA6fIlDLwsIrXBiT+EWuPAIwBeshIB82OzMaXgfmmva58FsPpTNkgT5nID/RpMCxYTLcaefVsFzqqJOmevquqfajbINlHVBxKwaQozoFuoTCECdh2l5DqWNbs38rGWWHGIPwH9BwL036ftAaKVH7pYDPQd27VUCDWLYKfq4IQZ0Bjztrz80jR3hv4QbEStqMzIiQqdwAh7BBwUpZuJRZVzBIxK26GsYlA4pbXHjqVqy8tlpQCh3xw== 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=1HiuoiTzF2Gt5JrOQT/p0aQLXmjwp5/c1vbRIL/JQvA=; b=NHn985IfQ13JfY+/T9DDAV7sDgzP/GBU7LFG+PYsVgsrYl0aogmaYBV/ku4aIWNLcHBaaprUa+eP8etIzd+prDPBZ/+2KizYGhfXj0H2fFYaXbNy3d+tF8+GiocIFcC17sb3HS2I3YbVo8PqDs7qkbKbIkIPXqpV4aC85eDMJbkN1DU9YWwoe5+rGAgvvswAf3fhe62hP+8kXoAgjo3+LHMF4MHjade3WGdBVms0AV95XrEv/9aN9YthZuzWYtx92t22XlY2VYEPZde0Winxs7PbBLEhg4Ve1+tYZ0ngFEufPhbksg37VsOuyETHIEymnjLBvrMhC4mtWpoB4N5E6Q== Received: from MN2PR04MB5981.namprd04.prod.outlook.com (2603:10b6:208:da::10) by MN2PR04MB6255.namprd04.prod.outlook.com (2603:10b6:208:d5::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4415.22; Thu, 19 Aug 2021 07:43:37 +0000 Received: from MN2PR04MB5981.namprd04.prod.outlook.com ([fe80::5d83:1c26:c2b1:3a30]) by MN2PR04MB5981.namprd04.prod.outlook.com ([fe80::5d83:1c26:c2b1:3a30%6]) with mapi id 15.20.4415.024; Thu, 19 Aug 2021 07:43:37 +0000 From: Soft Works To: "ffmpeg-devel@ffmpeg.org" Thread-Topic: [PATCH 8/9] fftools/ffmpeg: Replace sub2video with subtitle frame filtering Thread-Index: AdeUsAnIHELCVIH2Twq961pdVO0OEg== Date: Thu, 19 Aug 2021 07:43:37 +0000 Message-ID: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-messagesentrepresentingtype: 1 x-tmn: [mKhz39+ZgCuYOpP/FE4KflTER2CE+O6m] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: e91e3e9b-15df-41f6-c459-08d962e50e1e x-ms-traffictypediagnostic: MN2PR04MB6255: x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: Q43OmB+xcKD+hdfW2ZPOlyJMYIr7DzNjTzX7QfSpJXHPjtooEwPrOgeqPY1oxzr1hbX44AFB96BTNdB6XBC3f0W4o3Q6l+ym3PXdoafaL9vKXf3MmAC8SiuT0bz/5QYf0QIoR5qjEvh13Lxib/brvZByy1QksxFdMnhZPzThCer082soy+YMzAXnU5zVVyCWp47tre5s48+28hdRMBN0Fb3CpeRChvhULIOOhAOnC2SLNhflJH9qxUfzx/F+TIiwQ5imayTH8o6vcTaOCn8rqgQenOfnqE+RH0dko4QtzOxNmeuF2nSe83QBS7wM7x7wVoQirA3EIuchLzMEBkIrW1Dv+Ctbxbqb5VZ0Gt//S8v/BVLtu3/g1IKGFTUYGXYJCmWvtjVaYiNKXLNHCUIpzC3/q1UXc+Uf4HlnjHwhMr3Lb2otOY206DDslqTwLQ+O x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: GMKufWotWXwY7P8JUKRGLC4buPc0sPnJ92Ub8qOBD9MTvDa33pvXFCv2TqqfHqK5mWyZQIqdOjfzaT4ywIf4XZN1jOI56KRS7S4Ja4EN60CoYQbYbvool1NACBqo0HaJ1hy3CSW8k6pGp4VKP7HGFg== 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: e91e3e9b-15df-41f6-c459-08d962e50e1e X-MS-Exchange-CrossTenant-originalarrivaltime: 19 Aug 2021 07:43:37.2276 (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: MN2PR04MB6255 Subject: [FFmpeg-devel] [PATCH 8/9] fftools/ffmpeg: Replace sub2video with subtitle frame filtering 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: 63IZ/lr30AlZ Signed-off-by: softworkz --- fftools/ffmpeg.c | 324 +++++++++++++++++++++++----------------- fftools/ffmpeg.h | 7 +- fftools/ffmpeg_filter.c | 198 +++++++++++++++++------- fftools/ffmpeg_hw.c | 2 +- fftools/ffmpeg_opt.c | 3 +- 5 files changed, 330 insertions(+), 204 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index b0ce7c7c32..aec8422111 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -174,114 +174,99 @@ static void free_input_threads(void); This is a temporary solution until libavfilter gets real subtitles support. */ -static int sub2video_get_blank_frame(InputStream *ist) +static int send_frame_to_filters(InputStream *ist, AVFrame *decoded_frame); + + +static int get_subtitle_format_from_codecdesc(const AVCodecDescriptor *codec_descriptor) { - int ret; - AVFrame *frame = ist->sub2video.frame; + int format; - av_frame_unref(frame); - ist->sub2video.frame->width = ist->dec_ctx->width ? ist->dec_ctx->width : ist->sub2video.w; - ist->sub2video.frame->height = ist->dec_ctx->height ? ist->dec_ctx->height : ist->sub2video.h; - ist->sub2video.frame->format = AV_PIX_FMT_RGB32; - if ((ret = av_frame_get_buffer(frame, 0)) < 0) - return ret; - memset(frame->data[0], 0, frame->height * frame->linesize[0]); - return 0; + if(codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB) + format = SUBTITLE_BITMAP; + else if(codec_descriptor->props & AV_CODEC_PROP_TEXT_SUB) + format = SUBTITLE_ASS; + else + format = SUBTITLE_TEXT; + + return format; } -static void sub2video_copy_rect(uint8_t *dst, int dst_linesize, int w, int h, - AVSubtitleRect *r) +static void avsubtitle_free_ref(void *opaque, uint8_t *data) { - uint32_t *pal, *dst2; - uint8_t *src, *src2; - int x, y; + avsubtitle_free((AVSubtitle *)data); +} - if (r->type != SUBTITLE_BITMAP) { - av_log(NULL, AV_LOG_WARNING, "sub2video: non-bitmap subtitle\n"); +static void sub2video_resend_current(InputStream *ist, int64_t heartbeat_pts) +{ + AVFrame *frame; + AVSubtitle *current_sub; + int8_t *dst; + int num_rects, i, ret; + int64_t pts, end_pts, pts_sub; + int format = get_subtitle_format_from_codecdesc(ist->dec_ctx->codec_descriptor); + + /* If we are initializing the system, utilize current heartbeat + PTS as the start time, and show until the following subpicture + is received. Otherwise, utilize the previous subpicture's end time + as the fall-back value. */ + pts = ist->sub2video.end_pts <= 0 ? + heartbeat_pts : ist->sub2video.end_pts; + end_pts = INT64_MAX; + + ////av_log(ist->dec_ctx, AV_LOG_ERROR, "sub2video_resend_current1: heartbeat_pts: %lld ist->sub2video.end_pts: %lld\n", heartbeat_pts, ist->sub2video.end_pts); + + pts = av_rescale_q(pts * 1000LL, + AV_TIME_BASE_Q, ist->st->time_base); + + frame = av_frame_alloc(); + if (!frame) { + av_log(ist->dec_ctx, AV_LOG_ERROR, "Unable to alloc frame (out of memory).\n"); return; } - if (r->x < 0 || r->x + r->w > w || r->y < 0 || r->y + r->h > h) { - av_log(NULL, AV_LOG_WARNING, "sub2video: rectangle (%d %d %d %d) overflowing %d %d\n", - r->x, r->y, r->w, r->h, w, h - ); + + frame->format = get_subtitle_format_from_codecdesc(ist->dec_ctx->codec_descriptor); + + if ((ret = av_frame_get_buffer2(frame, AVMEDIA_TYPE_SUBTITLE, 0)) < 0) { + av_log(ist->dec_ctx, AV_LOG_ERROR, "Error (av_frame_get_buffer): %d.\n", ret); return; } - dst += r->y * dst_linesize + r->x * 4; - src = r->data[0]; - pal = (uint32_t *)r->data[1]; - for (y = 0; y < r->h; y++) { - dst2 = (uint32_t *)dst; - src2 = src; - for (x = 0; x < r->w; x++) - *(dst2++) = pal[*(src2++)]; - dst += dst_linesize; - src += r->linesize[0]; + frame->width = ist->sub2video.w; + frame->height = ist->sub2video.h; + + if (ist->sub2video.current_subtitle) { + frame->buf[0] = av_buffer_ref(ist->sub2video.current_subtitle); + frame->data[0] = ist->sub2video.current_subtitle->data; + } + else { + AVBufferRef *empty_sub_buffer; + AVSubtitle *empty_sub = av_mallocz(sizeof(*empty_sub)); + empty_sub->format = format; + empty_sub->num_rects = 0; + empty_sub->pts = av_rescale_q(pts, ist->st->time_base, AV_TIME_BASE_Q); + empty_sub->end_display_time = 1000; + empty_sub_buffer = av_buffer_create((uint8_t*)empty_sub, sizeof(*empty_sub), avsubtitle_free_ref, NULL, AV_BUFFER_FLAG_READONLY); + frame->buf[0] = empty_sub_buffer; + frame->data[0] = empty_sub_buffer->data; } -} -static void sub2video_push_ref(InputStream *ist, int64_t pts) -{ - AVFrame *frame = ist->sub2video.frame; - int i; - int ret; + current_sub = (AVSubtitle *)frame->data[0]; - av_assert1(frame->data[0]); - ist->sub2video.last_pts = frame->pts = pts; - for (i = 0; i < ist->nb_filters; i++) { - ret = av_buffersrc_add_frame_flags(ist->filters[i]->filter, frame, - AV_BUFFERSRC_FLAG_KEEP_REF | - AV_BUFFERSRC_FLAG_PUSH); - if (ret != AVERROR_EOF && ret < 0) - av_log(NULL, AV_LOG_WARNING, "Error while add the frame to buffer source(%s).\n", - av_err2str(ret)); - } -} + frame->pts = pts; + ist->sub2video.last_pts = pts; -void sub2video_update(InputStream *ist, int64_t heartbeat_pts, AVSubtitle *sub) -{ - AVFrame *frame = ist->sub2video.frame; - int8_t *dst; - int dst_linesize; - int num_rects, i; - int64_t pts, end_pts; + ////av_log(ist->dec_ctx, AV_LOG_ERROR, ": frame->pts: %lld current_sub: %lld\n", frame->pts, current_sub->pts); + + send_frame_to_filters(ist, frame); - if (!frame) - return; - if (sub) { - pts = av_rescale_q(sub->pts + sub->start_display_time * 1000LL, - AV_TIME_BASE_Q, ist->st->time_base); - end_pts = av_rescale_q(sub->pts + sub->end_display_time * 1000LL, - AV_TIME_BASE_Q, ist->st->time_base); - num_rects = sub->num_rects; - } else { - /* If we are initializing the system, utilize current heartbeat - PTS as the start time, and show until the following subpicture - is received. Otherwise, utilize the previous subpicture's end time - as the fall-back value. */ - pts = ist->sub2video.initialize ? - heartbeat_pts : ist->sub2video.end_pts; - end_pts = INT64_MAX; - num_rects = 0; - } - if (sub2video_get_blank_frame(ist) < 0) { - av_log(ist->dec_ctx, AV_LOG_ERROR, - "Impossible to get a blank canvas.\n"); - return; - } - dst = frame->data [0]; - dst_linesize = frame->linesize[0]; - for (i = 0; i < num_rects; i++) - sub2video_copy_rect(dst, dst_linesize, frame->width, frame->height, sub->rects[i]); - sub2video_push_ref(ist, pts); ist->sub2video.end_pts = end_pts; - ist->sub2video.initialize = 0; } static void sub2video_heartbeat(InputStream *ist, int64_t pts) { - InputFile *infile = input_files[ist->file_index]; - int i, j, nb_reqs; + const InputFile *infile = input_files[ist->file_index]; + int i, j; + unsigned nb_reqs; int64_t pts2; /* When a frame is read from a file, examine all sub2video streams in @@ -290,7 +275,7 @@ static void sub2video_heartbeat(InputStream *ist, int64_t pts) (possibly overlay) is desperately waiting for a subtitle frame. */ for (i = 0; i < infile->nb_streams; i++) { InputStream *ist2 = input_streams[infile->ist_index + i]; - if (!ist2->sub2video.frame) + if (!ist2->sub2video.is_active) continue; /* subtitles seem to be usually muxed ahead of other streams; if not, subtracting a larger time here is necessary */ @@ -298,15 +283,18 @@ static void sub2video_heartbeat(InputStream *ist, int64_t pts) /* do not send the heartbeat frame if the subtitle is already ahead */ if (pts2 <= ist2->sub2video.last_pts) continue; - if (pts2 >= ist2->sub2video.end_pts || ist2->sub2video.initialize) + if (pts2 >= ist2->sub2video.end_pts) { /* if we have hit the end of the current displayed subpicture, or if we need to initialize the system, update the overlayed subpicture and its start/end times */ - sub2video_update(ist2, pts2 + 1, NULL); - for (j = 0, nb_reqs = 0; j < ist2->nb_filters; j++) - nb_reqs += av_buffersrc_get_nb_failed_requests(ist2->filters[j]->filter); - if (nb_reqs) - sub2video_push_ref(ist2, pts2); + av_buffer_unref(&ist2->sub2video.current_subtitle); + ist2->sub2video.current_subtitle = NULL; + sub2video_resend_current(ist2, pts2 + 1); + } + //for (j = 0, nb_reqs = 0; j < ist2->nb_filters; j++) + // nb_reqs += av_buffersrc_get_nb_failed_requests(ist2->filters[j]->filter); + //if (nb_reqs) + // sub2video_resend_current(ist2, pts2); } } @@ -316,7 +304,7 @@ static void sub2video_flush(InputStream *ist) int ret; if (ist->sub2video.end_pts < INT64_MAX) - sub2video_update(ist, INT64_MAX, NULL); + sub2video_resend_current(ist, INT64_MAX); for (i = 0; i < ist->nb_filters; i++) { ret = av_buffersrc_add_frame(ist->filters[i]->filter, NULL); if (ret != AVERROR_EOF && ret < 0) @@ -535,15 +523,6 @@ static void ffmpeg_cleanup(int ret) av_frame_free(&frame); } av_fifo_freep(&ifilter->frame_queue); - if (ist->sub2video.sub_queue) { - while (av_fifo_size(ist->sub2video.sub_queue)) { - AVSubtitle sub; - av_fifo_generic_read(ist->sub2video.sub_queue, - &sub, sizeof(sub), NULL); - avsubtitle_free(&sub); - } - av_fifo_freep(&ist->sub2video.sub_queue); - } av_buffer_unref(&ifilter->hw_frames_ctx); av_freep(&ifilter->name); av_freep(&fg->inputs[j]); @@ -636,7 +615,6 @@ static void ffmpeg_cleanup(int ret) av_packet_free(&ist->pkt); av_dict_free(&ist->decoder_opts); avsubtitle_free(&ist->prev_sub.subtitle); - av_frame_free(&ist->sub2video.frame); av_freep(&ist->filters); av_freep(&ist->hwaccel_device); av_freep(&ist->dts_buffer); @@ -1061,13 +1039,19 @@ error: static void do_subtitle_out(OutputFile *of, OutputStream *ost, - AVSubtitle *sub) + AVFrame *frame) { int subtitle_out_max_size = 1024 * 1024; int subtitle_out_size, nb, i; AVCodecContext *enc; AVPacket *pkt = ost->pkt; int64_t pts; + AVSubtitle *sub = (AVSubtitle *)frame->data[0]; + + if (!sub) + return; + + ////av_log(NULL, AV_LOG_VERBOSE, "do_subtitle_out: sub->pts: %lld frame->pts: %lld\n", sub->pts, frame->pts); if (sub->pts == AV_NOPTS_VALUE) { av_log(NULL, AV_LOG_ERROR, "Subtitle packets must have a pts\n"); @@ -1576,8 +1560,11 @@ static int reap_filters(int flush) } do_audio_out(of, ost, filtered_frame); break; + case AVMEDIA_TYPE_SUBTITLE: + + do_subtitle_out(of, ost, filtered_frame); + break; default: - // TODO support subtitle filters av_assert0(0); } @@ -2173,7 +2160,8 @@ static int ifilter_has_all_input_formats(FilterGraph *fg) int i; for (i = 0; i < fg->nb_inputs; i++) { if (fg->inputs[i]->format < 0 && (fg->inputs[i]->type == AVMEDIA_TYPE_AUDIO || - fg->inputs[i]->type == AVMEDIA_TYPE_VIDEO)) + fg->inputs[i]->type == AVMEDIA_TYPE_VIDEO || + fg->inputs[i]->type == AVMEDIA_TYPE_SUBTITLE)) return 0; } return 1; @@ -2270,7 +2258,7 @@ static int ifilter_send_eof(InputFilter *ifilter, int64_t pts) // the filtergraph was never configured if (ifilter->format < 0) ifilter_parameters_from_codecpar(ifilter, ifilter->ist->st->codecpar); - if (ifilter->format < 0 && (ifilter->type == AVMEDIA_TYPE_AUDIO || ifilter->type == AVMEDIA_TYPE_VIDEO)) { + if (ifilter->format < 0 && (ifilter->type == AVMEDIA_TYPE_AUDIO || ifilter->type == AVMEDIA_TYPE_VIDEO || ifilter->type == AVMEDIA_TYPE_SUBTITLE)) { av_log(NULL, AV_LOG_ERROR, "Cannot determine format of input stream %d:%d after EOF\n", ifilter->ist->file_index, ifilter->ist->st->index); return AVERROR_INVALIDDATA; } @@ -2528,12 +2516,24 @@ fail: static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output, int *decode_failed) { - AVSubtitle subtitle; - int free_sub = 1; - int i, ret = avcodec_decode_subtitle2(ist->dec_ctx, - &subtitle, got_output, pkt); + AVFrame *decoded_frame; + AVCodecContext *avctx = ist->dec_ctx; + int i = 0, ret = 0, err = 0; + int64_t pts, end_pts; + AVSubtitle *subtitle = av_mallocz(sizeof(*subtitle)); + if (!subtitle) + return NULL; + + if (!ist->decoded_frame && !(ist->decoded_frame = av_frame_alloc())) + return AVERROR(ENOMEM); + if (!ist->filter_frame && !(ist->filter_frame = av_frame_alloc())) + return AVERROR(ENOMEM); + decoded_frame = ist->decoded_frame; + + ret = avcodec_decode_subtitle2(avctx, subtitle, got_output, pkt); - check_decode_result(NULL, got_output, ret); + if (ret != AVERROR_EOF) + check_decode_result(NULL, got_output, ret); if (ret < 0 || !*got_output) { *decode_failed = 1; @@ -2545,10 +2545,10 @@ static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output, if (ist->fix_sub_duration) { int end = 1; if (ist->prev_sub.got_output) { - end = av_rescale(subtitle.pts - ist->prev_sub.subtitle.pts, + end = av_rescale(subtitle->pts - ist->prev_sub.subtitle.pts, 1000, AV_TIME_BASE); if (end < ist->prev_sub.subtitle.end_display_time) { - av_log(ist->dec_ctx, AV_LOG_DEBUG, + av_log(avctx, AV_LOG_DEBUG, "Subtitle duration reduced from %"PRId32" to %d%s\n", ist->prev_sub.subtitle.end_display_time, end, end <= 0 ? ", dropping it" : ""); @@ -2557,35 +2557,79 @@ static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output, } FFSWAP(int, *got_output, ist->prev_sub.got_output); FFSWAP(int, ret, ist->prev_sub.ret); - FFSWAP(AVSubtitle, subtitle, ist->prev_sub.subtitle); + FFSWAP(AVSubtitle, *subtitle, ist->prev_sub.subtitle); if (end <= 0) - goto out; + return end; } if (!*got_output) return ret; - if (ist->sub2video.frame) { - sub2video_update(ist, INT64_MIN, &subtitle); - } else if (ist->nb_filters) { - if (!ist->sub2video.sub_queue) - ist->sub2video.sub_queue = av_fifo_alloc(8 * sizeof(AVSubtitle)); - if (!ist->sub2video.sub_queue) + ////decoded_frame = av_frame_alloc(); + ////if (!decoded_frame) + //// return AVERROR(ENOMEM); + + decoded_frame->format = get_subtitle_format_from_codecdesc(avctx->codec_descriptor); + + if ((ret = av_frame_get_buffer2(decoded_frame, AVMEDIA_TYPE_SUBTITLE, 0)) < 0) + return ret; + + av_buffer_unref(&ist->sub2video.current_subtitle); + ist->sub2video.current_subtitle = av_buffer_create((uint8_t*)subtitle, sizeof(*subtitle), avsubtitle_free_ref, NULL, AV_BUFFER_FLAG_READONLY); + + decoded_frame->buf[0] = av_buffer_ref(ist->sub2video.current_subtitle); + decoded_frame->data[0] = ist->sub2video.current_subtitle->data; + + pts = av_rescale_q(subtitle->pts + subtitle->start_display_time * 1000LL, + AV_TIME_BASE_Q, ist->st->time_base); + end_pts = av_rescale_q(subtitle->pts + subtitle->end_display_time * 1000LL, + AV_TIME_BASE_Q, ist->st->time_base); + + ist->sub2video.last_pts = decoded_frame->pts = pts; + ist->sub2video.end_pts = end_pts; + + ////av_log(ist->dec_ctx, AV_LOG_ERROR, "frame->pts: %lld subtitle->pts: %lld\n", decoded_frame->pts, subtitle->pts); + + for (i = 0; i < nb_output_streams; i++) { + OutputStream *ost = output_streams[i]; + + if (!ost->pkt && !(ost->pkt = av_packet_alloc())) exit_program(1); - if (!av_fifo_space(ist->sub2video.sub_queue)) { - ret = av_fifo_realloc2(ist->sub2video.sub_queue, 2 * av_fifo_size(ist->sub2video.sub_queue)); - if (ret < 0) - exit_program(1); - } - av_fifo_generic_write(ist->sub2video.sub_queue, &subtitle, sizeof(subtitle), NULL); - free_sub = 0; + if (!check_output_constraints(ist, ost) || !ost->encoding_needed + || ost->enc->type != AVMEDIA_TYPE_SUBTITLE) + continue; + + do_subtitle_out(output_files[ost->file_index], ost, decoded_frame); } - if (!subtitle.num_rects) - goto out; + err = send_frame_to_filters(ist, decoded_frame); - ist->frames_decoded++; + av_frame_unref(ist->filter_frame); + av_frame_unref(decoded_frame); + return err < 0 ? err : ret; +//// if (ist->sub2video.frame) { +//// sub2video_update(ist, INT64_MIN, subtitle); +//// free_sub = 0; +//// } else if (ist->nb_filters) { +//// if (!ist->sub2video.sub_queue) +//// ist->sub2video.sub_queue = av_fifo_alloc(8 * sizeof(AVSubtitle)); +//// if (!ist->sub2video.sub_queue) +//// exit_program(1); +//// if (!av_fifo_space(ist->sub2video.sub_queue)) { +//// ret = av_fifo_realloc2(ist->sub2video.sub_queue, 2 * av_fifo_size(ist->sub2video.sub_queue)); +//// if (ret < 0) +//// exit_program(1); +//// } +//// av_fifo_generic_write(ist->sub2video.sub_queue, &subtitle, sizeof(subtitle), NULL); +//// free_sub = 0; +//// } +//// +//// if (!subtitle->num_rects) +//// goto out; +//// +//// ist->frames_decoded++; +//// for (i = 0; i < nb_output_streams; i++) { OutputStream *ost = output_streams[i]; @@ -2595,13 +2639,13 @@ static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output, || ost->enc->type != AVMEDIA_TYPE_SUBTITLE) continue; - do_subtitle_out(output_files[ost->file_index], ost, &subtitle); + do_subtitle_out(output_files[ost->file_index], ost, subtitle); } - -out: - if (free_sub) - avsubtitle_free(&subtitle); - return ret; +//// +////out: +//// if (free_sub) +//// avsubtitle_free(subtitle); +//// return ret; } static int send_filter_eof(InputStream *ist) diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index d2dd7ca092..59e9dd775c 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -352,12 +352,11 @@ typedef struct InputStream { } prev_sub; struct sub2video { + int is_active; int64_t last_pts; int64_t end_pts; - AVFifoBuffer *sub_queue; ///< queue of AVSubtitle* before filter init - AVFrame *frame; + AVBufferRef *current_subtitle; int w, h; - unsigned int initialize; ///< marks if sub2video_update should force an initialization } sub2video; int dr1; @@ -664,8 +663,6 @@ int filtergraph_is_simple(FilterGraph *fg); int init_simple_filtergraph(InputStream *ist, OutputStream *ost); int init_complex_filtergraph(FilterGraph *fg); -void sub2video_update(InputStream *ist, int64_t heartbeat_pts, AVSubtitle *sub); - int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame); int ffmpeg_parse_options(int argc, char **argv); diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index 49076f13ee..139843402c 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -19,6 +19,7 @@ */ #include +#include #include "ffmpeg.h" @@ -222,8 +223,8 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in) int i; // TODO: support other filter types - if (type != AVMEDIA_TYPE_VIDEO && type != AVMEDIA_TYPE_AUDIO) { - av_log(NULL, AV_LOG_FATAL, "Only video and audio filters supported " + if (type != AVMEDIA_TYPE_VIDEO && type != AVMEDIA_TYPE_AUDIO && type != AVMEDIA_TYPE_SUBTITLE) { + av_log(NULL, AV_LOG_FATAL, "Only video, audio and subtitle filters supported " "currently.\n"); exit_program(1); } @@ -243,10 +244,6 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in) for (i = 0; i < s->nb_streams; i++) { enum AVMediaType stream_type = s->streams[i]->codecpar->codec_type; - if (stream_type != type && - !(stream_type == AVMEDIA_TYPE_SUBTITLE && - type == AVMEDIA_TYPE_VIDEO /* sub2video hack */)) - continue; if (check_stream_specifier(s, s->streams[i], *p == ':' ? p + 1 : p) == 1) { st = s->streams[i]; break; @@ -416,6 +413,39 @@ static int insert_filter(AVFilterContext **last_filter, int *pad_idx, return 0; } +static int configure_output_subtitle_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out) +{ + char *pix_fmts; + OutputStream *ost = ofilter->ost; + OutputFile *of = output_files[ost->file_index]; + AVFilterContext *last_filter = out->filter_ctx; + int pad_idx = out->pad_idx; + int ret; + char name[255]; + + snprintf(name, sizeof(name), "out_%d_%d", ost->file_index, ost->index); + ret = avfilter_graph_create_filter(&ofilter->filter, + avfilter_get_by_name("sbuffersink"), + name, NULL, NULL, fg->graph); + + if (ret < 0) + return ret; + + ////snprintf(name, sizeof(name), "trim_out_%d_%d", + //// ost->file_index, ost->index); + ////ret = insert_trim(of->start_time, of->recording_time, + //// &last_filter, &pad_idx, name); + ////if (ret < 0) + //// return ret; + + ////ost->st->codecpar->codec_tag = MKTAG('a', 's', 's', 's'); + + if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0) + return ret; + + return 0; +} + static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out) { char *pix_fmts; @@ -594,7 +624,8 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter, int i; for (i=0; ictx->nb_streams; i++) - if (of->ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) + if (of->ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO || + of->ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) break; if (ictx->nb_streams) { @@ -628,6 +659,7 @@ static int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, switch (avfilter_pad_get_type(out->filter_ctx->output_pads, out->pad_idx)) { case AVMEDIA_TYPE_VIDEO: return configure_output_video_filter(fg, ofilter, out); case AVMEDIA_TYPE_AUDIO: return configure_output_audio_filter(fg, ofilter, out); + case AVMEDIA_TYPE_SUBTITLE: return configure_output_subtitle_filter(fg, ofilter, out); default: av_assert0(0); return 0; } } @@ -652,46 +684,110 @@ static int sub2video_prepare(InputStream *ist, InputFilter *ifilter) AVFormatContext *avf = input_files[ist->file_index]->ctx; int i, w, h; - /* Compute the size of the canvas for the subtitles stream. - If the subtitles codecpar has set a size, use it. Otherwise use the - maximum dimensions of the video streams in the same file. */ + ist->sub2video.is_active = 1; + w = ifilter->width; h = ifilter->height; if (!(w && h)) { - for (i = 0; i < avf->nb_streams; i++) { - if (avf->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { - w = FFMAX(w, avf->streams[i]->codecpar->width); - h = FFMAX(h, avf->streams[i]->codecpar->height); - } - } - if (!(w && h)) { - w = FFMAX(w, 720); - h = FFMAX(h, 576); - } - av_log(avf, AV_LOG_INFO, "sub2video: using %dx%d canvas\n", w, h); + w = ist->dec_ctx->width; + h = ist->dec_ctx->height; } - ist->sub2video.w = ifilter->width = w; - ist->sub2video.h = ifilter->height = h; - ifilter->width = ist->dec_ctx->width ? ist->dec_ctx->width : ist->sub2video.w; - ifilter->height = ist->dec_ctx->height ? ist->dec_ctx->height : ist->sub2video.h; + ist->sub2video.w = w; + ist->sub2video.h = h; + av_log(avf, AV_LOG_INFO, "sub2video: decoding size %dx%d\n", ist->sub2video.w, ist->sub2video.h); - /* rectangles are AV_PIX_FMT_PAL8, but we have no guarantee that the - palettes for all rectangles are identical or compatible */ - ifilter->format = AV_PIX_FMT_RGB32; + ifilter->width = w; + ifilter->height = h; - ist->sub2video.frame = av_frame_alloc(); - if (!ist->sub2video.frame) - return AVERROR(ENOMEM); ist->sub2video.last_pts = INT64_MIN; - ist->sub2video.end_pts = INT64_MIN; + ist->sub2video.end_pts = 0; + + return 0; +} + +static int configure_input_subtitle_filter(FilterGraph *fg, InputFilter *ifilter, + AVFilterInOut *in) +{ + AVFilterContext *last_filter; + const AVFilter *buffer_filt = avfilter_get_by_name("sbuffer"); + InputStream *ist = ifilter->ist; + InputFile *f = input_files[ist->file_index]; + AVBPrint args; + char name[255]; + int ret, pad_idx = 0; + int64_t tsoffset = 0; + AVBufferSrcParameters *par = av_buffersrc_parameters_alloc(); + + if (!par) + return AVERROR(ENOMEM); + memset(par, 0, sizeof(*par)); + par->format = AV_PIX_FMT_NONE; + + if (ist->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) { + av_log(NULL, AV_LOG_ERROR, "Cannot connect subtitle filter to audio input\n"); + ret = AVERROR(EINVAL); + goto fail; + } + + if (ist->dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO) { + av_log(NULL, AV_LOG_ERROR, "Cannot connect subtitle filter to video input\n"); + ret = AVERROR(EINVAL); + goto fail; + } + + ret = sub2video_prepare(ist, ifilter); + if (ret < 0) + goto fail; + + snprintf(name, sizeof(name), "graph %d subtitle input from stream %d:%d", fg->index, + ist->file_index, ist->st->index); + - /* sub2video structure has been (re-)initialized. - Mark it as such so that the system will be - initialized with the first received heartbeat. */ - ist->sub2video.initialize = 1; + av_bprint_init(&args, 0, AV_BPRINT_SIZE_AUTOMATIC); + av_bprintf(&args, + "subtitle_type=%d:time_base=%d/%d:", + ifilter->format, + ist->st->time_base.num, ist->st->time_base.den); + if ((ret = avfilter_graph_create_filter(&ifilter->filter, buffer_filt, name, + args.str, NULL, fg->graph)) < 0) + goto fail; + + par->hw_frames_ctx = ifilter->hw_frames_ctx; + par->format = ifilter->format; + + ret = av_buffersrc_parameters_set(ifilter->filter, par); + if (ret < 0) + goto fail; + av_freep(&par); + last_filter = ifilter->filter; + if (in->filter_ctx->input_pads[in->pad_idx].type == AVMEDIA_TYPE_VIDEO) { + ret = insert_filter(&last_filter, &pad_idx, "sub2video", NULL); + if (ret < 0) + return ret; + } + + ////snprintf(name, sizeof(name), "trim_in_%d_%d", + //// ist->file_index, ist->st->index); + ////if (copy_ts) { + //// tsoffset = f->start_time == AV_NOPTS_VALUE ? 0 : f->start_time; + //// if (!start_at_zero && f->ctx->start_time != AV_NOPTS_VALUE) + //// tsoffset += f->ctx->start_time; + ////} + ////ret = insert_trim(((f->start_time == AV_NOPTS_VALUE) || !f->accurate_seek) ? + //// AV_NOPTS_VALUE : tsoffset, f->recording_time, + //// &last_filter, &pad_idx, name); + ////if (ret < 0) + //// return ret; + + if ((ret = avfilter_link(last_filter, 0, in->filter_ctx, in->pad_idx)) < 0) + return ret; return 0; +fail: + av_freep(&par); + + return ret; } static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter, @@ -709,8 +805,13 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter, char name[255]; int ret, pad_idx = 0; int64_t tsoffset = 0; - AVBufferSrcParameters *par = av_buffersrc_parameters_alloc(); + AVBufferSrcParameters *par; + if (ist->dec_ctx->codec_type == AVMEDIA_TYPE_SUBTITLE) { + return configure_input_subtitle_filter(fg, ifilter, in); + } + + par = av_buffersrc_parameters_alloc(); if (!par) return AVERROR(ENOMEM); memset(par, 0, sizeof(*par)); @@ -725,12 +826,6 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter, if (!fr.num) fr = av_guess_frame_rate(input_files[ist->file_index]->ctx, ist->st, NULL); - if (ist->dec_ctx->codec_type == AVMEDIA_TYPE_SUBTITLE) { - ret = sub2video_prepare(ist, ifilter); - if (ret < 0) - goto fail; - } - sar = ifilter->sample_aspect_ratio; if(!sar.den) sar = (AVRational){0,1}; @@ -742,7 +837,7 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter, tb.num, tb.den, sar.num, sar.den); if (fr.num && fr.den) av_bprintf(&args, ":frame_rate=%d/%d", fr.num, fr.den); - snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index, + snprintf(name, sizeof(name), "graph %d video input from stream %d:%d", fg->index, ist->file_index, ist->st->index); @@ -938,6 +1033,7 @@ static int configure_input_filter(FilterGraph *fg, InputFilter *ifilter, switch (avfilter_pad_get_type(in->filter_ctx->input_pads, in->pad_idx)) { case AVMEDIA_TYPE_VIDEO: return configure_input_video_filter(fg, ifilter, in); case AVMEDIA_TYPE_AUDIO: return configure_input_audio_filter(fg, ifilter, in); + case AVMEDIA_TYPE_SUBTITLE: return configure_input_subtitle_filter(fg, ifilter, in); default: av_assert0(0); return 0; } } @@ -1110,19 +1206,6 @@ int configure_filtergraph(FilterGraph *fg) } } - /* process queued up subtitle packets */ - for (i = 0; i < fg->nb_inputs; i++) { - InputStream *ist = fg->inputs[i]->ist; - if (ist->sub2video.sub_queue && ist->sub2video.frame) { - while (av_fifo_size(ist->sub2video.sub_queue)) { - AVSubtitle tmp; - av_fifo_generic_read(ist->sub2video.sub_queue, &tmp, sizeof(tmp), NULL); - sub2video_update(ist, INT64_MIN, &tmp); - avsubtitle_free(&tmp); - } - } - } - return 0; fail: @@ -1143,6 +1226,7 @@ int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame) ifilter->sample_rate = frame->sample_rate; ifilter->channels = frame->channels; ifilter->channel_layout = frame->channel_layout; + ifilter->type = frame->type; if (frame->hw_frames_ctx) { ifilter->hw_frames_ctx = av_buffer_ref(frame->hw_frames_ctx); diff --git a/fftools/ffmpeg_hw.c b/fftools/ffmpeg_hw.c index 41aaf776d7..f8b49fd5ac 100644 --- a/fftools/ffmpeg_hw.c +++ b/fftools/ffmpeg_hw.c @@ -449,7 +449,7 @@ int hw_device_setup_for_encode(OutputStream *ost) AVBufferRef *frames_ref = NULL; int i; - if (ost->filter) { + if (ost->filter && ost->filter->filter) { frames_ref = av_buffersink_get_hw_frames_ctx(ost->filter->filter); if (frames_ref && ((AVHWFramesContext*)frames_ref->data)->format == diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c index 428934a3d8..9776455cca 100644 --- a/fftools/ffmpeg_opt.c +++ b/fftools/ffmpeg_opt.c @@ -2144,8 +2144,9 @@ static void init_output_filter(OutputFilter *ofilter, OptionsContext *o, switch (ofilter->type) { case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(o, oc, -1); break; case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(o, oc, -1); break; + case AVMEDIA_TYPE_SUBTITLE: ost = new_subtitle_stream(o, oc, -1); break; default: - av_log(NULL, AV_LOG_FATAL, "Only video and audio filters are supported " + av_log(NULL, AV_LOG_FATAL, "Only video, audio and subtitle filters are supported " "currently.\n"); exit_program(1); } From patchwork Thu Aug 19 07:43:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Soft Works X-Patchwork-Id: 29602 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6602:2a4a:0:0:0:0 with SMTP id k10csp65230iov; Thu, 19 Aug 2021 00:44:56 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxQwgr+OA3+MXsGCpSiUDKJVjYHVlJof7RUvNvv/L8id3Zc5lYG5TcE3PAc6CYYuu5W5ajs X-Received: by 2002:a17:906:ae51:: with SMTP id lf17mr14063817ejb.161.1629359096374; Thu, 19 Aug 2021 00:44:56 -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 oy17si2438175ejb.531.2021.08.19.00.44.56; Thu, 19 Aug 2021 00:44:56 -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=reXVq6i2; 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 D4DAC68A464; Thu, 19 Aug 2021 10:43:50 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from NAM04-BN8-obe.outbound.protection.outlook.com (mail-bn8nam08olkn2105.outbound.protection.outlook.com [40.92.47.105]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 6AFFE6801C5 for ; Thu, 19 Aug 2021 10:43:48 +0300 (EEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=OoIV4iE1BQza4Aw209sn6TOYLBhHhIpVcCqRMn1/WxJDZBf4YcfSMEp5oq4LATFTEwBaZH8p3/X3z2yAfeH1IfJ03hF2OWfCkAATc+N4AbeoOTU5FfMU6uTCuzk0B7Rp4STDLWRy4NwHTuDp6ROjeyEUU4VwJVXIHS/oj0Ap2TDS1EGbYhHqhRskWid7B89sUzW/5ntK9b21yhj1YVJ/hhfME6091HZDxT1DWeFbb8e0z8iTxHTHjKlYbOoull77k3THzpf0u2VdVImzIxFtBgkKbW1vQZOKjutIbkAemwkAaUVEC/Nnt6IAdGdApeVWv/sv2958LQbZKjlG8USLvA== 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:X-MS-Exchange-SenderADCheck; bh=JxvP5VE5IRxmo6MHX8hjVxDFgPJwUubC6+nJj8H05cw=; b=ZeQd2fDQesl1+NtzcK08eL8y+ZQ0BAnNJpI3ql4xtTYB1gpE5MParMSgkkyzzvM2WolTDMDtHoFk+Tl3+4hlNRp2D+Sprm9IHRCE1p//XkpcM4lgYBbiTk3eCfC2Hrx1SosffFNIEtcg4oa4o13TNdaZAft+swIl5OyrEphdY5OHE3Q30iiUkb6HXIKFC0Akto/FSkBhJFxrWie1t18M44NUZdhMwdd7YvZUpzRafeCCEgrTmO/y2GFz/3lSAbysKoLitSpk+jHkXRYivwcy+O4q0z1ahnjts3zQk6S/hZnw1oKez/rDRLRXCT8dLFHbG9Gl3T02Gp2TMbrB0vsiAg== 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=JxvP5VE5IRxmo6MHX8hjVxDFgPJwUubC6+nJj8H05cw=; b=reXVq6i2vCAbk7M/kIg6nC2CskEr2HAGlhtGla0dRVpm+5ALG2IgDtLqQaI/Y0Yl/ou3PlNXOiq0g6Xp4Pz8YDCB4IgtADfO6K+nDVt/xBCyAaBYp/5Rj+gJk0qL6IHXayMUGXuJVrZKyQ9DsR9wsUPoDqe/BK4pXJaB1rFXZpN7dqeOENmv1h5s6+cIPI9H4DcwnJ+YOVe0aHcnYxNFTfuVkVbnOE8YJ6xnDkpo1Ipyqon8T92iy4EX8/E0JtVG5qmwI0lROs1kB0KqQ4zASOqlhHraR/1lMU7SLcIZ1Rrfav8Xih6gktfHNghwFLC4zhKetY0D0ZnqcFWAXs/p4A== Received: from MN2PR04MB5981.namprd04.prod.outlook.com (2603:10b6:208:da::10) by MN2PR04MB5888.namprd04.prod.outlook.com (2603:10b6:208:a0::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4436.19; Thu, 19 Aug 2021 07:43:44 +0000 Received: from MN2PR04MB5981.namprd04.prod.outlook.com ([fe80::5d83:1c26:c2b1:3a30]) by MN2PR04MB5981.namprd04.prod.outlook.com ([fe80::5d83:1c26:c2b1:3a30%6]) with mapi id 15.20.4415.024; Thu, 19 Aug 2021 07:43:44 +0000 From: Soft Works To: "ffmpeg-devel@ffmpeg.org" Thread-Topic: [PATCH 9/9] Adjust sub2video Fate tests Thread-Index: AdeUwGzBNUDZ5XvnRWKaELlaX4B1sA== Date: Thu, 19 Aug 2021 07:43:44 +0000 Message-ID: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-messagesentrepresentingtype: 1 x-tmn: [arzRfKwetEuwZYCn/A+c8AGLRxqVx7B9] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 4b898d7d-a297-4d77-8c25-08d962e51294 x-ms-traffictypediagnostic: MN2PR04MB5888: x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: WTa6LXCSIMatdUpRcX7Ffs23jEDkkHhKmPLDk7iqFo57zPb1gzLTscVT3D+RIZDeeIXwDxlsiuRgwX+h9LOUIvvZw71JnouyHl0vgxsfPsXOMaErAefMpz4Jm53AKfQPeIDV1qXLRDaShPZk0OqVSd7Ga8J6shYUNJkL/eHs1FP7JSBqmirFC8mNFgImlRvsUQNm6FbyKab0diLiCr8ItOJYjDTyAufrXWLDVutim3KRaBTBPICm4RdhV0hHZ26mQ6Jml3j1jd13197lwQ/NKGwcL10vJtknQKMIrQOGmgIrgo/y0abQXe/Ai6I6ByKXeLWTg7IS0tA/8AfLMNRKH3KpKXpPvsVoItHkpaxXJgvgXZLa696XgOBYAJ5ruWRz3DgUufEWJcTmY5B0JcIMNfjV0hk8VNCBy5OzGBTNM0T3QEAL+zxHZJIWt1BVjNXa x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: 4IZneHIlYbpNxi8AZyUYbJ8wrEPxttqI0ebz0UtDV3n1+N+JlrjstfaTkRU9QFSAeLeiOXQEjqU09bS9f6+CGsyyaUuuOUTafNX9s0+VsePR6jU8yybJHxhXb4U1zFmswC+HRqBt/L5Eewe20MWVow== 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: 4b898d7d-a297-4d77-8c25-08d962e51294 X-MS-Exchange-CrossTenant-originalarrivaltime: 19 Aug 2021 07:43:44.7194 (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: MN2PR04MB5888 Subject: [FFmpeg-devel] [PATCH 9/9] Adjust sub2video Fate tests 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: HzG3HDxvjXIQ Signed-off-by: softworkz --- tests/ref/fate/filter-overlay-dvdsub-2397 | 179 +++++++++++----------- tests/ref/fate/sub-dvb | 162 +++++++++++--------- tests/ref/fate/sub2video | 49 +++--- tests/ref/fate/sub2video_basic | 178 +++++++++++---------- tests/ref/fate/sub2video_time_limited | 4 +- 5 files changed, 292 insertions(+), 280 deletions(-) diff --git a/tests/ref/fate/filter-overlay-dvdsub-2397 b/tests/ref/fate/filter-overlay-dvdsub-2397 index 483e5fa4e0..0770856372 100644 --- a/tests/ref/fate/filter-overlay-dvdsub-2397 +++ b/tests/ref/fate/filter-overlay-dvdsub-2397 @@ -495,363 +495,362 @@ 1, 3917, 3917, 10, 2013, 0x261a881e 1, 3927, 3927, 10, 2013, 0x7f2d9f72 1, 3937, 3937, 10, 2013, 0x0105b38d -0, 118, 118, 1, 518400, 0x41890ed6 +0, 118, 118, 1, 518400, 0xa47de755 1, 3952, 3952, 10, 2013, 0x0e5db67e 1, 3962, 3962, 10, 2013, 0xfc9baf97 -0, 119, 119, 1, 518400, 0x588534fc +0, 119, 119, 1, 518400, 0xaade171d 1, 3972, 3972, 10, 2013, 0x8e02a1b1 1, 3982, 3982, 10, 2013, 0x6eecaac8 1, 3992, 3992, 10, 2013, 0xf5558f0c 1, 4002, 4002, 10, 2013, 0x512ba99b -0, 120, 120, 1, 518400, 0x2145ebc1 +0, 120, 120, 1, 518400, 0xbc06d530 1, 4012, 4012, 10, 2013, 0x932b9932 1, 4022, 4022, 10, 2013, 0xc01ea987 -0, 121, 121, 1, 518400, 0x28bca595 +0, 121, 121, 1, 518400, 0xd4709c99 1, 4038, 4038, 10, 2013, 0x10879cf7 1, 4048, 4048, 10, 2013, 0x90679338 1, 4058, 4058, 10, 2013, 0x077d8a9e 1, 4068, 4068, 10, 2013, 0x969fa57c -0, 122, 122, 1, 518400, 0x77dc951e +0, 122, 122, 1, 518400, 0x12989321 1, 4078, 4078, 10, 2013, 0xe049ab07 1, 4088, 4088, 10, 2013, 0xf535b3b3 1, 4098, 4098, 10, 2013, 0xfe76bd37 -0, 123, 123, 1, 518400, 0xe8924c17 +0, 123, 123, 1, 518400, 0x3c875430 1, 4108, 4108, 10, 2013, 0xde79ad8c 1, 4123, 4123, 10, 2013, 0xe89b9c47 1, 4133, 4133, 10, 2013, 0xc570b0f0 -0, 124, 124, 1, 518400, 0xadb4cccc +0, 124, 124, 1, 518400, 0x8b18e05f 1, 4143, 4143, 10, 2013, 0xee709cd9 1, 4153, 4153, 10, 2013, 0xcfe5afab 1, 4163, 4163, 10, 2013, 0x98ff8ce4 -0, 125, 125, 1, 518400, 0x1d7b56ac +0, 125, 125, 1, 518400, 0xba537174 1, 4173, 4173, 10, 2013, 0x9d19b44c 1, 4183, 4183, 10, 2013, 0x4349917a 1, 4193, 4193, 10, 2013, 0xbf54a59a -0, 126, 126, 1, 518400, 0xad5739a4 +0, 126, 126, 1, 518400, 0x0f625b1a 1, 4208, 4208, 10, 2013, 0xc4a399e0 1, 4218, 4218, 10, 2013, 0x1bf58ff0 1, 4228, 4228, 10, 2013, 0x3518ac56 -0, 127, 127, 1, 518400, 0x2733d35a +0, 127, 127, 1, 518400, 0x16b103e4 1, 4238, 4238, 10, 2013, 0xcd38c1de 1, 4248, 4248, 10, 2013, 0xbe7d9c4d 1, 4258, 4258, 10, 2013, 0xe113a306 1, 4268, 4268, 10, 2013, 0x083197ea -0, 128, 128, 1, 518400, 0x78e76da2 +0, 128, 128, 1, 518400, 0xf1d8a234 1, 4278, 4278, 10, 2013, 0x1929b1eb 1, 4294, 4294, 10, 2013, 0x5d6ea5af 1, 4304, 4304, 10, 2013, 0x05519d53 -0, 129, 129, 1, 518400, 0x6c076013 +0, 129, 129, 1, 518400, 0x93109d3f 1, 4314, 4314, 10, 2013, 0x5773b380 1, 4324, 4324, 10, 2013, 0xaa70a8f5 1, 4334, 4334, 10, 2013, 0x990db0ec -0, 130, 130, 1, 518400, 0x7854f2b1 +0, 130, 130, 1, 518400, 0x902b37c7 1, 4344, 4344, 10, 2013, 0x91d3a623 1, 4354, 4354, 10, 2013, 0xc91f9824 1, 4364, 4364, 10, 2013, 0x1d058abf -0, 131, 131, 1, 518400, 0xd2ae1ecd +0, 131, 131, 1, 518400, 0xc41862c2 1, 4379, 4379, 10, 2013, 0x8de1b8d5 1, 4389, 4389, 10, 2013, 0x7872b06b 1, 4399, 4399, 10, 2013, 0xa084c203 -0, 132, 132, 1, 518400, 0xf5eab38d +0, 132, 132, 1, 518400, 0xf733feea 1, 4409, 4409, 10, 2013, 0xff90ae8d 1, 4419, 4419, 10, 2013, 0x61dead8e 1, 4429, 4429, 10, 2013, 0xee76b284 -0, 133, 133, 1, 518400, 0x994d3e9c +0, 133, 133, 1, 518400, 0x813b9340 1, 4439, 4439, 10, 2013, 0xe888af7f 1, 4449, 4449, 10, 2013, 0x5d57b115 1, 4464, 4464, 10, 2013, 0xcdbfb1d0 -0, 134, 134, 1, 518400, 0x95ab705a +0, 134, 134, 1, 518400, 0xc55fc66f 1, 4474, 4474, 10, 2013, 0x2e28a952 1, 4484, 4484, 10, 2013, 0x4795a994 1, 4494, 4494, 10, 2013, 0x7e7ea304 1, 4504, 4504, 10, 2013, 0x9502c1e1 -0, 135, 135, 1, 518400, 0x3c83c5ce +0, 135, 135, 1, 518400, 0xbd401cc5 1, 4514, 4514, 10, 2013, 0xf7c78ab2 1, 4524, 4524, 10, 2013, 0x24049816 1, 4534, 4534, 10, 2013, 0x52089dcf -0, 136, 136, 1, 518400, 0xfa22c508 +0, 136, 136, 1, 518400, 0x9d202a03 1, 4550, 4550, 10, 2013, 0x2150a0b1 1, 4560, 4560, 10, 2013, 0x3c2e9b93 1, 4570, 4570, 10, 2013, 0x491f932b -0, 137, 137, 1, 518400, 0xddda1712 +0, 137, 137, 1, 518400, 0x822f8062 1, 4580, 4580, 10, 2013, 0x31359cf8 1, 4590, 4590, 10, 2013, 0x1b00ac3f 1, 4600, 4600, 10, 2013, 0x8d7ab3cb -0, 138, 138, 1, 518400, 0x985a3b93 +0, 138, 138, 1, 518400, 0xe011aad7 1, 4610, 4610, 10, 2013, 0xb2c2a4de 1, 4620, 4620, 10, 2013, 0x80a4abf2 1, 4635, 4635, 10, 2013, 0x0701a4ee -0, 139, 139, 1, 518400, 0xea63c5e7 +0, 139, 139, 1, 518400, 0xb0934609 1, 4645, 4645, 10, 2013, 0xdc1ba5bc 1, 4655, 4655, 10, 2013, 0x6083a8a4 1, 4665, 4665, 10, 2013, 0x6226ad45 -0, 140, 140, 1, 518400, 0xef64983d +0, 140, 140, 1, 518400, 0xb22a25e0 1, 4675, 4675, 10, 2013, 0x2732a205 1, 4685, 4685, 10, 2013, 0x0f62a0d3 1, 4695, 4695, 10, 2013, 0xc1799249 -0, 141, 141, 1, 518400, 0x747bb193 +0, 141, 141, 1, 518400, 0x4a715018 1, 4705, 4705, 10, 2013, 0xbccfa9c8 1, 4720, 4720, 10, 2013, 0xded096e7 1, 4730, 4730, 10, 2013, 0x7f0daf43 -0, 142, 142, 1, 518400, 0xb8748862 +0, 142, 142, 1, 518400, 0x63f24360 1, 4740, 4740, 10, 2013, 0xc47ea682 1, 4750, 4750, 10, 2013, 0x5a72b07a 1, 4760, 4760, 10, 2013, 0x386faa8c 1, 4770, 4770, 10, 2013, 0xf9919a91 -0, 143, 143, 1, 518400, 0xaab55a5f +0, 143, 143, 1, 518400, 0x93002157 1, 4780, 4780, 10, 2013, 0x4908897e 1, 4790, 4790, 10, 2013, 0x4882b594 -0, 144, 144, 1, 518400, 0x7b468add +0, 144, 144, 1, 518400, 0xab6b616b 1, 4806, 4806, 10, 2013, 0x113e98d1 1, 4816, 4816, 10, 2013, 0x5098b30d 1, 4826, 4826, 10, 2013, 0x0ef7b857 1, 4836, 4836, 10, 2013, 0x216ea176 -0, 145, 145, 1, 518400, 0xf2078707 +0, 145, 145, 1, 518400, 0x331375bf 1, 4846, 4846, 10, 2013, 0xf906944a 1, 4856, 4856, 10, 2013, 0xee9b92fb 1, 4866, 4866, 10, 2013, 0xd6029209 -0, 146, 146, 1, 518400, 0x6a2d931e +0, 146, 146, 1, 518400, 0x4d8992ca 1, 4876, 4876, 10, 2013, 0x2256a12e 1, 4891, 4891, 10, 2013, 0x89de8e4a 1, 4901, 4901, 10, 2013, 0x0bf0a584 -0, 147, 147, 1, 518400, 0xbbe3c417 +0, 147, 147, 1, 518400, 0x60ebc989 1, 4911, 4911, 10, 2013, 0x6a5ebd58 1, 4921, 4921, 10, 2013, 0x3edd9aa4 1, 4931, 4931, 10, 2013, 0xbd66ac26 -0, 148, 148, 1, 518400, 0x6294e449 +0, 148, 148, 1, 518400, 0xcb0cf07d 1, 4941, 4941, 10, 2013, 0x313896ea 1, 4951, 4951, 10, 2013, 0x6b83a6a0 1, 4961, 4961, 10, 2013, 0x9aafb109 -0, 149, 149, 1, 518400, 0xa05721e7 +0, 149, 149, 1, 518400, 0x8374277a 1, 4976, 4976, 10, 2013, 0x5192a85a 1, 4986, 4986, 10, 2013, 0x1f919f79 1, 4996, 4996, 10, 2013, 0xc0799c40 -0, 150, 150, 1, 518400, 0x37749183 +0, 150, 150, 1, 518400, 0x72678781 1, 5006, 5006, 10, 2013, 0x2988bcd8 1, 5016, 5016, 10, 2013, 0x1482913a 1, 5026, 5026, 10, 2013, 0x74da9a94 1, 5036, 5036, 10, 2013, 0x763eb709 -0, 151, 151, 1, 518400, 0xf9d9dca0 +0, 151, 151, 1, 518400, 0x46e2d001 1, 5046, 5046, 10, 2013, 0x1285b405 1, 5062, 5062, 10, 2013, 0xb6ab9dfc -0, 152, 152, 1, 518400, 0x5f8ccf08 +0, 152, 152, 1, 518400, 0x892cac49 1, 5072, 5072, 10, 2013, 0xe4c8bf19 1, 5082, 5082, 10, 2013, 0xabbbade8 1, 5092, 5092, 10, 2013, 0xf8b69d89 1, 5102, 5102, 10, 2013, 0xce04a866 -0, 153, 153, 1, 518400, 0x7303f77b +0, 153, 153, 1, 518400, 0xd14dc25b 1, 5112, 5112, 10, 2013, 0x07528abf 1, 5122, 5122, 10, 2013, 0x74fb98bf 1, 5132, 5132, 10, 2013, 0x579fb1c9 -0, 154, 154, 1, 518400, 0x22b0513f +0, 154, 154, 1, 518400, 0x8c5e0503 1, 5147, 5147, 10, 2013, 0x7ddea2ed 1, 5157, 5157, 10, 2013, 0x296caa2c 1, 5167, 5167, 10, 2013, 0x346d9c4f -0, 155, 155, 1, 518400, 0x330485d2 +0, 155, 155, 1, 518400, 0x854e20f7 1, 5177, 5177, 10, 2013, 0x3e1fba15 1, 5187, 5187, 10, 2013, 0x48a2908f 1, 5197, 5197, 10, 2013, 0xc1938d09 -0, 156, 156, 1, 518400, 0x7f83daea +0, 156, 156, 1, 518400, 0x9a876ae7 1, 5207, 5207, 10, 2013, 0x0e96a060 1, 5217, 5217, 10, 2013, 0x7b6a9e06 1, 5232, 5232, 10, 2013, 0x5b779d28 -0, 157, 157, 1, 518400, 0xee19f2df +0, 157, 157, 1, 518400, 0xccf16959 1, 5242, 5242, 10, 2013, 0xf600aca1 1, 5252, 5252, 10, 2013, 0x3a6c9e68 1, 5262, 5262, 10, 2013, 0x0c8dc1b0 -0, 158, 158, 1, 518400, 0xb71b1c77 +0, 158, 158, 1, 518400, 0x64807453 1, 5272, 5272, 10, 2013, 0x26beb245 1, 5282, 5282, 10, 2013, 0x2bc09557 1, 5292, 5292, 10, 2013, 0x27fc8845 1, 5302, 5302, 10, 2013, 0x1025aa47 -0, 159, 159, 1, 518400, 0xbffc1856 +0, 159, 159, 1, 518400, 0xe6285a78 1, 5318, 5318, 10, 2013, 0xc2e69baa 1, 5328, 5328, 10, 2013, 0xdb249b92 1, 5338, 5338, 10, 2013, 0x6ccda29e -0, 160, 160, 1, 518400, 0xabc125aa +0, 160, 160, 1, 518400, 0xf8f353dc 1, 5348, 5348, 10, 2013, 0xeaf6a1cf 1, 5358, 5358, 10, 2013, 0x509ba397 1, 5368, 5368, 10, 2013, 0xfaf8a2df -0, 161, 161, 1, 518400, 0x5ee467f8 +0, 161, 161, 1, 518400, 0x12b87c38 1, 5378, 5378, 10, 2013, 0x41388f28 1, 5388, 5388, 10, 2013, 0xfe5eab39 1, 5403, 5403, 10, 2013, 0xd5ffa066 -0, 162, 162, 1, 518400, 0x6c2cf168 +0, 162, 162, 1, 518400, 0x845ef12d 1, 5413, 5413, 10, 2013, 0x6813a30a 1, 5423, 5423, 10, 2013, 0x9be89718 1, 5433, 5433, 10, 2013, 0xaec3a27b -0, 163, 163, 1, 518400, 0x63996b26 +0, 163, 163, 1, 518400, 0x01255194 1, 5446, 5446, 10, 2013, 0x579a983e 1, 5456, 5456, 10, 2013, 0x98cea21f 1, 5466, 5466, 10, 2013, 0xca77a58a -0, 164, 164, 1, 518400, 0xb34d789a +0, 164, 164, 1, 518400, 0x3e103dd6 1, 5476, 5476, 10, 2013, 0xcbc3b1ee 1, 5486, 5486, 10, 2013, 0xf3bb8f07 1, 5496, 5496, 10, 2013, 0x6aeebd92 -0, 165, 165, 1, 518400, 0xf49c030f +0, 165, 165, 1, 518400, 0xf47bafa0 1, 5506, 5506, 10, 2013, 0xe955a449 1, 5516, 5516, 10, 2013, 0x9436aa5b 1, 5531, 5531, 10, 2013, 0x4f0a8f9f -0, 166, 166, 1, 518400, 0x092dc41a +0, 166, 166, 1, 518400, 0x4ce46108 1, 5541, 5541, 10, 2013, 0x3551b22d 1, 5551, 5551, 10, 2013, 0x0959a3d4 1, 5561, 5561, 10, 2013, 0x2ed5a11b 1, 5571, 5571, 10, 2013, 0x8f52a5c3 -0, 167, 167, 1, 518400, 0x4134c577 +0, 167, 167, 1, 518400, 0x27ec4f32 1, 5581, 5581, 10, 2013, 0x6552978d 1, 5591, 5591, 10, 2013, 0x7dcca0c1 1, 5601, 5601, 10, 2013, 0xbcd4a3c9 -0, 168, 168, 1, 518400, 0x261de1ed +0, 168, 168, 1, 518400, 0xe0bc547a 1, 5616, 5616, 10, 2013, 0xfe41a8d8 1, 5626, 5626, 10, 2013, 0xc85aae14 1, 5636, 5636, 10, 2013, 0x1185b346 -0, 169, 169, 1, 518400, 0xcbc8566a +0, 169, 169, 1, 518400, 0xc36fc0c8 1, 5646, 5646, 10, 2013, 0xf7429a0d 1, 5656, 5656, 10, 2013, 0x48c2a160 1, 5666, 5666, 10, 2013, 0x9d85a85d -0, 170, 170, 1, 518400, 0x407a5c76 +0, 170, 170, 1, 518400, 0x34b5b437 1, 5676, 5676, 10, 2013, 0xbbe89fe9 1, 5686, 5686, 10, 2013, 0xea429fe2 1, 5702, 5702, 10, 2013, 0x221ca1d4 -0, 171, 171, 1, 518400, 0x1ed73bb2 +0, 171, 171, 1, 518400, 0x699e770b 1, 5712, 5712, 10, 2013, 0x394b925b 1, 5722, 5722, 10, 2013, 0x556dc26f 1, 5732, 5732, 10, 2013, 0xce21a5e1 -0, 172, 172, 1, 518400, 0x8467ddb5 +0, 172, 172, 1, 518400, 0xf5810fdc 1, 5742, 5742, 10, 2013, 0xbc87c0a8 1, 5752, 5752, 10, 2013, 0xbac4ac07 1, 5762, 5762, 10, 2013, 0xdeefa4aa 1, 5772, 5772, 10, 2013, 0x1f15b362 -0, 173, 173, 1, 518400, 0x0523dc73 +0, 173, 173, 1, 518400, 0xe345f768 1, 5787, 5787, 10, 2013, 0x6406b7b2 1, 5797, 5797, 10, 2013, 0x8030a03d -0, 174, 174, 1, 518400, 0x81f5e895 +0, 174, 174, 1, 518400, 0x3f4fe36a 1, 5807, 5807, 10, 2013, 0x0373a5b1 1, 5817, 5817, 10, 2013, 0x34ef93da 1, 5827, 5827, 10, 2013, 0x94c198fe 1, 5837, 5837, 10, 2013, 0xfefcabad -0, 175, 175, 1, 518400, 0xfc74608d +0, 175, 175, 1, 518400, 0x1a2d53bb 1, 5847, 5847, 10, 2013, 0x8755b3ec 1, 5857, 5857, 10, 2013, 0xe436a6fd 1, 5872, 5872, 10, 2013, 0x9cf5a11e -0, 176, 176, 1, 518400, 0xc4e0dae0 +0, 176, 176, 1, 518400, 0x7f31b326 1, 5882, 5882, 10, 2013, 0x03b8a98c 1, 5892, 5892, 10, 2013, 0x6216a138 1, 5902, 5902, 10, 2013, 0xd87b9f12 -0, 177, 177, 1, 518400, 0x98367f5b +0, 177, 177, 1, 518400, 0xc0a53fae 1, 5912, 5912, 10, 2013, 0x4ce99653 1, 5922, 5922, 10, 2013, 0x6c2ea9e2 1, 5932, 5932, 10, 2013, 0x918cae4c -0, 178, 178, 1, 518400, 0x0f1a869d +0, 178, 178, 1, 518400, 0xb58e38ee 1, 5942, 5942, 10, 2013, 0xd19fa5f2 1, 5958, 5958, 10, 2013, 0x0bdda7c6 1, 5968, 5968, 10, 2013, 0x0f9ab0ca -0, 179, 179, 1, 518400, 0x45b6ccf2 +0, 179, 179, 1, 518400, 0x920a6b68 1, 5978, 5978, 10, 2013, 0x410a92b1 1, 5988, 5988, 10, 2013, 0xcfbe9d1c 1, 5998, 5998, 10, 2013, 0x59ed9d15 -0, 180, 180, 1, 518400, 0x5f9ccb77 +0, 180, 180, 1, 518400, 0xcc2f5945 1, 6008, 6008, 10, 2013, 0x4e129e27 1, 6018, 6018, 10, 2013, 0x7bb9ac0a 1, 6028, 6028, 10, 2013, 0x826ca82b -0, 181, 181, 1, 518400, 0x5f15ea31 +0, 181, 181, 1, 518400, 0x939b6cbc 1, 6043, 6043, 10, 2013, 0x9ad5a74b 1, 6053, 6053, 10, 2013, 0x6c5f969a 1, 6063, 6063, 10, 2013, 0x8479a0e5 -0, 182, 182, 1, 518400, 0x86369f27 +0, 182, 182, 1, 518400, 0xbe7c0d58 1, 6073, 6073, 10, 2013, 0x165298ef 1, 6083, 6083, 10, 2013, 0xdcadb4a1 1, 6093, 6093, 10, 2013, 0xa90e987c 1, 6103, 6103, 10, 2013, 0x1ac5b510 -0, 183, 183, 1, 518400, 0x2e27f9fa +0, 183, 183, 1, 518400, 0x872c53f9 1, 6113, 6113, 10, 2013, 0x66728d85 1, 6128, 6128, 10, 2013, 0xe4859fc5 1, 6138, 6138, 10, 2013, 0x9901786e -0, 184, 184, 1, 518400, 0xc029a44d +0, 184, 184, 1, 518400, 0xef85f3e1 1, 6148, 6148, 10, 2013, 0x6aebb406 1, 6158, 6158, 10, 2013, 0x7d13a2cc 1, 6168, 6168, 10, 2013, 0x99b7a8cc -0, 185, 185, 1, 518400, 0xebee33b0 +0, 185, 185, 1, 518400, 0xbdbc70ff 1, 6178, 6178, 10, 2013, 0x80b8a624 1, 6188, 6188, 10, 2013, 0xbb6aa271 1, 6198, 6198, 10, 2013, 0x17af9e4a -0, 186, 186, 1, 518400, 0x19e5494f +0, 186, 186, 1, 518400, 0x16ad73b4 1, 6214, 6214, 10, 2013, 0xfaf0a8f1 1, 6224, 6224, 10, 2013, 0xd6849b93 1, 6234, 6234, 10, 2013, 0xe9829669 -0, 187, 187, 1, 518400, 0xf697bd7c +0, 187, 187, 1, 518400, 0x5356dbec 1, 6244, 6244, 10, 2013, 0x7ec98944 1, 6254, 6254, 10, 2013, 0x2b2099a4 1, 6264, 6264, 10, 2013, 0x1033a82f -0, 188, 188, 1, 518400, 0x82569002 +0, 188, 188, 1, 518400, 0xad4da4ed 1, 6274, 6274, 10, 2013, 0x5ec88990 1, 6284, 6284, 10, 2013, 0xd2a19b3d 1, 6299, 6299, 10, 2013, 0xa377b268 -0, 189, 189, 1, 518400, 0xfcb6d707 +0, 189, 189, 1, 518400, 0x06fbdb66 1, 6309, 6309, 10, 2013, 0xfa859901 1, 6319, 6319, 10, 2013, 0x1713955a 1, 6329, 6329, 10, 2013, 0x70aab0da 1, 6339, 6339, 10, 2013, 0xcdaea422 -0, 190, 190, 1, 518400, 0x82a9662b +0, 190, 190, 1, 518400, 0xdf0d6390 1, 6349, 6349, 10, 2013, 0x65c3bf80 1, 6359, 6359, 10, 2013, 0x1d75a55f 1, 6369, 6369, 10, 2013, 0xa5bea4de -0, 191, 191, 1, 518400, 0x212e16ee +0, 191, 191, 1, 518400, 0xbf4207ac 1, 6384, 6384, 10, 2013, 0x184db71c 1, 6394, 6394, 10, 2013, 0x99858ec8 1, 6404, 6404, 10, 2013, 0xb8f2aee5 -0, 192, 192, 1, 518400, 0x2ca34dca +0, 192, 192, 1, 518400, 0x119531ed 1, 6414, 6414, 10, 2013, 0x4435b2ef 1, 6424, 6424, 10, 2013, 0x8acfa6c7 1, 6434, 6434, 10, 2013, 0x42b4c01f -0, 193, 193, 1, 518400, 0xe9ebe0a5 +0, 193, 193, 1, 518400, 0xc160bca8 1, 6444, 6444, 10, 2013, 0x6e308c13 1, 6454, 6454, 10, 2013, 0x8227a0f6 1, 6470, 6470, 10, 2013, 0x6f12a7a2 -0, 194, 194, 1, 518400, 0x4e6b6917 +0, 194, 194, 1, 518400, 0xcd9b3639 1, 6480, 6480, 10, 2013, 0x785392be 1, 6490, 6490, 10, 2013, 0x81849c2b 1, 6500, 6500, 10, 2013, 0x5cf2af65 -0, 195, 195, 1, 518400, 0x7dcf20ab +0, 195, 195, 1, 518400, 0x7c4ad83a 1, 6510, 6510, 10, 2013, 0x0c6ca6b4 1, 6520, 6520, 10, 2013, 0x412fab9f 1, 6530, 6530, 10, 2013, 0x08e792b4 -0, 196, 196, 1, 518400, 0xf30fac97 +0, 196, 196, 1, 518400, 0xe3255ff4 1, 6540, 6540, 10, 2013, 0x407aace3 1, 6555, 6555, 10, 2013, 0xd26bac16 1, 6565, 6565, 10, 2013, 0xac8bb295 -0, 197, 197, 1, 518400, 0xcb9fc692 +0, 197, 197, 1, 518400, 0x257a6758 1, 6575, 6575, 10, 2013, 0xddd1949c 1, 6585, 6585, 10, 2013, 0x6b26b868 1, 6595, 6595, 10, 2013, 0x5eaba587 1, 6605, 6605, 10, 2013, 0xef0793b9 -0, 198, 198, 1, 518400, 0x5d05601e +0, 198, 198, 1, 518400, 0xcfa4f4e0 1, 6615, 6615, 10, 2013, 0xdef19bd6 1, 6625, 6625, 10, 2013, 0xca98a635 -0, 199, 199, 1, 518400, 0x456c1417 +0, 199, 199, 1, 518400, 0x5f159eff 1, 6640, 6640, 10, 2013, 0x06269a5a 1, 6650, 6650, 10, 2013, 0x32cb9952 1, 6660, 6660, 10, 2013, 0xf01fa95a 1, 6670, 6670, 10, 2013, 0xefab9e55 -0, 200, 200, 1, 518400, 0x9a0fd1ad +0, 200, 200, 1, 518400, 0x31d257bc 1, 6680, 6680, 10, 2013, 0x55a3b63a 1, 6690, 6690, 10, 2013, 0xcd36a553 1, 6700, 6700, 10, 2013, 0x2ec19877 -0, 201, 201, 1, 518400, 0x55db9716 +0, 201, 201, 1, 518400, 0x81c516b9 1, 6710, 6710, 10, 2013, 0xc18b924c 1, 6726, 6726, 10, 2013, 0xf132b04c 1, 6736, 6736, 10, 2013, 0x7975a44d -0, 202, 202, 1, 518400, 0x1f0d40d6 +0, 202, 202, 1, 518400, 0x56b7bf87 1, 6746, 6746, 10, 2013, 0x2aaf94cb 1, 6756, 6756, 10, 2013, 0x58cfa60f 1, 6766, 6766, 10, 2013, 0x9757a658 -0, 203, 203, 1, 518400, 0x73695c82 +0, 203, 203, 1, 518400, 0x4f83dd2e 1, 6776, 6776, 10, 2013, 0x67ebc0d5 1, 6786, 6786, 10, 2013, 0x3c50a70e 1, 6796, 6796, 10, 2013, 0x9c5799c6 -0, 204, 204, 1, 518400, 0xb0f10812 +0, 204, 204, 1, 518400, 0x0d4389d7 1, 6811, 6811, 10, 2013, 0x018d85b2 1, 6821, 6821, 10, 2013, 0x5367a956 -0, 205, 205, 1, 518400, 0xdec18505 -0, 208, 208, 1, 518400, 0xb147b947 -0, 240, 240, 1, 518400, 0x9d2e3977 +0, 205, 205, 1, 518400, 0x375b056f +0, 208, 208, 1, 518400, 0x9d2e3977 diff --git a/tests/ref/fate/sub-dvb b/tests/ref/fate/sub-dvb index cbd1801d64..8f33c75d70 100644 --- a/tests/ref/fate/sub-dvb +++ b/tests/ref/fate/sub-dvb @@ -1,75 +1,93 @@ #tb 0: 1/1000000 #media_type 0: subtitle #codec_id 0: dvb_subtitle -0, 15600000, 15600000, 159000, 1168, 0xd0f89d82 -0, 15759000, 15759000, 159000, 14, 0x064900eb -0, 15760000, 15760000, 239000, 1544, 0xe60f1751 -0, 15999000, 15999000, 239000, 14, 0x0729010b -0, 16000000, 16000000, 339000, 1658, 0xbe343093 -0, 16339000, 16339000, 339000, 14, 0x0809012b -0, 16340000, 16340000, 599000, 2343, 0xc68f07ef -0, 16939000, 16939000, 599000, 14, 0x08e9014b -0, 16940000, 16940000, 459000, 2568, 0x0ee657b1 -0, 17399000, 17399000, 459000, 14, 0x09c9016b -0, 17400000, 17400000, 359000, 3422, 0xba5b63ce -0, 17759000, 17759000, 359000, 14, 0x0aa9018b -0, 17760000, 17760000, 219000, 5078, 0x95b19902 -0, 17979000, 17979000, 219000, 14, 0x0b8901ab -0, 17980000, 17980000, 959000, 5808, 0xc9717b89 -0, 18939000, 18939000, 959000, 14, 0x0c6901cb -0, 18940000, 18940000, 219000, 6015, 0x0becbfac -0, 19159000, 19159000, 219000, 14, 0x064900eb -0, 19160000, 19160000, 259000, 6519, 0xfcd24d26 -0, 19419000, 19419000, 259000, 14, 0x0729010b -0, 19420000, 19420000, 99000, 7061, 0xf0320408 -0, 19519000, 19519000, 99000, 14, 0x0809012b -0, 19520000, 19520000, 219000, 4773, 0x66c93074 -0, 19739000, 19739000, 219000, 14, 0x08e9014b -0, 19740000, 19740000, 219000, 5546, 0x06052c81 -0, 19959000, 19959000, 219000, 14, 0x09c9016b -0, 19960000, 19960000, 239000, 5754, 0x904f7325 -0, 20199000, 20199000, 239000, 14, 0x0aa9018b -0, 20200000, 20200000, 139000, 6099, 0xe30cde07 -0, 20339000, 20339000, 139000, 14, 0x0b8901ab -0, 20340000, 20340000, 799000, 6839, 0x770fcb6c -0, 21139000, 21139000, 799000, 14, 0x0c6901cb -0, 21140000, 21140000, 239000, 4744, 0xa91e1b41 -0, 21379000, 21379000, 239000, 14, 0x064900eb -0, 21380000, 21380000, 339000, 5824, 0xcf6d782b -0, 21719000, 21719000, 339000, 14, 0x0729010b -0, 21720000, 21720000, 1439000, 6212, 0xabf8f7cf -0, 23159000, 23159000, 1439000, 14, 0x0809012b -0, 23160000, 23160000, 1319000, 7082, 0xd7ca10f2 -0, 24479000, 24479000, 1319000, 14, 0x08e9014b -0, 24480000, 24480000, 219000, 5345, 0x12b2cae0 -0, 24699000, 24699000, 219000, 14, 0x09c9016b -0, 24700000, 24700000, 219000, 5765, 0xc7d46192 -0, 24919000, 24919000, 219000, 14, 0x0aa9018b -0, 24920000, 24920000, 599000, 6557, 0xcb995d30 -0, 25519000, 25519000, 599000, 14, 0x0b8901ab -0, 25520000, 25520000, 219000, 7091, 0xe6ea0559 -0, 25739000, 25739000, 219000, 14, 0x0c6901cb -0, 25740000, 25740000, 239000, 7305, 0xb66c404e -0, 25979000, 25979000, 239000, 14, 0x064900eb -0, 25980000, 25980000, 359000, 7590, 0x0cc2a481 -0, 26339000, 26339000, 359000, 14, 0x0729010b -0, 26340000, 26340000, 219000, 4629, 0xe18cfea8 -0, 26559000, 26559000, 219000, 14, 0x0809012b -0, 26560000, 26560000, 719000, 4785, 0x82043fc0 -0, 27279000, 27279000, 719000, 14, 0x08e9014b -0, 27280000, 27280000, 459000, 6061, 0xbde7d245 -0, 27739000, 27739000, 459000, 14, 0x09c9016b -0, 27740000, 27740000, 239000, 6301, 0x92d01a51 -0, 27979000, 27979000, 239000, 14, 0x0aa9018b -0, 27980000, 27980000, 99000, 6736, 0xbd25a134 -0, 28079000, 28079000, 99000, 14, 0x0b8901ab -0, 28080000, 28080000, 219000, 7214, 0x7ef93c13 -0, 28299000, 28299000, 219000, 14, 0x0c6901cb -0, 28300000, 28300000, 239000, 7366, 0x5bed7fcd -0, 28539000, 28539000, 239000, 14, 0x064900eb -0, 28540000, 28540000, 599000, 4564, 0x7f4c014b -0, 29139000, 29139000, 599000, 14, 0x0729010b -0, 29140000, 29140000, 219000, 4637, 0x682626b7 -0, 29359000, 29359000, 219000, 14, 0x0809012b -0, 29360000, 29360000, 1679000, 5358, 0x29e30c48 -0, 31039000, 31039000, 1679000, 14, 0x08e9014b +0, 0, 0, 279000, 14, 0x05d900db +0, 279000, 279000, 279000, 14, 0x064900eb +0, 280000, 280000, 4999000, 14, 0x06b900fb +0, 5279000, 5279000, 4999000, 14, 0x0729010b +0, 5280000, 5280000, 5019000, 14, 0x0799011b +0, 10299000, 10299000, 5019000, 14, 0x0809012b +0, 10300000, 10300000, 3599000, 14, 0x0879013b +0, 13899000, 13899000, 3599000, 14, 0x08e9014b +0, 13900000, 13900000, 219000, 14, 0x0959015b +0, 14119000, 14119000, 219000, 14, 0x09c9016b +0, 14120000, 14120000, 1439000, 14, 0x0a39017b +0, 15559000, 15559000, 1439000, 14, 0x0aa9018b +0, 15560000, 15560000, 39000, 14, 0x0b19019b +0, 15599000, 15599000, 39000, 14, 0x0b8901ab +0, 15600000, 15600000, 159000, 1168, 0xd69da022 +0, 15759000, 15759000, 159000, 14, 0x0c6901cb +0, 15760000, 15760000, 239000, 1544, 0xc5f116f1 +0, 15999000, 15999000, 239000, 14, 0x064900eb +0, 16000000, 16000000, 339000, 1658, 0x73563033 +0, 16339000, 16339000, 339000, 14, 0x0729010b +0, 16340000, 16340000, 599000, 2343, 0x7ac2078f +0, 16939000, 16939000, 599000, 14, 0x0809012b +0, 16940000, 16940000, 459000, 2568, 0x6eaa5751 +0, 17399000, 17399000, 459000, 14, 0x08e9014b +0, 17400000, 17400000, 359000, 3422, 0xd9d0636e +0, 17759000, 17759000, 359000, 14, 0x09c9016b +0, 17760000, 17760000, 219000, 5078, 0x722c9862 +0, 17979000, 17979000, 219000, 14, 0x0aa9018b +0, 17980000, 17980000, 959000, 5808, 0x38dd7ae9 +0, 18939000, 18939000, 959000, 14, 0x0b8901ab +0, 18940000, 18940000, 219000, 6015, 0xd4d2c40c +0, 19159000, 19159000, 219000, 14, 0x0c6901cb +0, 19160000, 19160000, 259000, 6519, 0x08af4c86 +0, 19419000, 19419000, 259000, 14, 0x064900eb +0, 19420000, 19420000, 99000, 7061, 0xecf10368 +0, 19519000, 19519000, 99000, 14, 0x0729010b +0, 19520000, 19520000, 219000, 4773, 0xbee42fd4 +0, 19739000, 19739000, 219000, 14, 0x0809012b +0, 19740000, 19740000, 219000, 5546, 0xdb822be1 +0, 19959000, 19959000, 219000, 14, 0x08e9014b +0, 19960000, 19960000, 239000, 5754, 0xfdcc7285 +0, 20199000, 20199000, 239000, 14, 0x09c9016b +0, 20200000, 20200000, 139000, 6099, 0xa409dd67 +0, 20339000, 20339000, 139000, 14, 0x0aa9018b +0, 20340000, 20340000, 799000, 6839, 0xc5eecacc +0, 21139000, 21139000, 799000, 14, 0x0b8901ab +0, 21140000, 21140000, 239000, 4744, 0x4e451fa1 +0, 21379000, 21379000, 239000, 14, 0x0c6901cb +0, 21380000, 21380000, 339000, 5824, 0x5299778b +0, 21719000, 21719000, 339000, 14, 0x064900eb +0, 21720000, 21720000, 1439000, 6212, 0x6d15f72f +0, 23159000, 23159000, 1439000, 14, 0x0729010b +0, 23160000, 23160000, 1319000, 7082, 0xe5c91052 +0, 24479000, 24479000, 1319000, 14, 0x0809012b +0, 24480000, 24480000, 219000, 5345, 0x2e5eca40 +0, 24699000, 24699000, 219000, 14, 0x08e9014b +0, 24700000, 24700000, 219000, 5765, 0x118060f2 +0, 24919000, 24919000, 219000, 14, 0x09c9016b +0, 24920000, 24920000, 599000, 6557, 0x89275c90 +0, 25519000, 25519000, 599000, 14, 0x0aa9018b +0, 25520000, 25520000, 219000, 7091, 0x996904b9 +0, 25739000, 25739000, 219000, 14, 0x0b8901ab +0, 25740000, 25740000, 239000, 7305, 0xc23e44ae +0, 25979000, 25979000, 239000, 14, 0x0c6901cb +0, 25980000, 25980000, 359000, 7590, 0xc5a3a3e1 +0, 26339000, 26339000, 359000, 14, 0x064900eb +0, 26340000, 26340000, 219000, 4629, 0x7ad6fe08 +0, 26559000, 26559000, 219000, 14, 0x0729010b +0, 26560000, 26560000, 719000, 4785, 0xcd3f3f20 +0, 27279000, 27279000, 719000, 14, 0x0809012b +0, 27280000, 27280000, 459000, 6061, 0x8b04d1a5 +0, 27739000, 27739000, 459000, 14, 0x08e9014b +0, 27740000, 27740000, 239000, 6301, 0xe7de19b1 +0, 27979000, 27979000, 239000, 14, 0x09c9016b +0, 27980000, 27980000, 99000, 6736, 0x38b3a094 +0, 28079000, 28079000, 99000, 14, 0x0aa9018b +0, 28080000, 28080000, 219000, 7214, 0x0b783b73 +0, 28299000, 28299000, 219000, 14, 0x0b8901ab +0, 28300000, 28300000, 239000, 7366, 0x98bf842d +0, 28539000, 28539000, 239000, 14, 0x0c6901cb +0, 28540000, 28540000, 599000, 4564, 0x3d9600ab +0, 29139000, 29139000, 599000, 14, 0x064900eb +0, 29140000, 29140000, 219000, 4637, 0x01f02617 +0, 29359000, 29359000, 219000, 14, 0x0729010b +0, 29360000, 29360000, 1679000, 5358, 0x5b0f0ba8 +0, 31039000, 31039000, 1679000, 14, 0x0809012b +0, 31040000, 31040000, 359000, 14, 0x0879013b +0, 31399000, 31399000, 359000, 14, 0x08e9014b +0, 31400000, 31400000, 479000, 14, 0x0959015b +0, 31879000, 31879000, 479000, 14, 0x09c9016b diff --git a/tests/ref/fate/sub2video b/tests/ref/fate/sub2video index 80abe9c905..f6108f92ac 100644 --- a/tests/ref/fate/sub2video +++ b/tests/ref/fate/sub2video @@ -36,30 +36,31 @@ 0, 25, 25, 1, 518400, 0x7322e11c 0, 26, 26, 1, 518400, 0x45af1a84 0, 27, 27, 1, 518400, 0x7b781071 -0, 28, 28, 1, 518400, 0x4f7c706c -0, 29, 29, 1, 518400, 0xb227603b -0, 30, 30, 1, 518400, 0x7b4b89c2 -0, 31, 31, 1, 518400, 0x456da21e -0, 32, 32, 1, 518400, 0xb691979f -0, 33, 33, 1, 518400, 0x0dfaa66d -0, 34, 34, 1, 518400, 0x191a6f23 -0, 35, 35, 1, 518400, 0xa03b2605 -0, 36, 36, 1, 518400, 0xb36aff87 -0, 37, 37, 1, 518400, 0xf5f0bc4a -0, 38, 38, 1, 518400, 0x863d701a -0, 39, 39, 1, 518400, 0xd11b4dce -0, 40, 40, 1, 518400, 0x969236bd -0, 41, 41, 1, 518400, 0xb60a485c -0, 42, 42, 1, 518400, 0xe9796621 -0, 43, 43, 1, 518400, 0x3e8fc04b -0, 44, 44, 1, 518400, 0xac9944e3 -0, 45, 45, 1, 518400, 0x01452b4d -0, 46, 46, 1, 518400, 0xb384f6d2 -0, 47, 47, 1, 518400, 0xde69683f -0, 48, 48, 1, 518400, 0x7df08fba -0, 49, 49, 1, 518400, 0xbab197ea +0, 28, 28, 1, 518400, 0x08a0ed62 +0, 29, 29, 1, 518400, 0x39b1e7eb +0, 30, 30, 1, 518400, 0x20a11073 +0, 31, 31, 1, 518400, 0x7e19198d +0, 32, 32, 1, 518400, 0xeed206eb +0, 33, 33, 1, 518400, 0xcf451b3d +0, 34, 34, 1, 518400, 0xa0a2eb3c +0, 35, 35, 1, 518400, 0xd598a9e3 +0, 36, 36, 1, 518400, 0x10908608 +0, 37, 37, 1, 518400, 0xa3a03b86 +0, 38, 38, 1, 518400, 0x0190e39a +0, 39, 39, 1, 518400, 0x5d39b978 +0, 40, 40, 1, 518400, 0x5ba29f40 +0, 41, 41, 1, 518400, 0x86c1b3ed +0, 42, 42, 1, 518400, 0x77b1d91b +0, 43, 43, 1, 518400, 0xa28d38d6 +0, 44, 44, 1, 518400, 0xc86abb34 +0, 45, 45, 1, 518400, 0xe753a664 +0, 46, 46, 1, 518400, 0xc7ea803c +0, 47, 47, 1, 518400, 0x797eff2d +0, 48, 48, 1, 518400, 0xc69c300c +0, 49, 49, 1, 518400, 0x8d21303f 1, 15355000, 15355000, 4733000, 2094, 0x3c171425 -0, 77, 77, 1, 518400, 0x902285d9 +0, 77, 77, 1, 518400, 0xbab197ea +0, 78, 78, 1, 518400, 0x902285d9 0, 100, 100, 1, 518400, 0xbab197ea 1, 48797000, 48797000, 2560000, 2480, 0x7c0edf21 0, 244, 244, 1, 518400, 0x7a11c812 @@ -183,4 +184,4 @@ 0, 1139, 1139, 1, 518400, 0xbab197ea 1, 227834000, 227834000, 1262000, 1264, 0xc1d9fc57 0, 1140, 1140, 1, 518400, 0xb046dd30 -0, 1145, 1145, 1, 518400, 0xbab197ea +0, 1145, 1145, 1, 518400, 0xb046dd30 diff --git a/tests/ref/fate/sub2video_basic b/tests/ref/fate/sub2video_basic index 5f72e292c9..aaebb8f8df 100644 --- a/tests/ref/fate/sub2video_basic +++ b/tests/ref/fate/sub2video_basic @@ -1,95 +1,91 @@ #tb 0: 1/25 #media_type 0: video #codec_id 0: rawvideo -#dimensions 0: 720x480 +#dimensions 0: 1920x1080 #sar 0: 0/1 -0, 3312, 3312, 1, 1382400, 0x00000000 -0, 3312, 3312, 1, 1382400, 0x8c93c2ba -0, 3436, 3436, 1, 1382400, 0x00000000 -0, 3684, 3684, 1, 1382400, 0xb02e32ca -0, 3802, 3802, 1, 1382400, 0x00000000 -0, 4520, 4520, 1, 1382400, 0x83b71116 -0, 4584, 4584, 1, 1382400, 0x00000000 -0, 4586, 4586, 1, 1382400, 0x85547fd1 -0, 4645, 4645, 1, 1382400, 0x00000000 -0, 4648, 4648, 1, 1382400, 0x00000000 -0, 4648, 4648, 1, 1382400, 0xb6a8f181 -0, 4715, 4715, 1, 1382400, 0x00000000 -0, 4717, 4717, 1, 1382400, 0xb64d1a2c -0, 4748, 4748, 1, 1382400, 0x00000000 -0, 4750, 4750, 1, 1382400, 0x7b37ecf3 -0, 4792, 4792, 1, 1382400, 0x00000000 -0, 4993, 4993, 1, 1382400, 0xdc025bd1 -0, 5027, 5027, 1, 1382400, 0x00000000 -0, 5029, 5029, 1, 1382400, 0x688b294d -0, 5068, 5068, 1, 1382400, 0x00000000 -0, 5070, 5070, 1, 1382400, 0xa2b33d1b -0, 5117, 5117, 1, 1382400, 0x00000000 -0, 5119, 5119, 1, 1382400, 0xb3e525e3 -0, 5168, 5168, 1, 1382400, 0x00000000 -0, 5170, 5170, 1, 1382400, 0xaa8fbdd7 -0, 5216, 5216, 1, 1382400, 0x00000000 -0, 5218, 5218, 1, 1382400, 0x7b7f26dd -0, 5249, 5249, 1, 1382400, 0x00000000 -0, 5251, 5251, 1, 1382400, 0x15e2f836 -0, 5289, 5289, 1, 1382400, 0x00000000 -0, 5291, 5291, 1, 1382400, 0x0fee9b0c -0, 5358, 5358, 1, 1382400, 0x00000000 -0, 5360, 5360, 1, 1382400, 0x89d62791 -0, 5429, 5429, 1, 1382400, 0x00000000 -0, 5431, 5431, 1, 1382400, 0xa6a9fd74 -0, 5490, 5490, 1, 1382400, 0x00000000 -0, 5491, 5491, 1, 1382400, 0x7896178d -0, 5537, 5537, 1, 1382400, 0x00000000 -0, 5588, 5588, 1, 1382400, 0x01751a52 -0, 5647, 5647, 1, 1382400, 0x00000000 -0, 5688, 5688, 1, 1382400, 0xa3959c6f -0, 5770, 5770, 1, 1382400, 0x00000000 -0, 5772, 5772, 1, 1382400, 0x3d3ea47b -0, 5826, 5826, 1, 1382400, 0x00000000 -0, 5828, 5828, 1, 1382400, 0x593f8b24 -0, 5931, 5931, 1, 1382400, 0x00000000 -0, 5933, 5933, 1, 1382400, 0x171f05ba -0, 6001, 6001, 1, 1382400, 0x00000000 -0, 6003, 6003, 1, 1382400, 0xb014cdf1 -0, 6054, 6054, 1, 1382400, 0x00000000 -0, 6839, 6839, 1, 1382400, 0xd918e667 -0, 6880, 6880, 1, 1382400, 0x00000000 -0, 7386, 7386, 1, 1382400, 0xc9406331 -0, 7419, 7419, 1, 1382400, 0x00000000 -0, 7501, 7501, 1, 1382400, 0xaf08b10d -0, 7549, 7549, 1, 1382400, 0x00000000 -0, 7551, 7551, 1, 1382400, 0x00000000 -0, 7551, 7551, 1, 1382400, 0x853a9d93 -0, 7589, 7589, 1, 1382400, 0x00000000 -0, 7605, 7605, 1, 1382400, 0x7491a87d -0, 7647, 7647, 1, 1382400, 0x00000000 -0, 7649, 7649, 1, 1382400, 0xf7383c58 -0, 7697, 7697, 1, 1382400, 0x00000000 -0, 7699, 7699, 1, 1382400, 0xe66be411 -0, 7743, 7743, 1, 1382400, 0x00000000 -0, 8032, 8032, 1, 1382400, 0xd6850362 -0, 8082, 8082, 1, 1382400, 0x00000000 -0, 8084, 8084, 1, 1382400, 0x3e1ed109 -0, 8115, 8115, 1, 1382400, 0x00000000 -0, 8116, 8116, 1, 1382400, 0x39c1b7bd -0, 8160, 8160, 1, 1382400, 0x00000000 -0, 8180, 8180, 1, 1382400, 0x35b85f2e -0, 8207, 8207, 1, 1382400, 0x00000000 -0, 8209, 8209, 1, 1382400, 0x00000000 -0, 8209, 8209, 1, 1382400, 0x83f103e5 -0, 8247, 8247, 1, 1382400, 0x00000000 -0, 8249, 8249, 1, 1382400, 0xbc1ca9b3 -0, 8278, 8278, 1, 1382400, 0x00000000 -0, 8281, 8281, 1, 1382400, 0x94d4a51e -0, 8321, 8321, 1, 1382400, 0x00000000 -0, 8323, 8323, 1, 1382400, 0xf88cdfde -0, 8367, 8367, 1, 1382400, 0x00000000 -0, 8565, 8565, 1, 1382400, 0xdd51423b -0, 8611, 8611, 1, 1382400, 0x00000000 -0, 8669, 8669, 1, 1382400, 0x08259fa4 -0, 8708, 8708, 1, 1382400, 0x00000000 -0, 8941, 8941, 1, 1382400, 0x1663fa34 -0, 8994, 8994, 1, 1382400, 0x00000000 -0, 8996, 8996, 1, 1382400, 0xda2ceb55 -0, 9027, 9027, 1, 1382400, 0x00000000 +0, 3312, 3312, 1, 8294400, 0xc9cac2ba +0, 3684, 3684, 1, 8294400, 0x00000000 +0, 3684, 3684, 1, 8294400, 0xeb9032ca +0, 3802, 3802, 1, 8294400, 0x00000000 +0, 4520, 4520, 1, 8294400, 0x3c8a1116 +0, 4584, 4584, 1, 8294400, 0x00000000 +0, 4586, 4586, 1, 8294400, 0xa1547fd1 +0, 4645, 4645, 1, 8294400, 0x00000000 +0, 4648, 4648, 1, 8294400, 0x2b5bf181 +0, 4715, 4715, 1, 8294400, 0x00000000 +0, 4717, 4717, 1, 8294400, 0x718c1a2c +0, 4748, 4748, 1, 8294400, 0x00000000 +0, 4750, 4750, 1, 8294400, 0xcdf2ecf3 +0, 4792, 4792, 1, 8294400, 0x00000000 +0, 4993, 4993, 1, 8294400, 0x4fea5bd1 +0, 5027, 5027, 1, 8294400, 0x00000000 +0, 5029, 5029, 1, 8294400, 0xd630294d +0, 5068, 5068, 1, 8294400, 0x00000000 +0, 5070, 5070, 1, 8294400, 0x15af3d1b +0, 5117, 5117, 1, 8294400, 0x00000000 +0, 5119, 5119, 1, 8294400, 0x72ed25e3 +0, 5168, 5168, 1, 8294400, 0x00000000 +0, 5170, 5170, 1, 8294400, 0x4785bdd7 +0, 5216, 5216, 1, 8294400, 0x00000000 +0, 5218, 5218, 1, 8294400, 0x992a26dd +0, 5249, 5249, 1, 8294400, 0x00000000 +0, 5251, 5251, 1, 8294400, 0xbc7af836 +0, 5289, 5289, 1, 8294400, 0x00000000 +0, 5291, 5291, 1, 8294400, 0xf5ab9b0c +0, 5358, 5358, 1, 8294400, 0x00000000 +0, 5360, 5360, 1, 8294400, 0x96ce2791 +0, 5429, 5429, 1, 8294400, 0x00000000 +0, 5431, 5431, 1, 8294400, 0xb07efd74 +0, 5490, 5490, 1, 8294400, 0x00000000 +0, 5491, 5491, 1, 8294400, 0x698e178d +0, 5537, 5537, 1, 8294400, 0x00000000 +0, 5588, 5588, 1, 8294400, 0x524d1a52 +0, 5647, 5647, 1, 8294400, 0x00000000 +0, 5688, 5688, 1, 8294400, 0x9beb9c6f +0, 5770, 5770, 1, 8294400, 0x00000000 +0, 5772, 5772, 1, 8294400, 0x8ad6a47b +0, 5826, 5826, 1, 8294400, 0x00000000 +0, 5828, 5828, 1, 8294400, 0xa9648b24 +0, 5931, 5931, 1, 8294400, 0x00000000 +0, 5933, 5933, 1, 8294400, 0x184005ba +0, 6001, 6001, 1, 8294400, 0x00000000 +0, 6003, 6003, 1, 8294400, 0x34bacdf1 +0, 6054, 6054, 1, 8294400, 0x00000000 +0, 6839, 6839, 1, 8294400, 0xc461e667 +0, 6880, 6880, 1, 8294400, 0x00000000 +0, 7386, 7386, 1, 8294400, 0xa4526331 +0, 7419, 7419, 1, 8294400, 0x00000000 +0, 7501, 7501, 1, 8294400, 0xb957b10d +0, 7549, 7549, 1, 8294400, 0x00000000 +0, 7551, 7551, 1, 8294400, 0xe8b99d93 +0, 7589, 7589, 1, 8294400, 0x00000000 +0, 7605, 7605, 1, 8294400, 0x8bd5a87d +0, 7647, 7647, 1, 8294400, 0x00000000 +0, 7649, 7649, 1, 8294400, 0xa3293c58 +0, 7697, 7697, 1, 8294400, 0x00000000 +0, 7699, 7699, 1, 8294400, 0x738ce411 +0, 7743, 7743, 1, 8294400, 0x00000000 +0, 8032, 8032, 1, 8294400, 0xd7d70362 +0, 8082, 8082, 1, 8294400, 0x00000000 +0, 8084, 8084, 1, 8294400, 0xc79dd109 +0, 8115, 8115, 1, 8294400, 0x00000000 +0, 8116, 8116, 1, 8294400, 0xeb10b7bd +0, 8160, 8160, 1, 8294400, 0x00000000 +0, 8180, 8180, 1, 8294400, 0x9df85f2e +0, 8207, 8207, 1, 8294400, 0x00000000 +0, 8209, 8209, 1, 8294400, 0x4d1e03e5 +0, 8247, 8247, 1, 8294400, 0x00000000 +0, 8249, 8249, 1, 8294400, 0x77e1a9b3 +0, 8278, 8278, 1, 8294400, 0x00000000 +0, 8281, 8281, 1, 8294400, 0x8046a51e +0, 8321, 8321, 1, 8294400, 0x00000000 +0, 8323, 8323, 1, 8294400, 0x16eddfde +0, 8367, 8367, 1, 8294400, 0x00000000 +0, 8565, 8565, 1, 8294400, 0x80bc423b +0, 8611, 8611, 1, 8294400, 0x00000000 +0, 8669, 8669, 1, 8294400, 0x63569fa4 +0, 8708, 8708, 1, 8294400, 0x00000000 +0, 8941, 8941, 1, 8294400, 0xc93cfa34 +0, 8994, 8994, 1, 8294400, 0x00000000 +0, 8996, 8996, 1, 8294400, 0x69f9eb55 +0, 9027, 9027, 1, 8294400, 0x69f9eb55 diff --git a/tests/ref/fate/sub2video_time_limited b/tests/ref/fate/sub2video_time_limited index 9fb6fb06f9..715af02fee 100644 --- a/tests/ref/fate/sub2video_time_limited +++ b/tests/ref/fate/sub2video_time_limited @@ -2,7 +2,5 @@ #media_type 0: video #codec_id 0: rawvideo #dimensions 0: 1920x1080 -#sar 0: 0/1 -0, 2, 2, 1, 8294400, 0x00000000 +#sar 0: 1/1 0, 2, 2, 1, 8294400, 0xa87c518f -0, 10, 10, 1, 8294400, 0xa87c518f