yuv的數(shù)據(jù)是視頻一幀一幀的原始數(shù)據(jù)凡伊,里面并沒有包含像素格式、大小窒舟,因此我們要播放yuv數(shù)據(jù)系忙,就必須要指定像素格式、大小惠豺,否則你就不知道一幀的數(shù)據(jù)大小是多少银还,也就無法把yuv數(shù)據(jù)解析成一幀一幀的圖像了。本文我使用的yuv數(shù)據(jù)像素格式是yuv420p
洁墙,大小是540x960
蛹疯。yuv420p
格式是怎么存儲的呢,它是一幀一幀依序存儲的扫俺,一幀里面又是y
苍苞、u
、v
分量依序存儲,y
分量的size是540*960
羹呵,u
骂际、v
分量的size都是540*960/4
,所以一幀的數(shù)據(jù)大小就是540*960*3/2
冈欢。知道了這些信息歉铝,我們就可以取出一幀一幀的數(shù)據(jù),再通過OpenGL就可以渲染出來了凑耻,一個簡單的yuv播放器就實現(xiàn)了太示,非常簡單。
NSInteger videoW = 540;
NSInteger videoH = 960;
NSUInteger frameSizeY = videoW*videoH;
NSUInteger frameSizeU = videoW*videoH/4;
NSUInteger frameSizeV = videoW*videoH/4;
NSString *yuvPath = [[NSBundle mainBundle] pathForResource:@"bb1_test.yuv" ofType:nil];
NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:yuvPath];
NSUInteger i = 0;
NSTimeInterval sT = NSDate.date.timeIntervalSince1970;
while (1) {
NSData *dataY = [fileHandle readDataOfLength:frameSizeY];
NSData *dataU = [fileHandle readDataOfLength:frameSizeU];
NSData *dataV = [fileHandle readDataOfLength:frameSizeV];
if (dataY.length==0 || dataV.length==0 || dataU.length==0) {
break;
}
STMVideoFrameYUV *frame = STMVideoFrameYUV.new;
frame.format = STMVideoFrameFormatYUV;
frame.width = 540;
frame.height = 960;
frame.luma = dataY.bytes;
frame.chromaB = dataU.bytes;
frame.chromaR = dataV.bytes;
[self.GLView render:frame];
NSTimeInterval cT = NSDate.date.timeIntervalSince1970;
NSTimeInterval dT = cT-sT;
NSTimeInterval tT = i/25.0;
if (dT<tT) {
[NSThread sleepForTimeInterval:tT-dT];
}
i++;
}