video - RTP depacketization -


i'm trying parse rtp avc video stream prepare h264 decoder.

this packet stream captured wireshark first i'm trying find idr slice, sps , pps parameters, https://dl.dropboxusercontent.com/u/76817805/frame.pcapng

next i'm doing following:

1) find pps nad sps data , copying them nal units depacketization buffer [0x00 0x00 0x01] start sequense.

[00 00 01 | sps][00 00 01 | pps]

2) packets started [0x7c 0x85] (start bit = 1)i'm reconstructing first nal heder (0x65 case) , copying data folowed 0x7c 0x85 depacketization buffer start sequense.

[00 00 01 65 | video data ......]

3) packets started [0x7c 0x05] i'm copying data except 2 first bytes depacketization buffer.

[..... video data .....]

4) packets started [0x7c 0x45] (stop bit = 1) i'm copying data except 2 first bytes depacketization buffer. [..... video data (last byte)]

5) not fragmented packets i'm copying data depacketization buffer wiyh start sequense.

[00 00 01 | nalu]

so in end of parsing example video stream i've got binary file https://dl.dropboxusercontent.com/u/76817805/raw.264, can't decoded correctly. ![enter image description here][1]

can me please , find mistake in algorithm? doing wrong? lot everybody.

uint32 parsertp( uint8 * buf, int inputdatalen, uint32 curadr) { int result_len = 0;  // filter 0 bytes @ end of packet  (i = inputdatalen-1; i>0; i--) {     if (buf[i] == 0x00) inputdatalen--;     else break; }  // nal type nal = buf[0]; type = (nal & 0x1f);  if ((buf[0] == 0x7c) && (buf[1] == 0x85)) iframeisok = 1; // start of frame  if (type == 6)     return 0;  if (type == 7) // new sps {     memcpy((void*)sps, start_sequence, sizeof(start_sequence));     memcpy((void*)(sps + sizeof(start_sequence)), buf, inputdatalen);     sps_len = inputdatalen + sizeof(start_sequence);     spsisok = 1;     return 0; }  if (type == 8) // new pps {     memcpy((void*)pps, start_sequence, sizeof(start_sequence));     memcpy((void*)(pps + sizeof(start_sequence)), buf, inputdatalen);     pps_len = inputdatalen + sizeof(start_sequence);     ppsisok = 1;     return 0; }    if (spsisok == 1 && ppsisok == 1) {     if (iframeisok == 0) return 0; // wait i-frame      /*  simplify case.         these nal types used internally h264 codec      */     if (type >= 1 && type <= 23) type = 1;     switch (type)         {             case 0: // undefined;                 break;              case 1:                 // copy start sequence                  memcpy((void*)curadr, start_sequence, sizeof(start_sequence));                 curadr += sizeof(start_sequence);                  // copy data                 memcpy((void*)curadr, buf, inputdatalen);                 curadr += inputdatalen;                  result_len = sizeof(start_sequence) +  inputdatalen;                 break;              case 24: // stap-a (one packet, multiple nals)  not used in project                 break;             case 25: // stap-b             case 26: // mtap-16             case 27: // mtap-24             case 29: // fu-b                 //not used in project                 break;             case 28: // fu-a (fragmented nal)                  inputdatalen -= 2; // delete 2 first bytes fragmented units                 //skip fu_indicator                 buf++;                  uint8 fu_indicator = nal;                 uint8 fu_header = *buf; // read fu_header.                 uint8 start_bit = fu_header >> 7;                 uint8 reconstructed_nal;                 uint8 nal_type = (fu_header & 0x1f);                   /* reconstruct packet's true nal;                 data follows..*/                 reconstructed_nal = fu_indicator & (0xe0);                  /*the original nal forbidden bit , nri stored in                 packet's nal*/                 reconstructed_nal |= nal_type;                  // skip fu_header...                 buf++;                  if(start_bit)                 {                     if (need_configs)                     {                         // copy sps , pps first                         memcpy((void*)curadr, sps, sps_len);                         curadr += sps_len;                          memcpy((void*)curadr, pps, pps_len);                         curadr += pps_len;                      }                      // copy in start sequence                     memcpy((void*)curadr, start_sequence, sizeof(start_sequence));                     curadr += sizeof(start_sequence);                       // copy reconstructed nal                     memcpy((void*)curadr,&reconstructed_nal, sizeof(reconstructed_nal));                     curadr += sizeof(reconstructed_nal);                       // copy payload                     memcpy((void*)curadr,buf, inputdatalen);                     curadr += inputdatalen;                      if (need_configs)                     {                         result_len = (sps_len + pps_len + sizeof(start_sequence) + sizeof(reconstructed_nal) + inputdatalen);                         need_configs = 0;                     }                     else                     {                         result_len += (sizeof(start_sequence) + sizeof(reconstructed_nal) + inputdatalen);                     }                  }                 else                 {                      memcpy((void*)curadr,buf, inputdatalen);                     curadr += inputdatalen;                      result_len = inputdatalen;                 }                   break;             default:                 break;         }     return result_len; } else {     return 0; } 

}

depacketization rules described in rfc 6184 - rtp payload format h.264 video , should follow them rather trying invent own.

your assumption prepending fragment 00 00 01 65 reconstructing nal unit incorrect.

the idea nal unit large fit single packet, , it's fragmented parts. receive several rtp fragments , combine them single nal unit reconstructing in full, , in original state. see section 5.8. fragmentation units (fus) details.

instead of following mentioned above, adding 00 00 01 65 each part of nal unit - expectedly not going produce decodable output.

see also:


Comments

Popular posts from this blog

javascript - Jquery show_hide, what to add in order to make the page scroll to the bottom of the hidden field once button is clicked -

javascript - Highcharts multi-color line -

javascript - Enter key does not work in search box -