📄 parser.c
字号:
dprintf("skip %x\n", header); /* reset free format frame size to give a chance to get a new bitrate */ s->free_format_frame_size = 0; } else { if((header&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header) s->header_count= -3; s->header= header; s->header_count++; s->frame_size = ret;#if 0 /* free format: prepare to compute frame size */ if (decode_header(s, header) == 1) { s->frame_size = -1; }#endif } if(s->header_count > 1) avctx->sample_rate= sr; } } else#if 0 if (s->frame_size == -1) { /* free format : find next sync to compute frame size */ len = MPA_MAX_CODED_FRAME_SIZE - len; if (len > buf_size) len = buf_size; if (len == 0) { /* frame too long: resync */ s->frame_size = 0; memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1); s->inbuf_ptr--; } else { uint8_t *p, *pend; uint32_t header1; int padding; memcpy(s->inbuf_ptr, buf_ptr, len); /* check for header */ p = s->inbuf_ptr - 3; pend = s->inbuf_ptr + len - 4; while (p <= pend) { header = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; header1 = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) | (s->inbuf[2] << 8) | s->inbuf[3]; /* check with high probability that we have a valid header */ if ((header & SAME_HEADER_MASK) == (header1 & SAME_HEADER_MASK)) { /* header found: update pointers */ len = (p + 4) - s->inbuf_ptr; buf_ptr += len; buf_size -= len; s->inbuf_ptr = p; /* compute frame size */ s->free_format_next_header = header; s->free_format_frame_size = s->inbuf_ptr - s->inbuf; padding = (header1 >> 9) & 1; if (s->layer == 1) s->free_format_frame_size -= padding * 4; else s->free_format_frame_size -= padding; dprintf("free frame size=%d padding=%d\n", s->free_format_frame_size, padding); decode_header(s, header1); goto next_data; } p++; } /* not found: simply increase pointers */ buf_ptr += len; s->inbuf_ptr += len; buf_size -= len; } } else#endif if (len < s->frame_size) { if (s->frame_size > MPA_MAX_CODED_FRAME_SIZE) s->frame_size = MPA_MAX_CODED_FRAME_SIZE; len = FFMIN(s->frame_size - len, buf_size); memcpy(s->inbuf_ptr, buf_ptr, len); buf_ptr += len; s->inbuf_ptr += len; buf_size -= len; } if(s->frame_size > 0 && buf_ptr - buf == s->inbuf_ptr - s->inbuf && buf_size + buf_ptr - buf >= s->frame_size){ if(s->header_count > 0){ *poutbuf = buf; *poutbuf_size = s->frame_size; } buf_ptr = buf + s->frame_size; s->inbuf_ptr = s->inbuf; s->frame_size = 0; break; } // next_data: if (s->frame_size > 0 && (s->inbuf_ptr - s->inbuf) >= s->frame_size) { if(s->header_count > 0){ *poutbuf = s->inbuf; *poutbuf_size = s->inbuf_ptr - s->inbuf; } s->inbuf_ptr = s->inbuf; s->frame_size = 0; break; } } return buf_ptr - buf;}#endif /* CONFIG_MPEGAUDIO_PARSER */#if defined(CONFIG_AC3_PARSER) || defined(CONFIG_AAC_PARSER)/* also used for ADTS AAC */typedef struct AC3ParseContext { uint8_t *inbuf_ptr; int frame_size; int header_size; int (*sync)(const uint8_t *buf, int *channels, int *sample_rate, int *bit_rate, int *samples); uint8_t inbuf[8192]; /* input buffer */} AC3ParseContext;#define AC3_HEADER_SIZE 7#define AAC_HEADER_SIZE 7#ifdef CONFIG_AC3_PARSERstatic const int ac3_sample_rates[4] = { 48000, 44100, 32000, 0};static const int ac3_frame_sizes[64][3] = { { 64, 69, 96 }, { 64, 70, 96 }, { 80, 87, 120 }, { 80, 88, 120 }, { 96, 104, 144 }, { 96, 105, 144 }, { 112, 121, 168 }, { 112, 122, 168 }, { 128, 139, 192 }, { 128, 140, 192 }, { 160, 174, 240 }, { 160, 175, 240 }, { 192, 208, 288 }, { 192, 209, 288 }, { 224, 243, 336 }, { 224, 244, 336 }, { 256, 278, 384 }, { 256, 279, 384 }, { 320, 348, 480 }, { 320, 349, 480 }, { 384, 417, 576 }, { 384, 418, 576 }, { 448, 487, 672 }, { 448, 488, 672 }, { 512, 557, 768 }, { 512, 558, 768 }, { 640, 696, 960 }, { 640, 697, 960 }, { 768, 835, 1152 }, { 768, 836, 1152 }, { 896, 975, 1344 }, { 896, 976, 1344 }, { 1024, 1114, 1536 }, { 1024, 1115, 1536 }, { 1152, 1253, 1728 }, { 1152, 1254, 1728 }, { 1280, 1393, 1920 }, { 1280, 1394, 1920 },};static const int ac3_bitrates[64] = { 32, 32, 40, 40, 48, 48, 56, 56, 64, 64, 80, 80, 96, 96, 112, 112, 128, 128, 160, 160, 192, 192, 224, 224, 256, 256, 320, 320, 384, 384, 448, 448, 512, 512, 576, 576, 640, 640,};static const uint8_t ac3_channels[8] = { 2, 1, 2, 3, 3, 4, 4, 5};static const uint8_t eac3_blocks[4] = { 1, 2, 3, 6};#endif /* CONFIG_AC3_PARSER */#ifdef CONFIG_AAC_PARSERstatic const int aac_sample_rates[16] = { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350};static const int aac_channels[8] = { 0, 1, 2, 3, 4, 5, 6, 8};#endif#ifdef CONFIG_AC3_PARSERstatic int ac3_sync(const uint8_t *buf, int *channels, int *sample_rate, int *bit_rate, int *samples){ unsigned int fscod, frmsizecod, acmod, bsid, lfeon; unsigned int strmtyp, substreamid, frmsiz, fscod2, numblkscod; GetBitContext bits; init_get_bits(&bits, buf, AC3_HEADER_SIZE * 8); if(get_bits(&bits, 16) != 0x0b77) return 0; bsid = show_bits_long(&bits, 29) & 0x1f; if(bsid <= 8) { /* Normal AC-3 */ skip_bits(&bits, 16); /* crc */ fscod = get_bits(&bits, 2); frmsizecod = get_bits(&bits, 6); if(fscod == 3) return 0; skip_bits(&bits, 5); /* bsid */ skip_bits(&bits, 3); /* bsmod */ acmod = get_bits(&bits, 3); if(acmod & 1 && acmod != 1) skip_bits(&bits, 2); /* cmixlev */ if(acmod & 4) skip_bits(&bits, 2); /* surmixlev */ if(acmod & 2) skip_bits(&bits, 2); /* dsurmod */ lfeon = get_bits1(&bits); *sample_rate = ac3_sample_rates[fscod]; *bit_rate = ac3_bitrates[frmsizecod] * 1000; *channels = ac3_channels[acmod] + lfeon; *samples = 6 * 256; return ac3_frame_sizes[frmsizecod][fscod] * 2; } else if (bsid >= 10 && bsid <= 16) { /* Enhanced AC-3 */ strmtyp = get_bits(&bits, 2); substreamid = get_bits(&bits, 3); if (strmtyp != 0 || substreamid != 0) return 0; /* Currently don't support additional streams */ frmsiz = get_bits(&bits, 11) + 1; fscod = get_bits(&bits, 2); if (fscod == 3) { fscod2 = get_bits(&bits, 2); numblkscod = 3; if(fscod2 == 3) return 0; *sample_rate = ac3_sample_rates[fscod2] / 2; } else { numblkscod = get_bits(&bits, 2); *sample_rate = ac3_sample_rates[fscod]; } acmod = get_bits(&bits, 3); lfeon = get_bits1(&bits); *samples = eac3_blocks[numblkscod] * 256; *bit_rate = frmsiz * (*sample_rate) * 16 / (*samples); *channels = ac3_channels[acmod] + lfeon; return frmsiz * 2; } /* Unsupported bitstream version */ return 0;}#endif /* CONFIG_AC3_PARSER */#ifdef CONFIG_AAC_PARSERstatic int aac_sync(const uint8_t *buf, int *channels, int *sample_rate, int *bit_rate, int *samples){ GetBitContext bits; int size, rdb, ch, sr; init_get_bits(&bits, buf, AAC_HEADER_SIZE * 8); if(get_bits(&bits, 12) != 0xfff) return 0; skip_bits1(&bits); /* id */ skip_bits(&bits, 2); /* layer */ skip_bits1(&bits); /* protection_absent */ skip_bits(&bits, 2); /* profile_objecttype */ sr = get_bits(&bits, 4); /* sample_frequency_index */ if(!aac_sample_rates[sr]) return 0; skip_bits1(&bits); /* private_bit */ ch = get_bits(&bits, 3); /* channel_configuration */ if(!aac_channels[ch]) return 0; skip_bits1(&bits); /* original/copy */ skip_bits1(&bits); /* home */ /* adts_variable_header */ skip_bits1(&bits); /* copyright_identification_bit */ skip_bits1(&bits); /* copyright_identification_start */ size = get_bits(&bits, 13); /* aac_frame_length */ skip_bits(&bits, 11); /* adts_buffer_fullness */ rdb = get_bits(&bits, 2); /* number_of_raw_data_blocks_in_frame */ *channels = aac_channels[ch]; *sample_rate = aac_sample_rates[sr]; *samples = (rdb + 1) * 1024; *bit_rate = size * 8 * *sample_rate / *samples; return size;}#endif /* CONFIG_AAC_PARSER */#ifdef CONFIG_AC3_PARSERstatic int ac3_parse_init(AVCodecParserContext *s1){ AC3ParseContext *s = s1->priv_data; s->inbuf_ptr = s->inbuf; s->header_size = AC3_HEADER_SIZE; s->sync = ac3_sync; return 0;}#endif#ifdef CONFIG_AAC_PARSERstatic int aac_parse_init(AVCodecParserContext *s1){ AC3ParseContext *s = s1->priv_data; s->inbuf_ptr = s->inbuf; s->header_size = AAC_HEADER_SIZE; s->sync = aac_sync; return 0;}#endif/* also used for ADTS AAC */static int ac3_parse(AVCodecParserContext *s1, AVCodecContext *avctx, uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size){ AC3ParseContext *s = s1->priv_data; const uint8_t *buf_ptr; int len, sample_rate, bit_rate, channels, samples; *poutbuf = NULL; *poutbuf_size = 0; buf_ptr = buf; while (buf_size > 0) { len = s->inbuf_ptr - s->inbuf; if (s->frame_size == 0) { /* no header seen : find one. We need at least s->header_size bytes to parse it */ len = FFMIN(s->header_size - len, buf_size); memcpy(s->inbuf_ptr, buf_ptr, len); buf_ptr += len; s->inbuf_ptr += len; buf_size -= len; if ((s->inbuf_ptr - s->inbuf) == s->header_size) { len = s->sync(s->inbuf, &channels, &sample_rate, &bit_rate, &samples); if (len == 0) { /* no sync found : move by one byte (inefficient, but simple!) */ memmove(s->inbuf, s->inbuf + 1, s->header_size - 1); s->inbuf_ptr--; } else { s->frame_size = len; /* update codec info */ avctx->sample_rate = sample_rate; /* set channels,except if the user explicitly requests 1 or 2 channels, XXX/FIXME this is a bit ugly */ if(avctx->codec_id == CODEC_ID_AC3){ if(avctx->channels!=1 && avctx->channels!=2){ avctx->channels = channels; } } else { avctx->channels = channels; } avctx->bit_rate = bit_rate; avctx->frame_size = samples; } } } else { len = FFMIN(s->frame_size - len, buf_size); memcpy(s->inbuf_ptr, buf_ptr, len); buf_ptr += len; s->inbuf_ptr += len; buf_size -= len; if(s->inbuf_ptr - s->inbuf == s->frame_size){ *poutbuf = s->inbuf; *poutbuf_size = s->frame_size; s->inbuf_ptr = s->inbuf; s->frame_size = 0; break; } } } return buf_ptr - buf;}#endif /* CONFIG_AC3_PARSER || CONFIG_AAC_PARSER */#ifdef CONFIG_MPEG4VIDEO_PARSERAVCodecParser mpeg4video_parser = { { CODEC_ID_MPEG4 }, sizeof(ParseContext1), mpeg4video_parse_init, mpeg4video_parse, ff_parse1_close, ff_mpeg4video_split,};#endif#ifdef CONFIG_MPEGAUDIO_PARSERAVCodecParser mpegaudio_parser = { { CODEC_ID_MP2, CODEC_ID_MP3 }, sizeof(MpegAudioParseContext), mpegaudio_parse_init, mpegaudio_parse, NULL,};#endif#ifdef CONFIG_AC3_PARSERAVCodecParser ac3_parser = { { CODEC_ID_AC3 }, sizeof(AC3ParseContext), ac3_parse_init, ac3_parse, NULL,};#endif#ifdef CONFIG_AAC_PARSERAVCodecParser aac_parser = { { CODEC_ID_AAC }, sizeof(AC3ParseContext), aac_parse_init, ac3_parse, NULL,};#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -