📄 av_parsers.c
字号:
if (idx<0) return GF_NON_COMPLIANT_BITSTREAM; if (width) *width = avc.sps[idx].width; if (height) *height = avc.sps[idx].height; if (par_n) *par_n = avc.sps[idx].par_num ? avc.sps[idx].par_num : (u32) -1; if (par_d) *par_d = avc.sps[idx].par_den ? avc.sps[idx].par_den : (u32) -1; return GF_OK;}#endifGF_EXPORTconst char *gf_avc_get_profile_name(u8 video_prof){ switch (video_prof) { case 0x42: return "Baseline"; case 0x4D: return "Main"; case 0x58: return "Extended"; case 0x64: return "High"; case 0x6E: return "High 10"; case 0x7A: return "High 4:2:2"; case 0x90: return "High 4:4:4"; default: return "Unknown"; }}#ifndef GPAC_READ_ONLY/* AC3 parser taken from MPEG4IP - MPL*/static u32 AC3_FindSyncCode(u8 *buf, u32 buflen){ u32 end = buflen - 6; u32 offset = 0; while (offset <= end) { if (buf[offset] == 0x0b && buf[offset + 1] == 0x77) { return offset; } offset++; } return buflen;}static const u32 ac3_sizecod_to_bitrate[] = { 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 384000, 448000, 512000, 576000, 640000};static const u32 ac3_sizecod2_to_framesize[] = { 96, 120, 144, 168, 192, 240, 288, 336, 384, 480, 576, 672, 768, 960, 1152, 1344, 1536, 1728, 1920};static const u32 ac3_sizecod1_to_framesize[] = { 69, 87, 104, 121, 139, 174, 208, 243, 278, 348, 417, 487, 557, 696, 835, 975, 1114, 1253, 1393};static const u32 ac3_sizecod0_to_framesize[] = { 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 512, 640, 768, 896, 1024, 1152, 1280};static const u32 ac3_mod_to_chans[] = { 2, 1, 2, 3, 3, 4, 4, 5};Bool gf_ac3_parser(u8 *buf, u32 buflen, u32 *pos, GF_AC3Header *hdr){ u32 fscod, frmsizecod, bsid, ac3_mod, freq, framesize; if (buflen < 6) return 0; (*pos) = AC3_FindSyncCode(buf, buflen); if (*pos >= buflen) return 0; buf += (*pos); fscod = (buf[4] >> 6) & 0x3; frmsizecod = (buf[4] & 0x3f); bsid = (buf[5] >> 3) & 0x1f; ac3_mod = (buf[6] >> 5) & 0x7; if (bsid >= 12) return 0; if (hdr) memset(hdr, 0, sizeof(GF_AC3Header)); if (hdr) { hdr->bitrate = ac3_sizecod_to_bitrate[frmsizecod / 2]; if (bsid > 8) hdr->bitrate = hdr->bitrate >> (bsid - 8); } switch (fscod) { case 0: freq = 48000; framesize = ac3_sizecod0_to_framesize[frmsizecod / 2] * 2; break; case 1: freq = 44100; framesize = (ac3_sizecod1_to_framesize[frmsizecod / 2] + (frmsizecod & 0x1)) * 2; break; case 2: freq = 32000; framesize = ac3_sizecod2_to_framesize[frmsizecod / 2] * 2; break; default: return 0; } if (hdr) { u16 maskbit, b67; hdr->sample_rate = freq; hdr->framesize = framesize; hdr->channels = ac3_mod_to_chans[ac3_mod]; maskbit = 0x100; if ((ac3_mod & 0x1) && (ac3_mod != 1)) maskbit >>= 2; if (ac3_mod & 0x4) maskbit >>= 2; if (ac3_mod == 0x2) maskbit += 2; b67 = (buf[6] << 8) | buf[7]; if ((b67 & maskbit) != 0) hdr->channels += 1; } return 1;}#endif/* Vorbis parser*/static u32 vorbis_book_maptype1_quantvals(u32 entries, u32 dim){ u32 vals = (u32) floor(pow(entries, 1.0/dim)); while(1) { u32 acc=1; u32 acc1=1; u32 i; for (i=0;i<dim;i++) { acc*=vals; acc1*=vals+1; } if(acc<=entries && acc1>entries) return (vals); else { if (acc>entries) vals--; else vals++; } }}u32 _ilog_(u32 v){ u32 ret=0; while(v) { ret++; v>>=1; } return(ret);}static u32 ilog(u32 v){ u32 ret=0; if(v) --v; while(v) { ret++; v>>=1; } return (ret);}static u32 icount(u32 v){ u32 ret=0; while(v) { ret += v&1; v>>=1; } return(ret);}GF_EXPORTBool gf_vorbis_parse_header(GF_VorbisParser *vp, char *data, u32 data_len){ u32 pack_type, i, j, k, times, nb_part, nb_books, nb_modes; char szNAME[8]; oggpack_buffer opb; oggpack_readinit(&opb, (u8*)data, data_len); pack_type = oggpack_read(&opb, 8); i=0; while (i<6) { szNAME[i] = oggpack_read(&opb, 8); i++;} szNAME[i] = 0; if (strcmp(szNAME, "vorbis")) return vp->is_init = 0; switch (pack_type) { case 0x01: vp->version = oggpack_read(&opb, 32); if (vp->version!=0) return 0; vp->channels = oggpack_read(&opb, 8); vp->sample_rate = oggpack_read(&opb, 32); vp->max_r = oggpack_read(&opb, 32); vp->avg_r = oggpack_read(&opb, 32); vp->low_r = oggpack_read(&opb, 32); vp->min_block = 1<<oggpack_read(&opb, 4); vp->max_block = 1<<oggpack_read(&opb, 4); if (vp->sample_rate < 1) return vp->is_init = 0; if (vp->channels < 1) return vp->is_init = 0; if (vp->min_block<8) return vp->is_init = 0; if (vp->max_block < vp->min_block) return vp->is_init = 0; if (oggpack_read(&opb, 1) != 1) return vp->is_init = 0; vp->is_init = 1; return 1; case 0x03: /*trash comments*/ vp->is_init ++; return 1; case 0x05: /*need at least bitstream header to make sure we're parsing the right thing*/ if (!vp->is_init) return 0; break; default: vp->is_init = 0; return 0; } /*OK parse codebook*/ nb_books = oggpack_read(&opb, 8) + 1; /*skip vorbis static books*/ for (i=0; i<nb_books; i++) { u32 j, map_type, qb, qq; u32 entries, dim; oggpack_read(&opb, 24); dim = oggpack_read(&opb, 16); entries = oggpack_read(&opb, 24); if ( (s32) entries < 0) entries = 0; if (oggpack_read(&opb, 1) == 0) { if (oggpack_read(&opb, 1)) { for (j=0; j<entries; j++) { if (oggpack_read(&opb, 1)) { oggpack_read(&opb, 5); } } } else { for (j=0; j<entries; j++) oggpack_read(&opb, 5); } } else { oggpack_read(&opb, 5); for (j=0; j<entries;) { u32 num = oggpack_read(&opb, _ilog_(entries-j)); for (k=0; k<num && j<entries; k++, j++) { } } } switch ((map_type=oggpack_read(&opb, 4))) { case 0: break; case 1: case 2: oggpack_read(&opb, 32); oggpack_read(&opb, 32); qq = oggpack_read(&opb, 4)+1; oggpack_read(&opb, 1); if (map_type==1) qb = vorbis_book_maptype1_quantvals(entries, dim); else if (map_type==2) qb = entries * dim; else qb = 0; for (j=0;j<qb;j++) oggpack_read(&opb, qq); break; } } times = oggpack_read(&opb, 6)+1; for (i=0;i<times;i++) oggpack_read(&opb, 16); times = oggpack_read(&opb, 6)+1; for (i=0;i<times;i++) { u32 type = oggpack_read(&opb, 16); if (type) { u32 *parts, *class_dims, count, rangebits; u32 max_class = 0; nb_part = oggpack_read(&opb, 5); parts = (u32*)malloc(sizeof(u32) * nb_part); for (j=0;j<nb_part;j++) { parts[j] = oggpack_read(&opb, 4); if (max_class<parts[j]) max_class = parts[j]; } class_dims = (u32*)malloc(sizeof(u32) * (max_class+1)); for (j=0; j<max_class+1;j++) { u32 class_sub; class_dims[j] = oggpack_read(&opb, 3) + 1; class_sub = oggpack_read(&opb, 2); if (class_sub) oggpack_read(&opb, 8); for (k=0; k < (u32) (1<<class_sub); k++) oggpack_read(&opb, 8); } oggpack_read(&opb, 2); rangebits=oggpack_read(&opb, 4); count = 0; for (j=0,k=0;j<nb_part;j++) { count+=class_dims[parts[j]]; for (;k<count;k++) oggpack_read(&opb, rangebits); } free(parts); free(class_dims); } else { u32 j, nb_books; oggpack_read(&opb, 8+16+16+6+8); nb_books = oggpack_read(&opb, 4)+1; for (j=0; j<nb_books; j++) oggpack_read(&opb, 8); } } times = oggpack_read(&opb, 6)+1; for (i=0;i<times;i++) { u32 acc = 0; oggpack_read(&opb, 16);/*type*/ oggpack_read(&opb, 24); oggpack_read(&opb,24); oggpack_read(&opb,24); nb_part = oggpack_read(&opb, 6)+1; oggpack_read(&opb, 8); for (j=0; j<nb_part;j++) { u32 cascade = oggpack_read(&opb, 3); if (oggpack_read(&opb, 1)) cascade |= (oggpack_read(&opb, 5)<<3); acc += icount(cascade); } for (j=0;j<acc;j++) oggpack_read(&opb, 8); } times = oggpack_read(&opb, 6)+1; for (i=0; i<times; i++) { u32 sub_maps = 1; oggpack_read(&opb, 16); if (oggpack_read(&opb, 1)) sub_maps = oggpack_read(&opb, 4)+1; if (oggpack_read(&opb, 1)) { u32 nb_steps = oggpack_read(&opb, 8)+1; for (j=0;j<nb_steps;j++) { oggpack_read(&opb, ilog(vp->channels)); oggpack_read(&opb, ilog(vp->channels)); } } oggpack_read(&opb, 2); if (sub_maps>1) { for(j=0; j<vp->channels; j++) oggpack_read(&opb, 4); } for (j=0;j<sub_maps;j++) { oggpack_read(&opb, 8); oggpack_read(&opb, 8); oggpack_read(&opb, 8); } } nb_modes = oggpack_read(&opb, 6)+1; for (i=0; i<nb_modes; i++) { vp->mode_flag[i] = oggpack_read(&opb, 1); oggpack_read(&opb, 16); oggpack_read(&opb, 16); oggpack_read(&opb, 8); } vp->modebits = 0; j = nb_modes; while(j>1) { vp->modebits++; j>>=1; } return 1;}GF_EXPORTu32 gf_vorbis_check_frame(GF_VorbisParser *vp, char *data, u32 data_length){ s32 block_size; oggpack_buffer opb; if (!vp->is_init) return 0; oggpack_readinit(&opb, (unsigned char*)data, data_length); /*not audio*/ if (oggpack_read(&opb, 1) !=0) return 0; block_size = oggpack_read(&opb, vp->modebits); if (block_size == -1) return 0; return ((vp->mode_flag[block_size]) ? vp->max_block : vp->min_block) / (2);}GF_EXPORTvoid gf_img_parse(GF_BitStream *bs, u8 *OTI, u32 *mtype, u32 *width, u32 *height, char **dsi, u32 *dsi_len){ u8 b1, b2, b3; u32 size, type; u64 pos; pos = gf_bs_get_position(bs); gf_bs_seek(bs, 0); *mtype = *width = *height = 0; *OTI = 0; if (dsi) { *dsi = NULL; *dsi_len = 0; } b1 = gf_bs_read_u8(bs); b2 = gf_bs_read_u8(bs); b3 = gf_bs_read_u8(bs); /*JPEG*/ if ((b1==0xFF) && (b2==0xD8) && (b3==0xFF)) { gf_bs_read_u8(bs); /*get frame header FFC0*/ while (gf_bs_available(bs)) { u32 type, w, h; if (gf_bs_read_u8(bs) != 0xFF) continue; type = gf_bs_read_u8(bs); switch (type) { case 0xC0: case 0xC1: case 0xC2: gf_bs_skip_bytes(bs, 3); h = gf_bs_read_int(bs, 16); w = gf_bs_read_int(bs, 16); if ((w > *width) || (h > *height)) { *width = w; *height = h; } break; case 0xD0: case 0xD1: case 0xD2: case 0xD3: case 0xD4: case 0xD5: case 0xD6: case 0xD7: break; } } *OTI = 0x6C; *mtype = GF_4CC('j','p','e','g'); } /*PNG*/ else if ((b1==0x89) && (b2==0x50) && (b3==0x4E)) { /*check for PNG sig*/ if ( (gf_bs_read_u8(bs) != 0x47) || (gf_bs_read_u8(bs) != 0x0D) || (gf_bs_read_u8(bs) != 0x0A) || (gf_bs_read_u8(bs) != 0x1A) || (gf_bs_read_u8(bs) != 0x0A) ) goto exit; gf_bs_read_u32(bs); /*check for PNG IHDR*/ if ( (gf_bs_read_u8(bs) != 'I') || (gf_bs_read_u8(bs) != 'H') || (gf_bs_read_u8(bs) != 'D') || (gf_bs_read_u8(bs) != 'R')) goto exit; *width = gf_bs_read_u32(bs); *height = gf_bs_read_u32(bs); *OTI = 0x6D; *mtype = GF_4CC('p','n','g',' '); } size = gf_bs_read_u8(bs); type = gf_bs_read_u32(bs); if ( ((size==12) && (type==GF_4CC('j','P',' ',' ') )) || (type==GF_4CC('j','p','2','h') ) ) { if (type==GF_4CC('j','p','2','h')) { *OTI = 0x6E; *mtype = GF_4CC('j','p','2',' '); goto j2k_restart; } type = gf_bs_read_u32(bs); if (type!=0x0D0A870A) goto exit; *OTI = 0x6E; *mtype = GF_4CC('j','p','2',' '); while (gf_bs_available(bs)) {j2k_restart: size = gf_bs_read_u32(bs); type = gf_bs_read_u32(bs); switch (type) { case GF_4CC('j','p','2','h'): goto j2k_restart; case GF_4CC('i','h','d','r'): { u16 nb_comp; u8 BPC, C, UnkC, IPR; *height = gf_bs_read_u32(bs); *width = gf_bs_read_u32(bs); nb_comp = gf_bs_read_u16(bs); BPC = gf_bs_read_u8(bs); C = gf_bs_read_u8(bs); UnkC = gf_bs_read_u8(bs); IPR = gf_bs_read_u8(bs); if (dsi) { GF_BitStream *bs_dsi = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); gf_bs_write_u32(bs_dsi, *height); gf_bs_write_u32(bs_dsi, *width); gf_bs_write_u16(bs_dsi, nb_comp); gf_bs_write_u8(bs_dsi, BPC); gf_bs_write_u8(bs_dsi, C); gf_bs_write_u8(bs_dsi, UnkC); gf_bs_write_u8(bs_dsi, IPR); gf_bs_get_content(bs_dsi, dsi, dsi_len); gf_bs_del(bs_dsi); } goto exit; } break; default: gf_bs_skip_bytes(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -