From patchwork Mon Apr 8 20:13:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonas Karlman X-Patchwork-Id: 12650 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id C503644864A for ; Mon, 8 Apr 2019 23:13:12 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id B061E68ACAF; Mon, 8 Apr 2019 23:13:12 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from EUR01-VE1-obe.outbound.protection.outlook.com (mail-oln040092066098.outbound.protection.outlook.com [40.92.66.98]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id E488B68ACAD for ; Mon, 8 Apr 2019 23:13:05 +0300 (EEST) Received: from DB5EUR01FT044.eop-EUR01.prod.protection.outlook.com (10.152.4.59) by DB5EUR01HT175.eop-EUR01.prod.protection.outlook.com (10.152.5.226) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.1771.16; Mon, 8 Apr 2019 20:13:05 +0000 Received: from AM3PR03MB0966.eurprd03.prod.outlook.com (10.152.4.58) by DB5EUR01FT044.mail.protection.outlook.com (10.152.4.182) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.1771.16 via Frontend Transport; Mon, 8 Apr 2019 20:13:04 +0000 Received: from AM3PR03MB0966.eurprd03.prod.outlook.com ([fe80::c89:4e52:34c1:7009]) by AM3PR03MB0966.eurprd03.prod.outlook.com ([fe80::c89:4e52:34c1:7009%5]) with mapi id 15.20.1771.016; Mon, 8 Apr 2019 20:13:04 +0000 From: Jonas Karlman To: "ffmpeg-devel@ffmpeg.org" Thread-Topic: [RFC 3/6] Add V4L2 request API mpeg2 hwaccel Thread-Index: AQHU7kd5GIspRW1PzEOqpkMeGWoh+w== Date: Mon, 8 Apr 2019 20:13:04 +0000 Message-ID: References: In-Reply-To: Accept-Language: sv-SE, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: AM6P195CA0015.EURP195.PROD.OUTLOOK.COM (2603:10a6:209:81::28) To AM3PR03MB0966.eurprd03.prod.outlook.com (2a01:111:e400:884c::23) x-incomingtopheadermarker: OriginalChecksum:D66368D45A2B2DDE881B238F4B38642D0AD26F41ABCFC62E4176D118E7048DF7; UpperCasedChecksum:24C38945CCA0C840B95929C156B40C3365A9E5E909E445F1F0F643D32F51F1D2; SizeAsReceived:7584; Count:51 x-ms-exchange-messagesentrepresentingtype: 1 x-mailer: git-send-email 2.17.1 x-tmn: [RNev3H6pIldkrYsAqc+1hTfZvDKsJV8l] x-microsoft-original-message-id: <20190408201256.4484-1-jonas@kwiboo.se> x-ms-publictraffictype: Email x-incomingheadercount: 51 x-eopattributedmessage: 0 x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390118)(7020095)(20181119110)(201702061078)(5061506573)(5061507331)(1603103135)(2017031320274)(2017031323274)(2017031324274)(2017031322404)(1601125500)(1603101475)(1701031045); SRVR:DB5EUR01HT175; x-ms-traffictypediagnostic: DB5EUR01HT175: x-microsoft-antispam-message-info: CvDh0GCXe3I7PvcNGai0I2OM7/RzFd0HaFiRzrCbt/2ngikEZLDlL095kvDUhnD6 MIME-Version: 1.0 X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-CrossTenant-Network-Message-Id: 62cc1e2e-1369-418f-4851-08d6bc5e9ba4 X-MS-Exchange-CrossTenant-rms-persistedconsumerorg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-CrossTenant-originalarrivaltime: 08 Apr 2019 20:13:04.9170 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Internet X-MS-Exchange-CrossTenant-id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB5EUR01HT175 Subject: [FFmpeg-devel] [RFC 3/6] Add V4L2 request API mpeg2 hwaccel X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: "jernej.skrabec@siol.net" , Jonas Karlman Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Signed-off-by: Jonas Karlman --- configure | 3 + libavcodec/Makefile | 1 + libavcodec/hwaccels.h | 1 + libavcodec/mpeg12dec.c | 6 ++ libavcodec/v4l2_request_mpeg2.c | 154 ++++++++++++++++++++++++++++++++ 5 files changed, 165 insertions(+) create mode 100644 libavcodec/v4l2_request_mpeg2.c diff --git a/configure b/configure index ea3945d34a..79fa5530f1 100755 --- a/configure +++ b/configure @@ -2919,6 +2919,8 @@ mpeg2_dxva2_hwaccel_deps="dxva2" mpeg2_dxva2_hwaccel_select="mpeg2video_decoder" mpeg2_nvdec_hwaccel_deps="nvdec" mpeg2_nvdec_hwaccel_select="mpeg2video_decoder" +mpeg2_v4l2request_hwaccel_deps="v4l2_request mpeg2_v4l2_request" +mpeg2_v4l2request_hwaccel_select="mpeg2video_decoder" mpeg2_vaapi_hwaccel_deps="vaapi" mpeg2_vaapi_hwaccel_select="mpeg2video_decoder" mpeg2_vdpau_hwaccel_deps="vdpau" @@ -6381,6 +6383,7 @@ check_cc vp8_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_VP8;" check_cc vp9_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_VP9;" check_func_headers "linux/media.h linux/videodev2.h" v4l2_timeval_to_ns +check_cc mpeg2_v4l2_request linux/videodev2.h "int i = V4L2_PIX_FMT_MPEG2_SLICE;" check_headers sys/videoio.h test_code cc sys/videoio.h "struct v4l2_frmsizeenum vfse; vfse.discrete.width = 0;" && enable_sanitized struct_v4l2_frmivalenum_discrete diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 796727dde7..a26c6b38ea 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -889,6 +889,7 @@ OBJS-$(CONFIG_MPEG2_D3D11VA_HWACCEL) += dxva2_mpeg2.o OBJS-$(CONFIG_MPEG2_DXVA2_HWACCEL) += dxva2_mpeg2.o OBJS-$(CONFIG_MPEG2_NVDEC_HWACCEL) += nvdec_mpeg12.o OBJS-$(CONFIG_MPEG2_QSV_HWACCEL) += qsvdec_other.o +OBJS-$(CONFIG_MPEG2_V4L2REQUEST_HWACCEL) += v4l2_request_mpeg2.o OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL) += vaapi_mpeg2.o OBJS-$(CONFIG_MPEG2_VDPAU_HWACCEL) += vdpau_mpeg12.o OBJS-$(CONFIG_MPEG2_VIDEOTOOLBOX_HWACCEL) += videotoolbox.o diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h index 7d73da8676..ef54de2a3b 100644 --- a/libavcodec/hwaccels.h +++ b/libavcodec/hwaccels.h @@ -47,6 +47,7 @@ extern const AVHWAccel ff_mpeg2_d3d11va_hwaccel; extern const AVHWAccel ff_mpeg2_d3d11va2_hwaccel; extern const AVHWAccel ff_mpeg2_nvdec_hwaccel; extern const AVHWAccel ff_mpeg2_dxva2_hwaccel; +extern const AVHWAccel ff_mpeg2_v4l2request_hwaccel; extern const AVHWAccel ff_mpeg2_vaapi_hwaccel; extern const AVHWAccel ff_mpeg2_vdpau_hwaccel; extern const AVHWAccel ff_mpeg2_videotoolbox_hwaccel; diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c index 83e537884b..305127bc94 100644 --- a/libavcodec/mpeg12dec.c +++ b/libavcodec/mpeg12dec.c @@ -1156,6 +1156,9 @@ static const enum AVPixelFormat mpeg2_hwaccel_pixfmt_list_420[] = { #endif #if CONFIG_MPEG2_VIDEOTOOLBOX_HWACCEL AV_PIX_FMT_VIDEOTOOLBOX, +#endif +#if CONFIG_MPEG2_V4L2REQUEST_HWACCEL + AV_PIX_FMT_DRM_PRIME, #endif AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE @@ -2941,6 +2944,9 @@ AVCodec ff_mpeg2video_decoder = { #endif #if CONFIG_MPEG2_XVMC_HWACCEL HWACCEL_XVMC(mpeg2), +#endif +#if CONFIG_MPEG2_V4L2REQUEST_HWACCEL + HWACCEL_V4L2REQUEST(mpeg2), #endif NULL }, diff --git a/libavcodec/v4l2_request_mpeg2.c b/libavcodec/v4l2_request_mpeg2.c new file mode 100644 index 0000000000..782b9c2471 --- /dev/null +++ b/libavcodec/v4l2_request_mpeg2.c @@ -0,0 +1,154 @@ +/* + * 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 "hwaccel.h" +#include "mpegvideo.h" +#include "v4l2_request.h" + +typedef struct V4L2RequestControlsMPEG2 { + struct v4l2_ctrl_mpeg2_slice_params slice_params; + struct v4l2_ctrl_mpeg2_quantization quantization; +} V4L2RequestControlsMPEG2; + +static int v4l2_request_mpeg2_start_frame(AVCodecContext *avctx, + av_unused const uint8_t *buffer, + av_unused uint32_t size) +{ + const MpegEncContext *s = avctx->priv_data; + V4L2RequestControlsMPEG2 *controls = s->current_picture_ptr->hwaccel_picture_private; + V4L2RequestDescriptor *req = (V4L2RequestDescriptor*)s->current_picture_ptr->f->data[0]; + + controls->slice_params = (struct v4l2_ctrl_mpeg2_slice_params) { + .bit_size = 0, + .data_bit_offset = 0, + + /* ISO/IEC 13818-2, ITU-T Rec. H.262: Slice */ + .quantiser_scale_code = s->qscale >> 1, + + .sequence = { + /* ISO/IEC 13818-2, ITU-T Rec. H.262: Sequence header */ + .horizontal_size = s->width, + .vertical_size = s->height, + .vbv_buffer_size = req->output.size, + + /* ISO/IEC 13818-2, ITU-T Rec. H.262: Sequence extension */ + .profile_and_level_indication = 0, + .progressive_sequence = s->progressive_sequence, + .chroma_format = s->chroma_format, + }, + + .picture = { + /* ISO/IEC 13818-2, ITU-T Rec. H.262: Picture header */ + .picture_coding_type = s->pict_type, + + /* ISO/IEC 13818-2, ITU-T Rec. H.262: Picture coding extension */ + .f_code[0][0] = s->mpeg_f_code[0][0], + .f_code[0][1] = s->mpeg_f_code[0][1], + .f_code[1][0] = s->mpeg_f_code[1][0], + .f_code[1][1] = s->mpeg_f_code[1][1], + .intra_dc_precision = s->intra_dc_precision, + .picture_structure = s->picture_structure, + .top_field_first = s->top_field_first, + .frame_pred_frame_dct = s->frame_pred_frame_dct, + .concealment_motion_vectors = s->concealment_motion_vectors, + .q_scale_type = s->q_scale_type, + .intra_vlc_format = s->intra_vlc_format, + .alternate_scan = s->alternate_scan, + .repeat_first_field = s->repeat_first_field, + .progressive_frame = s->progressive_frame, + }, + }; + + switch (s->pict_type) { + case AV_PICTURE_TYPE_B: + controls->slice_params.backward_ref_ts = ff_v4l2_request_get_capture_timestamp(s->next_picture.f); + // fall-through + case AV_PICTURE_TYPE_P: + controls->slice_params.forward_ref_ts = ff_v4l2_request_get_capture_timestamp(s->last_picture.f); + } + + controls->quantization = (struct v4l2_ctrl_mpeg2_quantization) { + /* ISO/IEC 13818-2, ITU-T Rec. H.262: Quant matrix extension */ + .load_intra_quantiser_matrix = 1, + .load_non_intra_quantiser_matrix = 1, + .load_chroma_intra_quantiser_matrix = 1, + .load_chroma_non_intra_quantiser_matrix = 1, + }; + + for (int i = 0; i < 64; i++) { + int n = s->idsp.idct_permutation[ff_zigzag_direct[i]]; + controls->quantization.intra_quantiser_matrix[i] = s->intra_matrix[n]; + controls->quantization.non_intra_quantiser_matrix[i] = s->inter_matrix[n]; + controls->quantization.chroma_intra_quantiser_matrix[i] = s->chroma_intra_matrix[n]; + controls->quantization.chroma_non_intra_quantiser_matrix[i] = s->chroma_inter_matrix[n]; + } + + return ff_v4l2_request_reset_frame(avctx, s->current_picture_ptr->f); +} + +static int v4l2_request_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) +{ + const MpegEncContext *s = avctx->priv_data; + + return ff_v4l2_request_append_output_buffer(avctx, s->current_picture_ptr->f, buffer, size); +} + +static int v4l2_request_mpeg2_end_frame(AVCodecContext *avctx) +{ + const MpegEncContext *s = avctx->priv_data; + V4L2RequestControlsMPEG2 *controls = s->current_picture_ptr->hwaccel_picture_private; + V4L2RequestDescriptor *req = (V4L2RequestDescriptor*)s->current_picture_ptr->f->data[0]; + + struct v4l2_ext_control control[] = { + { + .id = V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS, + .ptr = &controls->slice_params, + .size = sizeof(controls->slice_params), + }, + { + .id = V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION, + .ptr = &controls->quantization, + .size = sizeof(controls->quantization), + }, + }; + + controls->slice_params.bit_size = req->output.used * 8; + + return ff_v4l2_request_decode_frame(avctx, s->current_picture_ptr->f, control, FF_ARRAY_ELEMS(control)); +} + +static int v4l2_request_mpeg2_init(AVCodecContext *avctx) +{ + return ff_v4l2_request_init(avctx, V4L2_PIX_FMT_MPEG2_SLICE, 1024 * 1024, NULL, 0); +} + +const AVHWAccel ff_mpeg2_v4l2request_hwaccel = { + .name = "mpeg2_v4l2request", + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_MPEG2VIDEO, + .pix_fmt = AV_PIX_FMT_DRM_PRIME, + .start_frame = v4l2_request_mpeg2_start_frame, + .decode_slice = v4l2_request_mpeg2_decode_slice, + .end_frame = v4l2_request_mpeg2_end_frame, + .frame_priv_data_size = sizeof(V4L2RequestControlsMPEG2), + .init = v4l2_request_mpeg2_init, + .uninit = ff_v4l2_request_uninit, + .priv_data_size = sizeof(V4L2RequestContext), + .frame_params = ff_v4l2_request_frame_params, + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, +};