2

我正在努力将我们的应用程序从一些专有编解码器转移到 iOS 本机 h264 编码器(VideoToolbox.framework)并且有疑问:

有没有办法为压缩数据设置比特率或数据率?

这是我创建编码器会话的方式:

CFMutableDictionaryRef sessionAttributes = CFDictionaryCreateMutable(
                                                                     NULL, 
                                                                     0,    
                                                                     &kCFTypeDictionaryKeyCallBacks,
                                                                     &kCFTypeDictionaryValueCallBacks);

//** bitrate
int fixedBitrate = bitrate; // 2000 * 1024 -> assume 2 Mbits/s

CFNumberRef bitrateNum = CFNumberCreate(NULL, kCFNumberSInt32Type, &fixedBitrate);
CFDictionarySetValue(sessionAttributes, kVTCompressionPropertyKey_AverageBitRate, bitrateNum);
CFRelease(bitrateNum);

CFDictionarySetValue(sessionAttributes, kVTCompressionPropertyKey_ProfileLevel, kVTProfileLevel_H264_High_AutoLevel);

CFDictionarySetValue(sessionAttributes, kVTCompressionPropertyKey_RealTime, kCFBooleanTrue);

OSStatus error = VTCompressionSessionCreate(kCFAllocatorDefault,
                                            width,
                                            height,
                                            kCMVideoCodecType_H264,
                                            sessionAttributes, 
                                            NULL, 
                                            kCFAllocatorDefault,  
                                            &EncoderCallback,
                                            this, *outputCallbackRefCon,
                                            &m_EncoderSession);

我玩过很多不同的价值观,kVTCompressionPropertyKey_AverageBitRate但这对我没有任何帮助,我也尝试 kVTCompressionPropertyKey_DataRateLimits过不同的价值观,但也没有任何运气。

欢迎任何想法,建议

4

1 回答 1

9

简短的故事是您需要VTSessionSetProperty在创建会话后使用。

您作为第五个参数传入的字典实际上用于指定要使用的编码器,而不是编码器设置。这有点令人困惑,但 Apple 文档指出:

要在创建压缩会话时指定特定的视频编码器,请传递包含此键和 EncoderID 作为其值的编码器规范 CFDictionary。EncoderID CFString 可以从 VTCopyVideoEncoderList 返回的数组中的 kVTVideoEncoderList_EncoderID 条目中获取。

使用该函数创建会话后,您需要设置kVTCompressionPropertyKey_AverageBitRate和属性。kVTCompressionPropertyKey_DataRateLimitsVTSessionSetProperty

例如:

 status = VTSessionSetProperty(session, kVTCompressionPropertyKey_AverageBitRate, (__bridge CFTypeRef)@(600 * 1024));
 status = VTSessionSetProperty(session, kVTCompressionPropertyKey_DataRateLimits, (__bridge CFArrayRef)@[800 * 1024 / 8, 1]);

请记住,这kVTCompressionPropertyKey_AverageBitRate需要位, kVTCompressionPropertyKey_DataRateLimits需要字节和秒。

于 2015-07-19T15:15:24.123 回答