static int ac3_eac3_probe(AVProbeData *p, enum CodecID expected_codec_id) { int max_frames, first_frames = 0, frames; uint8_t *buf, *buf2, *end; AC3HeaderInfo hdr; GetBitContext gbc; enum CodecID codec_id = CODEC_ID_AC3; max_frames = 0; buf = p->buf; end = buf + p->buf_size; for(; buf < end; buf++) { buf2 = buf; for(frames = 0; buf2 < end; frames++) { if(!memcmp(buf2, "\x1\x10\0\0\0\0\0\0", 8)) buf2+=16; init_get_bits(&gbc, buf2, 54); if(avpriv_ac3_parse_header(&gbc, &hdr) < 0) break; if(buf2 + hdr.frame_size > end || av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, buf2 + 2, hdr.frame_size - 2)) break; if (hdr.bitstream_id > 10) codec_id = CODEC_ID_EAC3; buf2 += hdr.frame_size; } max_frames = FFMAX(max_frames, frames); if(buf == p->buf) first_frames = frames; } if(codec_id != expected_codec_id) return 0; // keep this in sync with mp3 probe, both need to avoid // issues with MPEG-files! if (first_frames>=4) return AVPROBE_SCORE_MAX/2+1; else if(max_frames>200)return AVPROBE_SCORE_MAX/2; else if(max_frames>=4) return AVPROBE_SCORE_MAX/4; else if(max_frames>=1) return 1; else return 0; }
static int ac3_eac3_probe(AVProbeData *p, enum AVCodecID expected_codec_id) { int max_frames, first_frames = 0, frames; uint8_t *buf, *buf2, *end; AC3HeaderInfo hdr; GetBitContext gbc; enum AVCodecID codec_id = AV_CODEC_ID_AC3; max_frames = 0; buf = p->buf; end = buf + p->buf_size; for(; buf < end; buf++) { if(buf > p->buf && !(buf[0] == 0x0B && buf[1] == 0x77) && !(buf[0] == 0x77 && buf[1] == 0x0B) ) continue; buf2 = buf; for(frames = 0; buf2 < end; frames++) { uint8_t buf3[4096]; int i; if(!memcmp(buf2, "\x1\x10\0\0\0\0\0\0", 8)) buf2+=16; if (buf[0] == 0x77 && buf[1] == 0x0B) { for(i=0; i<8; i+=2) { buf3[i ] = buf[i+1]; buf3[i+1] = buf[i ]; } init_get_bits(&gbc, buf3, 54); }else init_get_bits(&gbc, buf2, 54); if(avpriv_ac3_parse_header(&gbc, &hdr) < 0) break; if(buf2 + hdr.frame_size > end) break; if (buf[0] == 0x77 && buf[1] == 0x0B) { av_assert0(hdr.frame_size <= sizeof(buf3)); for(i=8; i<hdr.frame_size; i+=2) { buf3[i ] = buf[i+1]; buf3[i+1] = buf[i ]; } } if(av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, gbc.buffer + 2, hdr.frame_size - 2)) break; if (hdr.bitstream_id > 10) codec_id = AV_CODEC_ID_EAC3; buf2 += hdr.frame_size; } max_frames = FFMAX(max_frames, frames); if(buf == p->buf) first_frames = frames; } if(codec_id != expected_codec_id) return 0; // keep this in sync with mp3 probe, both need to avoid // issues with MPEG-files! if (first_frames>=4) return AVPROBE_SCORE_MAX/2+1; else if(max_frames>200)return AVPROBE_SCORE_MAX/2; else if(max_frames>=4) return AVPROBE_SCORE_MAX/4; else if(max_frames>=1) return 1; else return 0; }
static av_cold int ffat_create_decoder(AVCodecContext *avctx, AVPacket *pkt) { ATDecodeContext *at = avctx->priv_data; OSStatus status; int i; enum AVSampleFormat sample_fmt = (avctx->bits_per_raw_sample == 32) ? AV_SAMPLE_FMT_S32 : AV_SAMPLE_FMT_S16; AudioStreamBasicDescription in_format = { .mFormatID = ffat_get_format_id(avctx->codec_id, avctx->profile), .mBytesPerPacket = (avctx->codec_id == AV_CODEC_ID_ILBC) ? avctx->block_align : 0, }; AudioStreamBasicDescription out_format = { .mFormatID = kAudioFormatLinearPCM, .mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked, .mFramesPerPacket = 1, .mBitsPerChannel = av_get_bytes_per_sample(sample_fmt) * 8, }; avctx->sample_fmt = sample_fmt; if (ffat_usable_extradata(avctx)) { UInt32 format_size = sizeof(in_format); UInt32 cookie_size; uint8_t *cookie = ffat_get_magic_cookie(avctx, &cookie_size); if (!cookie) return AVERROR(ENOMEM); status = AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, cookie_size, cookie, &format_size, &in_format); if (cookie != at->extradata) av_free(cookie); if (status != 0) { av_log(avctx, AV_LOG_ERROR, "AudioToolbox header-parse error: %i\n", (int)status); return AVERROR_UNKNOWN; } #if CONFIG_MP1_AT_DECODER || CONFIG_MP2_AT_DECODER || CONFIG_MP3_AT_DECODER } else if (pkt && pkt->size >= 4 && (avctx->codec_id == AV_CODEC_ID_MP1 || avctx->codec_id == AV_CODEC_ID_MP2 || avctx->codec_id == AV_CODEC_ID_MP3)) { enum AVCodecID codec_id; int bit_rate; if (ff_mpa_decode_header(AV_RB32(pkt->data), &avctx->sample_rate, &in_format.mChannelsPerFrame, &avctx->frame_size, &bit_rate, &codec_id) < 0) return AVERROR_INVALIDDATA; avctx->bit_rate = bit_rate; in_format.mSampleRate = avctx->sample_rate; #endif #if CONFIG_AC3_AT_DECODER || CONFIG_EAC3_AT_DECODER } else if (pkt && pkt->size >= 7 && (avctx->codec_id == AV_CODEC_ID_AC3 || avctx->codec_id == AV_CODEC_ID_EAC3)) { AC3HeaderInfo hdr, *phdr = &hdr; GetBitContext gbc; init_get_bits(&gbc, pkt->data, pkt->size); if (avpriv_ac3_parse_header(&gbc, &phdr) < 0) return AVERROR_INVALIDDATA; in_format.mSampleRate = hdr.sample_rate; in_format.mChannelsPerFrame = hdr.channels; avctx->frame_size = hdr.num_blocks * 256; avctx->bit_rate = hdr.bit_rate; #endif } else { in_format.mSampleRate = avctx->sample_rate ? avctx->sample_rate : 44100; in_format.mChannelsPerFrame = avctx->channels ? avctx->channels : 1; } avctx->sample_rate = out_format.mSampleRate = in_format.mSampleRate; avctx->channels = out_format.mChannelsPerFrame = in_format.mChannelsPerFrame; if (avctx->codec_id == AV_CODEC_ID_ADPCM_IMA_QT) in_format.mFramesPerPacket = 64; status = AudioConverterNew(&in_format, &out_format, &at->converter); if (status != 0) { av_log(avctx, AV_LOG_ERROR, "AudioToolbox init error: %i\n", (int)status); return AVERROR_UNKNOWN; } if ((status = ffat_set_extradata(avctx)) < 0) return status; for (i = 0; i < (sizeof(at->channel_map) / sizeof(at->channel_map[0])); i++) at->channel_map[i] = i; ffat_update_ctx(avctx); if(!(at->decoded_data = av_malloc(av_get_bytes_per_sample(avctx->sample_fmt) * avctx->frame_size * avctx->channels))) return AVERROR(ENOMEM); at->last_pts = AV_NOPTS_VALUE; return 0; } static av_cold int ffat_init_decoder(AVCodecContext *avctx) { ATDecodeContext *at = avctx->priv_data; at->extradata = avctx->extradata; at->extradata_size = avctx->extradata_size; if ((avctx->channels && avctx->sample_rate) || ffat_usable_extradata(avctx)) return ffat_create_decoder(avctx, NULL); else return 0; } static OSStatus ffat_decode_callback(AudioConverterRef converter, UInt32 *nb_packets, AudioBufferList *data, AudioStreamPacketDescription **packets, void *inctx) { AVCodecContext *avctx = inctx; ATDecodeContext *at = avctx->priv_data; if (at->eof) { *nb_packets = 0; if (packets) { *packets = &at->pkt_desc; at->pkt_desc.mDataByteSize = 0; } return 0; } av_packet_unref(&at->in_pkt); av_packet_move_ref(&at->in_pkt, &at->new_in_pkt); if (!at->in_pkt.data) { *nb_packets = 0; return 1; } data->mNumberBuffers = 1; data->mBuffers[0].mNumberChannels = 0; data->mBuffers[0].mDataByteSize = at->in_pkt.size; data->mBuffers[0].mData = at->in_pkt.data; *nb_packets = 1; if (packets) { *packets = &at->pkt_desc; at->pkt_desc.mDataByteSize = at->in_pkt.size; } return 0; }