From patchwork Tue May 28 10:48:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Andreas_H=C3=A5kon?= X-Patchwork-Id: 13316 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 D8AD3447EAC for ; Tue, 28 May 2019 13:48:16 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id B62DB689F6E; Tue, 28 May 2019 13:48:16 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-40135.protonmail.ch (mail-40135.protonmail.ch [185.70.40.135]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 98DA76891D2 for ; Tue, 28 May 2019 13:48:10 +0300 (EEST) Date: Tue, 28 May 2019 10:48:03 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=default; t=1559040489; bh=bsY1NL3GbATtLdmuoC+r/QgX0RfhUcxkplIPJR+5lcQ=; h=Date:To:From:Reply-To:Subject:Feedback-ID:From; b=KQKFYHC1diLMVoq4cyDVF6to1jID7kV6Nj6y8mSXHgWFLbgVoT7+FmJvEW521/m/K /LwWVyD6A2VeoXGCoCNTFbybscJcF4oXL9n2iNBeHimoVM0NsiXSbFqbSMjg/RWAZk JoEhjXdBojDLQnsY0AGue0sfOmraHDtqXlql1Yyc= To: FFmpeg development discussions and patches From: =?UTF-8?Q?Andreas_H=C3=A5kon?= Message-ID: Feedback-ID: Mx8CaiV20jk_fqXDN0fFpg3vRaGkb9VCTrYRnZNHwEija3aOdqvFspzl6ODkmHrlSKJSx29p-LzkuvS_96L02A==:Ext:ProtonMail MIME-Version: 1.0 X-Spam-Status: No, score=-1.2 required=7.0 tests=ALL_TRUSTED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,HTML_MESSAGE autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.protonmail.ch X-Content-Filtered-By: Mailman/MimeDel 2.1.20 Subject: [FFmpeg-devel] [PATCH] libavformat/qsvenc: repeat mpeg2 missing headers [v2] 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Hi, This patch supersedes #13105 (https://patchwork.ffmpeg.org/patch/13105/) A new (simpler and more robust) implementationof of the reinsertion of the missing headers in the MPEG-2 bitstream from the HW QSV encoder. The problem is quite simple: The bitstream generated by the MPEG-2 QSV encoder only incorporates the SEQ_START_CODE and EXT_START_CODE headers in the first GOP. This generates a result that is not suitable for streaming or broadcasting. With this patch the "mpeg2_qsv" encoder is at the same level as the "mpeg2video", as the software implementation repeats these headers by default in each GOP. Regards. A.H. --- From 8a139ea03b0445e3057122577126f3a48744fe29 Mon Sep 17 00:00:00 2001 From: Andreas Hakon Date: Tue, 28 May 2019 11:27:05 +0100 Subject: [PATCH] libavformat/qsvenc: repeat mpeg2 missing headers [v2] The current implementation of the QSV MPEG-2 HW encoder writes the value of MPEG-2 sequence headers in-band one time only. That is, in the first GOP of the stream. This behavior generates a bitstream that is not suitable for streaming or broadcasting. This patch resolves this problem by storing the headers in the configuration phase, and reinserting them back if necessary into each GOP. Signed-off-by: Andreas Hakon --- libavcodec/qsvenc.c | 27 +++++++++++++++++++++++++++ libavcodec/qsvenc.h | 3 +++ 2 files changed, 30 insertions(+) diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index 8dbad71..63ee198 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -859,6 +859,15 @@ static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q) q->packet_size = q->param.mfx.BufferSizeInKB * q->param.mfx.BRCParamMultiplier * 1000; + if (avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO) { + av_log(avctx, AV_LOG_DEBUG, "Reading MPEG-2 initial Sequence Sections (SPSBuffer:%d)\n", extradata.SPSBufSize); + q->add_headers = av_malloc(extradata.SPSBufSize); + if (!q->add_headers) + return AVERROR(ENOMEM); + q->add_headers_size = extradata.SPSBufSize; + memcpy(q->add_headers, extradata.SPSBuffer, q->add_headers_size); + } + if (!extradata.SPSBufSize || (need_pps && !extradata.PPSBufSize) #if QSV_HAVE_CO_VPS || (q->hevc_vps && !extradata_vps.VPSBufSize) @@ -999,6 +1008,7 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q) int ret; q->param.AsyncDepth = q->async_depth; + q->add_headers_size = 0; q->async_fifo = av_fifo_alloc(q->async_depth * qsv_fifo_item_size()); if (!q->async_fifo) @@ -1437,6 +1447,20 @@ int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q, ret = MFXVideoCORE_SyncOperation(q->session, *sync, 1000); } while (ret == MFX_WRN_IN_EXECUTION); + if (avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO && q->add_headers_size > 0 && + (bs->FrameType & MFX_FRAMETYPE_I || bs->FrameType & MFX_FRAMETYPE_IDR || bs->FrameType & MFX_FRAMETYPE_xI || bs->FrameType & MFX_FRAMETYPE_xIDR)) { + if (bs->Data[0] == 0x00 && bs->Data[1] == 0x00 && bs->Data[2] == 0x01 && bs->Data[3] != 0xb3 ) { + av_log(avctx, AV_LOG_DEBUG, "Missing MPEG-2 Sequence Sections, reinsertion required\n"); + if (q->add_headers_size + bs->DataLength <= q->packet_size) { + memmove(new_pkt.data + q->add_headers_size, new_pkt.data, bs->DataLength); + memcpy(new_pkt.data, q->add_headers, q->add_headers_size); + bs->DataLength += q->add_headers_size; + } else { + av_log(avctx, AV_LOG_WARNING, "Insufficient spacing to reinsert MPEG-2 Sequence Sections"); + } + } + } + new_pkt.dts = av_rescale_q(bs->DecodeTimeStamp, (AVRational){1, 90000}, avctx->time_base); new_pkt.pts = av_rescale_q(bs->TimeStamp, (AVRational){1, 90000}, avctx->time_base); new_pkt.size = bs->DataLength; @@ -1545,5 +1569,8 @@ int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q) av_freep(&q->extparam); + if (q->add_headers_size > 0) + av_freep(&q->add_headers); + return 0; } diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h index f2f4d38..ee81c51 100644 --- a/libavcodec/qsvenc.h +++ b/libavcodec/qsvenc.h @@ -177,6 +177,9 @@ typedef struct QSVEncContext { int low_power; int gpb; + int add_headers_size; + uint8_t *add_headers; + int a53_cc; #if QSV_HAVE_MF