2121
2222#include "config.h"
2323
24+ #include "h2645_parse.h"
25+ #include "h264.h"
2426#include "nvenc.h"
2527
2628#include "libavutil/hwcontext_cuda.h"
@@ -1073,6 +1075,15 @@ static av_cold int nvenc_setup_encoder(AVCodecContext *avctx)
10731075 ctx -> init_encode_params .frameRateNum = avctx -> time_base .den ;
10741076 ctx -> init_encode_params .frameRateDen = avctx -> time_base .num * avctx -> ticks_per_frame ;
10751077
1078+ /* if (avctx->ticks_per_frame == 1) {
1079+ if(avctx->time_base.den < INT_MAX/2) {
1080+ avctx->time_base.den *= 2;
1081+ } else {
1082+ avctx->time_base.num /= 2;
1083+ }
1084+ avctx->ticks_per_frame = 2;
1085+ } */
1086+
10761087 ctx -> init_encode_params .enableEncodeAsync = 0 ;
10771088 ctx -> init_encode_params .enablePTD = 1 ;
10781089
@@ -1678,6 +1689,55 @@ static int nvenc_set_timestamp(AVCodecContext *avctx,
16781689 return 0 ;
16791690}
16801691
1692+ static int get_second_slice_offset (AVCodecContext * avctx , const uint8_t * buf , int length , int * offset )
1693+ {
1694+ NvencContext * ctx = avctx -> priv_data ;
1695+
1696+ H2645Packet h2645_pkt = { 0 };
1697+ int idx = -1 , count = 0 , slice_count = 0 ;
1698+ int i , res ;
1699+
1700+ // NVENC does not support HEVC interlaced encoding, so don't even bother.
1701+ if (avctx -> codec -> id != AV_CODEC_ID_H264 || ctx -> encode_config .frameFieldMode != NV_ENC_PARAMS_FRAME_FIELD_MODE_FIELD ) {
1702+ * offset = 0 ;
1703+ return 0 ;
1704+ }
1705+
1706+ res = ff_h2645_packet_split (& h2645_pkt , buf , length , avctx , 0 , 0 , avctx -> codec -> id , 1 );
1707+ if (res < 0 )
1708+ return res ;
1709+
1710+ for (i = 0 ; i < h2645_pkt .nb_nals ; i ++ )
1711+ if (h2645_pkt .nals [i ].type == H264_NAL_SLICE || h2645_pkt .nals [i ].type == H264_NAL_IDR_SLICE )
1712+ slice_count ++ ;
1713+
1714+ if (slice_count < 2 )
1715+ goto fail ;
1716+
1717+ for (i = 0 ; i < h2645_pkt .nb_nals ; i ++ ) {
1718+ if (h2645_pkt .nals [i ].type == H264_NAL_SLICE || h2645_pkt .nals [i ].type == H264_NAL_IDR_SLICE ) {
1719+ if (++ count == slice_count / 2 ) {
1720+ idx = i ;
1721+ break ;
1722+ }
1723+ }
1724+ }
1725+
1726+ if (i >= h2645_pkt .nb_nals || idx < 0 )
1727+ goto fail ;
1728+
1729+ * offset = h2645_pkt .nals [idx + 1 ].raw_data - 4 - buf ;
1730+
1731+ ff_h2645_packet_uninit (& h2645_pkt );
1732+
1733+ return 0 ;
1734+
1735+ fail :
1736+ ff_h2645_packet_uninit (& h2645_pkt );
1737+ * offset = 0 ;
1738+ return 0 ;
1739+ }
1740+
16811741static int process_output_surface (AVCodecContext * avctx , AVPacket * pkt , NvencSurface * tmpoutsurf )
16821742{
16831743 NvencContext * ctx = avctx -> priv_data ;
@@ -1688,10 +1748,16 @@ static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, NvencSur
16881748 uint32_t * slice_offsets = NULL ;
16891749 NV_ENC_LOCK_BITSTREAM lock_params = { 0 };
16901750 NVENCSTATUS nv_status ;
1751+ int main_size , second_slice_offset = -1 ;
16911752 int res = 0 ;
16921753
16931754 enum AVPictureType pict_type ;
16941755
1756+ if (ctx -> extra_packet ) {
1757+ av_log (avctx , AV_LOG_ERROR , "extra_packet already allocated!\n" );
1758+ return AVERROR_BUG ;
1759+ }
1760+
16951761 switch (avctx -> codec -> id ) {
16961762 case AV_CODEC_ID_H264 :
16971763 slice_mode_data = ctx -> encode_config .encodeCodecConfig .h264Config .sliceModeData * 2 ;
@@ -1721,12 +1787,32 @@ static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, NvencSur
17211787 goto error ;
17221788 }
17231789
1724- if (res = ff_alloc_packet2 (avctx , pkt , lock_params .bitstreamSizeInBytes , 0 )) {
1790+ res = get_second_slice_offset (avctx , lock_params .bitstreamBufferPtr , lock_params .bitstreamSizeInBytes , & second_slice_offset );
1791+ if (res < 0 )
1792+ goto error ;
1793+
1794+ main_size = second_slice_offset > 0 ? second_slice_offset : lock_params .bitstreamSizeInBytes ;
1795+
1796+ if (res = ff_alloc_packet2 (avctx , pkt , main_size , 0 )) {
17251797 p_nvenc -> nvEncUnlockBitstream (ctx -> nvencoder , tmpoutsurf -> output_surface );
17261798 goto error ;
17271799 }
17281800
1729- memcpy (pkt -> data , lock_params .bitstreamBufferPtr , lock_params .bitstreamSizeInBytes );
1801+ memcpy (pkt -> data , lock_params .bitstreamBufferPtr , main_size );
1802+
1803+ if (second_slice_offset > 0 ) {
1804+ ctx -> extra_packet = av_packet_alloc ();
1805+ if (!ctx -> extra_packet ) {
1806+ res = AVERROR (ENOMEM );
1807+ goto error ;
1808+ }
1809+
1810+ res = av_new_packet (ctx -> extra_packet , lock_params .bitstreamSizeInBytes - second_slice_offset );
1811+ if (res < 0 )
1812+ goto error ;
1813+
1814+ memcpy (ctx -> extra_packet -> data , (uint8_t * )lock_params .bitstreamBufferPtr + second_slice_offset , ctx -> extra_packet -> size );
1815+ }
17301816
17311817 nv_status = p_nvenc -> nvEncUnlockBitstream (ctx -> nvencoder , tmpoutsurf -> output_surface );
17321818 if (nv_status != NV_ENC_SUCCESS )
@@ -1776,6 +1862,15 @@ FF_ENABLE_DEPRECATION_WARNINGS
17761862 if (res < 0 )
17771863 goto error2 ;
17781864
1865+ if (ctx -> extra_packet ) {
1866+ //TODO: The timebase needs to be fixed(if ticks_per_frame == 1).
1867+ ctx -> extra_packet -> dts = AV_NOPTS_VALUE ;
1868+ ctx -> extra_packet -> pts = AV_NOPTS_VALUE ;
1869+
1870+ ff_side_data_set_encoder_stats (ctx -> extra_packet ,
1871+ (lock_params .frameAvgQP - 1 ) * FF_QP2LAMBDA , NULL , 0 , pict_type );
1872+ }
1873+
17791874 av_free (slice_offsets );
17801875
17811876 return 0 ;
@@ -1933,7 +2028,11 @@ int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
19332028 if (!ctx -> cu_context || !ctx -> nvencoder )
19342029 return AVERROR (EINVAL );
19352030
1936- if (output_ready (avctx , ctx -> encoder_flushing )) {
2031+ if (ctx -> extra_packet ) {
2032+ av_packet_move_ref (pkt , ctx -> extra_packet );
2033+ av_packet_free (& ctx -> extra_packet );
2034+ return 0 ;
2035+ } else if (output_ready (avctx , ctx -> encoder_flushing )) {
19372036 av_fifo_generic_read (ctx -> output_surface_ready_queue , & tmp_out_surf , sizeof (tmp_out_surf ), NULL );
19382037
19392038 cu_res = dl_fn -> cuda_dl -> cuCtxPushCurrent (ctx -> cu_context );
0 commit comments