Created
September 4, 2023 06:46
-
-
Save qvoid/dbef84f5b569015dae6f9177eb618c40 to your computer and use it in GitHub Desktop.
Convert H.264 bistream from AVCC to ANNEXB format
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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