2013-03-28 38 views
4

我有一個由類型1(P幀),5(I幀),7(SPS)和8(PPS)組成的H.264/AVC NAL流。我想將它們寫入.mov文件而不用重新編碼。我試圖用AVAssetWriter來做到這一點。 AVAssetWriterInput的文檔狀態如下:AVAssetWriterInput H.264直通到QuickTime(.mov) - 傳入SPS/PPS創建avcC原子?

傳遞nil給outputSettings指示輸入通過附加採樣,在寫入輸出文件之前不進行處理。例如,如果你正在追加已經處於理想壓縮格式的緩衝區,這很有用。但是,僅在寫入QuickTime影片文件時才支持直通(即,AVAssetWriter已使用AVFileTypeQuickTimeMovie進行初始化)。對於其他文件類型,您必須指定非零輸出設置。

我試圖創建CMSampleBuffers這些的NAL並將其追加到資產作家輸入,但我無法輸入的數據在產生一個結構良好的.mov文件的方式,我可以在如何做到這一點的任何地方找不到任何線索。

到目前爲止我所得到的最好結果是以附件B字節流格式(以7 8 5 1 1 1的順序重複)傳遞NAL並在VLC中播放結果。因此,我知道NAL包含有效數據,但由於.mov文件沒有avcC原子,並且mdat原子填充了附件B字節流,因此QuickTime不會播放視頻。

現在我試圖通過一個4字節(由lengthSizeMinusOne字段指定)長度字段而不是附件B分隔符,這是他們應該如何打包到mdat原子我所知道的。

我不知道如何讓資產編寫者編寫avcC原子。我追加的每個樣本都會被推入mdat原子中。

有誰知道我可以如何將原始的H.264數據傳遞到配置爲pass through(nil outputSettings)配置的AVAssetWriterInput並讓它生成一個正確形成的QuickTime文件?

+0

考慮人的狹隘集團可能已經成功地做到了這一點,你有沒有想到提交TSI和得到一個蘋果在這個問題上的正確答案?無論如何,有趣的事情,你在這裏和你的最後一個問題...... +1 – Till 2013-03-28 02:57:35

+1

謝謝你的建議。我想我可以繼續做下去。我會在這裏更新任何其他發現。 – bsirang 2013-03-28 03:16:37

回答

6

我已經提交了蘋果的TSI並找到了答案。我希望這能在未來節省一些時間。

CMSampleBuffers與它們關聯了一個CMFormatDescription,它包含樣本緩衝區中數據的描述。

的函數原型創建格式描述如下:

OSStatus CMVideoFormatDescriptionCreate (
    CFAllocatorRef allocator, 
    CMVideoCodecType codecType, 
    int32_t width, 
    int32_t height, 
    CFDictionaryRef extensions, 
    CMVideoFormatDescriptionRef *outDesc 
); 

我瞭解到,從Apple技術員,我可以使用擴展參數在含有AVCC原子數據字典來傳遞。

延伸部字典應爲以下形式:

[kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms ---> ["avcC" ---> <avcC Data>]] 

的[]的表示字典。這個字典可能被用來傳遞除avcC以外的任意原子的數據。

這裏是我用來創建extensions字典,我進入CMVideoFormatDescriptionCreate代碼:

const char *avcC = "avcC"; 
    const CFStringRef avcCKey = CFStringCreateWithCString(kCFAllocatorDefault, avcC, kCFStringEncodingUTF8); 
    const CFDataRef avcCValue = CFDataCreate(kCFAllocatorDefault, [_avccData bytes], [_avccData length]); 
    const void *atomDictKeys[] = { avcCKey }; 
    const void *atomDictValues[] = { avcCValue }; 
    CFDictionaryRef atomsDict = CFDictionaryCreate(kCFAllocatorDefault, atomDictKeys, atomDictValues, 1, nil, nil); 

    const void *extensionDictKeys[] = { kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms }; 
    const void *extensionDictValues[] = { atomsDict }; 
    CFDictionaryRef extensionDict = CFDictionaryCreate(kCFAllocatorDefault, extensionDictKeys, extensionDictValues, 1, nil, nil); 
+0

對我來說看起來很有趣 - 變量_avccData是否意味着你在那裏保存了一個完整的NAL樣本緩衝區?那意味着你有格式描述和CMSampleBuffer中的樣本數據? – konran 2013-06-05 14:17:52

+0

_avccData變量是一個NSData對象,它包含一個字節流,表示可在mp4或mov文件中找到的avcC原子。數據的語法可以在ISO/IEC 14496-15:2004(E)第5.2.4.1節中看到。數據包含序列參數集和圖片參數集(sps/pps),它們本身分別是NAL類型7和8。要明確SPS/PPS是NAL,但它們不包含幀樣本。 – bsirang 2013-06-05 21:59:08

+0

好的,謝謝...很高興知道:-) – konran 2013-06-06 13:28:18