nsresult AppleVTDecoder::InitializeSession() { OSStatus rv; AutoCFRelease<CFDictionaryRef> extensions = CreateDecoderExtensions(); rv = CMVideoFormatDescriptionCreate(kCFAllocatorDefault, kCMVideoCodecType_H264, mPictureWidth, mPictureHeight, extensions, &mFormat); if (rv != noErr) { NS_ERROR("Couldn't create format description!"); return NS_ERROR_FAILURE; } // Contruct video decoder selection spec. AutoCFRelease<CFDictionaryRef> spec = CreateDecoderSpecification(); // Contruct output configuration. AutoCFRelease<CFDictionaryRef> outputConfiguration = CreateOutputConfiguration(); VTDecompressionOutputCallbackRecord cb = { PlatformCallback, this }; rv = VTDecompressionSessionCreate(kCFAllocatorDefault, mFormat, spec, // Video decoder selection. outputConfiguration, // Output video format. &cb, &mSession); if (rv != noErr) { NS_ERROR("Couldn't create decompression session!"); return NS_ERROR_FAILURE; } if (AppleVTLinker::skPropUsingHWAccel) { CFBooleanRef isUsingHW = nullptr; rv = VTSessionCopyProperty(mSession, AppleVTLinker::skPropUsingHWAccel, kCFAllocatorDefault, &isUsingHW); if (rv != noErr) { LOG("AppleVTDecoder: system doesn't support hardware acceleration"); } mIsHardwareAccelerated = rv == noErr && isUsingHW == kCFBooleanTrue; LOG("AppleVTDecoder: %s hardware accelerated decoding", mIsHardwareAccelerated ? "using" : "not using"); } else { LOG("AppleVTDecoder: couldn't determine hardware acceleration status."); } return NS_OK; }
nsresult AppleVTDecoder::InitializeSession() { OSStatus rv; #ifdef LOG_MEDIA_SHA1 SHA1Sum avc_hash; avc_hash.update(mExtraData->Elements(),mExtraData->Length()); uint8_t digest_buf[SHA1Sum::kHashSize]; avc_hash.finish(digest_buf); nsAutoCString avc_digest; for (size_t i = 0; i < sizeof(digest_buf); i++) { avc_digest.AppendPrintf("%02x", digest_buf[i]); } LOG("AVCDecoderConfig %ld bytes sha1 %s", mExtraData->Length(), avc_digest.get()); #endif // LOG_MEDIA_SHA1 AutoCFRelease<CFDictionaryRef> extensions = CreateDecoderExtensions(); rv = CMVideoFormatDescriptionCreate(kCFAllocatorDefault, kCMVideoCodecType_H264, mPictureWidth, mPictureHeight, extensions, &mFormat); if (rv != noErr) { NS_ERROR("Couldn't create format description!"); return NS_ERROR_FAILURE; } // Contruct video decoder selection spec. AutoCFRelease<CFDictionaryRef> spec = CreateDecoderSpecification(); // Contruct output configuration. AutoCFRelease<CFDictionaryRef> outputConfiguration = CreateOutputConfiguration(); VTDecompressionOutputCallbackRecord cb = { PlatformCallback, this }; rv = VTDecompressionSessionCreate(kCFAllocatorDefault, mFormat, spec, // Video decoder selection. outputConfiguration, // Output video format. &cb, &mSession); if (rv != noErr) { NS_ERROR("Couldn't create decompression session!"); return NS_ERROR_FAILURE; } if (AppleVTLinker::skPropUsingHWAccel) { CFBooleanRef isUsingHW = nullptr; rv = VTSessionCopyProperty(mSession, AppleVTLinker::skPropUsingHWAccel, kCFAllocatorDefault, &isUsingHW); if (rv != noErr) { LOG("AppleVTDecoder: system doesn't support hardware acceleration"); } mIsHardwareAccelerated = rv == noErr && isUsingHW == kCFBooleanTrue; LOG("AppleVTDecoder: %s hardware accelerated decoding", mIsHardwareAccelerated ? "using" : "not using"); } else { LOG("AppleVTDecoder: couldn't determine hardware acceleration status."); } return NS_OK; }
// 打开 bool CVideoEncodeVt::Open(const STRUCT_PUSH_STREAM_PARAM& aPushStreamParam) { if(m_bOpen) return true; int ret = 0; CFMutableDictionaryRef pixelBufferInfo = NULL; CMVideoCodecType codecType = kCMVideoCodecType_H264; CFStringRef profileLevel = NULL; do { m_bCompressErr = false; m_bHasBFrames = false; m_iEntropy = H264_ENTROPY_NOT_SET; m_iProfile = H264_PROF_HIGH; m_iLevel = 0; m_iFrameRate = aPushStreamParam.iVideoFrameRate; //参数检查 if(m_iProfile == H264_PROF_BASELINE) { m_bHasBFrames = false; if(H264_CABAC == m_iEntropy) { m_iEntropy = H264_ENTROPY_NOT_SET; } } m_iDtsDelta = m_bHasBFrames ? -1 : 0; //取得profile level ret = GetProfileLevel(m_bHasBFrames, m_iProfile, m_iLevel, &profileLevel); if(ret < 0) { CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "GetProfileLevel failed!"); assert(false); break; } //取得pixel buffer info ret = GetCVPixelBufferInfo(aPushStreamParam.iVideoPushStreamWidth, aPushStreamParam.iVideoPushStreamHeight, &pixelBufferInfo); if(ret < 0) { CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "CreateCVPixelBufferInfo failed!"); assert(false); break; } //清空编码缓存队列 ClearEncodeBuffQueue(); //获得附加数据 ret = GetExtraData(aPushStreamParam, codecType, profileLevel, pixelBufferInfo); if(ret < 0) { CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "EncExtraData failed!"); assert(false); break; } //创建编码器 ret = CreateEncoder(aPushStreamParam, codecType, profileLevel, pixelBufferInfo, &m_EncodeSession); if(ret < 0) { CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "CreateEncoder failed!"); assert(false); break; } //是否使用B帧 CFBooleanRef hasBFrames; ret = VTSessionCopyProperty(m_EncodeSession, kVTCompressionPropertyKey_AllowFrameReordering, kCFAllocatorDefault, &hasBFrames); if (0 == ret) { m_bHasBFrames = CFBooleanGetValue(hasBFrames); CFRelease(hasBFrames); } }while(0); if (NULL != pixelBufferInfo) { CFRelease(pixelBufferInfo); } m_bOpen = ret == 0 ? true : false; return m_bOpen; }