#include "DxDecoderWrap.h" #include "SfxDecoder.h" DxDecoderWrap::DxDecoderWrap( const DxConfig * cfg ) { m_pDec = NULL; m_bRun = FALSE; m_bPause = FALSE; m_skip = 1; memset( &m_cfg, 0, sizeof( DxDecoderConfig ) ); memset( &m_frames, 0, sizeof( DxGPUFrames ) ); memcpy( &m_cfg.cfg, cfg, sizeof( DxConfig ) ); InitializeCriticalSection( &m_frames.cir ); memset( m_src_data, 0, sizeof( m_src_data ) ); memset( m_dst_data, 0, sizeof( m_dst_data ) ); memset( m_src_linesize, 0, sizeof( m_src_linesize ) ); memset( m_dst_linesize, 0, sizeof( m_dst_linesize ) ); m_out = NULL; m_outSize = 0; return; } DxDecoderWrap::~DxDecoderWrap() { DxCloseDecoder(); DeleteCriticalSection( &m_frames.cir ); if ( NULL != m_out ) { free( m_out ); m_out = NULL; } return; } int DxDecoderWrap::DxOpenDecoder( const char * uri, unsigned int skip ) { int ret = 0; if ( NULL != m_pDec ) { return -1; } if (! SfxStreamHandlerInterface::SfxCheckCompatible( uri ) ) { return -1; } m_nums = 0; m_skip = skip; m_bReal = FALSE; m_bPause = FALSE; m_frames.size = DX_GPU_FRAME_DEFAULT_SIZE; m_frames.frames = ( DxGPUFrame * )malloc( sizeof( DxGPUFrame ) * m_frames.size ); if ( NULL == m_frames.frames ) { return -1; } memset( m_frames.frames, 0, sizeof( DxGPUFrame ) * m_frames.size ); m_bRun = TRUE; m_cfg.userPtr = this; m_cfg.cfg.type = DX_DECODER_TYPE_SFXLAB; m_cfg.escbk = DxCUDADecoderCallback; m_cfg.logcbk = DxDecoderLogCallback; m_pDec = new SfxDecoder(&m_cfg); if ( NULL == m_pDec ) { m_bRun = FALSE; return -1; } #ifdef _MSC_VER if ( 0 == _memicmp( uri, "rtsp://", strlen( "rtsp://" ) ) ) #else if ( 0 == memicmp( uri, "rtsp://", strlen( "rtsp://" ) ) ) #endif { m_bReal = TRUE; } ret = m_pDec->OpenDecoder( uri ); if ( 0 != ret ) { m_bRun = FALSE; } return ret; } int DxDecoderWrap::DxCloseDecoder() { int pos = 0; m_bRun = FALSE; if ( NULL != m_pDec ) { m_pDec->CloseDecoder(); delete m_pDec; m_pDec = NULL; } if ( NULL != m_frames.frames ) { while ( pos < m_frames.size ) { if ( NULL != m_frames.frames[pos].frame ) { if ( DX_DECODER_TYPE_CPU == m_cfg.cfg.type ) { free( m_frames.frames[pos].frame ); m_frames.frames[pos].frame = NULL; } else if ( DX_DECODER_TYPE_SFXLAB == m_cfg.cfg.type || DX_DECODER_TYPE_CUDA == m_cfg.cfg.type ) { cudaFree( m_frames.frames[pos].frame ); m_frames.frames[pos].frame = NULL; } } pos++; } free( m_frames.frames ); m_frames.frames = NULL; } return 0; } int DxDecoderWrap::DxGetResolution( int * width, int * height ) { if ( 0 == m_frames.width ) { return -1; } if ( width ) { *width = m_frames.width; } if ( height ) { *height = m_frames.height; } return 0; } int DxDecoderWrap::DxGetFrameCount(){ if(m_pDec != nullptr){ return m_pDec->GetFrameCount(); } return -1; } int DxDecoderWrap::PauseDecoder() { m_bPause = TRUE; return 0; } int DxDecoderWrap::ResumeDecoder() { m_bPause = FALSE; return 0; } BOOL DxDecoderWrap::DxDecoderIsRun() const { return m_bRun; } BOOL DxDecoderWrap::DxFrameIsEmpty() const { return 0 == m_frames.counts; } int DxDecoderWrap::DxLockFrame( DxGPUFrame * frame ) { if ( NULL == frame ) { return -1; } EnterCriticalSection( &m_frames.cir ); if ( NULL == m_frames.frames || 0 == m_frames.frames[m_frames.read].size ) { DxUnlockFrame(); return -1; } frame->width = m_frames.width; frame->height = m_frames.height; frame->size = m_frames.frames[m_frames.read].size; frame->frame = m_frames.frames[m_frames.read].frame; frame->timestamp = m_frames.frames[m_frames.read].timestamp; m_frames.frames[m_frames.read].size = 0; m_frames.read++; m_frames.counts--; if ( m_frames.read == m_frames.size ) { m_frames.read = 0; } return 0; } void DxDecoderWrap::DxUnlockFrame() { LeaveCriticalSection( &m_frames.cir ); return; } int DxDecoderWrap::DxDecoderLogCallback( const void * userPtr, DxLogLevel level, const char * log, unsigned int logLen ) { int index = 0; DxDecoderWrap * pThis = NULL; pThis = ( DxDecoderWrap * )userPtr; if ( NULL == pThis ) { return 0; } if ( DX_LOG_LEVEL_FATAL == level ) { EnterCriticalSection( &pThis->m_frames.cir ); while ( index < pThis->m_frames.size ) { pThis->m_frames.frames[index].size = 0; if ( pThis->m_frames.frames[index].frame ) { if ( DX_DECODER_TYPE_CPU == pThis->m_cfg.cfg.type ) { free( pThis->m_frames.frames[index].frame ); pThis->m_frames.frames[index].frame = NULL; } else if ( DX_DECODER_TYPE_SFXLAB == pThis->m_cfg.cfg.type || DX_DECODER_TYPE_CUDA == pThis->m_cfg.cfg.type ) { cudaFree( pThis->m_frames.frames[index].frame ); pThis->m_frames.frames[index].frame = NULL; } } index++; } LeaveCriticalSection( &pThis->m_frames.cir ); return 0; } if (DX_LOG_LEVEL_IMPORTANT == level) //modify by zsh 220602 { if (0 == memcmp( log, SFX_STD_LOG_DONE, strlen(SFX_STD_LOG_DONE) + 1)) { pThis->m_bRun = FALSE; return 0; } if (0 == memcmp( log, "progress ", strlen( "progress ") ) ) { //printf("%s\n", log); //打印进度 格式:progress 100 } } if ( DX_LOG_LEVEL_CLEANUP == level ) { //printf( "%s\n", log ); pThis->m_bRun = FALSE; } return 0; } void DxDecoderWrap::DxCUDADecoderCallback( const void * userPtr, void * buf, unsigned int size, unsigned long long timestamp ) { static unsigned int s_dbg = 0; unsigned int rgbSize = 0; DxDecoderWrap * pThis = NULL; cudaError_t cudaStatus = cudaSuccess; pThis = ( DxDecoderWrap * )userPtr; if ( NULL == pThis ) { return; } if ( 0 == size ) { //#ifdef DX_DXDECODER_OUTPUT_NV12 // cuda_common::setColorSpace( 0 == pThis->m_cfg.cfg.colorFmt ? ITU709 : ITU601, 0 ); //#endif if ((DxVideoConfig *)buf == nullptr) { printf(" ( DxVideoConfig * )buf nullptr\n"); return; } pThis->m_frames.width = ( ( DxVideoConfig * )buf )->width; pThis->m_frames.height = ( (DxVideoConfig * )buf )->height; //printf("wrap %d %d\n", pThis->m_frames.width, pThis->m_frames.height); return; } while ( pThis->m_bRun ) { if ( pThis->m_bPause ) { if ( pThis->m_bReal ) { return; } Sleep( 10 ); continue; } break; } if ( !pThis->m_bRun ) { return; } if ( pThis->m_skip > 0 ) { if ( pThis->m_nums % pThis->m_skip ) { pThis->m_nums++; return; } } if ( !pThis->m_bReal ) { while ( pThis->m_frames.size == pThis->m_frames.counts ) { if ( !pThis->m_bRun ) { return; } Sleep( 10 ); } } //#ifdef DX_DXDECODER_OUTPUT_NV12 // rgbSize = pThis->m_frames.width * pThis->m_frames.height * 3 * sizeof( float ); rgbSize = pThis->m_frames.width * pThis->m_frames.height * 1.5 * sizeof(unsigned char); //#endif EnterCriticalSection( &pThis->m_frames.cir ); if ( NULL == pThis->m_frames.frames[pThis->m_frames.write].frame ) { cudaMalloc((void**)&pThis->m_frames.frames[pThis->m_frames.write].frame, rgbSize ); if ( NULL == pThis->m_frames.frames[pThis->m_frames.write].frame ) { LeaveCriticalSection( &pThis->m_frames.cir ); return; } } if ( pThis->m_frames.frames[pThis->m_frames.write].size ) { pThis->m_frames.counts--; pThis->m_frames.frames[pThis->m_frames.write].size = 0; if ( pThis->m_frames.write == pThis->m_frames.read ) { pThis->m_frames.read++; if ( pThis->m_frames.read == pThis->m_frames.size ) { pThis->m_frames.read = 0; } } } LeaveCriticalSection( &pThis->m_frames.cir ); //#ifndef DX_DXDECODER_OUTPUT_NV12 cudaMemcpy(pThis->m_frames.frames[pThis->m_frames.write].frame, buf, rgbSize, cudaMemcpyDeviceToDevice); //#else // cudaStatus = cuda_common::NV12ToRGB( // ( CUdeviceptr )buf, // size, // ( float * )pThis->m_frames.frames[pThis->m_frames.write].frame, // pThis->m_frames.width, // pThis->m_frames.height // ); // if (cudaStatus != cudaSuccess) // { // fprintf(stderr, "cuda_common::NV12ToRGB failed: %s\n", cudaGetErrorString(cudaStatus)); // // return; // } // size = rgbSize; //#endif EnterCriticalSection( &pThis->m_frames.cir ); pThis->m_frames.frames[pThis->m_frames.write].size = pThis->m_frames.width; pThis->m_frames.frames[pThis->m_frames.write].timestamp = timestamp; pThis->m_frames.write++; pThis->m_frames.counts++; if ( pThis->m_frames.write == pThis->m_frames.size ) { pThis->m_frames.write = 0; } pThis->m_nums++; LeaveCriticalSection( &pThis->m_frames.cir ); return; }