OSX,VideoToolbox,压缩会话
OSX, VideoToolbox, Compression Session
环境
- OSX约塞米蒂
- xcode 6.4
- C++
用例
给定由单个关键帧和多个相应的增量帧组成的h264 GOP,对GOP进行解码,然后对单个4.2Mbit关键帧进行编码
问题描述
我能够解码GOP并对关键帧进行编码,然而,生成的关键帧质量较低(低比特率(,也就是说,尽管我特别将比特率设置为4.2Mbit(这可以在下面的代码快照中看到(,但考虑到我只需要一个单个关键帧,有什么方法可以设置VideoToolBox编码器来输出高比特率的关键帧吗?
const CMVideoCodecType fourcc = (CMVideoCodecType)CMVideoFormatDescriptionGetCodecType(fmt);
// Else, generate a h264 KeyFrame
CFObjectSmartPtr< CFMutableDictionaryRef > dictEncSpec;
dictEncSpec.Attach(CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
//dictEncSpec.Attach(CFDictionaryCreateMutable(NULL, 0, 0, 0));
// CFDictionarySetNumVal(dictEncSpec, kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder, TRUE);
CFDictionarySetValue(dictEncSpec, kVTCompressionPropertyKey_ProfileLevel, kVTProfileLevel_H264_High_3_2);
// CFDictionarySetValue(dictEncSpec, kVTCompressionPropertyKey_RealTime, kCFBooleanTrue);
// CFDictionarySetValue(dictEncSpec, kVTCompressionPropertyKey_H264EntropyMode, kVTH264EntropyMode_CABAC);
CFDictionarySetNumVal(dictEncSpec, kVTCompressionPropertyKey_AverageBitRate, 4200000);
CFDictionarySetNumVal(dictEncSpec, kVTCompressionPropertyKey_Quality, 1.0f);
CFDictionarySetNumVal(dictEncSpec, kVTCompressionPropertyKey_MaxFrameDelayCount, 0);
CFDictionarySetNumVal(dictEncSpec, kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration, 1);
CFDictionarySetNumVal(dictEncSpec, kVTCompressionPropertyKey_ExpectedDuration, 1);
CFDictionarySetNumVal(dictEncSpec, kVTCompressionPropertyKey_ExpectedFrameRate, 10);
// CFDictionarySetNumVal(dictEncSpec, kVTCompressionPropertyKey_SourceFrameCount, 1);
CFDictionarySetNumVal(dictEncSpec, kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder, TRUE);
CFObjectSmartPtr< VTCompressionSessionRef > sessionCompression;
status = VTCompressionSessionCreate(0, res.width, res.height, fourcc, (CFDictionaryRef)dictEncSpec, 0, 0, CompressionCallback, &ctx, &sessionCompression);
if (noErr != status)
return HRESULT_FROM_ERRNO(status);
if (noErr != (status = VTCompressionSessionEncodeFrame(sessionCompression, ctx.yuvFrame, timestamp, timestamp, 0, 0, 0)))
return HRESULT_FROM_ERRNO(status);
if(noErr != (status = VTCompressionSessionCompleteFrames(sessionCompression, timestamp)))
return HRESULT_FROM_ERRNO(status);
if (0 == ctx.keyFrame) {
assert(false);
return E_UNEXPECTED;
}
ctx.keyFrame最终是一个非常低质量的
您需要注意的另一个因素是,在创建VTCompressionSession后,您需要在VTCompressionsSessionEncodeFrame中正确设置帧时间戳。
相关文章:
- C++中高效的大型稀疏块压缩线性方程
- 嵌入方指针压缩已禁用
- C++使用整数的压缩数组初始化对象
- 为多个会话保留XPtr
- 在C++中将函数压缩为两种方式
- 是否可以用"iostream"包装现有的TCP/OOpenSSL会话
- 在C++中使用LZ4压缩目录
- 使用C++进行运行长度解压缩
- 为什么大多数 pair 实现默认不使用压缩(空基优化)?
- 如何修复 Onnx运行时会话>运行问题?
- 捕获标准输出以压缩并使用 CTRL-C 中断会给出损坏的 zip 文件
- C++ 如何将数组值解压缩为函数参数
- struct.error:解压缩 C++ 结构时,解包需要 288 字节的缓冲区
- 在 Qt(C++) 中使用 QProcess 解压缩 - 提取目录问题
- 为什么 KMS drmModeSetCrtc() 在 X11 会话中运行时会失败并被拒绝权限?
- 浏览压缩文件与游览解压缩它们
- 直接 2D 呈现到命令列表和打印:图片压缩
- 如何在 OpenCV c++ 中压缩 TIFF 格式的图像?
- 如何在带有 gdb GUI 前端的 ARM gdbserver 的 PC 上执行远程 gdb 会话?
- OSX,VideoToolbox,压缩会话