int CVideoEncodeVt::SetExtraData(CMSampleBufferRef sampleBuffer) { CMVideoFormatDescriptionRef videoFmtDesc; //取得sample buffer中的格式描述信息 videoFmtDesc = CMSampleBufferGetFormatDescription(sampleBuffer); if(NULL == videoFmtDesc) { CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "CMSampleBufferGetFormatDescription failed!"); assert(false); return -1; } //取得参数集 int iParamsSize = 0; int ret = GetParamSize(videoFmtDesc, &iParamsSize); if(ret < 0) { CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "GetParamSize failed!"); assert(false); return -1; } //分配缓冲用于保存参数集 m_pExtraData = (uint8_t*)av_mallocz(iParamsSize); if(NULL == m_pExtraData) { CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "m_pExtraData alloc failed!"); assert(false); return -1; } m_iExtraDataSize = iParamsSize; //拷贝参数集 ret = CopyParamSets(videoFmtDesc, m_pExtraData, m_iExtraDataSize); if(ret <= 0) { CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "CopyParamSets failed!"); assert(false); return -1; } return 0; }
HPARAM CParams::Add(DWORD function, LPCTSTR pParams) {_STT(); // Allocate memory LPPARAMINFO node = (LPPARAMINFO)New(); if ( node == NULL ) return NULL; // Copy the function id node->function = function; // Copy description if any if ( pParams != NULL ) { strcpy_sz( node->pdesc, pParams ); } else return node; char type[ 512 ]; char size[ 512 ]; char name[ 512 ]; char min[ 512 ]; char max[ 512 ]; char def[ 512 ]; char step[ 512 ]; DWORD i = 0; node->n = 0; // Calculate total size needed DWORD sz = 0; while( ( sz = GetParam( &node->pdesc[ i ], type, size, NULL, NULL, NULL, NULL, NULL ) ) != 0 ) { node->n++; node->size += GetParamSize( GetParamType( type ), strtoul( size, NULL, 10 ) ); i += sz; } // end while // Anything to allocate? if ( node->size == 0 || node->n == 0 ) { node->n = 0; node->size = 0; return node; } // end if // Allocate memory for param data node->pdata = new BYTE[ node->size + 1 ]; if ( node->pdata == NULL ) { DeleteObject( node ); return NULL; } // end if ZeroMemory( node->pdata, node->size + 1 ); // Allocate memory for param index node->param = new PARAM[ node->n ]; if ( node->param == NULL ) { DeleteObject( node ); return NULL; } // end if ZeroMemory( node->param, sizeof( PARAM ) * node->n ); // Save param info so it's easy to index i = 0; DWORD p = 0, o = 0; while( ( sz = GetParam( &node->pdesc[ i ], type, size, name, min, max, def, step ) ) != 0 ) { node->param[ p ].type = GetParamType( type ); node->param[ p ].data = &node->pdata[ o ]; node->param[ p ].size = GetParamSize( node->param[ p ].type, strtoul( size, NULL, 10 ) ); o += node->param[ p ].size; strcpy_sz( node->param[ p ].name, name ); if ( *min ) { node->param[ p ].flags |= PFLAG_MIN; node->param[ p ].min = strtod( min, NULL ); } else node->param[ p ].min = 0; strcpy_sz( node->param[ p ].pmin, min ); if ( *max ) { node->param[ p ].flags |= PFLAG_MAX; node->param[ p ].max = strtod( max, NULL ); } else node->param[ p ].max = 0; strcpy_sz( node->param[ p ].pmax, max ); if ( *def ) { node->param[ p ].flags |= PFLAG_DEF; node->param[ p ].def = strtod( def, NULL ); } else node->param[ p ].def = 0; strcpy_sz( node->param[ p ].pdef, def ); if ( *step ) { node->param[ p ].flags |= PFLAG_STEP; node->param[ p ].step = strtod( step, NULL ); } else node->param[ p ].step = 0; strcpy_sz( node->param[ p ].pstep, step ); // Set default value SetValue( node, p, GetDef( node, p ) ); p++; i += sz; } // end while // We're ready return node; }
int CVideoEncodeVt::CopySampleBufferToAVPakcet(CMSampleBufferRef sampleBuffer, AVPacket* apPacket) { //取得头大小 int iLengthCodeSize = 0; int ret = GetLengthCodeSize(sampleBuffer, &iLengthCodeSize); if(ret < 0) { CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "GetLengthCodeSize failed!"); assert(false); return -1; } int iHeaderSize = 0; bool bIsKeyFrame = IsKeyFrame(sampleBuffer); bool bAddHeader = bIsKeyFrame; CMVideoFormatDescriptionRef videoFmtDesc = NULL; //需要添加头 if (bAddHeader) { videoFmtDesc = CMSampleBufferGetFormatDescription(sampleBuffer); if (NULL == videoFmtDesc) { CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "CMSampleBufferGetFormatDescription failed!"); assert(false); return -1; } //取得头大小 ret = GetParamSize(videoFmtDesc, &iHeaderSize); if(ret < 0) { CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "GetParamSize failed!"); assert(false); return -1; } } //nalu的数量 int iNaluCnt = 0; ret = GetNaluCnt(sampleBuffer, iLengthCodeSize, &iNaluCnt); if(ret < 0) { CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "GetNaluCnt failed!"); assert(false); return -1; } int iSampleSize = (int)CMSampleBufferGetTotalSampleSize(sampleBuffer); int iPacketSize = iHeaderSize + iSampleSize + iNaluCnt * ((int)sizeof(StartCode) - (int)iLengthCodeSize); av_free_packet(apPacket); ret = av_new_packet(apPacket, iPacketSize); if(ret < 0) { CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "av_new_packet failed!"); assert(false); return -1; } do { //添加头 if(bAddHeader) { //参数集拷贝到头 ret = CopyParamSets(videoFmtDesc, apPacket->data, iPacketSize); if(ret < 0) { CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "CopyParamSets failed!"); assert(false); break; } } //拷贝每个nalu ret = CopyNalus(sampleBuffer, iLengthCodeSize, apPacket->data + iHeaderSize, apPacket->size - iHeaderSize); if(ret < 0) { CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "CopyNalus failed!"); assert(false); break; } if (bIsKeyFrame) { apPacket->flags |= AV_PKT_FLAG_KEY; } //设置时间戳 CMTime pts = CMSampleBufferGetPresentationTimeStamp(sampleBuffer); CMTime dts = CMSampleBufferGetDecodeTimeStamp(sampleBuffer); if (CMTIME_IS_INVALID(dts)) { if (!m_bHasBFrames) { dts = pts; } else { CLog::GetInstance().Log(ENUM_LOG_LEVEL::enum_Log_Level5, "dts is invalid!"); assert(false); break; } } int64_t iDtsDelta = m_iDtsDelta >= 0 ? m_iDtsDelta : 0; apPacket->pts = pts.value / m_iFrameRate; apPacket->dts = dts.value / m_iFrameRate - iDtsDelta; apPacket->size = iPacketSize; return 0; }while(0); av_free_packet(apPacket); return -1; }