@@ -288,6 +288,51 @@ void RGYInputAvcodec::vc1AddFrameHeader(AVPacket *pkt) {
288288 }
289289}
290290
291+ void RGYInputAvcodec::hevcMp42Annexb (AVPacket *pkt) {
292+ static const uint8_t SC[] = { 0 , 0 , 0 , 1 };
293+ const uint8_t *ptr, *ptr_fin;
294+ if (pkt == NULL ) {
295+ m_hevcMp42AnnexbBuffer.reserve (m_Demux.video .nExtradataSize + 128 );
296+ ptr = m_Demux.video .pExtradata ;
297+ ptr_fin = ptr + m_Demux.video .nExtradataSize ;
298+ ptr += 0x16 ;
299+ } else {
300+ m_hevcMp42AnnexbBuffer.reserve (pkt->size + 128 );
301+ ptr = pkt->data ;
302+ ptr_fin = ptr + pkt->size ;
303+ }
304+ const int numOfArrays = *ptr;
305+ ptr += !!numOfArrays;
306+
307+ while (ptr + 6 < ptr_fin) {
308+ ptr += !!numOfArrays;
309+ const int count = readUB16 (ptr); ptr += 2 ;
310+ int units = (numOfArrays) ? count : 1 ;
311+ for (int i = (std::max)(1 , units); i; i--) {
312+ uint32_t size = readUB16 (ptr); ptr += 2 ;
313+ uint32_t uppper = count << 16 ;
314+ size += (numOfArrays) ? 0 : uppper;
315+ m_hevcMp42AnnexbBuffer.insert (m_hevcMp42AnnexbBuffer.end (), SC, SC+4 );
316+ m_hevcMp42AnnexbBuffer.insert (m_hevcMp42AnnexbBuffer.end (), ptr, ptr+size); ptr += size;
317+ }
318+ }
319+ if (pkt) {
320+ if (pkt->buf ->size < (int )m_hevcMp42AnnexbBuffer.size ()) {
321+ av_grow_packet (pkt, (int )m_hevcMp42AnnexbBuffer.size ());
322+ }
323+ memcpy (pkt->data , m_hevcMp42AnnexbBuffer.data (), m_hevcMp42AnnexbBuffer.size ());
324+ pkt->size = (int )m_hevcMp42AnnexbBuffer.size ();
325+ } else {
326+ if (m_Demux.video .pExtradata ) {
327+ av_free (m_Demux.video .pExtradata );
328+ }
329+ m_Demux.video .pExtradata = (uint8_t *)av_malloc (m_hevcMp42AnnexbBuffer.size ());
330+ m_Demux.video .nExtradataSize = (int )m_hevcMp42AnnexbBuffer.size ();
331+ memcpy (m_Demux.video .pExtradata , m_hevcMp42AnnexbBuffer.data (), m_hevcMp42AnnexbBuffer.size ());
332+ }
333+ m_hevcMp42AnnexbBuffer.clear ();
334+ }
335+
291336RGY_ERR RGYInputAvcodec::getFirstFramePosAndFrameRate (const sTrim *pTrimList, int nTrimCount, bool bDetectpulldown) {
292337 AVRational fpsDecoder = m_Demux.video .pStream ->avg_frame_rate ;
293338 const bool fpsDecoderInvalid = (fpsDecoder.den == 0 || fpsDecoder.num == 0 );
@@ -942,7 +987,9 @@ RGY_ERR RGYInputAvcodec::Init(const TCHAR *strFileName, VideoInfo *pInputInfo, c
942987
943988 // 必要ならbitstream filterを初期化
944989 if (m_Demux.video .nHWDecodeDeviceId >= 0 && m_Demux.video .pStream ->codecpar ->extradata && m_Demux.video .pStream ->codecpar ->extradata [0 ] == 1 ) {
945- if (m_Demux.video .pStream ->codecpar ->codec_id == AV_CODEC_ID_H264 ||
990+ if (m_Demux.video .pStream ->codecpar ->codec_id == AV_CODEC_ID_HEVC) {
991+ m_Demux.video .bUseHEVCmp42AnnexB = true ;
992+ } else if (m_Demux.video .pStream ->codecpar ->codec_id == AV_CODEC_ID_H264 ||
946993 m_Demux.video .pStream ->codecpar ->codec_id == AV_CODEC_ID_HEVC) {
947994 const char *filtername = nullptr ;
948995 switch (m_Demux.video .pStream ->codecpar ->codec_id ) {
@@ -1035,7 +1082,7 @@ RGY_ERR RGYInputAvcodec::Init(const TCHAR *strFileName, VideoInfo *pInputInfo, c
10351082 AddMessage (RGY_LOG_ERROR, _T (" failed to copy codec param to context for parser: %s.\n " ), qsv_av_err2str (ret).c_str ());
10361083 return RGY_ERR_UNKNOWN;
10371084 }
1038- if (m_Demux.video .pBsfcCtx ) {
1085+ if (m_Demux.video .pBsfcCtx || m_Demux. video . bUseHEVCmp42AnnexB ) {
10391086 SetExtraData (codecParamCopy.get (), m_Demux.video .pExtradata , m_Demux.video .nExtradataSize );
10401087 }
10411088 if (0 > (ret = avcodec_parameters_to_context (m_Demux.video .pCodecCtxParser , codecParamCopy.get ()))) {
@@ -1157,7 +1204,7 @@ RGY_ERR RGYInputAvcodec::Init(const TCHAR *strFileName, VideoInfo *pInputInfo, c
11571204 AddMessage (RGY_LOG_ERROR, _T (" failed to copy codec param to context for parser: %s.\n " ), qsv_av_err2str (ret).c_str ());
11581205 return RGY_ERR_UNKNOWN;
11591206 }
1160- if (m_Demux.video .pBsfcCtx ) {
1207+ if (m_Demux.video .pBsfcCtx || m_Demux. video . bUseHEVCmp42AnnexB ) {
11611208 SetExtraData (codecParamCopy.get (), m_Demux.video .pExtradata , m_Demux.video .nExtradataSize );
11621209 }
11631210 if (0 > (ret = avcodec_parameters_to_context (m_Demux.video .pCodecCtxDecode , codecParamCopy.get ()))) {
@@ -1452,6 +1499,9 @@ int RGYInputAvcodec::getSample(AVPacket *pkt, bool bTreatFirstPacketAsKeyframe)
14521499 if (m_Demux.video .pStream ->codecpar ->codec_id == AV_CODEC_ID_VC1) {
14531500 vc1AddFrameHeader (pkt);
14541501 }
1502+ if (m_Demux.video .bUseHEVCmp42AnnexB ) {
1503+ hevcMp42Annexb (pkt);
1504+ }
14551505 // 最初のキーフレームを取得するまではスキップする
14561506 // スキップした枚数はi_samplesでカウントし、trim時に同期を適切にとるため、m_sTrimParam.offsetに格納する
14571507 // ただし、bTreatFirstPacketAsKeyframeが指定されている場合には、キーフレームでなくてもframePosListへの追加を許可する
@@ -1749,7 +1799,9 @@ RGY_ERR RGYInputAvcodec::GetHeader(RGYBitstream *pBitstream) {
17491799 memcpy (m_Demux.video .pExtradata , m_Demux.video .pStream ->codecpar ->extradata , m_Demux.video .nExtradataSize );
17501800 memset (m_Demux.video .pExtradata + m_Demux.video .nExtradataSize , 0 , AV_INPUT_BUFFER_PADDING_SIZE);
17511801
1752- if (m_Demux.video .pBsfcCtx && m_Demux.video .pExtradata [0 ] == 1 ) {
1802+ if (m_Demux.video .bUseHEVCmp42AnnexB ) {
1803+ hevcMp42Annexb (nullptr );
1804+ } else if (m_Demux.video .pBsfcCtx && m_Demux.video .pExtradata [0 ] == 1 ) {
17531805 if (m_Demux.video .nExtradataSize < m_Demux.video .pBsfcCtx ->par_out ->extradata_size ) {
17541806 m_Demux.video .pExtradata = (uint8_t *)av_realloc (m_Demux.video .pExtradata , m_Demux.video .pBsfcCtx ->par_out ->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
17551807 }
0 commit comments