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:
- how process raw udp packets can decoded decoder filter in directshow source filter "depacketize data" section
Comments
Post a Comment