int h264_parse(Track *tr, uint8_t *data, ssize_t len) { // double nal_time; // see page 9 and 7.4.1.2 size_t nalsize = 0, index = 0; uint8_t *p, *q; if (tr->h264.is_avc) { const size_t nal_length_size = tr->h264.nal_length_size; while (1) { unsigned int i; if(index >= len) break; //get the nal size nalsize = 0; for(i = 0; i < 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) { struct MParserBuffer *buffer = g_slice_new0(struct MParserBuffer); buffer->timestamp = tr->pts; buffer->delivery = tr->dts; buffer->duration = tr->frame_duration; buffer->marker = true; buffer->data_size = nalsize; buffer->data = g_memdup(data + index, buffer->data_size); track_write(tr, buffer); fnc_log(FNC_LOG_VERBOSE, "[h264] single NAL"); } else { // single NAL, to be fragmented, FU-A; frag_fu_a(data + index, nalsize, tr); } index += nalsize; } } else {
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 - 3; p++) { if (p[0] == 0 && p[1] == 0 && p[2] == 1) { break; } } if (p >= data + len) return ERR_PARSE; while (1) { //seek to the next startcode [0 0 1] for (q = p; q<data+len-3;q++) { if (q[0] == 0 && q[1] == 0 && q[2] == 1) { break; } } if (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; }