Example #1
0
// 关闭
void CVideoEncodeVt::Close()
{
    if(NULL != m_EncodeSession)
    {
        VTCompressionSessionCompleteFrames(m_EncodeSession, kCMTimeIndefinite);
        
        CFRelease(m_EncodeSession);
        m_EncodeSession = NULL;
    }
 
    ClearEncodeBuffQueue();
 
    if(NULL != m_pExtraData)
    {
        av_free(m_pExtraData);
        m_pExtraData = NULL;
        m_iExtraDataSize = 0;
    }
    
    m_bOpen = false;
}
Example #2
0
    void
    H264Encode::setBitrate(int bitrate)
    {
#if VERSION_OK
        if(bitrate == m_bitrate) {
            return;
        }
        m_bitrate = bitrate;
        if(m_compressionSession) {
            m_encodeMutex.lock();
            int v = m_bitrate * 0.9; // headroom
            CFNumberRef ref = CFNumberCreate(NULL, kCFNumberSInt32Type, &v);
            
            VTCompressionSessionCompleteFrames((VTCompressionSessionRef)m_compressionSession, kCMTimeInvalid);
            
            VTSessionSetProperty((VTCompressionSessionRef)m_compressionSession, kVTCompressionPropertyKey_AverageBitRate, ref);
            CFRelease(ref);
            
            
            v = bitrate / 8;
            CFNumberRef bytes = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &v);
            v = 1;
            CFNumberRef duration = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &v);
            
            CFMutableArrayRef limit = CFArrayCreateMutable(kCFAllocatorDefault, 2, &kCFTypeArrayCallBacks);
            CFArrayAppendValue(limit, bytes);
            CFArrayAppendValue(limit, duration);
            
            VTSessionSetProperty((VTCompressionSessionRef)m_compressionSession, kVTCompressionPropertyKey_DataRateLimits, limit);
            
            CFRelease(bytes);
            CFRelease(duration);
            CFRelease(limit);
            
            //m_forceKeyframe = true;
            m_encodeMutex.unlock();
            
        }
#endif
    }
Example #3
0
int CVideoEncodeVt::GetExtraData(const STRUCT_PUSH_STREAM_PARAM& aPushStreamParam, CMVideoCodecType aeCodecType,
                                 CFStringRef aProfileLevel, CFDictionaryRef aPixelBufferInfo)
{
    int ret = 0;
    AVFrame* pFrame = NULL;
    VTCompressionSessionRef session = NULL;
    CMSampleBufferRef sampleBuf = NULL;
    
    do
    {
        //创建编码器
        ret = CreateEncoder(aPushStreamParam, aeCodecType, aProfileLevel, aPixelBufferInfo, &session);
        if(ret < 0)
        {
            CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "CreateEncoder failed!");
            assert(false);
            break;
        }
        
        //创建一个avframe,并分配缓存,设置参数
        pFrame = av_frame_alloc();
        if(NULL == pFrame)
        {
            CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "av_frame_alloc failed!");
            assert(false);
            break;
        }
        
        int iWidth = aPushStreamParam.iVideoPushStreamWidth;
        int iHeight = aPushStreamParam.iVideoPushStreamHeight;
        int iYSize = iWidth * iHeight;
        int iUVSize = (iWidth / 2) * (iHeight / 2);
        
        pFrame->buf[0] = av_buffer_alloc(iYSize + iUVSize * 2);
        if(NULL == pFrame->buf[0])
        {
            CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "av_buffer_alloc failed!");
            assert(false);
            break;
        }
        pFrame->data[0] = pFrame->buf[0]->data;
        pFrame->data[1] = pFrame->buf[0]->data + iYSize;
        pFrame->data[2] = pFrame->buf[0]->data + iYSize + iUVSize;
        memset(pFrame->data[0], 0, iYSize);
        memset(pFrame->data[1], 128, iUVSize);
        memset(pFrame->data[2], 128, iUVSize);
        pFrame->linesize[0] = iWidth;
        pFrame->linesize[1] = (iWidth + 1) / 2;
        pFrame->linesize[2] = (iWidth + 1) / 2;
        pFrame->format = AV_PIX_FMT_YUV420P;
        pFrame->width = iWidth;
        pFrame->height = iHeight;
        pFrame->pts = 0;

        //编码
        ret = EncodeFrame(pFrame, session);
        if(ret < 0)
        {
            CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "EncodeFrame failed!");
            assert(false);
            break;
        }
        
        //等待编码结束
        ret = VTCompressionSessionCompleteFrames(session, kCMTimeIndefinite);
        if(0 != ret)
        {
            CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "VTCompressionSessionCompleteFrames failed!");
            break;
        }
        
        //取得编码后的数据
        ret = PopBuff(&sampleBuf);
        if(ret < 0)
        {
            CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "PopBuff failed!");
            assert(false);
            break;
        }
        
    }while(0);
    
    if(NULL != sampleBuf)
    {
        CFRelease(sampleBuf);
        sampleBuf = NULL;
    }

    if(NULL != pFrame)
    {
        av_frame_unref(pFrame);
        av_frame_free(&pFrame);
    }
    
    
    if(NULL != session)
    {
        CFRelease(session);
        session = NULL;
    }
    
    assert(0 == ret && m_pExtraData && m_iExtraDataSize > 0);
    
    return ret;
}