分享一段H264视频和AAC音频的RTP封包代码

1. H264视频的RTP封包

static int h264_parse(Track *tr, uint8_t *data, size_t len) { h264_priv *priv = tr->private_data; // double nal_time; // see page 9 and 7.4.1.2 size_t nalsize = 0, index = 0; uint8_t *p, *q; if (priv->is_avc) { while (1) { unsigned int i; if(index >= len) break; //get the nal size nalsize = 0; for(i = 0; i < priv->nal_length_size; i++) nalsize = (nalsize << 8) | data[index++]; if(nalsize <= 1 || nalsize > len) { if(nalsize == 1) { index++; continue; } else { fnc_log(FNC_LOG_VERBOSE, "[h264] AVC: nal size %d", nalsize); break; } } if (DEFAULT_MTU >= nalsize) { mparser_buffer_write(tr, tr->properties.pts, tr->properties.dts, tr->properties.frame_duration, 1, data + index, nalsize); fnc_log(FNC_LOG_VERBOSE, "[h264] single NAL"); } else { // single NAL, to be fragmented, FU-A; frag_fu_a(data + index, nalsize, DEFAULT_MTU, tr); } index += nalsize; } } else { //seek to the first startcode for (p = data; p= data + len) return ERR_PARSE; while (1) { //seek to the next startcode [0 0 1] for (q = p; q= data + len) break; if (DEFAULT_MTU >= q - p) { fnc_log(FNC_LOG_VERBOSE, "[h264] Sending NAL %d",p[0]&0x1f); mparser_buffer_write(tr, tr->properties.pts, tr->properties.dts, tr->properties.frame_duration, 1, p, q - p); fnc_log(FNC_LOG_VERBOSE, "[h264] single NAL"); } else { //FU-A fnc_log(FNC_LOG_VERBOSE, "[h264] frags"); frag_fu_a(p, q - p, DEFAULT_MTU, tr); } p = q; } // last NAL fnc_log(FNC_LOG_VERBOSE, "[h264] last NAL %d",p[0]&0x1f); if (DEFAULT_MTU >= len - (p - data)) { fnc_log(FNC_LOG_VERBOSE, "[h264] no frags"); mparser_buffer_write(tr, tr->properties.pts, tr->properties.dts, tr->properties.frame_duration, 1, p, len - (p - data)); } else { //FU-A fnc_log(FNC_LOG_VERBOSE, "[h264] frags"); frag_fu_a(p, len - (p - data), DEFAULT_MTU, tr); } } fnc_log(FNC_LOG_VERBOSE, "[h264] Frame completed"); return ERR_NOERROR; }

 

2. AAC的RTP封包

static int aac_parse(Track *tr, uint8_t *data, size_t len) { //XXX handle the last packet on EOF int off = 0; uint32_t payload = DEFAULT_MTU - AU_HEADER_SIZE; uint8_t *packet = g_malloc0(DEFAULT_MTU); if(!packet) return ERR_ALLOC; // trim away extradata // data += AAC_EXTRA; // len -= AAC_EXTRA; packet[0] = 0x00; packet[1] = 0x10; packet[2] = (len & 0x1fe0) >> 5; packet[3] = (len & 0x1f) << 3; if (len > payload) { while (len > payload) { memcpy(packet + AU_HEADER_SIZE, data + off, payload); mparser_buffer_write(tr, tr->properties.pts, tr->properties.dts, tr->properties.frame_duration, 0, packet, DEFAULT_MTU); len -= payload; off += payload; } } memcpy(packet + AU_HEADER_SIZE, data + off, len); mparser_buffer_write(tr, tr->properties.pts, tr->properties.dts, tr->properties.frame_duration, 1, packet, len + AU_HEADER_SIZE); g_free(packet); return ERR_NOERROR; }

 

上面的变量 AU_HEADER_SIZE=4

 

/* au header

      +---------------------------------------+

      |     AU-size                           |

      +---------------------------------------+

      |     AU-Index / AU-Index-delta         |

      +---------------------------------------+

      |     CTS-flag                          |

      +---------------------------------------+

      |     CTS-delta                         |

      +---------------------------------------+

      |     DTS-flag                          |

      +---------------------------------------+

      |     DTS-delta                         |

      +---------------------------------------+

      |     RAP-flag                          |

      +---------------------------------------+

      |     Stream-state                      |

      +---------------------------------------+

*/

你可能感兴趣的:(流媒体)