получение sps и pps из CMSampleBufferRef

#video-streaming #video-processing #video-encoding #ios8

#потоковое видео #обработка видео #кодирование видео #ios8

Вопрос:

я отправляю изображение с камеры в кодировщик VideoToolbox с помощью нового API и получаю закодированный CMSampleBufferRef из обратного вызова кодировщика

мне нужны эти sps и pts для CMVideoFormatDescriptionCreateFromH264ParameterSets для настройки декодера

может ли кто-нибудь помочь / направить меня?) СПАСИБО

Ответ №1:

Довольно легко сделать это наоборот, соответствующая функция CMVideoFormatDescriptionGetH264ParameterSetAtIndex и будет использоваться что-то вроде

 CMFormatDescriptionRef format = CMSampleBufferGetFormatDescription(sampleBuffer);
size_t spsSize, ppsSize;
size_t parmCount;
const uint8_t* sps, *pps;

CMVideoFormatDescriptionGetH264ParameterSetAtIndex(format, 0, amp;sps, amp;spsSize, amp;parmCount, nullptr );
CMVideoFormatDescriptionGetH264ParameterSetAtIndex(format, 1, amp;pps, amp;ppsSize, amp;parmCount, nullptr );
 

Ответ №2:

Извлеките элемент ‘avcC’ из словаря ‘SampleDescriptionExtensionAtoms’, затем используйте ‘CFDataGetLength’ и ‘CFDataGetBytePtr’, чтобы получить прямой указатель на структуру avcC, затем эта структура может быть проанализирована следующим образом:

 #pragma pack(push, 1)
struct AVCC {
    uint8_t  version;
    uint8_t  profile_idc;
    uint8_t  compatibility;
    uint8_t  level_idc;
    uint8_t  nalu_size  : 2;// indicates the length in bytes of the NALUnitLength field in an AVC video sample or AVC parameter set sample of the associated stream **minus one**
    uint8_t  reserved1  : 6;
    uint8_t  numSPS     : 5;// length size minus one
    uint8_t  reserved2  : 3;
    uint16_t SPSlen; 
    uint8_t  pSPS[15];      // Sequence parameter set
    uint8_t  numPPS;
    uint16_t PPSlen;
    uint32_t pPPS[1];       // Picture parameter set
};
#pragma pack(pop)

int _tmain(int argc, _TCHAR* argv[])
{
    AVCC* pAVCC = (AVCC*)g_pAVCC;

    pAVCC->SPSlen = ((pAVCC->SPSlen amp; 0x00FF) << 8) | ((pAVCC->SPSlen amp; 0xFF00) >> 8);
    pAVCC->PPSlen = ((pAVCC->PPSlen amp; 0x00FF) << 8) | ((pAVCC->PPSlen amp; 0xFF00) >> 8);


    uint8_t* pSPS = (uint8_t*)pAVCC->pSPS;
    uint8_t* pPPS = (uint8_t*)pAVCC->pPPS;

    ...

    return 0;
}