/** * Initialize the audio resampler based on the input and output codec settings. * If the input and output sample formats differ, a conversion is required * libswresample takes care of this, but requires initialization. */ int AudioDecoder::init_resampler(AVCodecContext *input_codec_context, AVCodecContext *output_codec_context) { int error; /** * Create a resampler context for the conversion. * Set the conversion parameters. * Default channel layouts based on the number of channels * are assumed for simplicity (they are sometimes not detected * properly by the demuxer and/or decoder). */ resample_context = swr_alloc_set_opts(NULL, av_get_default_channel_layout(output_codec_context->channels), output_codec_context->sample_fmt, output_codec_context->sample_rate, av_get_default_channel_layout(input_codec_context->channels), input_codec_context->sample_fmt, input_codec_context->sample_rate, 0, NULL); if (!resample_context) { ELOG_WARN( "Could not allocate resample context\n"); return AVERROR(ENOMEM); } /** * Perform a sanity check so that the number of converted samples is * not greater than the number of samples to be converted. * If the sample rates differ, this case has to be handled differently */ ELOG_DEBUG( "audio input sample_rate = %d, out %d", input_codec_context->sample_rate, output_codec_context->sample_rate); /** Open the resampler with the specified parameters. */ if ((error = swr_init(resample_context)) < 0) { ELOG_WARN( "Could not open resample context"); swr_free(&resample_context); return error; } /** Open the resampler with the specified parameters. */ if ((error = swr_init(resample_context)) < 0) { ELOG_DEBUG( "Could not open resample context"); swr_free(&resample_context); return error; } ELOG_DEBUG( "swr_init done"); return 0; }
void Parser::InitResampler() { swr_ctx = swr_alloc_set_opts(NULL, av_get_default_channel_layout(cdc_ctx_out->channels), cdc_ctx_out->sample_fmt, cdc_ctx_out->sample_rate, channelLayoutIn, (AVSampleFormat)sampleFormatIn, sampleRateIn, 0,0); if(!swr_ctx) throw ContextCreatorException() << errno_code(MIR_ERR_ALLOC_SWR_CONTEXT); // set options av_opt_set_int(swr_ctx, "in_channel_layout", channelLayoutIn, 0); av_opt_set_int(swr_ctx, "in_sample_rate", sampleRateIn, 0); av_opt_set_int(swr_ctx, "in_bit_rate", bitRateIn, 0); av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", (AVSampleFormat)sampleFormatIn, 0); av_opt_set_int(swr_ctx, "out_channel_layout", cdc_ctx_out->channel_layout, 0); av_opt_set_int(swr_ctx, "out_sample_rate", cdc_ctx_out->sample_rate, 0); av_opt_set_int(swr_ctx, "out_bit_rate", cdc_ctx_out->bit_rate, 0); av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", cdc_ctx_out->sample_fmt, 0); if (swr_init(swr_ctx) < 0) throw ContextCreatorException() << errno_code(MIR_ERR_INIT_SWR_CONTEXT); }
static int config_output(AVFilterLink *outlink) { int ret; AVFilterContext *ctx = outlink->src; AVFilterLink *inlink = ctx->inputs[0]; AConvertContext *aconvert = ctx->priv; char buf1[64], buf2[64]; /* if not specified in args, use the format and layout of the output */ if (aconvert->out_sample_fmt == AV_SAMPLE_FMT_NONE) aconvert->out_sample_fmt = outlink->format; if (aconvert->out_chlayout == 0) aconvert->out_chlayout = outlink->channel_layout; aconvert->swr = swr_alloc_set_opts(aconvert->swr, aconvert->out_chlayout, aconvert->out_sample_fmt, inlink->sample_rate, inlink->channel_layout, inlink->format, inlink->sample_rate, 0, ctx); if (!aconvert->swr) return AVERROR(ENOMEM); ret = swr_init(aconvert->swr); if (ret < 0) return ret; av_get_channel_layout_string(buf1, sizeof(buf1), -1, inlink ->channel_layout); av_get_channel_layout_string(buf2, sizeof(buf2), -1, outlink->channel_layout); av_log(ctx, AV_LOG_VERBOSE, "fmt:%s cl:%s -> fmt:%s cl:%s\n", av_get_sample_fmt_name(inlink ->format), buf1, av_get_sample_fmt_name(outlink->format), buf2); return 0; }
void MediaThread::Pcm::save(const AVFrame *frame, double stamp) { stamp_ = stamp; #if 0 memset(buf_, 0, 4096); data_len_ = 4096; #else if (!swr_) { // 总是输出 2, s16, 32000 ... swr_ = swr_alloc_set_opts(0, AV_CH_LAYOUT_STEREO, AV_SAMPLE_FMT_S16, 32000, frame->channel_layout, (AVSampleFormat)frame->format, frame->sample_rate, 0, 0); ch_ = 2; samplerate_ = 32000; bitsize_ = 16; swr_init(swr_); } size_t out_size = frame->nb_samples * 2 * 2; // samples * bytes per sample * channels if (buf_len_ < out_size) { buf_ = (unsigned char*)realloc(buf_, out_size); buf_len_ = out_size; } int samples = swr_convert(swr_, &buf_, frame->nb_samples, (const uint8_t**)frame->extended_data, frame->nb_samples); data_len_ = samples * 2 * 2; // samples * bytes per sample * channels #endif }
EC_U32 AudioWaveScale::Init(MediaCtxInfo* pMediaInfo, AudioPCMBuffer *pFirstFrame) { if (EC_NULL == pMediaInfo) return Audio_Render_Err_InitFail; EC_S32 out_sample_rate = pMediaInfo->m_nSampleRate; EC_S64 out_channel_layout = AV_CH_LAYOUT_STEREO; EC_S32 out_channels = av_get_channel_layout_nb_channels(out_channel_layout); AVSampleFormat out_sample_fmt = AV_SAMPLE_FMT_S16; AVCodecContext *pCodecCtx = (AVCodecContext*)(pMediaInfo->m_pAudioCodecInfo); EC_S64 in_channel_layout = av_get_default_channel_layout(pCodecCtx->channels); EC_S32 in_sample_rate = pCodecCtx->sample_rate; AVSampleFormat in_sample_fmt = pCodecCtx->sample_fmt; m_nOutChannels = out_channels; m_nOutSampleFormat = out_sample_fmt; m_pWaveScaleContext = swr_alloc(); m_pWaveScaleContext = swr_alloc_set_opts(m_pWaveScaleContext, out_channel_layout, out_sample_fmt, out_sample_rate, in_channel_layout, in_sample_fmt, in_sample_rate, 0, NULL); EC_S32 nRet = swr_init(m_pWaveScaleContext); if (nRet < 0) return Audio_Render_Err_InitFail; m_pScaleOutbuffer = (uint8_t *)av_malloc(MAX_AUDIO_FRAME_SIZE * 2); if (m_pScaleOutbuffer == EC_NULL) return EC_Err_Memory_Low; return Audio_Render_Err_None; }
// 函数实现 void* renderopen(void *surface, AVRational frate, int pixfmt, int w, int h, int64_t ch_layout, AVSampleFormat sndfmt, int srate) { WAVEFORMATEX wfx = {0}; RENDER *render = (RENDER*)malloc(sizeof(RENDER)); memset(render, 0, sizeof(RENDER)); render->hRenderWnd = (HWND)surface; // save hwnd // init for audio wfx.cbSize = sizeof(wfx); wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.wBitsPerSample = 16; // 16bit wfx.nSamplesPerSec = 44100; // 44.1k wfx.nChannels = 2; // stereo wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8; wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec; waveOutOpen(&(render->hWaveOut), WAVE_MAPPER, &wfx, (DWORD_PTR)waveOutProc, (DWORD)render, CALLBACK_FUNCTION); waveOutPause(render->hWaveOut); wavqueue_create(&(render->WavQueue), render->hWaveOut, ((int64_t)44100 * 4 * frate.den / frate.num) & ~0x3); /* allocate & init swr context */ render->pSWRContext = swr_alloc_set_opts(NULL, AV_CH_LAYOUT_STEREO, AV_SAMPLE_FMT_S16, 44100, ch_layout, sndfmt, srate, 0, NULL); swr_init(render->pSWRContext); // init for video render->nVideoWidth = w; render->nVideoHeight = h; render->nRenderWidth = GetSystemMetrics(SM_CXSCREEN); render->nRenderHeight= GetSystemMetrics(SM_CYSCREEN); render->nRenderNewW = render->nRenderWidth; render->nRenderNewH = render->nRenderHeight; render->PixelFormat = (PixelFormat)pixfmt; // create sws context render->pSWSContext = sws_getContext( render->nVideoWidth, render->nVideoHeight, render->PixelFormat, render->nRenderWidth, render->nRenderHeight, PIX_FMT_RGB32, SWS_BILINEAR, 0, 0, 0); render->iFrameTick = 1000 * frate.den / frate.num; render->iSleepTick = render->iFrameTick; // create dc & bitmaps render->hRenderDC = GetDC(render->hRenderWnd); render->hBufferDC = CreateCompatibleDC(render->hRenderDC); // create bmp queue bmpqueue_create(&(render->BmpQueue), render->hBufferDC, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), 32); render->nRenderStatus = 0; pthread_create(&(render->hVideoThread), NULL, VideoRenderThreadProc, render); return render; }
/* * ZSL * 虽然名字叫 decode,其实并不解码,只是从 is->sampq 里拿出 af(audioframe,Frame类型) * 把 af->frame(AVFrame类型)里的 data 经过 swr_convert() 之后,存入 is->audio_buf * 返回存入的大小(即 resample 之后的大小) * */ int audio_decode_frame(VideoState *is) { int resampled_data_size,out_size; Frame *af; af = frame_queue_peek_readable(&is->sampq); frame_queue_next(&is->sampq); if (!is->swr_ctx) { is->swr_ctx = swr_alloc_set_opts(NULL, AV_CH_LAYOUT_STEREO, AV_SAMPLE_FMT_S16, is->audio_ctx->sample_rate, av_get_default_channel_layout(is->audio_ctx->channels), is->audio_ctx->sample_fmt, is->audio_ctx->sample_rate, 0, NULL); swr_init(is->swr_ctx); } const uint8_t **in = (const uint8_t **)af->frame->extended_data; uint8_t **out = &is->audio_buf; //out_size = av_samples_get_buffer_size(NULL, 2, af->frame->nb_samples, AV_SAMPLE_FMT_S16, 1); out_size = 2 * 1152 * 2; if (out_size < 0) { /*比如 af->frame->nb_samples==0 的时候,这必须要处理一下,不然一会儿 av_fast_malloc() 就出问题了 */ av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n"); return -1; } int len2; av_fast_malloc(&is->audio_buf, &is->audio_buf_size, out_size); len2 = swr_convert(is->swr_ctx, out, af->frame->nb_samples, in, af->frame->nb_samples); resampled_data_size = len2 * 2 * av_get_bytes_per_sample(AV_SAMPLE_FMT_S16); return resampled_data_size; }
static int opus_init_resample(OpusStreamContext *s) { static const float delay[16] = { 0.0 }; const uint8_t *delayptr[2] = { (uint8_t*)delay, (uint8_t*)delay }; int ret; #if CONFIG_SWRESAMPLE av_opt_set_int(s->swr, "in_sample_rate", s->silk_samplerate, 0); ret = swr_init(s->swr); #elif CONFIG_AVRESAMPLE av_opt_set_int(s->avr, "in_sample_rate", s->silk_samplerate, 0); ret = avresample_open(s->avr); #endif if (ret < 0) { av_log(s->avctx, AV_LOG_ERROR, "Error opening the resampler.\n"); return ret; } #if CONFIG_SWRESAMPLE ret = swr_convert(s->swr, NULL, 0, delayptr, silk_resample_delay[s->packet.bandwidth]); #elif CONFIG_AVRESAMPLE ret = avresample_convert(s->avr, NULL, 0, 0, delayptr, sizeof(delay), silk_resample_delay[s->packet.bandwidth]); #endif if (ret < 0) { av_log(s->avctx, AV_LOG_ERROR, "Error feeding initial silence to the resampler.\n"); return ret; } return 0; }
struct SwrContext * av_swr_alloc(int in_ch,int in_rate,enum AVSampleFormat in_fmt, int out_ch,int out_rate,enum AVSampleFormat out_fmt) { int ret; struct SwrContext * swr = swr_alloc(); if (!swr) { av_log(NULL, AV_LOG_FATAL, "Could not allocate resampler context.\n"); return NULL; } /* set options */ av_opt_set_int(swr, "in_channel_count", in_ch, 0); av_opt_set_int(swr, "in_sample_rate", in_rate, 0); av_opt_set_sample_fmt(swr, "in_sample_fmt", in_fmt, 0); av_opt_set_int(swr, "out_channel_count", out_ch, 0); av_opt_set_int(swr, "out_sample_rate", out_rate, 0); av_opt_set_sample_fmt(swr, "out_sample_fmt", out_fmt, 0); /* initialize the resampling context */ if ((ret = swr_init(swr)) < 0) { av_log(NULL, AV_LOG_FATAL, "Failed to initialize the resampling context\n"); return NULL; } return swr; }
CAudioReader::CAudioReader(CAudioSource *source, AudioTrack *info) { m_Source = source; m_Info = info; m_MediaInfo = info->m_Media; m_DestSampleRate = source->m_SampleRate; m_DestChannels = source->m_Channels; m_DestPacketBytes = source->m_PacketBytes; if (m_MediaInfo->m_IsPlanar) { m_SourceChannels = m_MediaInfo->m_nChannel; m_SourcePacketBytes = av_get_bytes_per_sample((enum AVSampleFormat)m_MediaInfo->m_SampleFormat); } else { m_SourceChannels = 1; m_SourcePacketBytes = m_MediaInfo->m_nChannel * av_get_bytes_per_sample((enum AVSampleFormat)m_MediaInfo->m_SampleFormat); } m_SourceSampleRate = m_MediaInfo->m_SampleRate; for(int i = 0; i < m_SourceChannels; i++) { m_hFiles[i] = CreateFile(m_MediaInfo->m_AudioTmpFile[i], GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); } if ( (m_MediaInfo->m_SampleRate != m_Source->m_SampleRate) || (m_MediaInfo->m_nChannel != m_Source->m_Channels) || (m_MediaInfo->m_SampleFormat != m_Source->m_SampleFormat) || (m_MediaInfo->m_channel_layout != m_Source->m_Layout) ) { swr_context = swr_alloc_set_opts(NULL, m_Source->m_Layout, (AVSampleFormat)source->m_SampleFormat, m_Source->m_SampleRate, m_MediaInfo->m_channel_layout, (AVSampleFormat)m_MediaInfo->m_SampleFormat, m_MediaInfo->m_SampleRate, 0, NULL); swr_init(swr_context); for(int i = 0; i < m_SourceChannels; i++) { m_ReadBuffer[i] = (uint8_t *)MemoryAlloc(m_SourceSampleRate * m_SourcePacketBytes); } for(int i = 0; i < m_DestChannels; i++) { m_ResampleBuffer[i] = (uint8_t *)MemoryAlloc(m_DestSampleRate * m_DestPacketBytes * 2); } } ResetStartStop(); }
// Initialization and runtime control static int control(struct af_instance_s* af, int cmd, void* arg) { af_resample_t* s = (af_resample_t*)af->setup; af_data_t *data= (af_data_t*)arg; int out_rate, test_output_res; // helpers for checking input format switch(cmd){ case AF_CONTROL_REINIT: if((af->data->rate == data->rate) || (af->data->rate == 0)) return AF_DETACH; af->data->nch = data->nch; if (af->data->nch > AF_NCH) af->data->nch = AF_NCH; af->data->format = AF_FORMAT_S16_NE; af->data->bps = 2; af->mul = (double)af->data->rate / data->rate; af->delay = af->data->nch * s->filter_length / FFMIN(af->mul, 1); // *bps*.5 if (s->ctx_out_rate != af->data->rate || s->ctx_in_rate != data->rate || s->ctx_filter_size != s->filter_length || s->ctx_phase_shift != s->phase_shift || s->ctx_linear != s->linear || s->ctx_cutoff != s->cutoff) { swr_free(&s->swrctx); if((s->swrctx=swr_alloc()) == NULL) return AF_ERROR; av_opt_set_int(s->swrctx, "out_sample_rate", af->data->rate, 0); av_opt_set_int(s->swrctx, "in_sample_rate", data->rate, 0); av_opt_set_int(s->swrctx, "filter_size", s->filter_length, 0); av_opt_set_int(s->swrctx, "phase_shift", s->phase_shift, 0); av_opt_set_int(s->swrctx, "linear_interp", s->linear, 0); av_opt_set_double(s->swrctx, "cutoff", s->cutoff, 0); av_opt_set_sample_fmt(s->swrctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0); av_opt_set_sample_fmt(s->swrctx, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0); av_opt_set_int(s->swrctx, "in_channel_count", af->data->nch, 0); av_opt_set_int(s->swrctx, "out_channel_count", af->data->nch, 0); if(swr_init(s->swrctx) < 0) return AF_ERROR; s->ctx_out_rate = af->data->rate; s->ctx_in_rate = data->rate; s->ctx_filter_size = s->filter_length; s->ctx_phase_shift = s->phase_shift; s->ctx_linear = s->linear; s->ctx_cutoff = s->cutoff; } // hack to make af_test_output ignore the samplerate change out_rate = af->data->rate; af->data->rate = data->rate; test_output_res = af_test_output(af, (af_data_t*)arg); af->data->rate = out_rate; return test_output_res; case AF_CONTROL_COMMAND_LINE:{ s->cutoff= 0.0; sscanf((char*)arg,"%d:%d:%d:%d:%lf", &af->data->rate, &s->filter_length, &s->linear, &s->phase_shift, &s->cutoff); if(s->cutoff <= 0.0) s->cutoff= FFMAX(1.0 - 6.5/(s->filter_length+8), 0.80); return AF_OK; } case AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET: af->data->rate = *(int*)arg; return AF_OK; } return AF_UNKNOWN; }
static void audio_convert(dtaudio_decoder_t *decoder, AVFrame * dst, AVFrame * src) { int nb_sample; int dst_buf_size; int out_channels; //for audio post processor //struct SwsContext *m_sws_ctx = NULL; struct SwrContext *m_swr_ctx = NULL; //ResampleContext *m_resample_ctx=NULL; enum AVSampleFormat src_fmt = avctxp->sample_fmt; enum AVSampleFormat dst_fmt = AV_SAMPLE_FMT_S16; dst->linesize[0] = src->linesize[0]; *dst = *src; dst->data[0] = NULL; out_channels = decoder->para.dst_channels; nb_sample = frame->nb_samples; dst_buf_size = nb_sample * av_get_bytes_per_sample(dst_fmt) * out_channels; dst->data[0] = (uint8_t *) av_malloc(dst_buf_size); avcodec_fill_audio_frame(dst, out_channels, dst_fmt, dst->data[0], dst_buf_size, 0); dt_debug(TAG, "SRCFMT:%d dst_fmt:%d \n", src_fmt, dst_fmt); /* resample toAV_SAMPLE_FMT_S16 */ if (src_fmt != dst_fmt || out_channels != decoder->para.channels) { if (!m_swr_ctx) { uint64_t in_channel_layout = av_get_default_channel_layout(avctxp->channels); uint64_t out_channel_layout = av_get_default_channel_layout(out_channels); m_swr_ctx = swr_alloc_set_opts(NULL, out_channel_layout, dst_fmt, avctxp->sample_rate, in_channel_layout, src_fmt, avctxp->sample_rate, 0, NULL); swr_init(m_swr_ctx); } uint8_t **out = (uint8_t **) & dst->data; const uint8_t **in = (const uint8_t **) src->extended_data; if (m_swr_ctx) { int ret, out_count; out_count = nb_sample; ret = swr_convert(m_swr_ctx, out, out_count, in, nb_sample); if (ret < 0) { //set audio mute memset(dst->data[0], 0, dst_buf_size); printf("audio convert failed, set mute data\n"); } } } else { // no need to convert ,just copy memcpy(dst->data[0], src->data[0], src->linesize[0]); } //free context if (m_swr_ctx != NULL) { swr_free(&m_swr_ctx); } //if(m_resample_ctx!=NULL) // audio_resample_close(m_resample_ctx); }
SimpleAT3::SimpleAT3() : codec_(0), codecCtx_(0), swrCtx_(0) { frame_ = av_frame_alloc(); codec_ = avcodec_find_decoder(AV_CODEC_ID_ATRAC3P); if (!codec_) { // Eh, we shouldn't even have managed to compile. But meh. ERROR_LOG(ME, "This version of FFMPEG does not support AV_CODEC_ID_ATRAC3P (Atrac3+). Update your submodule."); return; } codecCtx_ = avcodec_alloc_context3(codec_); if (!codecCtx_) { ERROR_LOG(ME, "Failed to allocate a codec context"); return; } codecCtx_->channels = 2; codecCtx_->channel_layout = AV_CH_LAYOUT_STEREO; AVDictionary *opts = 0; av_dict_set(&opts, "channels", "2", 0); av_dict_set(&opts, "sample_rate", "44100", 0); if (avcodec_open2(codecCtx_, codec_, &opts) < 0) { ERROR_LOG(ME, "Failed to open codec"); return; } av_dict_free(&opts); // Initializing the sample rate convert. We only really use it to convert float output // into int. int wanted_channels = 2; int64_t wanted_channel_layout = av_get_default_channel_layout(wanted_channels); int64_t dec_channel_layout = av_get_default_channel_layout(2); swrCtx_ = swr_alloc_set_opts( swrCtx_, wanted_channel_layout, AV_SAMPLE_FMT_S16, codecCtx_->sample_rate, dec_channel_layout, codecCtx_->sample_fmt, codecCtx_->sample_rate, 0, NULL); if (!swrCtx_ || swr_init(swrCtx_) < 0) { ERROR_LOG(ME, "swr_init: Failed to initialize the resampling context"); avcodec_close(codecCtx_); codec_ = 0; return; } }
void setSampleRate(int sr) { if (swr) { int64_t outSampleRate; av_opt_get_int(swr, "out_sample_rate", 0, &outSampleRate); if (outSampleRate != host.sampleRate) { av_opt_set_int(swr, "out_sample_rate", host.sampleRate, 0); swr_init(swr); JIF(swr_init(swr), "failed to init audio resampler."); } } host.sampleRate = sr; return; err: host.state = CodecBoxDecoderState::Failed; close(); }
static int control(struct af_instance *af, int cmd, void *arg) { struct af_resample *s = af->priv; switch (cmd) { case AF_CONTROL_REINIT: { struct mp_audio *in = arg; struct mp_audio *out = af->data; struct mp_audio orig_in = *in; if (((out->rate == in->rate) || (out->rate == 0)) && (out->format == in->format) && (mp_chmap_equals(&out->channels, &in->channels) || out->nch == 0) && s->allow_detach && s->playback_speed == 1.0) return AF_DETACH; if (out->rate == 0) out->rate = in->rate; if (mp_chmap_is_empty(&out->channels)) mp_audio_set_channels(out, &in->channels); if (af_to_avformat(in->format) == AV_SAMPLE_FMT_NONE) mp_audio_set_format(in, AF_FORMAT_FLOAT); if (check_output_conversion(out->format) == AV_SAMPLE_FMT_NONE) mp_audio_set_format(out, in->format); int r = ((in->format == orig_in.format) && mp_chmap_equals(&in->channels, &orig_in.channels)) ? AF_OK : AF_FALSE; if (r == AF_OK) r = configure_lavrr(af, in, out, true); return r; } case AF_CONTROL_SET_PLAYBACK_SPEED_RESAMPLE: { s->playback_speed = *(double *)arg; return AF_OK; } case AF_CONTROL_RESET: if (s->avrctx) { #if HAVE_LIBSWRESAMPLE swr_close(s->avrctx); if (swr_init(s->avrctx) < 0) { close_lavrr(af); return AF_ERROR; } #else while (avresample_read(s->avrctx, NULL, 1000) > 0) {} #endif } return AF_OK; } return AF_UNKNOWN; }
static void open_audio(AVFormatContext *oc, AVCodec *codec, OutputStream *ost, AVDictionary *opt_arg) { AVCodecContext *c; int nb_samples; int ret; AVDictionary *opt = NULL; c = ost->st->codec; /* open it */ av_dict_copy(&opt, opt_arg, 0); ret = avcodec_open2(c, codec, &opt); av_dict_free(&opt); if (ret < 0) { fprintf(stderr, "Could not open audio codec: %s\n", av_err2str(ret)); exit(1); } /* init signal generator */ ost->t = 0; ost->tincr = 2 * M_PI * 110.0 / c->sample_rate; /* increment frequency by 110 Hz per second */ ost->tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate; if (c->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE) nb_samples = 10000; else nb_samples = c->frame_size; ost->frame = alloc_audio_frame(c->sample_fmt, c->channel_layout, c->sample_rate, nb_samples); ost->tmp_frame = alloc_audio_frame(AV_SAMPLE_FMT_S16, c->channel_layout, c->sample_rate, nb_samples); /* create resampler context */ ost->swr_ctx = swr_alloc(); if (!ost->swr_ctx) { fprintf(stderr, "Could not allocate resampler context\n"); exit(1); } /* set options */ av_opt_set_int (ost->swr_ctx, "in_channel_count", c->channels, 0); av_opt_set_int (ost->swr_ctx, "in_sample_rate", c->sample_rate, 0); av_opt_set_sample_fmt(ost->swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0); av_opt_set_int (ost->swr_ctx, "out_channel_count", c->channels, 0); av_opt_set_int (ost->swr_ctx, "out_sample_rate", c->sample_rate, 0); av_opt_set_sample_fmt(ost->swr_ctx, "out_sample_fmt", c->sample_fmt, 0); /* initialize the resampling context */ if ((ret = swr_init(ost->swr_ctx)) < 0) { fprintf(stderr, "Failed to initialize the resampling context\n"); exit(1); } }
bool FFMPEGer::open_audio(AVCodec *codec, OutputStream *ost, AVDictionary *opt_arg){ AVCodecContext *c; int nb_samples; int ret; AVDictionary *opt = NULL; c = ost->st->codec; /* open it */ av_dict_copy(&opt, opt_arg, 0); ret = avcodec_open2(c, codec, &opt); av_dict_free(&opt); if (ret < 0) { ALOGE("Could not open audio codec: %s", av_err2str(ret)); return false; } if (c->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE) nb_samples = 10000; else nb_samples = c->frame_size; ost->frame = alloc_audio_frame(c->sample_fmt, c->channel_layout, c->sample_rate, nb_samples); ost->tmp_frame = alloc_audio_frame(AV_SAMPLE_FMT_S16, c->channel_layout, c->sample_rate, nb_samples); /* create resampler context */ ost->swr_ctx = swr_alloc(); if (!ost->swr_ctx) { ALOGE("Could not allocate resampler context"); return false; } /* set options */ av_opt_set_int (ost->swr_ctx, "in_channel_count", c->channels, 0); av_opt_set_int (ost->swr_ctx, "in_sample_rate", c->sample_rate, 0); av_opt_set_sample_fmt(ost->swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0); av_opt_set_int (ost->swr_ctx, "out_channel_count", c->channels, 0); av_opt_set_int (ost->swr_ctx, "out_sample_rate", c->sample_rate, 0); av_opt_set_sample_fmt(ost->swr_ctx, "out_sample_fmt", c->sample_fmt, 0); /* initialize the resampling context */ ret = swr_init(ost->swr_ctx); if (ret < 0){ ALOGE("Failed to initialize the resampling context"); return false; } return true; }
kxMovieError openAudioStream(size_t audioStream) { AVCodecContext *codecCtx = _formatCtx->streams[audioStream]->codec; SwrContext *swrContext = NULL; AVCodec *codec = avcodec_find_decoder(codecCtx->codec_id); if(!codec) return kxMovieErrorCodecNotFound; if (avcodec_open2(codecCtx, codec, NULL) < 0) return kxMovieErrorOpenCodec; if (!audioCodecIsSupported(codecCtx)) { swrContext = swr_alloc_set_opts(NULL, av_get_default_channel_layout(codecCtx->channels), AV_SAMPLE_FMT_S16, codecCtx->sample_rate, av_get_default_channel_layout(codecCtx->channels), codecCtx->sample_fmt, codecCtx->sample_rate, 0, NULL); if (!swrContext || swr_init(swrContext)) { if (swrContext) swr_free(&swrContext); avcodec_close(codecCtx); return kxMovieErroReSampler; } } _audioFrame = av_frame_alloc(); if (!_audioFrame) { if (swrContext) swr_free(&swrContext); avcodec_close(codecCtx); return kxMovieErrorAllocateFrame; } _audioStream = audioStream; _audioCodecCtx = codecCtx; _swrContext = swrContext; return kxMovieErrorNone; }
int AudioResampling(AVCodecContext * audio_dec_ctx, AVFrame * pAudioDecodeFrame, enum AVSampleFormat out_sample_fmt, int out_channels, int out_sample_rate, uint8_t* out_buf) { struct SwrContext * swr_ctx = 0; swr_ctx = swr_alloc_set_opts(swr_ctx,audio_dec_ctx->channel_layout,out_sample_fmt,out_sample_rate, audio_dec_ctx->channel_layout,audio_dec_ctx->sample_fmt,audio_dec_ctx->sample_rate,0,0); int ret = 0; int dst_linesize = 0; int resampled_data_size = av_samples_get_buffer_size(&dst_linesize, out_channels,audio_dec_ctx->frame_size,audio_dec_ctx->sample_fmt, 1); uint8_t *dst_data = (uint8_t*)av_malloc(resampled_data_size); if ((ret = swr_init(swr_ctx)) < 0) { printf("Failed to initialize the resampling context\n"); return -1; } if (swr_ctx){ ret = swr_convert(swr_ctx, &dst_data, dst_linesize, (const uint8_t **)pAudioDecodeFrame->data, pAudioDecodeFrame->nb_samples); resampled_data_size = av_samples_get_buffer_size(&dst_linesize,out_channels,ret,out_sample_fmt,1); if (ret < 0) { printf("swr_convert error \n"); return -1; } if (resampled_data_size < 0) { printf("av_samples_get_buffer_size error \n"); return -1; } } else{ printf("swr_ctx null error \n"); return -1; } memcpy(out_buf, dst_data, resampled_data_size); if (dst_data) { av_free(dst_data); } if (swr_ctx) { swr_free(&swr_ctx); } return resampled_data_size; }
static void OpenAudio(AVFormatContext *oc, AVCodec *codec, OutputStream *ost, AVDictionary *opt_arg, int sample_rate) { AVCodecContext *c = NULL; int nb_samples = 0; int ret = 0; AVDictionary *opt = NULL; c = ost->st->codec; // コーデックを初期化 av_dict_copy(&opt, opt_arg, 0); ret = avcodec_open2(c, codec, &opt); av_dict_free(&opt); if (ret < 0) { fprintf(stderr, "Could not open audio codec: %s\n", MakeErrorString(ret)); return; } if (c->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE) nb_samples = 10000; else nb_samples = c->frame_size; ost->frame = AllocAudioFrame(c->sample_fmt, c->channel_layout, c->sample_rate, nb_samples); ost->tmp_frame = AllocAudioFrame(AV_SAMPLE_FMT_S16, c->channel_layout, sample_rate, nb_samples/(c->sample_rate/sample_rate)); // サンプル変換部 ost->swr_ctx = swr_alloc(); if (!ost->swr_ctx) { fprintf(stderr, "Could not allocate resampler context\n"); return; } // 音声フォーマットの設定 av_opt_set_int (ost->swr_ctx, "in_channel_count", c->channels, 0); av_opt_set_int (ost->swr_ctx, "in_sample_rate", sample_rate, 0); av_opt_set_sample_fmt(ost->swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0); av_opt_set_int (ost->swr_ctx, "out_channel_count", c->channels, 0); av_opt_set_int (ost->swr_ctx, "out_sample_rate", c->sample_rate, 0); av_opt_set_sample_fmt(ost->swr_ctx, "out_sample_fmt", c->sample_fmt, 0); // サンプル変換部を初期化 if ((ret = swr_init(ost->swr_ctx)) < 0) { fprintf(stderr, "Failed to initialize the resampling context\n"); return; } }
void render_audio(void *hrender, AVFrame *audio) { RENDER *render = (RENDER*)hrender; int sampnum = 0; DWORD apts = (DWORD)audio->pts; if (!render->adev) return; do { if (render->nAdevBufAvail == 0) { adev_request(render->adev, &render->pAdevHdrCur); apts += render->nFramePeriod * render->nRenderSpeedCur / 100; render->nAdevBufAvail = (int )render->pAdevHdrCur->size; render->pAdevBufCur = (BYTE*)render->pAdevHdrCur->data; } if (render->nRenderSpeedCur != render->nRenderSpeedNew) { render->nRenderSpeedCur = render->nRenderSpeedNew; // set vdev frame rate int framerate = (render->FrameRate.num * render->nRenderSpeedCur) / (render->FrameRate.den * 100); vdev_setfrate(render->vdev, framerate > 1 ? framerate : 1); //++ allocate & init swr context if (render->pSWRContext) { swr_free(&render->pSWRContext); } int samprate = 44100 * 100 / render->nRenderSpeedCur; render->pSWRContext = swr_alloc_set_opts(NULL, AV_CH_LAYOUT_STEREO, AV_SAMPLE_FMT_S16, samprate, render->nChanLayout, render->SampleFormat, render->nSampleRate, 0, NULL); swr_init(render->pSWRContext); //-- allocate & init swr context } //++ do resample audio data ++// sampnum = swr_convert(render->pSWRContext, (uint8_t**)&render->pAdevBufCur, render->nAdevBufAvail / 4, (const uint8_t**)audio->extended_data, audio->nb_samples); audio->extended_data = NULL; audio->nb_samples = 0; render->nAdevBufAvail -= sampnum * 4; render->pAdevBufCur += sampnum * 4; //-- do resample audio data --// if (render->nAdevBufAvail == 0) { adev_post(render->adev, apts); } } while (sampnum > 0); }
Swr::Swr(std::int64_t out_ch_layout, AVSampleFormat out_sample_fmt, int out_sample_rate, std::int64_t in_ch_layout, AVSampleFormat in_sample_fmt, int in_sample_rate, int log_offset, void* log_ctx) { this->context = swr_alloc_set_opts(nullptr, out_ch_layout, out_sample_fmt, out_sample_rate, in_ch_layout, in_sample_fmt, in_sample_rate, log_offset, log_ctx); if (this->context == nullptr) { throw std::bad_alloc(); } assert(this->context != nullptr); swr_init(this->context); }
int ffmpeg_open_codec(struct ffmpeg_file *file) { AVStream *s = file->format->streams[file->stream]; AVCodec *decoder = avcodec_find_decoder(s->codec->codec_id); if (avcodec_open2(s->codec, decoder, NULL) < 0) { return -1; } file->codec = s->codec; file->pkt = av_malloc(sizeof(AVPacket)); av_init_packet(file->pkt); av_packet_unref(file->pkt); file->time = 0; file->frame = av_frame_alloc(); if (!file->frame) { return -1; } file->swr = swr_alloc(); if (!file->swr) { return -1; } av_opt_set_int(file->swr, "in_channel_count", file->codec->channels, 0); av_opt_set_int(file->swr, "out_channel_count", file->channels, 0); av_opt_set_int(file->swr, "in_channel_layout", file->codec->channel_layout, 0); av_opt_set_int(file->swr, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0); av_opt_set_int(file->swr, "in_sample_rate", file->codec->sample_rate, 0); av_opt_set_int(file->swr, "out_sample_rate", file->sample_rate, 0); av_opt_set_sample_fmt(file->swr, "in_sample_fmt", file->codec->sample_fmt, 0); av_opt_set_sample_fmt(file->swr, "out_sample_fmt", file->sample_fmt, 0); swr_init(file->swr); if (!swr_is_initialized(file->swr)) { return -1; } return 0; }
BOOL CVideoLivRecord::open_audio(AVStream *st, AVCodec* codec, AVDictionary* opt) { AVCodecContext * avcc = st->codec; int nb_samples; int ret; AVDictionary* opt_dst = NULL;//必须初始化为空。 av_dict_copy(&opt_dst, opt, 0); ret = avcodec_open2(avcc, codec, &opt_dst); av_dict_free(&opt_dst); if (ret < 0){ log("[CVideoLivRecord::open_audio] -- avcodec_open2() error"); return FALSE; } m_t = 0; m_tincr = 2 * M_PI * 110.0 / avcc->sample_rate; m_tincr2 = 2 * M_PI * 110.0 / avcc->sample_rate / avcc->sample_rate; if (avcc->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE){ nb_samples = 10000; } else { nb_samples = avcc->frame_size; } m_pAudioFrame = alloc_audio_frame(avcc->sample_fmt, avcc->channel_layout, avcc->sample_rate, nb_samples); m_pAudioBkFrame = alloc_audio_frame(AV_SAMPLE_FMT_S16, avcc->channel_layout, avcc->sample_rate, nb_samples); m_pAudioSwrctx = swr_alloc(); if (!m_pAudioSwrctx){ log("[CVideoLivRecord::open_audio] -- swr_alloc() error"); return FALSE; } av_opt_set_int (m_pAudioSwrctx, "in_channel_count", avcc->channels, 0); av_opt_set_int (m_pAudioSwrctx, "in_sample_rate", avcc->sample_rate, 0); av_opt_set_sample_fmt(m_pAudioSwrctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0); av_opt_set_int (m_pAudioSwrctx, "out_channel_count", avcc->channels, 0); av_opt_set_int (m_pAudioSwrctx, "out_sample_rate", avcc->sample_rate, 0); av_opt_set_sample_fmt(m_pAudioSwrctx, "out_sample_fmt", avcc->sample_fmt, 0); if (swr_init(m_pAudioSwrctx) < 0){ log("[CVideoLivRecord::open_audio] -- swr_init() error"); return FALSE; } return TRUE; }
int frame_puller_open_audio(frame_puller **o_fp, const char *path, int output_sample_rate) { *o_fp = NULL; int ret; frame_puller *fp; if ((ret = _frame_puller_new(&fp, path)) < 0) return ret; fp->type = FRAME_PULLER_AUDIO; if ((ret = _frame_puller_init(fp, AVMEDIA_TYPE_AUDIO)) < 0) return ret; fp->output_sample_rate = output_sample_rate > 0 ? output_sample_rate : fp->codec_ctx->sample_rate; fp->sample_scale_rate = (double)fp->output_sample_rate / (double)fp->codec_ctx->sample_rate; // Initialize the libswresample context for audio resampling. // > Create the buffer for the converted frame to store data fp->frame = av_frame_alloc(); fp->frame->format = AV_SAMPLE_FMT_S16P; fp->frame->channel_layout = fp->codec_ctx->channel_layout; fp->frame->sample_rate = fp->output_sample_rate; if ((fp->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE) || !strcmp(fp->codec->name, "pcm_mulaw")) fp->frame->nb_samples = 4096; else fp->frame->nb_samples = fp->sample_scale_rate * fp->codec_ctx->frame_size; av_log(NULL, AV_LOG_INFO, "frame_puller: number of samples per frame = %d\n", fp->frame->nb_samples); if ((ret = av_frame_get_buffer(fp->frame, 0)) < 0) return ret; // > Create the SwrContext fp->libsw.swr_ctx = swr_alloc(); if (!fp->libsw.swr_ctx) { av_log(NULL, AV_LOG_ERROR, "frame_puller: Cannot initialize audio resampling library" "(possibly caused by insufficient memory)\n"); return AVERROR_UNKNOWN; } // > Provide options for the SwrContext av_opt_set_channel_layout(fp->libsw.swr_ctx, "in_channel_layout", fp->codec_ctx->channel_layout, 0); av_opt_set_channel_layout(fp->libsw.swr_ctx, "out_channel_layout", fp->codec_ctx->channel_layout, 0); av_opt_set_int(fp->libsw.swr_ctx, "in_sample_rate", fp->codec_ctx->sample_rate, 0); av_opt_set_int(fp->libsw.swr_ctx, "out_sample_rate", fp->output_sample_rate, 0); av_opt_set_sample_fmt(fp->libsw.swr_ctx, "in_sample_fmt", fp->codec_ctx->sample_fmt, 0); av_opt_set_sample_fmt(fp->libsw.swr_ctx, "out_sample_fmt", AV_SAMPLE_FMT_S16P, 0); // > Fully initialize the SwrContext if ((ret = swr_init(fp->libsw.swr_ctx)) < 0) return ret; // For use in @ref frame_puller_last_time. fp->frame->pts = -233333; *o_fp = fp; return 0; }
void init_swr(){ uint64_t out_channel_layout=AV_CH_LAYOUT_STEREO; //nb_samples: AAC-1024 MP3-1152 out_sample_rate=pCodecCtx->sample_rate; out_channels=av_get_channel_layout_nb_channels(out_channel_layout); out_buffer=(uint8_t *)av_malloc(MAX_AUDIO_FRAME_SIZE*out_channels); //FIX:Some Codec's Context Information is missing int in_channel_layout=av_get_default_channel_layout(pCodecCtx->channels); //Swr au_convert_ctx = swr_alloc(); swr_alloc_set_opts(au_convert_ctx,out_channel_layout, out_sample_fmt, out_sample_rate, in_channel_layout, pCodecCtx->sample_fmt , pCodecCtx->sample_rate,0, NULL); if(swr_init(au_convert_ctx)<0){ au_convert_ctx=NULL; } createBufferQueueAudioPlayer(2,out_sample_rate); }
void AudioResampleImpl::initResampler() { m_resampler.reset(swr_alloc(), [](SwrContext * context){ swr_free(&context); }); assert(m_from.isValid()); assert(m_to.isValid()); av_opt_set_int(m_resampler.get(), "in_channel_layout", av_get_default_channel_layout(m_from.channelCount()), 0); /// @todo Дополнить раскладкой AudioFormat av_opt_set_int(m_resampler.get(), "out_channel_layout", av_get_default_channel_layout(m_to.channelCount()), 0); av_opt_set_int(m_resampler.get(), "in_sample_rate", m_from.sampleRate(), 0); av_opt_set_int(m_resampler.get(), "out_sample_rate", m_to.sampleRate(), 0); av_opt_set_sample_fmt(m_resampler.get(), "in_sample_fmt", m_from.sampleFormat(), 0); av_opt_set_sample_fmt(m_resampler.get(), "out_sample_fmt", m_to.sampleFormat(), 0); /// Non planar int res = swr_init(m_resampler.get()); if (res != 0) throw FFException(res); }
void ensureAudioPostProcess() { if (host.state < CodecBoxDecoderState::Metadata) return; if (swr) return; swr = swr_alloc(); JIF(!swr, "failed to alloc audio resampler."); av_opt_set_channel_layout(swr, "in_channel_layout", audioCodecContext->channel_layout, 0); av_opt_set_channel_layout(swr, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0); av_opt_set_int(swr, "in_sample_rate", audioCodecContext->sample_rate, 0); av_opt_set_int(swr, "out_sample_rate", host.sampleRate, 0); av_opt_set_sample_fmt(swr, "in_sample_fmt", audioCodecContext->sample_fmt, 0); av_opt_set_sample_fmt(swr, "out_sample_fmt", AV_SAMPLE_FMT_FLT, 0); JIF(swr_init(swr), "failed to init audio resampler."); return; err: host.state = CodecBoxDecoderState::Failed; close(); }
void AudioDec::set_audio_spec(AVCodecContext* pCodecCtx) { /* 오디오 출력을 위한 구조체 설정 파트 */ /* sample rate */ wfx.nSamplesPerSec = pCodecCtx->sample_rate; /* number of bits per sample of mono data */ switch (pCodecCtx->sample_fmt) { case AV_SAMPLE_FMT_U8: wfx.wBitsPerSample = 8; break; case AV_SAMPLE_FMT_S16: wfx.wBitsPerSample = 16; break; case AV_SAMPLE_FMT_S32: wfx.wBitsPerSample = 32; break; case AV_SAMPLE_FMT_FLT: wfx.wBitsPerSample = sizeof(double)* 8; break; case AV_SAMPLE_FMT_FLTP: wfx.wBitsPerSample = 16; break; default: wfx.wBitsPerSample = 0; break; } wfx.wBitsPerSample = 16; wfx.nChannels = FFMIN(2, pCodecCtx->channels); /* the count in bytes of the size of extra information (after cbSize) */ wfx.cbSize = 0; wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.nBlockAlign = (wfx.wBitsPerSample * wfx.nChannels) / 8; wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec; MMRESULT result = waveOutOpen(&hWaveOut, WAVE_MAPPER, &wfx, (DWORD)audio_callback_func_static, (DWORD)&waveFreeBlockCount, CALLBACK_FUNCTION); if (result != MMSYSERR_NOERROR) { // 오디오 출력장치를 열지 못했다... TRACE("err waveOutOpen \n"); return; } pSwrContext = swr_alloc_set_opts( NULL, AV_CH_LAYOUT_STEREO, AV_SAMPLE_FMT_S16, pCodecCtx->sample_rate, wfx.nChannels, pCodecCtx->sample_fmt, pCodecCtx->sample_rate, 0, NULL); swr_init(pSwrContext); }
int swr_set_compensation(struct SwrContext *s, int sample_delta, int compensation_distance){ int ret; if (!s || compensation_distance < 0) return AVERROR(EINVAL); if (!compensation_distance && sample_delta) return AVERROR(EINVAL); if (!s->resample) { s->flags |= SWR_FLAG_RESAMPLE; ret = swr_init(s); if (ret < 0) return ret; } if (!s->resampler->set_compensation){ return AVERROR(EINVAL); }else{ return s->resampler->set_compensation(s->resample, sample_delta, compensation_distance); } }