/* Append RTCP header data to the buffer. Version and padding are set to fixed values, i.e. 2 and 0; */ static void rtcp_append_headers(sbuf_t *buffer, rtcp_t *packet) { packet->common.version = 2; packet->common.p = 0; uint8_t byte = 0; byte |= packet->common.version << 6; byte |= packet->common.p << 5; byte |= packet->common.count; sbuf_put_byte(buffer, byte); byte = packet->common.pt; sbuf_put_byte(buffer, byte); sbuf_append(buffer, &packet->common.length, sizeof(packet->common.length)); }
/* * End the section padding to the specified length with the specified * character. */ ssize_t sbuf_end_section(struct sbuf *s, ssize_t old_len, size_t pad, int c) { ssize_t len; assert_sbuf_integrity(s); assert_sbuf_state(s, 0); KASSERT(SBUF_ISSECTION(s), ("attempt to end a section when not in a section")); if (pad > 1) { len = roundup(s->s_sect_len, pad) - s->s_sect_len; for (; s->s_error == 0 && len > 0; len--) sbuf_put_byte(s, c); } len = s->s_sect_len; if (old_len == -1) { s->s_sect_len = 0; SBUF_CLEARFLAG(s, SBUF_INSECTION); } else { s->s_sect_len += old_len; } if (s->s_error != 0) return (-1); return (len); }
/* * Append a non-NUL character to an sbuf. This prototype signature is * suitable for use with kvcprintf(9). */ static void sbuf_putc_func(int c, void *arg) { if (c != '\0') sbuf_put_byte(arg, c); }
/* * Append a character to an sbuf. */ int sbuf_putc(struct sbuf *s, int c) { sbuf_put_byte(s, c); if (s->s_error != 0) return (-1); return (0); }
/* Append RTCP receiver report data to the buffer. */ static void rtcp_append_rr(sbuf_t *buffer, rtcp_t *packet) { uint8_t byte = 0; rtcp_rr_t report = packet->r.rr.rr[0]; sbuf_append(buffer, &packet->r.rr.ssrc, sizeof(packet->r.rr.ssrc)); sbuf_append(buffer, &report.ssrc, sizeof(report.ssrc)); byte = report.fraction; sbuf_put_byte(buffer, byte); // Set the lost number in 3 times byte = (report.lost & 0xff0000) >> 16; sbuf_put_byte(buffer, byte); byte = (report.lost & 0x00ff00) >> 8; sbuf_put_byte(buffer, byte); byte = report.lost & 0x0000ff; sbuf_put_byte(buffer, byte); sbuf_append(buffer, &report.last_seq, sizeof(report.last_seq)); sbuf_append(buffer, &report.jitter, sizeof(report.jitter)); sbuf_append(buffer, &report.lsr, sizeof(report.lsr)); sbuf_append(buffer, &report.dlsr, sizeof(report.dlsr)); }
/* * Append a string to an sbuf. */ int sbuf_cat(struct sbuf *s, const char *str) { assert_sbuf_integrity(s); assert_sbuf_state(s, 0); if (s->s_error != 0) return (-1); while (*str != '\0') { sbuf_put_byte(s, *str++); if (s->s_error != 0) return (-1); } return (0); }
/* * Append a byte string to an sbuf. */ int sbuf_bcat(struct sbuf *s, const void *buf, size_t len) { const char *str = buf; const char *end = str + len; assert_sbuf_integrity(s); assert_sbuf_state(s, 0); if (s->s_error != 0) return (-1); for (; str < end; str++) { sbuf_put_byte(s, *str); if (s->s_error != 0) return (-1); } return (0); }
static int isom_write_avcc(sbuf_t *sb, const uint8_t *data, int len) { if (len > 6) { /* check for h264 start code */ if (RB32(data) == 0x00000001 || RB24(data) == 0x000001) { uint8_t *buf=NULL, *end, *start; uint32_t *sps_size_array=0, *pps_size_array=0; uint32_t pps_count=0,sps_count=0; uint8_t **sps_array=0, **pps_array=0; int i; int ret = avc_parse_nal_units_buf(data, &buf, &len); if (ret < 0) return ret; start = buf; end = buf + len; /* look for sps and pps */ while (buf < end) { unsigned int size; uint8_t nal_type; size = RB32(buf); nal_type = buf[4] & 0x1f; if (nal_type == 7) { /* SPS */ sps_array = realloc(sps_array,sizeof(uint8_t*)*(sps_count+1)); sps_size_array = realloc(sps_size_array,sizeof(uint32_t)*(sps_count+1)); sps_array[sps_count] = buf + 4; sps_size_array[sps_count] = size; sps_count++; } else if (nal_type == 8) { /* PPS */ pps_size_array = realloc(pps_size_array,sizeof(uint32_t)*(pps_count+1)); pps_array = realloc(pps_array,sizeof (uint8_t*)*(pps_count+1)); pps_array[pps_count] = buf + 4; pps_size_array[pps_count] = size; pps_count++; } buf += size + 4; } if(!sps_count || !pps_count) { free(start); if (sps_count) free(sps_array); if (pps_count) free(pps_array); return -1; } sbuf_put_byte(sb, 1); /* version */ sbuf_put_byte(sb, sps_array[0][1]); /* profile */ sbuf_put_byte(sb, sps_array[0][2]); /* profile compat */ sbuf_put_byte(sb, sps_array[0][3]); /* level */ sbuf_put_byte(sb, 0xff); /* 6 bits reserved (111111) + 2 bits nal size length - 1 (11) */ sbuf_put_byte(sb, 0xe0+sps_count); /* 3 bits reserved (111) + 5 bits number of sps (00001) */ for (i=0;i<sps_count;i++) { sbuf_put_be16(sb, sps_size_array[i]); sbuf_append(sb, sps_array[i], sps_size_array[i]); } sbuf_put_byte(sb, pps_count); /* number of pps */ for (i=0;i<pps_count;i++) { sbuf_put_be16(sb, pps_size_array[i]); sbuf_append(sb, pps_array[i], pps_size_array[i]); } free(start); if (sps_count) free(sps_array); if (pps_count) free(pps_array); } else { sbuf_append(sb, data, len); } } return 0; }