}
int
-avc_parse_nal_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size)
+isom_write_avcc(sbuf_t *sb, const uint8_t *data, int len)
{
- sbuf_t sb;
-
- sbuf_init(&sb);
-
- avc_parse_nal_units(&sb, buf_in, *size);
+ sbuf_t b;
+ uint8_t *buf, *end;
+ uint32_t *sps_size_array, *pps_size_array;
+ uint32_t pps_count, sps_count;
+ uint8_t **sps_array, **pps_array;
+ int i, ret;
+
+ if (len <= 6)
+ return 0;
+
+ if (RB32(data) != 0x00000001 ||
+ RB24(data) != 0x000001) {
+ sbuf_append(sb, data, len);
+ return 0;
+ }
- *buf = sb.sb_data;
- *size = sb.sb_ptr;
- return 0;
-}
+ sbuf_init(&b);
+
+ len = avc_parse_nal_units(&b, data, len);
+
+ buf = b.sb_data;
+ end = buf + len;
+
+ sps_size_array = pps_size_array = NULL;
+ pps_count = sps_count = 0;
+ sps_array = pps_array = NULL;
+ ret = 0;
+
+ /* look for sps and pps */
+ while (end - buf > 4) {
+ unsigned int size;
+ uint8_t nal_type;
+ size = MIN(RB32(buf), end - buf - 4);
+ buf += 4;
+ nal_type = buf[0] & 0x1f;
+
+ if ((nal_type == 7) && (size >= 4) && (size <= UINT16_MAX)) { /* 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;
+ sps_size_array[sps_count] = size;
+ sps_count++;
+ } else if ((nal_type == 8) && (size <= UINT16_MAX)) { /* 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;
+ pps_size_array[pps_count] = size;
+ pps_count++;
+ }
+ buf += size;
+ }
-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, *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 (end - buf > 4) {
- unsigned int size;
- uint8_t nal_type;
- size = MIN(RB32(buf), end - buf - 4);
- buf += 4;
- nal_type = buf[0] & 0x1f;
-
- if ((nal_type == 7) && (size >= 4) && (size <= UINT16_MAX)) { /* 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;
- sps_size_array[sps_count] = size;
- sps_count++;
- } else if ((nal_type == 8) && (size <= UINT16_MAX)) { /* 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;
- pps_size_array[pps_count] = size;
- pps_count++;
- }
- buf += size;
- }
- if(!sps_count || !pps_count) {
- free(start);
- if (sps_count) {
- free(sps_array);
- free(sps_size_array);
- }
- if (pps_count) {
- free(pps_array);
- free(pps_size_array);
- }
- return -1;
- }
+ if(!sps_count || !pps_count) {
+ ret = -1;
+ goto end;
+ }
- 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, 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);
+ 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]);
+ }
- if (sps_count) {
- free(sps_array);
- free(sps_size_array);
- }
- if (pps_count) {
- free(pps_array);
- free(pps_size_array);
- }
- } else {
- sbuf_append(sb, data, len);
- }
+end:
+ if (sps_count) {
+ free(sps_array);
+ free(sps_size_array);
}
- return 0;
+ if (pps_count) {
+ free(pps_array);
+ free(pps_size_array);
+ }
+
+ sbuf_free(&b);
+ return ret;
}
th_pkt_t *