【发布时间】:2014-09-28 01:48:47
【问题描述】:
在详细回顾了 WWDC2014,Session513 之后,我尝试在 IOS8.0 上编写我的应用程序来解码和显示一个实时 H.264 流。首先,我成功构建了一个H264参数集。当我得到一个带有 4 位起始码的 I 帧时,就像“0x00 0x00 0x00 0x01 0x65 ...”一样,我将它放入 CMblockBuffer 中。然后我使用预览 CMBlockBuffer 构造一个 CMSampleBuffer。之后,我将 CMSampleBuffer 放入了 AVSampleBufferDisplayLayer。一切正常(我检查了返回的值),除了 AVSampleBufferDisplayLayer 不显示任何视频图像。由于这些 API 对每个人来说都是相当新的,所以我找不到任何可以解决这个问题的机构。
我将提供以下关键代码,如果您能帮助找出视频图像无法显示的原因,我将不胜感激。非常感谢。
(1) AVSampleBufferDisplayLayer 已初始化。 dsplayer 是我的主视图控制器的 objc 实例。
@property(nonatomic,strong)AVSampleBufferDisplayLayer *dspLayer;
if(!_dspLayer)
{
_dspLayer = [[AVSampleBufferDisplayLayer alloc]init];
[_dspLayer setFrame:CGRectMake(90,551,557,389)];
_dspLayer.videoGravity = AVLayerVideoGravityResizeAspect;
_dspLayer.backgroundColor = [UIColor grayColor].CGColor;
CMTimebaseRef tmBase = nil;
CMTimebaseCreateWithMasterClock(NULL,CMClockGetHostTimeClock(),&tmBase);
_dspLayer.controlTimebase = tmBase;
CMTimebaseSetTime(_dspLayer.controlTimebase, kCMTimeZero);
CMTimebaseSetRate(_dspLayer.controlTimebase, 1.0);
[self.view.layer addSublayer:_dspLayer];
}
(2)在另一个线程中,我得到一个 H.264 I 帧。 //构造h.264参数集ok
CMVideoFormatDescriptionRef formatDesc;
OSStatus formatCreateResult =
CMVideoFormatDescriptionCreateFromH264ParameterSets(NULL, ppsNum+1, props, sizes, 4, &formatDesc);
NSLog([NSString stringWithFormat:@"construct h264 param set:%ld",formatCreateResult]);
//构造cmBlockbuffer . //databuf 指向 H.264 数据。以“0x00 0x00 0x00 0x01 0x65 ........”开头
CMBlockBufferRef blockBufferOut = nil;
CMBlockBufferCreateEmpty (0,0,kCMBlockBufferAlwaysCopyDataFlag, &blockBufferOut);
CMBlockBufferAppendMemoryBlock(blockBufferOut,
dataBuf,
dataLen,
NULL,
NULL,
0,
dataLen,
kCMBlockBufferAlwaysCopyDataFlag);
//构造cmsamplebuffer ok
size_t sampleSizeArray[1] = {0};
sampleSizeArray[0] = CMBlockBufferGetDataLength(blockBufferOut);
CMSampleTiminginfo tmInfos[1] = {
{CMTimeMake(5,1), CMTimeMake(5,1), CMTimeMake(5,1)}
};
CMSampleBufferRef sampBuf = nil;
formatCreateResult = CMSampleBufferCreate(kCFAllocatorDefault,
blockBufferOut,
YES,
NULL,
NULL,
formatDesc,
1,
1,
tmInfos,
1,
sampleSizeArray,
&sampBuf);
//放到AVSampleBufferdisplayLayer,就一帧。但是我的视图中看不到任何视频帧
if([self.dspLayer isReadyForMoreMediaData])
{
[self.dspLayer enqueueSampleBuffer:sampBuf];
}
[self.dspLayer setNeedsDisplay];
【问题讨论】:
-
Scythe42 answer 可能会解决您遇到的问题。我在让它工作时也遇到了一些问题。但最后我做到了。你应该take a look。
-
这里也一样。有一个 vail & ready CMSampleBuffer 但它不会显示在屏幕上... :(