2

環境

  • OSX ヨセミテ
  • xcode 6.4
  • C++

使用事例

単一のキー フレームと複数の対応するデルタ フレームで構成される h264 GOP が与えられた場合、GOP をデコードしてから、単一の4.2M ビットキー フレームをエンコードします。

問題の説明

GOP をデコードしてキー フレームをエンコードすることはできますが、結果のキー フレームは低品質 (低ビット レート) です。次のコード スナップに見られます)、Key-Frame が 1 つしか必要ないことを念頭に置いて、VideoToolBox Encoder を設定して高ビットレートの Key-frame を出力する方法はありますか?

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品質が非常に低くなります

4

1 に答える 1