說一說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得到裸碼流以后進(jìn)行轉(zhuǎn)換反砌,在這里卡了好久

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末羞福,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子爽丹,更是在濱河造成了極大的恐慌缺虐,老刑警劉巖蹂季,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件麻汰,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡叠赐,警方通過查閱死者的電腦和手機(jī)欲账,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來芭概,“玉大人赛不,你說我怎么就攤上這事“罩蓿” “怎么了踢故?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)惹苗。 經(jīng)常有香客問我畴椰,道長(zhǎng),這世上最難降的妖魔是什么鸽粉? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮抓艳,結(jié)果婚禮上触机,老公的妹妹穿的比我還像新娘。我一直安慰自己玷或,他們只是感情好儡首,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著偏友,像睡著了一般蔬胯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上位他,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天氛濒,我揣著相機(jī)與錄音产场,去河邊找鬼。 笑死舞竿,一個(gè)胖子當(dāng)著我的面吹牛京景,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播骗奖,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼确徙,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了执桌?” 一聲冷哼從身側(cè)響起鄙皇,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎仰挣,沒想到半個(gè)月后伴逸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡椎木,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年违柏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片香椎。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡漱竖,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出畜伐,到底是詐尸還是另有隱情馍惹,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布玛界,位于F島的核電站万矾,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏慎框。R本人自食惡果不足惜良狈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望笨枯。 院中可真熱鬧薪丁,春花似錦、人聲如沸馅精。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽洲敢。三九已至漫玄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間压彭,已是汗流浹背睦优。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工渗常, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人刨秆。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓凳谦,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親衡未。 傳聞我的和親對(duì)象是個(gè)殘疾皇子尸执,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 對(duì)于視頻文件和rtsp之類的主流視頻傳輸協(xié)議,ffmpeg提供avformat_open_input接口缓醋,直接將文...
    我在鄱陽湖邊閱讀 3,465評(píng)論 6 10
  • /**ios常見的幾種加密方法: 普通的加密方法是講密碼進(jìn)行加密后保存到用戶偏好設(shè)置( [NSUserDefaul...
    彬至睢陽閱讀 2,912評(píng)論 0 7
  • 轉(zhuǎn)自:http://www.code4app.com/blog-866962-1317.html1如失、設(shè)置UILab...
    MMOTE閱讀 1,586評(píng)論 1 1
  • 20170830 心賞第16天 親愛的康夫君,我說我沒油了你二話不說立馬去加送粱,我一個(gè)十幾年駕齡的老司機(jī)好像除了會(huì)開...
    靜夜思CJ閱讀 241評(píng)論 0 1
  • 一褪贵、上午我去池陽小學(xué)聽了一節(jié)課和一場(chǎng)講座,觸動(dòng)了我了抗俄。那節(jié)課讓我真正的感受到一題多變脆丁,體現(xiàn)楊老師教學(xué)技藝精湛!那講...