说一说IOS使用GCDSocketMenger+硬解码遇到的坑

- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{

//_readagainTime = [self getTimeNow];

//[h264Decoder decodeNalu:(uint8_t *)[data bytes] withSize:(uint32_t)data.length];

int nRef = 0;

uint8_t *puf = nil;

if(tag == Data){

int type = [self typeOfNalu:data];

if (type == 7 || type == 8 || type == 6 || type == 5) { //SPS PPS SEI IDR

if (type == 7 || type == 8) {

if (h264Decoder) {

nRef = (int)data.length;

puf = (uint8_t *)malloc(data.length);

memcpy(puf,[data bytes],data.length);

const char bytes[] = "\x00\x00\x00\x01";

size_t length = (sizeof bytes) - 1;

NSData *ByteHeader = [NSData dataWithBytes:bytes length:length];

NSMutableData *h264Data = [[NSMutableData alloc] init];

[h264Data appendData:ByteHeader];

[h264Data appendData:[NSData dataWithBytes:puf length:nRef]];

h264Decoder.nalu_type = type;

[h264Decoder decodeNalu:(uint8_t *)[h264Data bytes] withSize:(uint32_t)h264Data.length];

free(puf);

puf = nil;

}

}else{

[keyFrame appendData:lastStartCode];

[keyFrame appendBytes:[data bytes] length:[data length] - [self startCodeLenth:data]];

}

}

if (type == 5 || type == 1  || type == 6) {//IDR P frame

if (type == 5 || type == 6) {

h264Decoder.nalu_type = type;

[h264Decoder decodeNalu:(uint8_t *)[keyFrame bytes] withSize:(uint32_t)keyFrame.length];

keyFrame = [[NSMutableData alloc] init];//reset keyframe

}else{

NSMutableData *nalu = [[NSMutableData alloc]initWithData:lastStartCode];

[nalu appendBytes:[data bytes] length:[data length]-[self startCodeLenth:data]];

char *chBuf = (char*)[nalu bytes];

// NSLog(@"chbuf ======== %x %x %x %x %x %x %x",chBuf[0],chBuf[1],chBuf[2],chBuf[3],chBuf[4],chBuf[5],chBuf[6]);

if (chBuf[0] == 0x00 && chBuf[1]==0x00 && chBuf[2]==0x01) {

nRef = (int)nalu.length-3;

puf = (uint8_t *)malloc(nalu.length-3);

memcpy(puf,[nalu bytes]+3,nalu.length-3);

const char bytes[] = "\x00\x00\x00\x01";

size_t length = (sizeof bytes) - 1;

NSData *ByteHeader = [NSData dataWithBytes:bytes length:length];

NSMutableData *h264Data = [[NSMutableData alloc] init];

[h264Data appendData:ByteHeader];

[h264Data appendData:[NSData dataWithBytes:puf length:nRef]];

h264Decoder.nalu_type = type;

[h264Decoder decodeNalu:(uint8_t *)[h264Data bytes] withSize:(uint32_t)h264Data.length];

}else if (chBuf[0] == 0x00 && chBuf[1]==0x00 && chBuf[2]==0x00 && chBuf[3]==0x01) {

nRef = (int)nalu.length-4;

puf = (uint8_t *)malloc(nalu.length-4);

memcpy(puf,[nalu bytes]+4,nalu.length-4);

const char bytes[] = "\x00\x00\x00\x01";

size_t length = (sizeof bytes) - 1;

NSData *ByteHeader = [NSData dataWithBytes:bytes length:length];

NSMutableData *h264Data = [[NSMutableData alloc] init];

[h264Data appendData:ByteHeader];

[h264Data appendData:[NSData dataWithBytes:puf length:nRef]];

h264Decoder.nalu_type = type;

[h264Decoder decodeNalu:(uint8_t *)[h264Data bytes] withSize:(uint32_t)h264Data.length];

} else{

const char bytes[] = "\x00\x00\x00\x01";

size_t length = (sizeof bytes) - 1;

NSData *ByteHeader = [NSData dataWithBytes:bytes length:length];

NSMutableData *h264Data = [[NSMutableData alloc] init];

[h264Data appendData:ByteHeader];

[h264Data appendData:nalu];

h264Decoder.nalu_type = type;

[h264Decoder decodeNalu:(uint8_t *)[h264Data bytes] withSize:(uint32_t)h264Data.length];

}

//NSLog(@"chBuf %x %x %x %x %x %x %x %x %x %x",chBuf[0],chBuf[1],chBuf[2],chBuf[3],chBuf[4],chBuf[5],chBuf[6],chBuf[7],chBuf[8],chBuf[9]);

}

}else{

//            isGetData = NO;

[socket readDataToData:startcodeData withTimeout:-1 tag:Data];

}

}

if (data.length > [self startCodeLenth:data]) {

[self saveStartCode:data];

}

}

- (int)typeOfNalu:(NSData *)data{

char first = *(char *)[data bytes];

return first & 0x1f;

}

- (int)startCodeLenth:(NSData *)data

{

char temp = *((char *)[data bytes] + [data length] - 4);

return temp == 0x00 ? 4 : 3;

}

- (void)saveStartCode:(NSData *)data

{

int startCodeLen = [self startCodeLenth:data];

NSRange startCodeRange = {[data length] - startCodeLen, startCodeLen};

lastStartCode = [data subdataWithRange:startCodeRange];

}

最主要的是通过socket得到裸码流以后进行转换,在这里卡了好久

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 对于视频文件和rtsp之类的主流视频传输协议,ffmpeg提供avformat_open_input接口,直接将文...
    我在鄱阳湖边阅读 3,548评论 6 10
  • /**ios常见的几种加密方法: 普通的加密方法是讲密码进行加密后保存到用户偏好设置( [NSUserDefaul...
    彬至睢阳阅读 3,071评论 0 7
  • 转自:http://www.code4app.com/blog-866962-1317.html1、设置UILab...
    MMOTE阅读 1,740评论 1 1
  • 20170830 心赏第16天 亲爱的康夫君,我说我没油了你二话不说立马去加,我一个十几年驾龄的老司机好像除了会开...
    静夜思CJ阅读 249评论 0 1
  • 一、上午我去池阳小学听了一节课和一场讲座,触动了我了。那节课让我真正的感受到一题多变,体现杨老师教学技艺精湛!那讲...