头部格式介绍请参见https://www.cnblogs.com/zhangxuan/p/8809245.html,本文主要介绍代码解析ADTS 头格式。
另外,根据笔者的测试,AAC文件的最后一帧会触发VLC播放停止。但最后一帧的头信息并没有特殊标记,仅长度比较短。如果需要循环播放AAC文件,可将最后一帧过滤。
资源下载地址(包含源码和测试文件):
打印adts aac 头部字段。 static void aac_hdr_dump(unsigned char aac_hdr[]) { static int idx = 0; //bytes 0,1 unsigned short sync = (aac_hdr[0] << 4) | (aac_hdr[1] >> 4); unsigned char version = (aac_hdr[1] & 0x08) >> 3; unsigned char layer = (aac_hdr[1] & 0x06) >> 1; unsigned char absent = aac_hdr[1] & 0x01; //bytes 2 unsigned char profile = (aac_hdr[2] & 0xC0) >> 6; unsigned char fidex = (aac_hdr[2] & 0x3C) >> 2; unsigned char private_stream = (aac_hdr[2] & 0x02) >> 1; unsigned char channel = ((aac_hdr[2] & 0x01) << 2) | ((aac_hdr[3] & 0xC0) >> 6); unsigned char originality = (aac_hdr[3] & 0x20) >> 5; unsigned char home = (aac_hdr[3] & 0x10) >> 4; unsigned char copystream = (aac_hdr[3] & 0x08) >> 3; unsigned char copystart = (aac_hdr[3] & 0x04) >> 2; unsigned short framelen = ((aac_hdr[3] & 0x03) << 11) | ((aac_hdr[4] << 3)) | ((aac_hdr[5] & 0xE0) >> 5); unsigned short bufferfullness = ((aac_hdr[5] & 0x1F) << 6) | ((aac_hdr[6] & 0xFC) >> 2); unsigned char numaacframes = aac_hdr[6] & 0x03; printf("###%d:\n", ++idx); printf("\tsync=0x%x,version=%d,layer=%d,absent=%d,profile=%d,fidex=%d\n",sync, version, layer, absent, profile, fidex); printf("\tprivate_stream=%d,channel=%d,originality=%d,home=%d,copystream=%d,copystart=%d,\n", private_stream, channel, originality, home, copystream, copystart); printf("\tframelen=%04d,bufferfullness=%04d,numaacframes=%d\n", framelen, bufferfullness, numaacframes); } 读取aac每一帧。 int main(int argc, char* argv[]) { FILE *rfd = NULL; unsigned char aac_hdr[7] = {0}; ssize_t read_size = 0; int aac_flen = 0; //aac frame length. if (argc != 2) { printf("[Usage]: ./main test.aac\n"); return -1; } /* Open aac_file once. */ printf("Open file(%s)...\n", argv[1]); rfd = fopen(argv[1], "re"); if (!rfd) { fprintf(stderr, "AUDIO:open aac file(%s) failed\n", argv[1]); return 0; } while(1) { /* Read aac header, 7bytes. */ read_size = fread(aac_hdr, 1, sizeof(aac_hdr), rfd); if (read_size != sizeof(aac_hdr)) { fprintf(stderr, "AUDIO:read aac header failed\n"); fclose(rfd); return 0; } aac_hdr_dump(aac_hdr); /* Get aac frame length frome aac header */ aac_flen = ((aac_hdr[3]&0x03)<<11) | (aac_hdr[4]<<3) | ((aac_hdr[5]&0xE0)>>5); /* Skip current frame */ fseek(rfd, aac_flen-7, SEEK_CUR); } fclose(rfd); return 0; }