Skip to content

Instantly share code, notes, and snippets.

@qvoid
Created September 4, 2023 06:46
Show Gist options
  • Save qvoid/dbef84f5b569015dae6f9177eb618c40 to your computer and use it in GitHub Desktop.
Save qvoid/dbef84f5b569015dae6f9177eb618c40 to your computer and use it in GitHub Desktop.
Convert H.264 bistream from AVCC to ANNEXB format
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#define AVCC_HEADER_OFFSET 4
#define AVCC_NALU_LEN_UINT_SIZE_MINUS_1_MASK 0x3
#define AVCC_HEADER_SPS_CNT_OFFSET 5
#define SPS_CNT_MASK 0x1f
#define START_CODE_SIZE 4
int main(int argc, char *argv[]) {
int i = 0;
const uint8_t start_code[] = {0, 0, 0, 1};
if (argc < 3) {
printf("Invalid args\n");
return -1;
}
FILE *in_file = fopen(argv[1], "r");
if (!in_file) {
printf("Failed to open %s\n", argv[1]);
return -1;
}
fseek(in_file, 0, SEEK_END);
int in_size = ftell(in_file);
uint8_t *in_data = (uint8_t *) malloc(in_size + 1);
uint8_t *pos = in_data + AVCC_HEADER_OFFSET;
fseek(in_file, 0, SEEK_SET);
fread(in_data, 1, in_size, in_file);
fclose(in_file);
FILE *out_file = fopen(argv[2], "wb");
int nalu_len_unit_size = (*pos) & AVCC_NALU_LEN_UINT_SIZE_MINUS_1_MASK + 1;
pos++;
int sps_cnt = (*pos) & SPS_CNT_MASK;
pos++;
printf("NALU len using %d bytes\n", nalu_len_unit_size);
printf("SPS cnt %d\n", sps_cnt);
for(i = 0; i < sps_cnt; i++) {
int sps_len = (pos[0] << 8) + pos[1];
pos += 2;
printf("SPS[%d], length %d\n", i, sps_len);
fwrite(start_code, 1, START_CODE_SIZE, out_file);
fwrite(pos, 1, sps_len, out_file);
pos += sps_len;
}
int pps_cnt = *pos;
pos++;
printf("PPS cnt %d\n", pps_cnt);
for (i = 0; i < pps_cnt; i++) {
int pps_len = (pos[0] << 8) + pos[1];
pos += 2;
printf("PPS[%d], length %d\n", i, pps_len);
fwrite(start_code, 1, START_CODE_SIZE, out_file);
fwrite(pos, 1, pps_len, out_file);
pos += pps_len;
}
int read_len = pos - in_data + 1;
uint32_t nalu_len = 0;
while (read_len <= in_size) {
for (i = 0; i < nalu_len_unit_size; i++) {
nalu_len = nalu_len + (pos[i] << (8 * (nalu_len_unit_size - 1 - i)));
}
printf("nalu length 0x%x\n", nalu_len);
pos += nalu_len_unit_size;
fwrite(start_code, 1, START_CODE_SIZE, out_file);
fwrite(pos, 1, nalu_len, out_file);
pos += nalu_len;
read_len = read_len + nalu_len_unit_size + nalu_len;
nalu_len = 0;
}
fclose(out_file);
free(in_data);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment