예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
// 打开
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;
}