From patchwork Mon Jul 1 12:16:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 50243 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:cc64:0:b0:482:c625:d099 with SMTP id k4csp1739550vqv; Mon, 1 Jul 2024 05:17:46 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCW986ukWR7MrLfOwJ/rmaOZjIyS+4Qz3Tp2oa3+rzHJt50lWDvpGFQmpsC7azhjO2/0zZceA+YZLsnThrRsfO/AlKj0zqrgiNsw/Q== X-Google-Smtp-Source: AGHT+IHx2ru9cPyfJfKvqW7b/U350Ehf9N64ocRo5wRDJkt5RH33U03SpldfCI8X2m8EeCt7nm0+ X-Received: by 2002:a17:907:970e:b0:a72:b3e3:c04 with SMTP id a640c23a62f3a-a7514438ab2mr485236366b.42.1719836266415; Mon, 01 Jul 2024 05:17: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 a640c23a62f3a-a72ab0bbe44si359735666b.988.2024.07.01.05.17.46; Mon, 01 Jul 2024 05:17: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=@outlook.com header.s=selector1 header.b="JW/L7xbU"; 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=QUARANTINE dis=NONE) header.from=outlook.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id BCC8E68D34E; Mon, 1 Jul 2024 15:17:35 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from EUR02-DB5-obe.outbound.protection.outlook.com (mail-db5eur02olkn2029.outbound.protection.outlook.com [40.92.50.29]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 2880068D7A3 for ; Mon, 1 Jul 2024 15:17:31 +0300 (EEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=UfbOkxzQoO1+uoMBXpn9NaR+NJQH6hd3NdBbPjKWZrAfvHM3o/tCtPdrMbAWZU1CCO1WYJWw596XZwAUCRwZIsR0xhRtWts3D9cY6D27SLqrbQ30YPrhktvluefFdcjritfjiGTfnnvOUmSiSY9ac195cmIxFnVeYj8yoUBI6jtpEANYGldc+qDHLBBjsDp6sBthJNTiEgj2fW9m9bf2EdCklp/fnL16VRh7hFC2mNenDC4MOCm1KCTue8U7cYxGF0a0wOk+CpzxUrYT2kow60IEly3VMbrqhTTx8PSTOFolWFbyc0Of037XqogHlD5o3Ys2N7grKl9cyS+ck8LkxQ== 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-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=cg2j9VGVxNWYqMZNu4coAL9oceE9gLi+bABF4/536tQ=; b=YI7rtImfQs9he6al4ZEz+spH9bBg8DoMLIYEz4y31sRdQXJQpJsZnQX/Xk2NKgaIQHZFjPGWRRkzX5Vcbj+Gn1Ga1OCVChQGBIKLw1Wc8oFp9ajJFMiKPXO5+Wd/bopuogwXYmEoeKEzyFqAUN+nHChznm4yy4UbP5NVIT4qeba8Zd3R5ZjQ04umZzhgC/ASemvtkdx9tmoLSGgnBDBtDHkHCBQfPvdKyBWLceC+nFEZ0tBdyjni8bRR2HuGPyhZ1CSYsy9lSEhuL/5UoLpNgTB+bPf3jkLAFuk6lb9FY1+TU6JPITP8nUT1EVuLmPdFvoG3EsRq+c0s3PNA1thy5Q== 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=outlook.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=cg2j9VGVxNWYqMZNu4coAL9oceE9gLi+bABF4/536tQ=; b=JW/L7xbUzr3Y7HnKlz4mLloSwf3TaTIu/MAYZyKUpIZLtYDxM9JwZFNlTg93JinLJjt0kotj3mgKLaIvLzaWNoEG18hD0+obQSVO9j4DoCBB/NKtzFd7CH2dRln3QGPjudscXK85Q21qXbkR3mOfuEbqc2JZkYI4n7UpRmPqppTSqqCKvc9Ta6os3BMQ5JZifL0LbkyRKw44xui+/HoxP0rd3kCP7cQXcEK5UMf3feShAMZjKnt9iAnwHhRxFwo4N3HomALXrOviUVq5YE4vUwPX+TzH9ttXRbJKZOPbnpMPKqre4dEnZje9NMajqNcCl3zGhBLtPla+dDQuqwe4/A== Received: from GV1P250MB0737.EURP250.PROD.OUTLOOK.COM (2603:10a6:150:8e::17) by DU0P250MB0481.EURP250.PROD.OUTLOOK.COM (2603:10a6:10:349::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7719.32; Mon, 1 Jul 2024 12:17:23 +0000 Received: from GV1P250MB0737.EURP250.PROD.OUTLOOK.COM ([fe80::d6a1:e3af:a5f1:b614]) by GV1P250MB0737.EURP250.PROD.OUTLOOK.COM ([fe80::d6a1:e3af:a5f1:b614%5]) with mapi id 15.20.7719.029; Mon, 1 Jul 2024 12:17:23 +0000 From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Mon, 1 Jul 2024 14:16:03 +0200 Message-ID: X-Mailer: git-send-email 2.40.1 In-Reply-To: References: X-TMN: [rT1IJfr0R/7nYxJaGuca1ZmGaVauRUN1jVNBlrNPExg=] X-ClientProxiedBy: ZR0P278CA0149.CHEP278.PROD.OUTLOOK.COM (2603:10a6:910:41::11) To GV1P250MB0737.EURP250.PROD.OUTLOOK.COM (2603:10a6:150:8e::17) X-Microsoft-Original-Message-ID: <20240701121610.3560848-5-andreas.rheinhardt@outlook.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV1P250MB0737:EE_|DU0P250MB0481:EE_ X-MS-Office365-Filtering-Correlation-Id: ae4e8ed3-0d46-4e23-ea02-08dc99c7c302 X-Microsoft-Antispam: BCL:0; ARA:14566002|8060799006|461199028|440099028|3412199025|1710799026; X-Microsoft-Antispam-Message-Info: sGkIL8mY3tN/uzqJKiTiGmNTySi3r7cRbvIS9mzOmWuG+WPxGv/Mu29kVBYj6ZlP5Nr7BIZ5+rsuRF5wuueOTKtQas/dkyl7g7wxpJ2Ij2DPJsKj3GHkceJK77HFeqQBKZPF9N2vFeGS+S3fahf6n6WLyVpxo6kvpPWBnUzdhznBEoJWwDTINHHkyQviNXFXM0aC2dwl5r7aTS4fnsBBCdZklt0l3menMayXw9jlUB4E+Iz2FoFhevhaqawNqBrEUd4jgGx0l6fCOMrAJEucu0ZHPvR5PGxDhUKKWtsAfWYRRzgT0513xaeaeGDqQTG8R2BO2IWzJ+Ba2urBRycmowvRy2ooySBH5XC7bgUAk/R+fxl0bXDM8p+zDPpcAvFESVsJ/meOSWo1185i4H1coETncRCfruMLR6xBNSw1xpwcIpXDT4a5iIlGP65IfXB9Vfkml1azJgjBvU6xyHbe4g8HJ6zM9TIgG1XEe1qOgHLvHUM5F7Pq9a64zUUiYZIY2SXZ5M/pAlNQxGfKHzgY3N53bIdA0WKoq9vzzhlz+IBB2lu0dWovt7obwfFUmQQONzW3yUwReTVfV6pgJKNaUMKXlKzzDshKs+c8OkWQo9WKXUp9pHbN2AxpH/5OEHE2D3+QMPskeYRvgcTW+Egycg== X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: F/2KulASXAfJhMfBlms4hP983ZbSPKfop22luVB/hBNXigXxmfI9DtpA/m3wk97sqNWBKY7LhrxM9/hXFm49OIb4g2iOKDfyfGq7JuyoDYMUESbPTyai4IFRyxQj6aYUj7oK7AhfL1uER8JNM+QfgTkC2XkesmNAXZZHDIzDM79zUTv9pPa2uLdxdBD80TzEbGsQPct4zzCnxydJF6Z6DNtlpSQ3onhWondfGYhhqhWYSHxQCZpj04kon/OMpa9mkSebPZhDCEwt1ok88UMGCNW6RbC9z2p7h+0AP6ucARbykTLSHVOD/ZpNtdRxV2Z8sxQDlLsuJpAoCA35agp3eAfBBBKdrIpIWkLV8hdao3+9jAi5gzT9F7BLm2gP07NoNUrMTI3CMbMfQlYN1ny4+tH2DKbaEQgIIlSSTxEiJ45oWmBd5MfNNX8xfFWlTMxNOB/j9Jjb8kJlIuz98kVxGLDLQcHswJH7b64sZDsuyo60AHHHxlEO6i58IsrlYgNSM3yoaBmBrUBhxPFDiE+QL3ZlObAHKbWIVwu5ytyuIPajgyOE9AvtDkF5ytaoqNFA+bfHLUY06h5bH/V208jlBnkoKcEbsC3LNk2nK3OAlceCHxA07YL6Aj8UUlvK2ol0TCylANfFL5jaNlgH5W9UKSuPPEbyLKlL7bQHAF+D+LPk5S+nDMhztygk+IZFtkZa8Y5hFEksUAvkGcx47VpStLZbdBxj06R+p4QRn+vZA8t/3SDoN7x9PTK8QpzeyUQRfHC75j1tBTvcCxk+pePSdW9HSIUNe3ycZoocWVEx4p2WU0yn8tqgxxKDX13v9JxyIfgWx/N8RFguJ33/3Fqk342sa2qloAeM5agSudOtDGORSr6gmeips2gQFbg0iWfkUnRHl4JYipvZ6Qj/Q76V6KkhG4ZNnpDABIdRXRsrNFIqlMPnjXXIwVCvQd834X+V/xCHa0J9wgSalyvj2CpxfDFP6zAbiWoWsGaV3fMnc9nMgNCagVHuQANIDl+bUyJ4RQ8lXLBuXnrOO9NGMzGXnwgYT5OkVy4KNjiOPIRr4iXTPBdLWb3rb1YvESphRh6BPwatB012GCeClaDPDlMvvTupQVnngGRa7clPlI1XQv9Yo2EosziqBd1QUAZZ0YN06C1V42VGeRSsV3tT0dMOESV8zj7ShCql9+iWW7DMz4hnAdAL3khI6yQUROboLEb+5wSc2cj2XJqlaJPQ6BEQE5Msa9ZepcQHDw0Ueo7hdtQn02WK6npi7QsHTSr3jPDmp6qlImoGzHySZTBgHrUpdg== X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: ae4e8ed3-0d46-4e23-ea02-08dc99c7c302 X-MS-Exchange-CrossTenant-AuthSource: GV1P250MB0737.EURP250.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 01 Jul 2024 12:17:23.1235 (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: DU0P250MB0481 Subject: [FFmpeg-devel] [PATCH 06/13] avcodec/mpv_reconstruct_mb_template: Merge template into its users 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 Cc: Andreas Rheinhardt Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: u7CCGaE3j3IP A large part of this template is decoder-only. This makes the complexity of the IS_ENCODER-checks not worth it. So simply merge the template into both its users. Signed-off-by: Andreas Rheinhardt --- libavcodec/mpegvideo_dec.c | 218 +++++++++++++++++- libavcodec/mpegvideo_enc.c | 81 ++++++- libavcodec/mpv_reconstruct_mb_template.c | 272 ----------------------- 3 files changed, 294 insertions(+), 277 deletions(-) delete mode 100644 libavcodec/mpv_reconstruct_mb_template.c diff --git a/libavcodec/mpegvideo_dec.c b/libavcodec/mpegvideo_dec.c index 1cab108935..2222d50283 100644 --- a/libavcodec/mpegvideo_dec.c +++ b/libavcodec/mpegvideo_dec.c @@ -904,11 +904,225 @@ static inline void add_dct(MpegEncContext *s, } } -#define IS_ENCODER 0 -#include "mpv_reconstruct_mb_template.c" +/* put block[] to dest[] */ +static inline void put_dct(MpegEncContext *s, + int16_t *block, int i, uint8_t *dest, int line_size, int qscale) +{ + s->dct_unquantize_intra(s, block, i, qscale); + s->idsp.idct_put(dest, line_size, block); +} + +static inline void add_dequant_dct(MpegEncContext *s, + int16_t *block, int i, uint8_t *dest, int line_size, int qscale) +{ + if (s->block_last_index[i] >= 0) { + s->dct_unquantize_inter(s, block, i, qscale); + + s->idsp.idct_add(dest, line_size, block); + } +} + +#define NOT_MPEG12_H261 0 +#define MAY_BE_MPEG12_H261 1 +#define DEFINITELY_MPEG12_H261 2 + +/* generic function called after a macroblock has been parsed by the decoder. + + Important variables used: + s->mb_intra : true if intra macroblock + s->mv_dir : motion vector direction + s->mv_type : motion vector type + s->mv : motion vector + s->interlaced_dct : true if interlaced dct used (mpeg2) + */ +static av_always_inline +void mpv_reconstruct_mb_internal(MpegEncContext *s, int16_t block[12][64], + int lowres_flag, int is_mpeg12) +{ +#define IS_MPEG12_H261(s) (is_mpeg12 == MAY_BE_MPEG12_H261 ? ((s)->out_format <= FMT_H261) : is_mpeg12) + { + uint8_t *dest_y = s->dest[0], *dest_cb = s->dest[1], *dest_cr = s->dest[2]; + int dct_linesize, dct_offset; + const int linesize = s->cur_pic.linesize[0]; //not s->linesize as this would be wrong for field pics + const int uvlinesize = s->cur_pic.linesize[1]; + const int block_size = lowres_flag ? 8 >> s->avctx->lowres : 8; + + dct_linesize = linesize << s->interlaced_dct; + dct_offset = s->interlaced_dct ? linesize : linesize * block_size; + + if (!s->mb_intra) { + /* motion handling */ + if (HAVE_THREADS && is_mpeg12 != DEFINITELY_MPEG12_H261 && + s->avctx->active_thread_type & FF_THREAD_FRAME) { + if (s->mv_dir & MV_DIR_FORWARD) { + ff_thread_progress_await(&s->last_pic.ptr->progress, + lowest_referenced_row(s, 0)); + } + if (s->mv_dir & MV_DIR_BACKWARD) { + ff_thread_progress_await(&s->next_pic.ptr->progress, + lowest_referenced_row(s, 1)); + } + } + + if (lowres_flag) { + const h264_chroma_mc_func *op_pix = s->h264chroma.put_h264_chroma_pixels_tab; + + if (s->mv_dir & MV_DIR_FORWARD) { + MPV_motion_lowres(s, dest_y, dest_cb, dest_cr, 0, s->last_pic.data, op_pix); + op_pix = s->h264chroma.avg_h264_chroma_pixels_tab; + } + if (s->mv_dir & MV_DIR_BACKWARD) { + MPV_motion_lowres(s, dest_y, dest_cb, dest_cr, 1, s->next_pic.data, op_pix); + } + } else { + const op_pixels_func (*op_pix)[4]; + const qpel_mc_func (*op_qpix)[16]; + + if ((is_mpeg12 == DEFINITELY_MPEG12_H261 || !s->no_rounding) || s->pict_type == AV_PICTURE_TYPE_B) { + op_pix = s->hdsp.put_pixels_tab; + op_qpix = s->qdsp.put_qpel_pixels_tab; + } else { + op_pix = s->hdsp.put_no_rnd_pixels_tab; + op_qpix = s->qdsp.put_no_rnd_qpel_pixels_tab; + } + if (s->mv_dir & MV_DIR_FORWARD) { + ff_mpv_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_pic.data, op_pix, op_qpix); + op_pix = s->hdsp.avg_pixels_tab; + op_qpix = s->qdsp.avg_qpel_pixels_tab; + } + if (s->mv_dir & MV_DIR_BACKWARD) { + ff_mpv_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_pic.data, op_pix, op_qpix); + } + } + + /* skip dequant / idct if we are really late ;) */ + if (s->avctx->skip_idct) { + if( (s->avctx->skip_idct >= AVDISCARD_NONREF && s->pict_type == AV_PICTURE_TYPE_B) + ||(s->avctx->skip_idct >= AVDISCARD_NONKEY && s->pict_type != AV_PICTURE_TYPE_I) + || s->avctx->skip_idct >= AVDISCARD_ALL) + return; + } + + /* add dct residue */ + if (!(IS_MPEG12_H261(s) || s->msmpeg4_version != MSMP4_UNUSED || + (s->codec_id == AV_CODEC_ID_MPEG4 && !s->mpeg_quant))) { + add_dequant_dct(s, block[0], 0, dest_y , dct_linesize, s->qscale); + add_dequant_dct(s, block[1], 1, dest_y + block_size, dct_linesize, s->qscale); + add_dequant_dct(s, block[2], 2, dest_y + dct_offset , dct_linesize, s->qscale); + add_dequant_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize, s->qscale); + + if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { + av_assert2(s->chroma_y_shift); + add_dequant_dct(s, block[4], 4, dest_cb, uvlinesize, s->chroma_qscale); + add_dequant_dct(s, block[5], 5, dest_cr, uvlinesize, s->chroma_qscale); + } + } else if (is_mpeg12 == DEFINITELY_MPEG12_H261 || lowres_flag || (s->codec_id != AV_CODEC_ID_WMV2)) { + add_dct(s, block[0], 0, dest_y , dct_linesize); + add_dct(s, block[1], 1, dest_y + block_size, dct_linesize); + add_dct(s, block[2], 2, dest_y + dct_offset , dct_linesize); + add_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize); + + if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { + if (s->chroma_y_shift) {//Chroma420 + add_dct(s, block[4], 4, dest_cb, uvlinesize); + add_dct(s, block[5], 5, dest_cr, uvlinesize); + } else { + //chroma422 + dct_linesize = uvlinesize << s->interlaced_dct; + dct_offset = s->interlaced_dct ? uvlinesize : uvlinesize*block_size; + + add_dct(s, block[4], 4, dest_cb, dct_linesize); + add_dct(s, block[5], 5, dest_cr, dct_linesize); + add_dct(s, block[6], 6, dest_cb+dct_offset, dct_linesize); + add_dct(s, block[7], 7, dest_cr+dct_offset, dct_linesize); + if (!s->chroma_x_shift) {//Chroma444 + add_dct(s, block[8], 8, dest_cb+block_size, dct_linesize); + add_dct(s, block[9], 9, dest_cr+block_size, dct_linesize); + add_dct(s, block[10], 10, dest_cb+block_size+dct_offset, dct_linesize); + add_dct(s, block[11], 11, dest_cr+block_size+dct_offset, dct_linesize); + } + } + } //fi gray + } else if (CONFIG_WMV2_DECODER) { + ff_wmv2_add_mb(s, block, dest_y, dest_cb, dest_cr); + } + } else { + /* Only MPEG-4 Simple Studio Profile is supported in > 8-bit mode. + TODO: Integrate 10-bit properly into mpegvideo.c so that ER works properly */ + if (is_mpeg12 != DEFINITELY_MPEG12_H261 && CONFIG_MPEG4_DECODER && + /* s->codec_id == AV_CODEC_ID_MPEG4 && */ + s->avctx->bits_per_raw_sample > 8) { + ff_mpeg4_decode_studio(s, dest_y, dest_cb, dest_cr, block_size, + uvlinesize, dct_linesize, dct_offset); + } else if (!IS_MPEG12_H261(s)) { + /* dct only in intra block */ + put_dct(s, block[0], 0, dest_y , dct_linesize, s->qscale); + put_dct(s, block[1], 1, dest_y + block_size, dct_linesize, s->qscale); + put_dct(s, block[2], 2, dest_y + dct_offset , dct_linesize, s->qscale); + put_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize, s->qscale); + + if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { + if (s->chroma_y_shift) { + put_dct(s, block[4], 4, dest_cb, uvlinesize, s->chroma_qscale); + put_dct(s, block[5], 5, dest_cr, uvlinesize, s->chroma_qscale); + } else { + dct_offset >>=1; + dct_linesize >>=1; + put_dct(s, block[4], 4, dest_cb, dct_linesize, s->chroma_qscale); + put_dct(s, block[5], 5, dest_cr, dct_linesize, s->chroma_qscale); + put_dct(s, block[6], 6, dest_cb + dct_offset, dct_linesize, s->chroma_qscale); + put_dct(s, block[7], 7, dest_cr + dct_offset, dct_linesize, s->chroma_qscale); + } + } + } else { + s->idsp.idct_put(dest_y, dct_linesize, block[0]); + s->idsp.idct_put(dest_y + block_size, dct_linesize, block[1]); + s->idsp.idct_put(dest_y + dct_offset, dct_linesize, block[2]); + s->idsp.idct_put(dest_y + dct_offset + block_size, dct_linesize, block[3]); + + if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { + if (s->chroma_y_shift) { + s->idsp.idct_put(dest_cb, uvlinesize, block[4]); + s->idsp.idct_put(dest_cr, uvlinesize, block[5]); + } else { + dct_linesize = uvlinesize << s->interlaced_dct; + dct_offset = s->interlaced_dct ? uvlinesize : uvlinesize*block_size; + + s->idsp.idct_put(dest_cb, dct_linesize, block[4]); + s->idsp.idct_put(dest_cr, dct_linesize, block[5]); + s->idsp.idct_put(dest_cb + dct_offset, dct_linesize, block[6]); + s->idsp.idct_put(dest_cr + dct_offset, dct_linesize, block[7]); + if (!s->chroma_x_shift) { //Chroma444 + s->idsp.idct_put(dest_cb + block_size, dct_linesize, block[8]); + s->idsp.idct_put(dest_cr + block_size, dct_linesize, block[9]); + s->idsp.idct_put(dest_cb + block_size + dct_offset, dct_linesize, block[10]); + s->idsp.idct_put(dest_cr + block_size + dct_offset, dct_linesize, block[11]); + } + } + } //gray + } + } + } +} void ff_mpv_reconstruct_mb(MpegEncContext *s, int16_t block[12][64]) { + const int mb_xy = s->mb_y * s->mb_stride + s->mb_x; + uint8_t *mbskip_ptr = &s->mbskip_table[mb_xy]; + + s->cur_pic.qscale_table[mb_xy] = s->qscale; + + /* avoid copy if macroblock skipped in last frame too */ + if (s->mb_skipped) { + s->mb_skipped = 0; + av_assert2(s->pict_type!=AV_PICTURE_TYPE_I); + *mbskip_ptr = 1; + } else if (!s->cur_pic.reference) { + *mbskip_ptr = 1; + } else{ + *mbskip_ptr = 0; /* not skipped */ + } + if (s->avctx->debug & FF_DEBUG_DCT_COEFF) { /* print DCT coefficients */ av_log(s->avctx, AV_LOG_DEBUG, "DCT coeffs of MB at %dx%d:\n", s->mb_x, s->mb_y); diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index 31c5dd4736..774d16edad 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -1082,11 +1082,33 @@ av_cold int ff_mpv_encode_end(AVCodecContext *avctx) return 0; } -#define IS_ENCODER 1 -#include "mpv_reconstruct_mb_template.c" +/* put block[] to dest[] */ +static inline void put_dct(MpegEncContext *s, + int16_t *block, int i, uint8_t *dest, int line_size, int qscale) +{ + s->dct_unquantize_intra(s, block, i, qscale); + s->idsp.idct_put(dest, line_size, block); +} +static inline void add_dequant_dct(MpegEncContext *s, + int16_t *block, int i, uint8_t *dest, int line_size, int qscale) +{ + if (s->block_last_index[i] >= 0) { + s->dct_unquantize_inter(s, block, i, qscale); + + s->idsp.idct_add(dest, line_size, block); + } +} + +/** + * Performs dequantization and IDCT (if necessary) + */ static void mpv_reconstruct_mb(MpegEncContext *s, int16_t block[12][64]) { + const int mb_xy = s->mb_y * s->mb_stride + s->mb_x; + + s->cur_pic.qscale_table[mb_xy] = s->qscale; + if (s->avctx->debug & FF_DEBUG_DCT_COEFF) { /* print DCT coefficients */ av_log(s->avctx, AV_LOG_DEBUG, "DCT coeffs of MB at %dx%d:\n", s->mb_x, s->mb_y); @@ -1099,7 +1121,60 @@ static void mpv_reconstruct_mb(MpegEncContext *s, int16_t block[12][64]) } } - mpv_reconstruct_mb_internal(s, block, 0, MAY_BE_MPEG12_H261); + if ((s->avctx->flags & AV_CODEC_FLAG_PSNR) || s->frame_skip_threshold || s->frame_skip_factor || + !((s->intra_only || s->pict_type == AV_PICTURE_TYPE_B) && + s->avctx->mb_decision != FF_MB_DECISION_RD)) { // FIXME precalc + uint8_t *dest_y = s->dest[0], *dest_cb = s->dest[1], *dest_cr = s->dest[2]; + int dct_linesize, dct_offset; + const int linesize = s->cur_pic.linesize[0]; + const int uvlinesize = s->cur_pic.linesize[1]; + const int block_size = 8; + + dct_linesize = linesize << s->interlaced_dct; + dct_offset = s->interlaced_dct ? linesize : linesize * block_size; + + if (!s->mb_intra) { + /* No MC, as that was already done otherwise */ + add_dequant_dct(s, block[0], 0, dest_y , dct_linesize, s->qscale); + add_dequant_dct(s, block[1], 1, dest_y + block_size, dct_linesize, s->qscale); + add_dequant_dct(s, block[2], 2, dest_y + dct_offset , dct_linesize, s->qscale); + add_dequant_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize, s->qscale); + + if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { + if (s->chroma_y_shift) { + add_dequant_dct(s, block[4], 4, dest_cb, uvlinesize, s->chroma_qscale); + add_dequant_dct(s, block[5], 5, dest_cr, uvlinesize, s->chroma_qscale); + } else { + dct_linesize >>= 1; + dct_offset >>= 1; + add_dequant_dct(s, block[4], 4, dest_cb, dct_linesize, s->chroma_qscale); + add_dequant_dct(s, block[5], 5, dest_cr, dct_linesize, s->chroma_qscale); + add_dequant_dct(s, block[6], 6, dest_cb + dct_offset, dct_linesize, s->chroma_qscale); + add_dequant_dct(s, block[7], 7, dest_cr + dct_offset, dct_linesize, s->chroma_qscale); + } + } + } else { + /* dct only in intra block */ + put_dct(s, block[0], 0, dest_y , dct_linesize, s->qscale); + put_dct(s, block[1], 1, dest_y + block_size, dct_linesize, s->qscale); + put_dct(s, block[2], 2, dest_y + dct_offset , dct_linesize, s->qscale); + put_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize, s->qscale); + + if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { + if (s->chroma_y_shift) { + put_dct(s, block[4], 4, dest_cb, uvlinesize, s->chroma_qscale); + put_dct(s, block[5], 5, dest_cr, uvlinesize, s->chroma_qscale); + } else { + dct_offset >>=1; + dct_linesize >>=1; + put_dct(s, block[4], 4, dest_cb, dct_linesize, s->chroma_qscale); + put_dct(s, block[5], 5, dest_cr, dct_linesize, s->chroma_qscale); + put_dct(s, block[6], 6, dest_cb + dct_offset, dct_linesize, s->chroma_qscale); + put_dct(s, block[7], 7, dest_cr + dct_offset, dct_linesize, s->chroma_qscale); + } + } + } + } } static int get_sae(const uint8_t *src, int ref, int stride) diff --git a/libavcodec/mpv_reconstruct_mb_template.c b/libavcodec/mpv_reconstruct_mb_template.c deleted file mode 100644 index ae7a9e34ce..0000000000 --- a/libavcodec/mpv_reconstruct_mb_template.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * MPEG macroblock reconstruction - * Copyright (c) 2000,2001 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer - * - * 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 - */ - -#define NOT_MPEG12_H261 0 -#define MAY_BE_MPEG12_H261 1 -#define DEFINITELY_MPEG12_H261 2 - -/* put block[] to dest[] */ -static inline void put_dct(MpegEncContext *s, - int16_t *block, int i, uint8_t *dest, int line_size, int qscale) -{ - s->dct_unquantize_intra(s, block, i, qscale); - s->idsp.idct_put(dest, line_size, block); -} - -static inline void add_dequant_dct(MpegEncContext *s, - int16_t *block, int i, uint8_t *dest, int line_size, int qscale) -{ - if (s->block_last_index[i] >= 0) { - s->dct_unquantize_inter(s, block, i, qscale); - - s->idsp.idct_add(dest, line_size, block); - } -} - -/* generic function called after a macroblock has been parsed by the - decoder or after it has been encoded by the encoder. - - Important variables used: - s->mb_intra : true if intra macroblock - s->mv_dir : motion vector direction - s->mv_type : motion vector type - s->mv : motion vector - s->interlaced_dct : true if interlaced dct used (mpeg2) - */ -static av_always_inline -void mpv_reconstruct_mb_internal(MpegEncContext *s, int16_t block[12][64], - int lowres_flag, int is_mpeg12) -{ -#define IS_MPEG12_H261(s) (is_mpeg12 == MAY_BE_MPEG12_H261 ? ((s)->out_format <= FMT_H261) : is_mpeg12) - const int mb_xy = s->mb_y * s->mb_stride + s->mb_x; - - s->cur_pic.qscale_table[mb_xy] = s->qscale; - -#if IS_ENCODER - if ((s->avctx->flags & AV_CODEC_FLAG_PSNR) || s->frame_skip_threshold || s->frame_skip_factor || - !((s->intra_only || s->pict_type == AV_PICTURE_TYPE_B) && - s->avctx->mb_decision != FF_MB_DECISION_RD)) // FIXME precalc -#endif /* IS_ENCODER */ - { - uint8_t *dest_y = s->dest[0], *dest_cb = s->dest[1], *dest_cr = s->dest[2]; - int dct_linesize, dct_offset; - const int linesize = s->cur_pic.linesize[0]; //not s->linesize as this would be wrong for field pics - const int uvlinesize = s->cur_pic.linesize[1]; - const int block_size = lowres_flag ? 8 >> s->avctx->lowres : 8; - - /* avoid copy if macroblock skipped in last frame too */ - /* skip only during decoding as we might trash the buffers during encoding a bit */ - if (!IS_ENCODER) { - uint8_t *mbskip_ptr = &s->mbskip_table[mb_xy]; - - if (s->mb_skipped) { - s->mb_skipped = 0; - av_assert2(s->pict_type!=AV_PICTURE_TYPE_I); - *mbskip_ptr = 1; - } else if (!s->cur_pic.reference) { - *mbskip_ptr = 1; - } else{ - *mbskip_ptr = 0; /* not skipped */ - } - } - - dct_linesize = linesize << s->interlaced_dct; - dct_offset = s->interlaced_dct ? linesize : linesize * block_size; - - if (!s->mb_intra) { - /* motion handling */ - /* decoding or more than one mb_type (MC was already done otherwise) */ - -#if !IS_ENCODER - if (HAVE_THREADS && is_mpeg12 != DEFINITELY_MPEG12_H261 && - s->avctx->active_thread_type & FF_THREAD_FRAME) { - if (s->mv_dir & MV_DIR_FORWARD) { - ff_thread_progress_await(&s->last_pic.ptr->progress, - lowest_referenced_row(s, 0)); - } - if (s->mv_dir & MV_DIR_BACKWARD) { - ff_thread_progress_await(&s->next_pic.ptr->progress, - lowest_referenced_row(s, 1)); - } - } - - if (lowres_flag) { - const h264_chroma_mc_func *op_pix = s->h264chroma.put_h264_chroma_pixels_tab; - - if (s->mv_dir & MV_DIR_FORWARD) { - MPV_motion_lowres(s, dest_y, dest_cb, dest_cr, 0, s->last_pic.data, op_pix); - op_pix = s->h264chroma.avg_h264_chroma_pixels_tab; - } - if (s->mv_dir & MV_DIR_BACKWARD) { - MPV_motion_lowres(s, dest_y, dest_cb, dest_cr, 1, s->next_pic.data, op_pix); - } - } else { - const op_pixels_func (*op_pix)[4]; - const qpel_mc_func (*op_qpix)[16]; - - if ((is_mpeg12 == DEFINITELY_MPEG12_H261 || !s->no_rounding) || s->pict_type == AV_PICTURE_TYPE_B) { - op_pix = s->hdsp.put_pixels_tab; - op_qpix = s->qdsp.put_qpel_pixels_tab; - } else { - op_pix = s->hdsp.put_no_rnd_pixels_tab; - op_qpix = s->qdsp.put_no_rnd_qpel_pixels_tab; - } - if (s->mv_dir & MV_DIR_FORWARD) { - ff_mpv_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_pic.data, op_pix, op_qpix); - op_pix = s->hdsp.avg_pixels_tab; - op_qpix = s->qdsp.avg_qpel_pixels_tab; - } - if (s->mv_dir & MV_DIR_BACKWARD) { - ff_mpv_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_pic.data, op_pix, op_qpix); - } - } - - /* skip dequant / idct if we are really late ;) */ - if (s->avctx->skip_idct) { - if( (s->avctx->skip_idct >= AVDISCARD_NONREF && s->pict_type == AV_PICTURE_TYPE_B) - ||(s->avctx->skip_idct >= AVDISCARD_NONKEY && s->pict_type != AV_PICTURE_TYPE_I) - || s->avctx->skip_idct >= AVDISCARD_ALL) - return; - } - - /* add dct residue */ - if (!(IS_MPEG12_H261(s) || s->msmpeg4_version != MSMP4_UNUSED || - (s->codec_id == AV_CODEC_ID_MPEG4 && !s->mpeg_quant))) -#endif /* !IS_ENCODER */ - { - add_dequant_dct(s, block[0], 0, dest_y , dct_linesize, s->qscale); - add_dequant_dct(s, block[1], 1, dest_y + block_size, dct_linesize, s->qscale); - add_dequant_dct(s, block[2], 2, dest_y + dct_offset , dct_linesize, s->qscale); - add_dequant_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize, s->qscale); - - if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { - av_assert2(IS_ENCODER || s->chroma_y_shift); - if (!IS_ENCODER || s->chroma_y_shift) { - add_dequant_dct(s, block[4], 4, dest_cb, uvlinesize, s->chroma_qscale); - add_dequant_dct(s, block[5], 5, dest_cr, uvlinesize, s->chroma_qscale); - } else { - dct_linesize >>= 1; - dct_offset >>= 1; - add_dequant_dct(s, block[4], 4, dest_cb, dct_linesize, s->chroma_qscale); - add_dequant_dct(s, block[5], 5, dest_cr, dct_linesize, s->chroma_qscale); - add_dequant_dct(s, block[6], 6, dest_cb + dct_offset, dct_linesize, s->chroma_qscale); - add_dequant_dct(s, block[7], 7, dest_cr + dct_offset, dct_linesize, s->chroma_qscale); - } - } - } -#if !IS_ENCODER - else if (is_mpeg12 == DEFINITELY_MPEG12_H261 || lowres_flag || (s->codec_id != AV_CODEC_ID_WMV2)) { - add_dct(s, block[0], 0, dest_y , dct_linesize); - add_dct(s, block[1], 1, dest_y + block_size, dct_linesize); - add_dct(s, block[2], 2, dest_y + dct_offset , dct_linesize); - add_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize); - - if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { - if (s->chroma_y_shift) {//Chroma420 - add_dct(s, block[4], 4, dest_cb, uvlinesize); - add_dct(s, block[5], 5, dest_cr, uvlinesize); - } else { - //chroma422 - dct_linesize = uvlinesize << s->interlaced_dct; - dct_offset = s->interlaced_dct ? uvlinesize : uvlinesize*block_size; - - add_dct(s, block[4], 4, dest_cb, dct_linesize); - add_dct(s, block[5], 5, dest_cr, dct_linesize); - add_dct(s, block[6], 6, dest_cb+dct_offset, dct_linesize); - add_dct(s, block[7], 7, dest_cr+dct_offset, dct_linesize); - if (!s->chroma_x_shift) {//Chroma444 - add_dct(s, block[8], 8, dest_cb+block_size, dct_linesize); - add_dct(s, block[9], 9, dest_cr+block_size, dct_linesize); - add_dct(s, block[10], 10, dest_cb+block_size+dct_offset, dct_linesize); - add_dct(s, block[11], 11, dest_cr+block_size+dct_offset, dct_linesize); - } - } - } //fi gray - } else if (CONFIG_WMV2_DECODER) { - ff_wmv2_add_mb(s, block, dest_y, dest_cb, dest_cr); - } -#endif /* !IS_ENCODER */ - } else { -#if !IS_ENCODER - /* Only MPEG-4 Simple Studio Profile is supported in > 8-bit mode. - TODO: Integrate 10-bit properly into mpegvideo.c so that ER works properly */ - if (is_mpeg12 != DEFINITELY_MPEG12_H261 && CONFIG_MPEG4_DECODER && - /* s->codec_id == AV_CODEC_ID_MPEG4 && */ - s->avctx->bits_per_raw_sample > 8) { - ff_mpeg4_decode_studio(s, dest_y, dest_cb, dest_cr, block_size, - uvlinesize, dct_linesize, dct_offset); - } else if (!IS_MPEG12_H261(s)) -#endif /* !IS_ENCODER */ - { - /* dct only in intra block */ - put_dct(s, block[0], 0, dest_y , dct_linesize, s->qscale); - put_dct(s, block[1], 1, dest_y + block_size, dct_linesize, s->qscale); - put_dct(s, block[2], 2, dest_y + dct_offset , dct_linesize, s->qscale); - put_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize, s->qscale); - - if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { - if (s->chroma_y_shift) { - put_dct(s, block[4], 4, dest_cb, uvlinesize, s->chroma_qscale); - put_dct(s, block[5], 5, dest_cr, uvlinesize, s->chroma_qscale); - } else { - dct_offset >>=1; - dct_linesize >>=1; - put_dct(s, block[4], 4, dest_cb, dct_linesize, s->chroma_qscale); - put_dct(s, block[5], 5, dest_cr, dct_linesize, s->chroma_qscale); - put_dct(s, block[6], 6, dest_cb + dct_offset, dct_linesize, s->chroma_qscale); - put_dct(s, block[7], 7, dest_cr + dct_offset, dct_linesize, s->chroma_qscale); - } - } - } -#if !IS_ENCODER - else { - s->idsp.idct_put(dest_y, dct_linesize, block[0]); - s->idsp.idct_put(dest_y + block_size, dct_linesize, block[1]); - s->idsp.idct_put(dest_y + dct_offset, dct_linesize, block[2]); - s->idsp.idct_put(dest_y + dct_offset + block_size, dct_linesize, block[3]); - - if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { - if (s->chroma_y_shift) { - s->idsp.idct_put(dest_cb, uvlinesize, block[4]); - s->idsp.idct_put(dest_cr, uvlinesize, block[5]); - } else { - dct_linesize = uvlinesize << s->interlaced_dct; - dct_offset = s->interlaced_dct ? uvlinesize : uvlinesize*block_size; - - s->idsp.idct_put(dest_cb, dct_linesize, block[4]); - s->idsp.idct_put(dest_cr, dct_linesize, block[5]); - s->idsp.idct_put(dest_cb + dct_offset, dct_linesize, block[6]); - s->idsp.idct_put(dest_cr + dct_offset, dct_linesize, block[7]); - if (!s->chroma_x_shift) { //Chroma444 - s->idsp.idct_put(dest_cb + block_size, dct_linesize, block[8]); - s->idsp.idct_put(dest_cr + block_size, dct_linesize, block[9]); - s->idsp.idct_put(dest_cb + block_size + dct_offset, dct_linesize, block[10]); - s->idsp.idct_put(dest_cr + block_size + dct_offset, dct_linesize, block[11]); - } - } - } //gray - } -#endif /* !IS_ENCODER */ - } - } -} -