Avcodec_decode_video2クラッシュの問題の処理



Avcodec_decode_video2 Crash Problem Handling



I.イベントの背景

イベントはこんな感じです。ストリームを取得->デコード->レンダリングのプロセス。そして、このステップavcodec_decode_video2は、圧縮されたデータAVPacketをAVFrameにデコードすることです。いくつかのプロセスをチェックし、プロセスにエラーが見つからなかった前。 avcodec_decode_video2のフラッシュバックpFrameがNULLであることを確認します。しかし、当時の私の理解は次のとおりでした。pFrameがNULLであるのは正常です... AVPacketに問題がある可能性があり、デコードできません。しかし、それはそれ自身の状況のいくつかを要約しています...ビデオが閉じられたときだけです。ここでエラーを報告します。つまり、ビデオを閉じるときに、最初にリリースを実行します... pFrameがNULLになります。

int len = -1 len = avcodec_decode_video2(pCodecCtx264, pFrame, &gotframe, &packet)

リリースコード



-(void)CloseLoop { NSLog (@'CloseLoop release decoder') if (pFormatCtx != NULL) { pFormatCtx->interrupt_callback.opaque = NULL pFormatCtx->interrupt_callback.callback = NULL avformat_close_input(&pFormatCtx) avformat_free_context(pFormatCtx) pFormatCtx = NULL } if (pFrame != NULL) { av_free(pFrame) pFrame = NULL } if (pCodecCtx264 != NULL) { avcodec_close(pCodecCtx264) pCodecCtx264 = NULL } if (pCodecCtx265 != NULL) { avcodec_close(pCodecCtx265) pCodecCtx265 = NULL } }

最初にリリースコードを実行した可能性があります...デコードループがデコードを終了していません...その後、avcodec_decode_video2がフラッシュバックします

第二に、解決策

必ず最初にデコードループを終了してから解放してください。下側は、h.265のデコードを追加することです。



BOOL bFinish = YES int nRef = 0 uint8_t * puf = NULL int gotframe = 0 static dispatch_once_t onceToken dispatch_once(&onceToken, ^{ av_register_all() }) avcodec_register_all() avformat_network_init() if (pCodecCtx264 == NULL) { AVCodec *pCodec264 = avcodec_find_decoder(AV_CODEC_ID_H264) pCodecCtx264 = avcodec_alloc_context3(pCodec264) if(avcodec_open2(pCodecCtx264, pCodec264, NULL) <0) { NSLog(@'error h264') bFinish = NO } } if (pCodecCtx265 == NULL) { AVCodec *pCodec265 = avcodec_find_decoder(AV_CODEC_ID_HEVC) pCodecCtx265 = avcodec_alloc_context3(pCodec265) if(avcodec_open2(pCodecCtx265, pCodec265, NULL) 0) { [_buffer removeObjectAtIndex:0] } }else { packet.size = 0 } int len = -1 if (datainfo.encodeType == 0x01 || datainfo.encodeType == 0x07) { len = avcodec_decode_video2(pCodecCtx264, pFrame, &gotframe, &packet) } if (datainfo.encodeType == 0x02 || datainfo.encodeType == 0x08) { len = avcodec_decode_video2(pCodecCtx265, pFrame, &gotframe, &packet) } if (gotframe) { //I am here to directly send pFrame back to OpenGL to render it. if (buf != NULL && self.block) { self.block(pFrame,buf) } memset(pict, 0, sizeof(buf)) pict = nil free(buf) buf = nil if(puf) { free(puf) puf = nil } } if(len < 0) { printf('Decode Error = %d gotframe = %d . ',len,gotframe) } } av_free_packet(&packet) // Then I release it like this at the end. If _isfree is true, it will be released. if (_isfree) { [self CloseLoop] bFinish = NO break } } } }

これで終わりです。何かおかしいことがあれば、ポインタを教えてください。