Exemple #1
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);
}
Exemple #2
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;
}
Exemple #3
0
// 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;
}
Exemple #4
0
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);
    }
}
Exemple #5
0
	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;
	}
Exemple #6
0
value
ffmpeg_stream_new_audio(value ctx, value audio_info_)
{
  CAMLparam2(ctx, audio_info_);
  CAMLlocal1(stream);
  AVCodec* codec = avcodec_find_encoder(AV_CODEC_ID_AAC);
  stream = caml_alloc_tuple(StreamSize);
  int ret;

  Stream_aux_direct_val(stream) = caml_alloc_custom(&streamaux_ops, sizeof(struct StreamAux), 0, 1);
  Stream_aux_val(stream)->type = Val_int(STREAM_AUDIO);
  Stream_context_direct_val(stream) = ctx;
  Stream_aux_val(stream)->avstream = avformat_new_stream(Context_val(ctx)->fmtCtx, codec);

  Stream_aux_val(stream)->avstream->codec->codec_id    = AV_CODEC_ID_AAC;
  Stream_aux_val(stream)->avstream->codec->sample_rate = Int_val(Field(audio_info_, 0));
  Stream_aux_val(stream)->avstream->codec->channels    = Int_val(Field(audio_info_, 1));
  Stream_aux_val(stream)->avstream->codec->sample_fmt  = codec->sample_fmts ? codec->sample_fmts[0] : AV_SAMPLE_FMT_FLTP;
  Stream_aux_val(stream)->avstream->codec->channel_layout = AV_CH_LAYOUT_STEREO;
  //Stream_aux_val(stream)->avstream->codec->channels    = av_get_channel_layout_nb_channels(Stream_aux_val(stream)->avstream->codec->channel_layout);

  if (Context_val(ctx)->fmtCtx->oformat->flags & AVFMT_GLOBALHEADER) {
    Stream_aux_val(stream)->avstream->codec->flags   |= AV_CODEC_FLAG_GLOBAL_HEADER;
  }

  Stream_aux_val(stream)->avstream->time_base = (AVRational) {1, 10000};

  AVDictionary* codecOpts = NULL;
  AVCodecContext* codecCtx = Stream_aux_val(stream)->avstream->codec;

  caml_enter_blocking_section();
  ret = avcodec_open2(codecCtx, codec, &codecOpts);
  raise_and_leave_blocking_section_if_not(ret >= 0, ExnOpen, ret);
  caml_leave_blocking_section();

  if (Stream_aux_val(stream)->avstream->codec->sample_fmt != AV_SAMPLE_FMT_S16) {
    Stream_aux_val(stream)->swrCtx = swr_alloc();
    assert(Stream_aux_val(stream)->swrCtx);

    av_opt_set_int       (Stream_aux_val(stream)->swrCtx, "in_channel_count",   Stream_aux_val(stream)->avstream->codec->channels, 0);
    av_opt_set_int       (Stream_aux_val(stream)->swrCtx, "in_sample_rate",     Stream_aux_val(stream)->avstream->codec->sample_rate, 0);
    av_opt_set_sample_fmt(Stream_aux_val(stream)->swrCtx, "in_sample_fmt",      AV_SAMPLE_FMT_S16, 0);
    av_opt_set_int       (Stream_aux_val(stream)->swrCtx, "out_channel_count",  Stream_aux_val(stream)->avstream->codec->channels, 0);
    av_opt_set_int       (Stream_aux_val(stream)->swrCtx, "out_sample_rate",    Stream_aux_val(stream)->avstream->codec->sample_rate, 0);
    av_opt_set_sample_fmt(Stream_aux_val(stream)->swrCtx, "out_sample_fmt",     Stream_aux_val(stream)->avstream->codec->sample_fmt, 0);
  }
  

  CAMLreturn((value) stream);
}
Exemple #7
0
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;
	}
}
Exemple #8
0
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;
}
Exemple #9
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;
}
Exemple #10
0
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;
}
Exemple #11
0
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();
 }
Exemple #13
0
int AudioResampler::InitAudioResampling(IN const std::shared_ptr<MediaFrame>& _pFrame)
{
    // for fdkaac encoder, input samples should be PCM signed16le, otherwise do resampling
    if (_pFrame->AvFrame()->format != sampleFormat) {
#ifdef LOG_TRADITIONAL
        loginfo("input sample_format=%d, need sample_format=%d, initiate resampling",
#else
        loginfo("input sample_format={} need sample_format={}, initiate resampling",
#endif
            _pFrame->AvFrame()->format, sampleFormat);
        pSwr_ = swr_alloc();
        av_opt_set_int(pSwr_, "in_channel_layout", av_get_default_channel_layout(_pFrame->AvFrame()->channels), 0);
        av_opt_set_int(pSwr_, "out_channel_layout", av_get_default_channel_layout(nChannel), 0);
        av_opt_set_int(pSwr_, "in_sample_rate", _pFrame->AvFrame()->sample_rate, 0);
        av_opt_set_int(pSwr_, "out_sample_rate", nSampleRate, 0);
        av_opt_set_sample_fmt(pSwr_, "in_sample_fmt", static_cast<AVSampleFormat>(_pFrame->AvFrame()->format), 0);
        av_opt_set_sample_fmt(pSwr_, "out_sample_fmt", sampleFormat, 0);
        if (swr_init(pSwr_) != 0) {
            logerror("could not initiate resampling");
            return -1;
        }
    }
Exemple #14
0
void FFMS_AudioSource::SetOutputFormat(FFMS_ResampleOptions const& opt) {
	if (opt.SampleRate != AP.SampleRate)
		throw FFMS_Exception(FFMS_ERROR_RESAMPLING, FFMS_ERROR_UNSUPPORTED,
			"Sample rate changes are currently unsupported.");

#ifndef FFMS_RESAMPLING_ENABLED
	if (opt.SampleFormat != AP.SampleFormat || opt.SampleRate != AP.SampleRate || opt.ChannelLayout != AP.ChannelLayout)
		throw FFMS_Exception(FFMS_ERROR_RESAMPLING, FFMS_ERROR_UNSUPPORTED,
			"FFMS was not built with resampling enabled. The only supported conversion is interleaving planar audio.");
#endif
#ifdef WITH_AVRESAMPLE
	if (opt.SampleFormat != AP.SampleFormat || opt.ChannelLayout != AP.ChannelLayout)
		throw FFMS_Exception(FFMS_ERROR_RESAMPLING, FFMS_ERROR_UNSUPPORTED,
			"FFMS was not built with FFMPEG resampling enabled.");
#endif

	// Cache stores audio in the output format, so clear it and reopen the file
	Cache.clear();
	PacketNumber = 0;
	ReopenFile();
	FlushBuffers(CodecContext);

	BytesPerSample = av_get_bytes_per_sample(static_cast<AVSampleFormat>(opt.SampleFormat)) * av_get_channel_layout_nb_channels(opt.ChannelLayout);
	NeedsResample =
		opt.SampleFormat != (int)CodecContext->sample_fmt ||
		opt.SampleRate != AP.SampleRate ||
		opt.ChannelLayout != AP.ChannelLayout ||
		opt.ForceResample;

#ifdef FFMS_RESAMPLING_ENABLED
	if (!NeedsResample) return;

	FFResampleContext newContext;
	SetOptions(opt, newContext, resample_options);
	av_opt_set_int(newContext, "in_sample_rate", AP.SampleRate, 0);
	av_opt_set_int(newContext, "in_sample_fmt", CodecContext->sample_fmt, 0);
	av_opt_set_int(newContext, "in_channel_layout", AP.ChannelLayout, 0);

	av_opt_set_int(newContext, "out_sample_rate", opt.SampleRate, 0);

#ifdef WITH_SWRESAMPLE
	av_opt_set_channel_layout(newContext, "out_channel_layout", opt.ChannelLayout, 0);
	av_opt_set_sample_fmt(newContext, "out_sample_fmt", (AVSampleFormat)opt.SampleFormat, 0);
#endif

	if (ffms_open(newContext))
		throw FFMS_Exception(FFMS_ERROR_RESAMPLING, FFMS_ERROR_UNKNOWN,
			"Could not open avresample context");
	newContext.swap(ResampleContext);
#endif
}
Exemple #15
0
/**
 * Allocates and initializes the SwrContext so that we don't have to deal with planar sample formats.
 *
 * @param env JNIEnv
 * @param aio FFAudioIO
 * @return a negative value should an error occur
 */
static int init_swr(JNIEnv *env, FFAudioIO *aio) {
    int res = 0;

    aio->swr_context = swr_alloc();
    if (!aio->swr_context) {
        res = AVERROR(ENOMEM);
        throwIOExceptionIfError(env, res, "Could not allocate swr context.");
        goto bail;
    }

    av_opt_set_sample_fmt(aio->swr_context, "in_sample_fmt",  aio->stream->codecpar->format, 0);
    // make sure we get interleaved/packed output
    av_opt_set_sample_fmt(aio->swr_context, "out_sample_fmt", av_get_packed_sample_fmt(aio->stream->codecpar->format), 0);

    // keep everything else the way it was...
    av_opt_set_int(aio->swr_context, "in_channel_count",  aio->stream->codecpar->channels, 0);
    av_opt_set_int(aio->swr_context, "out_channel_count",  aio->stream->codecpar->channels, 0);
    av_opt_set_int(aio->swr_context, "in_channel_layout",  aio->stream->codecpar->channel_layout, 0);
    av_opt_set_int(aio->swr_context, "out_channel_layout", aio->stream->codecpar->channel_layout, 0);
    av_opt_set_int(aio->swr_context, "in_sample_rate",     aio->stream->codecpar->sample_rate, 0);
    av_opt_set_int(aio->swr_context, "out_sample_rate",    aio->stream->codecpar->sample_rate, 0);

    res = swr_init(aio->swr_context);
    if (res < 0) {
        res = AVERROR(ENOMEM);
        throwIOExceptionIfError(env, res, "Could not initialize swr context");
        goto bail;
    }

    //fprintf(stderr, "init_swr: dither context: %d\n", aio->swr_context->dither);
    //fprintf(stderr, "init_swr: output sample bits: %d\n", aio->swr_context->dither.output_sample_bits);

    bail:

    return res;
}
void ACapsConvertElement::iStream(const QbPacket &packet)
{
    if (!packet.caps().isValid() ||
        packet.caps().mimeType() != "audio/x-raw" ||
        this->state() != ElementStatePlaying)
        return;

    // Input Format
    AVSampleFormat iSampleFormat = av_get_sample_fmt(packet.caps().property("format").toString().toStdString().c_str());
    int iNChannels = packet.caps().property("channels").toInt();
    int64_t iChannelLayout = av_get_channel_layout(packet.caps().property("layout").toString().toStdString().c_str());
    int iNPlanes = av_sample_fmt_is_planar(iSampleFormat)? iNChannels: 1;
    int iSampleRate = packet.caps().property("rate").toInt();
    int iNSamples = packet.caps().property("samples").toInt();

    if (iNSamples < 1)
        iNSamples = 1024;

    bool sameMimeType = packet.caps().mimeType() == this->m_caps.mimeType();

    // Output Format
    AVSampleFormat oSampleFormat = (sameMimeType && this->m_caps.dynamicPropertyNames().contains("format"))?
                                        av_get_sample_fmt(this->m_caps.property("format").toString().toStdString().c_str()):
                                        iSampleFormat;

    int oNChannels = (sameMimeType && this->m_caps.dynamicPropertyNames().contains("channels"))?
                         this->m_caps.property("channels").toInt():
                         iNChannels;

    int64_t oChannelLayout = (sameMimeType && this->m_caps.dynamicPropertyNames().contains("layout"))?
                                 av_get_channel_layout(this->m_caps.property("layout").toString().toStdString().c_str()):
                                 iChannelLayout;

    int oSampleRate = (sameMimeType && this->m_caps.dynamicPropertyNames().contains("rate"))?
                          this->m_caps.property("rate").toInt():
                          iSampleRate;

    QVector<uint8_t *> iData(iNPlanes);
    int iLineSize;

    if (av_samples_fill_arrays(&iData.data()[0],
                               &iLineSize,
                               (const uint8_t *) packet.buffer().data(),
                               iNChannels,
                               iNSamples,
                               iSampleFormat,
                               1) < 0)
        return;

    QbCaps caps1(packet.caps());
    QbCaps caps2(this->m_curInputCaps);

    caps1.setProperty("samples", QVariant());
    caps2.setProperty("samples", QVariant());

    if (caps1 != caps2)
    {
        // create resampler context
        this->m_resampleContext = SwrContextPtr(swr_alloc(), this->deleteSwrContext);

        if (!this->m_resampleContext)
            return;

        // set options
        av_opt_set_int(this->m_resampleContext.data(), "in_channel_layout", iChannelLayout, 0);
        av_opt_set_int(this->m_resampleContext.data(), "in_sample_rate", iSampleRate, 0);
        av_opt_set_sample_fmt(this->m_resampleContext.data(), "in_sample_fmt", iSampleFormat, 0);

        av_opt_set_int(this->m_resampleContext.data(), "out_channel_layout", oChannelLayout, 0);
        av_opt_set_int(this->m_resampleContext.data(), "out_sample_rate", oSampleRate, 0);
        av_opt_set_sample_fmt(this->m_resampleContext.data(), "out_sample_fmt", oSampleFormat, 0);

        // initialize the resampling context
        if (swr_init(this->m_resampleContext.data()) < 0)
            return;

        this->m_curInputCaps = packet.caps();
    }

    // compute destination number of samples
    int oNSamples = av_rescale_rnd(swr_get_delay(this->m_resampleContext.data(),
                                                 iSampleRate) +
                                   iNSamples,
                                   oSampleRate,
                                   iSampleRate,
                                   AV_ROUND_UP);

    // buffer is going to be directly written to a rawaudio file, no alignment
    int oNPlanes = av_sample_fmt_is_planar(oSampleFormat)? oNChannels: 1;
    QVector<uint8_t *> oData(oNPlanes);

    int oLineSize;

    int oBufferSize = av_samples_get_buffer_size(&oLineSize,
                                                 oNChannels,
                                                 oNSamples,
                                                 oSampleFormat,
                                                 1);

    QSharedPointer<uchar> oBuffer(new uchar[oBufferSize]);

    if (!oBuffer)
        return;

    if (av_samples_fill_arrays(&oData.data()[0],
                               &oLineSize,
                               (const uint8_t *) oBuffer.data(),
                               oNChannels,
                               oNSamples,
                               oSampleFormat,
                               1) < 0)
        return;

    // convert to destination format
    if (swr_convert(this->m_resampleContext.data(),
                    oData.data(),
                    oNSamples,
                    (const uint8_t **) iData.data(),
                    iNSamples) < 0)
        return;

    const char *format = av_get_sample_fmt_name(oSampleFormat);
    char layout[256];

    av_get_channel_layout_string(layout,
                                 sizeof(layout),
                                 oNChannels,
                                 oChannelLayout);

    QString caps = QString("audio/x-raw,"
                           "format=%1,"
                           "channels=%2,"
                           "rate=%3,"
                           "layout=%4,"
                           "samples=%5").arg(format)
                                        .arg(oNChannels)
                                        .arg(oSampleRate)
                                        .arg(layout)
                                        .arg(oNSamples);

    QbPacket oPacket(caps,
                     oBuffer,
                     oBufferSize);

    oPacket.setPts(packet.pts());
    oPacket.setDuration(packet.duration());
    oPacket.setTimeBase(packet.timeBase());
    oPacket.setIndex(packet.index());

    emit this->oStream(oPacket);
}
int decode_frame_from_packet(State *state, AVPacket *aPacket, int *frame_size_ptr, int from_thread)
{
	int n;
	int16_t *samples;
	AVPacket *pkt = aPacket;
    AVFrame *decoded_frame = NULL;
    int got_frame = 0;
    
	int64_t src_ch_layout, dst_ch_layout;
	int src_rate, dst_rate;
	uint8_t **src_data = NULL, **dst_data = NULL;
	int src_nb_channels = 0, dst_nb_channels = 0;
	int src_linesize, dst_linesize;
	int src_nb_samples, dst_nb_samples, max_dst_nb_samples;
	enum AVSampleFormat src_sample_fmt, dst_sample_fmt;
	int dst_bufsize;
	const char *fmt;
	struct SwrContext *swr_ctx;
	double t;
    int ret;

    if (aPacket->stream_index == state->audio_stream) {
        	
    	if (!decoded_frame) {
    		if (!(decoded_frame = avcodec_alloc_frame())) {
    			__android_log_print(ANDROID_LOG_INFO, "TAG", "Could not allocate audio frame\n");
    	        return -2;
    		}
    	}
    	
    	if (avcodec_decode_audio4(state->audio_st->codec, decoded_frame, &got_frame, aPacket) < 0) {
    		__android_log_print(ANDROID_LOG_ERROR, "TAG", "avcodec_decode_audio4() decoded no frame");
    		return -2;
    	}
    	
    	int data_size = 0;
    	
    	if (got_frame) {
    		/* if a frame has been decoded, output it */
    		data_size = av_samples_get_buffer_size(NULL, state->audio_st->codec->channels,
    	    		decoded_frame->nb_samples,
    	    		state->audio_st->codec->sample_fmt, 1);
    	} else {
    		*frame_size_ptr = 0;
    	    return 0;
    	}
    	
        if (decoded_frame->format != AV_SAMPLE_FMT_S16) {
            src_nb_samples = decoded_frame->nb_samples;
            src_linesize = (int) decoded_frame->linesize;
            src_data = decoded_frame->data;
            
            if (decoded_frame->channel_layout == 0) {
            	decoded_frame->channel_layout = av_get_default_channel_layout(decoded_frame->channels);
            }
            
            /* create resampler context */
            swr_ctx = swr_alloc();
            if (!swr_ctx) {
            	//fprintf(stderr, "Could not allocate resampler context\n");
                //ret = AVERROR(ENOMEM);
                //goto end;
            }
            
            src_rate = decoded_frame->sample_rate;
            dst_rate = decoded_frame->sample_rate;
            src_ch_layout = decoded_frame->channel_layout;
            dst_ch_layout = decoded_frame->channel_layout;
            src_sample_fmt = decoded_frame->format;
            dst_sample_fmt = AV_SAMPLE_FMT_S16;
            
            av_opt_set_int(swr_ctx, "in_channel_layout", src_ch_layout, 0);
            av_opt_set_int(swr_ctx, "out_channel_layout", dst_ch_layout,  0);
            av_opt_set_int(swr_ctx, "in_sample_rate", src_rate, 0);
            av_opt_set_int(swr_ctx, "out_sample_rate", dst_rate, 0);
            av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", src_sample_fmt, 0);
            av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", dst_sample_fmt,  0);
            
            /* initialize the resampling context */
            if ((ret = swr_init(swr_ctx)) < 0) {
            	__android_log_print(ANDROID_LOG_INFO, "TAG", "Failed to initialize the resampling context\n");
            	//goto end;
            }

            /* allocate source and destination samples buffers */

            src_nb_channels = av_get_channel_layout_nb_channels(src_ch_layout);
            ret = av_samples_alloc_array_and_samples(&src_data, &src_linesize, src_nb_channels,
            		src_nb_samples, src_sample_fmt, 0);
            if (ret < 0) {
            	__android_log_print(ANDROID_LOG_INFO, "TAG", "Could not allocate source samples\n");
            	//goto end;
            }

            /* compute the number of converted samples: buffering is avoided
             * ensuring that the output buffer will contain at least all the
             * converted input samples */
            max_dst_nb_samples = dst_nb_samples =
            	av_rescale_rnd(src_nb_samples, dst_rate, src_rate, AV_ROUND_UP);

            /* buffer is going to be directly written to a rawaudio file, no alignment */
            dst_nb_channels = av_get_channel_layout_nb_channels(dst_ch_layout);
            ret = av_samples_alloc_array_and_samples(&dst_data, &dst_linesize, dst_nb_channels,
            		dst_nb_samples, dst_sample_fmt, 0);
            if (ret < 0) {
            	__android_log_print(ANDROID_LOG_INFO, "TAG", "Could not allocate destination samples\n");
            	//goto end;
            }
            
            /* compute destination number of samples */
            dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, src_rate) +
                                            src_nb_samples, dst_rate, src_rate, AV_ROUND_UP);
            
            /* convert to destination format */
            ret = swr_convert(swr_ctx, dst_data, dst_nb_samples, (const uint8_t **)decoded_frame->data, src_nb_samples);
            if (ret < 0) {
            	__android_log_print(ANDROID_LOG_INFO, "TAG", "Error while converting\n");
                //goto end;
            }
            dst_bufsize = av_samples_get_buffer_size(&dst_linesize, dst_nb_channels,
                                                     ret, dst_sample_fmt, 1);
            if (dst_bufsize < 0) {
                fprintf(stderr, "Could not get sample buffer size\n");
                //goto end;
            }
            
            samples = malloc(dst_bufsize);
    		memcpy(samples, dst_data[0], dst_bufsize);
    		data_size = dst_bufsize;
    		swr_free(&swr_ctx);
    	} else {
    		/* if a frame has been decoded, output it */
    	    data_size = av_samples_get_buffer_size(NULL, state->audio_st->codec->channels,
    	    		decoded_frame->nb_samples, state->audio_st->codec->sample_fmt, 1);
    		samples = malloc(data_size);
    		memcpy(samples, decoded_frame->data[0], data_size);
    	}
        
        *frame_size_ptr = data_size;
        
        // TODO add this call back!
        //*pts_ptr = pts;
        n = 2 * state->audio_st->codec->channels;
        state->audio_clock += (double)*frame_size_ptr /
        		(double)(n * state->audio_st->codec->sample_rate);

        /* if update, update the audio clock w/pts */
        if(pkt->pts != AV_NOPTS_VALUE) {
        	state->audio_clock = av_q2d(state->audio_st->time_base) * pkt->pts;
        }
    	
        //*frame_size_ptr = data_size;
        state->write_audio_callback(state->clazz, samples, data_size, from_thread);
        
    	avcodec_free_frame(&decoded_frame);
        
        free(samples);
        
    	return AUDIO_DATA_ID;
    }

    return 0;
}
Exemple #18
0
int main(int argc, char **argv)
{
    int64_t src_ch_layout = AV_CH_LAYOUT_STEREO, dst_ch_layout = AV_CH_LAYOUT_SURROUND;
    int src_rate = 48000, dst_rate = 44100;
    uint8_t **src_data = NULL, **dst_data = NULL;
    int src_nb_channels = 0, dst_nb_channels = 0;
    int src_linesize, dst_linesize;
    int src_nb_samples = 1024, dst_nb_samples, max_dst_nb_samples;
    enum AVSampleFormat src_sample_fmt = AV_SAMPLE_FMT_DBL, dst_sample_fmt = AV_SAMPLE_FMT_S16;
    const char *dst_filename = NULL;
    FILE *dst_file;
    int dst_bufsize;
    const char *fmt;
    struct SwrContext *swr_ctx;
    double t;
    int ret;

    if (argc != 2) {
        fprintf(stderr, "Usage: %s output_file\n"
                "API example program to show how to resample an audio stream with libswresample.\n"
                "This program generates a series of audio frames, resamples them to a specified "
                "output format and rate and saves them to an output file named output_file.\n",
            argv[0]);
        exit(1);
    }
    dst_filename = argv[1];

    dst_file = fopen(dst_filename, "wb");
    if (!dst_file) {
        fprintf(stderr, "Could not open destination file %s\n", dst_filename);
        exit(1);
    }

    /* create resampler context */
    swr_ctx = swr_alloc();
    if (!swr_ctx) {
        fprintf(stderr, "Could not allocate resampler context\n");
        ret = AVERROR(ENOMEM);
        goto end;
    }

    /* set options */
    av_opt_set_int(swr_ctx, "in_channel_layout",    src_ch_layout, 0);
    av_opt_set_int(swr_ctx, "in_sample_rate",       src_rate, 0);
    av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", src_sample_fmt, 0);

    av_opt_set_int(swr_ctx, "out_channel_layout",    dst_ch_layout, 0);
    av_opt_set_int(swr_ctx, "out_sample_rate",       dst_rate, 0);
    av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", dst_sample_fmt, 0);

    /* initialize the resampling context */
    if ((ret = swr_init(swr_ctx)) < 0) {
        fprintf(stderr, "Failed to initialize the resampling context\n");
        goto end;
    }

    /* allocate source and destination samples buffers */

    src_nb_channels = av_get_channel_layout_nb_channels(src_ch_layout);
    ret = alloc_samples_array_and_data(&src_data, &src_linesize, src_nb_channels,
                                       src_nb_samples, src_sample_fmt, 0);
    if (ret < 0) {
        fprintf(stderr, "Could not allocate source samples\n");
        goto end;
    }

    /* compute the number of converted samples: buffering is avoided
     * ensuring that the output buffer will contain at least all the
     * converted input samples */
    max_dst_nb_samples = dst_nb_samples =
        av_rescale_rnd(src_nb_samples, dst_rate, src_rate, AV_ROUND_UP);

    /* buffer is going to be directly written to a rawaudio file, no alignment */
    dst_nb_channels = av_get_channel_layout_nb_channels(dst_ch_layout);
    ret = alloc_samples_array_and_data(&dst_data, &dst_linesize, dst_nb_channels,
                                       dst_nb_samples, dst_sample_fmt, 0);
    if (ret < 0) {
        fprintf(stderr, "Could not allocate destination samples\n");
        goto end;
    }

    t = 0;
    do {
        /* generate synthetic audio */
        fill_samples((double *)src_data[0], src_nb_samples, src_nb_channels, src_rate, &t);

        /* compute destination number of samples */
        dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, src_rate) +
                                        src_nb_samples, dst_rate, src_rate, AV_ROUND_UP);
        if (dst_nb_samples > max_dst_nb_samples) {
            av_free(dst_data[0]);
            ret = av_samples_alloc(dst_data, &dst_linesize, dst_nb_channels,
                                   dst_nb_samples, dst_sample_fmt, 1);
            if (ret < 0)
                break;
            max_dst_nb_samples = dst_nb_samples;
        }

        /* convert to destination format */
        ret = swr_convert(swr_ctx, dst_data, dst_nb_samples, (const uint8_t **)src_data, src_nb_samples);
        if (ret < 0) {
            fprintf(stderr, "Error while converting\n");
            goto end;
        }
        dst_bufsize = av_samples_get_buffer_size(&dst_linesize, dst_nb_channels,
                                                 ret, dst_sample_fmt, 1);
        printf("t:%f in:%d out:%d\n", t, src_nb_samples, ret);
        fwrite(dst_data[0], 1, dst_bufsize, dst_file);
    } while (t < 10);

    if ((ret = get_format_from_sample_fmt(&fmt, dst_sample_fmt) < 0))
        goto end;
    fprintf(stderr, "Resampling succeeded. Play the output file with the command:\n"
            "ffplay -f %s -channel_layout %"PRId64" -channels %d -ar %d %s\n",
            fmt, dst_ch_layout, dst_nb_channels, dst_rate, dst_filename);

end:
    if (dst_file)
        fclose(dst_file);

    if (src_data)
        av_freep(&src_data[0]);
    av_freep(&src_data);

    if (dst_data)
        av_freep(&dst_data[0]);
    av_freep(&dst_data);

    swr_free(&swr_ctx);
    return ret < 0;
}
Exemple #19
0
/**
 * Re-configures SwrContext and Encoder to match the provided target_format.
 *
 * @param env           JNIEnv
 * @param object        stream instance this call stems from, i.e. a FFCodecInputStream
 * @param target_format target AudioFormat
 * @param aio_pointer   Pointer to the FFAudioIO struct of the FFNativePeerInputStream that opened the file/stream
 * @return pointer to the FFAudioIO struct that was given as parameter
 */
JNIEXPORT jlong JNICALL Java_com_tagtraum_ffsampledsp_FFCodecInputStream_open(JNIEnv *env, jobject object, jobject target_format, jlong aio_pointer) {
    int res = 0;
    enum AVSampleFormat out_sample_fmt = AV_SAMPLE_FMT_NONE;
    int out_channel_layout = AV_CH_LAYOUT_STEREO;
    int is_float = 0;
    int is_signed = 0;
    AVCodec *encoder = NULL;
    int dither_method = SWR_DITHER_NONE;
    int output_sample_bits = 0;

    init_ids(env);

    FFAudioIO *aio = (FFAudioIO*)(intptr_t)aio_pointer;

    jfloat sample_rate = (*env)->CallFloatMethod(env, target_format, getSampleRate_MID);
    jint sample_size_in_bits = (*env)->CallIntMethod(env, target_format, getSampleSizeInBits_MID);
    jint channels = (*env)->CallIntMethod(env, target_format, getChannels_MID);
    jboolean big_endian = (*env)->CallBooleanMethod(env, target_format, isBigEndian_MID);
    jobject encoding = (*env)->CallObjectMethod(env, target_format, getEncoding_MID);
    jstring jencoding_name = (jstring)(*env)->CallObjectMethod(env, encoding, toString_MID);

    const char *encoding_name = (*env)->GetStringUTFChars(env, jencoding_name, NULL);
    is_float = strcmp("PCM_FLOAT", encoding_name) == 0;
    is_signed = strcmp("PCM_SIGNED", encoding_name) == 0;
    (*env)->ReleaseStringUTFChars(env, jencoding_name, encoding_name);

#ifdef DEBUG
    fprintf(stderr, "encoding = %s\n", encoding_name);
    fprintf(stderr, "signed   = %d\n", is_signed);
    fprintf(stderr, "float    = %d\n", is_float);
    fprintf(stderr, "bits     = %d\n", (int)sample_size_in_bits);
#endif

    if (sample_size_in_bits <= 8) {
        out_sample_fmt = AV_SAMPLE_FMT_U8;
    } else if (sample_size_in_bits <=16) {
        out_sample_fmt = AV_SAMPLE_FMT_S16;
    } else if (sample_size_in_bits <= 32 && is_float) {
        out_sample_fmt = AV_SAMPLE_FMT_FLT;
    } else if (sample_size_in_bits <=32) {
        out_sample_fmt = AV_SAMPLE_FMT_S32;
    } else if (sample_size_in_bits <= 64 && is_float) {
        out_sample_fmt = AV_SAMPLE_FMT_DBL;
    } else {
        fprintf(stderr, "Will use 64 bit PCM_FLOAT even though it might not have been desired.\n");
        out_sample_fmt = AV_SAMPLE_FMT_DBL;
    }

    if (aio->stream->codecpar->channels == channels) {
        out_channel_layout = aio->stream->codecpar->channel_layout;
    } else if (channels == 1) {
        out_channel_layout = AV_CH_LAYOUT_MONO;
    } else if (channels == 2) {
        out_channel_layout = AV_CH_LAYOUT_STEREO;
    } else {
        fprintf(stderr, "Undetermined channel layout, will use stereo.\n");
        channels = 2;
    }

    if (aio->stream->codecpar->bits_per_coded_sample > sample_size_in_bits) {
        dither_method = SWR_DITHER_TRIANGULAR;
        output_sample_bits = sample_size_in_bits;
    }

#ifdef DEBUG
    fprintf(stderr, "setting out format to: %d\n", out_sample_fmt);
#endif

    // remove default setup
    if (aio->swr_context) {
        swr_free(&aio->swr_context);
    }
    // allocate new
    aio->swr_context = swr_alloc();
    if (!aio->swr_context) {
        res = AVERROR(ENOMEM);
        throwIOExceptionIfError(env, res, "Could not allocate swr context.");
        goto bail;
    }

    // standard stuff from input
    av_opt_set_sample_fmt(aio->swr_context, "in_sample_fmt",  aio->stream->codecpar->format, 0);
    av_opt_set_int(aio->swr_context, "in_channel_count",  aio->stream->codecpar->channels, 0);
    av_opt_set_int(aio->swr_context, "in_channel_layout",  aio->stream->codecpar->channel_layout, 0);
    av_opt_set_int(aio->swr_context, "in_sample_rate",     aio->stream->codecpar->sample_rate, 0);
    // custom stuff
    av_opt_set_int(aio->swr_context, "out_channel_layout", out_channel_layout, 0);
    av_opt_set_int(aio->swr_context, "out_channel_count", channels, 0);
    av_opt_set_int(aio->swr_context, "out_sample_rate", (int)round(sample_rate), 0);
    av_opt_set_sample_fmt(aio->swr_context, "out_sample_fmt", out_sample_fmt, 0);
    av_opt_set_int(aio->swr_context, "dither_method", dither_method, 0);
    av_opt_set_int(aio->swr_context, "output_sample_bits", output_sample_bits, 0);

    res = swr_init(aio->swr_context);
    if (res < 0) {
        res = AVERROR(ENOMEM);
        throwIOExceptionIfError(env, res, "Could not re-initialize swr context.");
        goto bail;
    }

#ifdef DEBUG
    fprintf(stderr, "open codec: dither method     : %d\n", dither_method);
    fprintf(stderr, "open codec: output sample bits: %d\n", aio->swr_context->dither.output_sample_bits);
#endif

    // re-adjust encoder
    encoder = ff_find_encoder(out_sample_fmt, sample_size_in_bits, big_endian, is_signed);
    if (!encoder) {
        res = AVERROR(EINVAL);
        throwIOExceptionIfError(env, res, "Could not find suitable encoder.");
        goto bail;
    }
    res = ff_init_encoder(env, aio, encoder);
    if (res < 0) {
        goto bail;
    }

    bail:

    return (jlong)(intptr_t)aio;
}
bool ChildFFMpegLoader::open(qint64 &position) {
	int res = 0;
	char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };

	uint64_t layout = _parentData->context->channel_layout;
	_inputFormat = _parentData->context->sample_fmt;
	switch (layout) {
	case AV_CH_LAYOUT_MONO:
		switch (_inputFormat) {
		case AV_SAMPLE_FMT_U8:
		case AV_SAMPLE_FMT_U8P: _format = AL_FORMAT_MONO8; _sampleSize = 1; break;
		case AV_SAMPLE_FMT_S16:
		case AV_SAMPLE_FMT_S16P: _format = AL_FORMAT_MONO16; _sampleSize = sizeof(uint16); break;
		default:
			_sampleSize = -1; // convert needed
		break;
		}
	break;
	case AV_CH_LAYOUT_STEREO:
		switch (_inputFormat) {
		case AV_SAMPLE_FMT_U8: _format = AL_FORMAT_STEREO8; _sampleSize = 2; break;
		case AV_SAMPLE_FMT_S16: _format = AL_FORMAT_STEREO16; _sampleSize = 2 * sizeof(uint16); break;
		default:
			_sampleSize = -1; // convert needed
		break;
		}
	break;
	default:
		_sampleSize = -1; // convert needed
	break;
	}
	if (_parentData->frequency != 44100 && _parentData->frequency != 48000) {
		_sampleSize = -1; // convert needed
	}

	if (_sampleSize < 0) {
		_swrContext = swr_alloc();
		if (!_swrContext) {
			LOG(("Audio Error: Unable to swr_alloc for file '%1', data size '%2'").arg(file.name()).arg(data.size()));
			return false;
		}
		int64_t src_ch_layout = layout, dst_ch_layout = AudioToChannelLayout;
		_srcRate = _parentData->frequency;
		AVSampleFormat src_sample_fmt = _inputFormat, dst_sample_fmt = AudioToFormat;
		_dstRate = (_parentData->frequency != 44100 && _parentData->frequency != 48000) ? AudioVoiceMsgFrequency : _parentData->frequency;

		av_opt_set_int(_swrContext, "in_channel_layout", src_ch_layout, 0);
		av_opt_set_int(_swrContext, "in_sample_rate", _srcRate, 0);
		av_opt_set_sample_fmt(_swrContext, "in_sample_fmt", src_sample_fmt, 0);
		av_opt_set_int(_swrContext, "out_channel_layout", dst_ch_layout, 0);
		av_opt_set_int(_swrContext, "out_sample_rate", _dstRate, 0);
		av_opt_set_sample_fmt(_swrContext, "out_sample_fmt", dst_sample_fmt, 0);

		if ((res = swr_init(_swrContext)) < 0) {
			LOG(("Audio Error: Unable to swr_init for file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
			return false;
		}

		_sampleSize = AudioToChannels * sizeof(short);
		_parentData->frequency = _dstRate;
		_parentData->length = av_rescale_rnd(_parentData->length, _dstRate, _srcRate, AV_ROUND_UP);
		position = av_rescale_rnd(position, _dstRate, _srcRate, AV_ROUND_DOWN);
		_format = AL_FORMAT_STEREO16;

		_maxResampleSamples = av_rescale_rnd(AVBlockSize / _sampleSize, _dstRate, _srcRate, AV_ROUND_UP);
		if ((res = av_samples_alloc_array_and_samples(&_dstSamplesData, 0, AudioToChannels, _maxResampleSamples, AudioToFormat, 0)) < 0) {
			LOG(("Audio Error: Unable to av_samples_alloc for file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
			return false;
		}
	}

	return true;
}
int decode_frame_from_packet(VideoState *is, AVFrame decoded_frame)
{
	int64_t src_ch_layout, dst_ch_layout;
	int src_rate, dst_rate;
	uint8_t **src_data = NULL, **dst_data = NULL;
	int src_nb_channels = 0, dst_nb_channels = 0;
	int src_linesize, dst_linesize;
	int src_nb_samples, dst_nb_samples, max_dst_nb_samples;
	enum AVSampleFormat src_sample_fmt, dst_sample_fmt;
	int dst_bufsize;
	int ret;

	src_nb_samples = decoded_frame.nb_samples;
	src_linesize = (int) decoded_frame.linesize;
	src_data = decoded_frame.data;

	if (decoded_frame.channel_layout == 0) {
		decoded_frame.channel_layout = av_get_default_channel_layout(decoded_frame.channels);
	}

	src_rate = decoded_frame.sample_rate;
	dst_rate = decoded_frame.sample_rate;
	src_ch_layout = decoded_frame.channel_layout;
	dst_ch_layout = decoded_frame.channel_layout;
	src_sample_fmt = decoded_frame.format;
	dst_sample_fmt = AV_SAMPLE_FMT_S16;

	av_opt_set_int(is->sws_ctx_audio, "in_channel_layout", src_ch_layout, 0);
	av_opt_set_int(is->sws_ctx_audio, "out_channel_layout", dst_ch_layout,  0);
	av_opt_set_int(is->sws_ctx_audio, "in_sample_rate", src_rate, 0);
	av_opt_set_int(is->sws_ctx_audio, "out_sample_rate", dst_rate, 0);
	av_opt_set_sample_fmt(is->sws_ctx_audio, "in_sample_fmt", src_sample_fmt, 0);
	av_opt_set_sample_fmt(is->sws_ctx_audio, "out_sample_fmt", dst_sample_fmt,  0);

	/* initialize the resampling context */
	if ((ret = swr_init(is->sws_ctx_audio)) < 0) {
		fprintf(stderr, "Failed to initialize the resampling context\n");
		return -1;
	}

	/* allocate source and destination samples buffers */
	src_nb_channels = av_get_channel_layout_nb_channels(src_ch_layout);
	ret = av_samples_alloc_array_and_samples(&src_data, &src_linesize, src_nb_channels, src_nb_samples, src_sample_fmt, 0);
	if (ret < 0) {
		fprintf(stderr, "Could not allocate source samples\n");
		return -1;
	}

	/* compute the number of converted samples: buffering is avoided
	 * ensuring that the output buffer will contain at least all the
	 * converted input samples */
	max_dst_nb_samples = dst_nb_samples = av_rescale_rnd(src_nb_samples, dst_rate, src_rate, AV_ROUND_UP);

	/* buffer is going to be directly written to a rawaudio file, no alignment */
	dst_nb_channels = av_get_channel_layout_nb_channels(dst_ch_layout);
	ret = av_samples_alloc_array_and_samples(&dst_data, &dst_linesize, dst_nb_channels, dst_nb_samples, dst_sample_fmt, 0);
	if (ret < 0) {
		fprintf(stderr, "Could not allocate destination samples\n");
		return -1;
	}

	/* compute destination number of samples */
	dst_nb_samples = av_rescale_rnd(swr_get_delay(is->sws_ctx_audio, src_rate) + src_nb_samples, dst_rate, src_rate, AV_ROUND_UP);

	/* convert to destination format */
	ret = swr_convert(is->sws_ctx_audio, dst_data, dst_nb_samples, (const uint8_t **)decoded_frame.data, src_nb_samples);
	if (ret < 0) {
		fprintf(stderr, "Error while converting\n");
		return -1;
	}

	dst_bufsize = av_samples_get_buffer_size(&dst_linesize, dst_nb_channels, ret, dst_sample_fmt, 1);
	if (dst_bufsize < 0) {
		fprintf(stderr, "Could not get sample buffer size\n");
		return -1;
	}

	memcpy(is->audio_buf, dst_data[0], dst_bufsize);

	if (src_data) {
		av_freep(&src_data[0]);
	}
	av_freep(&src_data);

	if (dst_data) {
		av_freep(&dst_data[0]);
	}
	av_freep(&dst_data);

	return dst_bufsize;
}
int audioResampling(AVCodecContext *audio_dec_ctx, AVFrame *pAudioDecodeFrame,
                    int out_sample_fmt, int out_channels, int out_sample_rate, char *out_buf) {
    __android_log_print(ANDROID_LOG_DEBUG, TAG, "stream12");
    SwrContext *swr_ctx = NULL;
    int data_size = 0;
    int ret = 0;
    int64_t src_ch_layout = AV_CH_LAYOUT_STEREO; //初始化这样根据不同文件做调整
    int64_t dst_ch_layout = AV_CH_LAYOUT_STEREO; //这里设定ok
    int dst_nb_channels = 0;
    int dst_linesize = 0;
    int src_nb_samples = 0;
    int dst_nb_samples = 0;
    int max_dst_nb_samples = 0;
    uint8_t **dst_data = NULL;
    int resampled_data_size = 0;
    //重新采样
    if (swr_ctx) {
        swr_free(&swr_ctx);
    }
    swr_ctx = swr_alloc();
    __android_log_print(ANDROID_LOG_DEBUG, TAG, "stream12-1");
    if (!swr_ctx) {
        printf("swr_alloc error \n");
        __android_log_print(ANDROID_LOG_DEBUG, TAG, "stream13");
        return -1;
    }

    src_ch_layout = (audio_dec_ctx->channel_layout &&
                     audio_dec_ctx->channels ==
                     av_get_channel_layout_nb_channels(audio_dec_ctx->channel_layout)) ?
                    audio_dec_ctx->channel_layout :
                    av_get_default_channel_layout(audio_dec_ctx->channels);
    if (out_channels == 1) {
        dst_ch_layout = AV_CH_LAYOUT_MONO;
    }
    else if (out_channels == 2) {
        dst_ch_layout = AV_CH_LAYOUT_STEREO;
    }
    else {
        //可扩展
    }
    __android_log_print(ANDROID_LOG_DEBUG, TAG, "stream12-2");
    if (src_ch_layout <= 0) {
        printf("src_ch_layout error \n");
        __android_log_print(ANDROID_LOG_DEBUG, TAG, "stream14");
        return -1;
    }
    __android_log_print(ANDROID_LOG_DEBUG, TAG, "stream12-3");
    src_nb_samples = pAudioDecodeFrame->nb_samples;
    if (src_nb_samples <= 0) {
        printf("src_nb_samples error \n");
        __android_log_print(ANDROID_LOG_DEBUG, TAG, "stream15");
        return -1;
    }

    /* set options */
    av_opt_set_int(swr_ctx, "in_channel_layout", src_ch_layout, 0);
    av_opt_set_int(swr_ctx, "in_sample_rate", audio_dec_ctx->sample_rate, 0);
    av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", audio_dec_ctx->sample_fmt, 0);

    av_opt_set_int(swr_ctx, "out_channel_layout", dst_ch_layout, 0);
    av_opt_set_int(swr_ctx, "out_sample_rate", out_sample_rate, 0);
    av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", (AVSampleFormat) out_sample_fmt, 0);
    swr_init(swr_ctx);
    max_dst_nb_samples = dst_nb_samples =
            av_rescale_rnd(src_nb_samples, out_sample_rate, audio_dec_ctx->sample_rate,
                           AV_ROUND_UP);
    if (max_dst_nb_samples <= 0) {
        printf("av_rescale_rnd error \n");
        return -1;
    }

    dst_nb_channels = av_get_channel_layout_nb_channels(dst_ch_layout);
    ret = av_samples_alloc_array_and_samples(&dst_data, &dst_linesize, dst_nb_channels,
                                             dst_nb_samples, (AVSampleFormat) out_sample_fmt, 0);
    if (ret < 0) {
        printf("av_samples_alloc_array_and_samples error \n");
        return -1;
    }


    dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, audio_dec_ctx->sample_rate) +
                                    src_nb_samples, out_sample_rate, audio_dec_ctx->sample_rate,
                                    AV_ROUND_UP);
    if (dst_nb_samples <= 0) {
        return -1;
    }
    if (dst_nb_samples > max_dst_nb_samples) {
        av_free(dst_data[0]);
        ret = av_samples_alloc(dst_data, &dst_linesize, dst_nb_channels,
                               dst_nb_samples, (AVSampleFormat) out_sample_fmt, 1);
        max_dst_nb_samples = dst_nb_samples;
    }
    data_size = av_samples_get_buffer_size(NULL, audio_dec_ctx->channels,
                                           pAudioDecodeFrame->nb_samples,
                                           audio_dec_ctx->sample_fmt, 1);
    if (data_size <= 0) {
        return -1;
    }
    resampled_data_size = data_size;
    if (swr_ctx) {
        ret = swr_convert(swr_ctx, dst_data, dst_nb_samples,
                          (const uint8_t **) pAudioDecodeFrame->data,
                          pAudioDecodeFrame->nb_samples);
        if (ret <= 0) {
            return -1;
        }

        resampled_data_size = av_samples_get_buffer_size(&dst_linesize, dst_nb_channels,
                                                         ret, (AVSampleFormat) out_sample_fmt, 1);
        if (resampled_data_size <= 0) {
            return -1;
        }
    }
    else {
        return -1;
    }
    //将值返回去
    memcpy(out_buf, dst_data[0], resampled_data_size);
    if (dst_data) {
        av_freep(&dst_data[0]);
    }
    av_freep(&dst_data);
    dst_data = NULL;

    if (swr_ctx) {
        swr_free(&swr_ctx);
    }
    return resampled_data_size;
}
Exemple #23
0
Chroma::Result Chroma::operator() (const QString& filename)
{
    std::shared_ptr<AVFormatContext> formatCtx;
    {
        AVFormatContext *formatCtxRaw = nullptr;
        if (avformat_open_input (&formatCtxRaw, filename.toLatin1 ().constData (), nullptr, nullptr))
            throw std::runtime_error ("error opening file");

        formatCtx.reset (formatCtxRaw,
        [] (AVFormatContext *ctx) {
            avformat_close_input (&ctx);
        });
    }

    {
        QMutexLocker locker (&CodecMutex_);
        if (avformat_find_stream_info (formatCtx.get (), nullptr) < 0)
            throw std::runtime_error ("could not find stream");
    }

    AVCodec *codec = nullptr;
    const auto streamIndex = av_find_best_stream (formatCtx.get (), AVMEDIA_TYPE_AUDIO, -1, -1, &codec, 0);
    if (streamIndex < 0)
        throw std::runtime_error ("could not find audio stream");

    auto stream = formatCtx->streams [streamIndex];

    bool codecOpened = false;

    std::shared_ptr<AVCodecContext> codecCtx (stream->codec,
    [&codecOpened] (AVCodecContext *ctx) {
        if (codecOpened) avcodec_close (ctx);
    });
    {
        QMutexLocker locker (&CodecMutex_);
        if (avcodec_open2 (codecCtx.get (), codec, nullptr) < 0)
            throw std::runtime_error ("couldn't open the codec");
    }
    codecOpened = true;

    if (codecCtx->channels <= 0)
        throw std::runtime_error ("no channels found");

    std::shared_ptr<SwrContext> swr;
    if (codecCtx->sample_fmt != AV_SAMPLE_FMT_S16)
    {
        swr.reset (swr_alloc (), [] (SwrContext *ctx) {
            if (ctx) swr_free (&ctx);
        });
        av_opt_set_int (swr.get (), "in_channel_layout", codecCtx->channel_layout, 0);
        av_opt_set_int (swr.get (), "out_channel_layout", codecCtx->channel_layout,  0);
        av_opt_set_int (swr.get (), "in_sample_rate", codecCtx->sample_rate, 0);
        av_opt_set_int (swr.get (), "out_sample_rate", codecCtx->sample_rate, 0);
        av_opt_set_sample_fmt (swr.get (), "in_sample_fmt", codecCtx->sample_fmt, 0);
        av_opt_set_sample_fmt (swr.get (), "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
        swr_init (swr.get ());
    }

    AVPacket packet;
    av_init_packet (&packet);

    const int maxLength = 120;
    auto remaining = maxLength * codecCtx->channels * codecCtx->sample_rate;
    chromaprint_start (Ctx_, codecCtx->sample_rate, codecCtx->channels);

    std::shared_ptr<AVFrame> frame (av_frame_alloc (),
    [] (AVFrame *frame) {
        av_frame_free (&frame);
    });
    auto maxDstNbSamples = 0;

    uint8_t *dstData [1] = { nullptr };
    std::shared_ptr<void> dstDataGuard (nullptr,
    [&dstData] (void*) {
        if (dstData [0]) av_freep (&dstData [0]);
    });
    while (true)
    {
        if (av_read_frame (formatCtx.get (), &packet) < 0)
            break;

        std::shared_ptr<void> guard (nullptr,
        [&packet] (void*) {
            if (packet.data) av_free_packet (&packet);
        });

        if (packet.stream_index != streamIndex)
            continue;

        av_frame_unref (frame.get ());
        int gotFrame = false;
        auto consumed = avcodec_decode_audio4 (codecCtx.get (), frame.get (), &gotFrame, &packet);

        if (consumed < 0 || !gotFrame)
            continue;

        uint8_t **data = nullptr;
        if (swr)
        {
            if (frame->nb_samples > maxDstNbSamples)
            {
                if (dstData [0])
                    av_freep (&dstData [0]);
                int linesize = 0;
                if (av_samples_alloc (dstData, &linesize, codecCtx->channels, frame->nb_samples, AV_SAMPLE_FMT_S16, 1) < 0)
                    throw std::runtime_error ("cannot allocate memory for resampling");
            }

            if (swr_convert (swr.get (), dstData, frame->nb_samples, const_cast<const uint8_t**> (frame->data), frame->nb_samples) < 0)
                throw std::runtime_error ("cannot resample audio");

            data = dstData;
        }
        else
            data = frame->data;

        auto length = std::min (remaining, frame->nb_samples * codecCtx->channels);
        if (!chromaprint_feed (Ctx_, data [0], length))
            throw std::runtime_error ("cannot feed data");

        bool finished = false;
        if (maxLength)
        {
            remaining -= length;
            if (remaining <= 0)
                finished = true;
        }
        if (finished)
            break;
    }

    if (!chromaprint_finish (Ctx_))
        throw std::runtime_error ("fingerprint calculation failed");

    char *fingerprint = 0;
    if (!chromaprint_get_fingerprint (Ctx_, &fingerprint))
        throw std::runtime_error ("unable to get fingerprint");

    QByteArray result (fingerprint);
    chromaprint_dealloc (fingerprint);

    const double divideFactor = 1. / av_q2d (stream->time_base);
    const double duration = stream->duration / divideFactor;

    return { result, static_cast<int> (duration) };
}
bool FFMpegLoader::open(qint64 &position) {
	if (!AbstractFFMpegLoader::open(position)) {
		return false;
	}

	int res = 0;
	char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };

	auto codecParams = fmtContext->streams[streamId]->codecpar;

	codecContext = avcodec_alloc_context3(nullptr);
	if (!codecContext) {
		LOG(("Audio Error: Unable to avcodec_alloc_context3 for file '%1', data size '%2'").arg(_file.name()).arg(_data.size()));
		return false;
	}
	if ((res = avcodec_parameters_to_context(codecContext, codecParams)) < 0) {
		LOG(("Audio Error: Unable to avcodec_parameters_to_context for file '%1', data size '%2', error %3, %4").arg(_file.name()).arg(_data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
		return false;
	}
	av_codec_set_pkt_timebase(codecContext, fmtContext->streams[streamId]->time_base);
	av_opt_set_int(codecContext, "refcounted_frames", 1, 0);

	if ((res = avcodec_open2(codecContext, codec, 0)) < 0) {
		LOG(("Audio Error: Unable to avcodec_open2 for file '%1', data size '%2', error %3, %4").arg(_file.name()).arg(_data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
		return false;
	}

	auto layout = codecParams->channel_layout;
	if (!layout) {
		auto channelsCount = codecParams->channels;
		switch (channelsCount) {
		case 1: layout = AV_CH_LAYOUT_MONO; break;
		case 2: layout = AV_CH_LAYOUT_STEREO; break;
		default: LOG(("Audio Error: Unknown channel layout for %1 channels.").arg(channelsCount)); break;
		}
	}
	inputFormat = codecContext->sample_fmt;
	switch (layout) {
	case AV_CH_LAYOUT_MONO:
		switch (inputFormat) {
		case AV_SAMPLE_FMT_U8:
		case AV_SAMPLE_FMT_U8P: fmt = AL_FORMAT_MONO8; sampleSize = 1; break;
		case AV_SAMPLE_FMT_S16:
		case AV_SAMPLE_FMT_S16P: fmt = AL_FORMAT_MONO16; sampleSize = sizeof(uint16); break;
		default:
			sampleSize = -1; // convert needed
		break;
		}
	break;
	case AV_CH_LAYOUT_STEREO:
		switch (inputFormat) {
		case AV_SAMPLE_FMT_U8: fmt = AL_FORMAT_STEREO8; sampleSize = 2; break;
		case AV_SAMPLE_FMT_S16: fmt = AL_FORMAT_STEREO16; sampleSize = 2 * sizeof(uint16); break;
		default:
			sampleSize = -1; // convert needed
		break;
		}
	break;
	default:
		sampleSize = -1; // convert needed
	break;
	}
	if (_samplesFrequency != 44100 && _samplesFrequency != 48000) {
		sampleSize = -1; // convert needed
	}

	if (sampleSize < 0) {
		swrContext = swr_alloc();
		if (!swrContext) {
			LOG(("Audio Error: Unable to swr_alloc for file '%1', data size '%2'").arg(_file.name()).arg(_data.size()));
			return false;
		}
		int64_t src_ch_layout = layout, dst_ch_layout = AudioToChannelLayout;
		srcRate = _samplesFrequency;
		AVSampleFormat src_sample_fmt = inputFormat, dst_sample_fmt = AudioToFormat;
		dstRate = (_samplesFrequency != 44100 && _samplesFrequency != 48000) ? Media::Player::kDefaultFrequency : _samplesFrequency;

		av_opt_set_int(swrContext, "in_channel_layout", src_ch_layout, 0);
		av_opt_set_int(swrContext, "in_sample_rate", srcRate, 0);
		av_opt_set_sample_fmt(swrContext, "in_sample_fmt", src_sample_fmt, 0);
		av_opt_set_int(swrContext, "out_channel_layout", dst_ch_layout, 0);
		av_opt_set_int(swrContext, "out_sample_rate", dstRate, 0);
		av_opt_set_sample_fmt(swrContext, "out_sample_fmt", dst_sample_fmt, 0);

		if ((res = swr_init(swrContext)) < 0) {
			LOG(("Audio Error: Unable to swr_init for file '%1', data size '%2', error %3, %4").arg(_file.name()).arg(_data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
			return false;
		}

		sampleSize = AudioToChannels * sizeof(short);
		_samplesFrequency = dstRate;
		_samplesCount = av_rescale_rnd(_samplesCount, dstRate, srcRate, AV_ROUND_UP);
		position = av_rescale_rnd(position, dstRate, srcRate, AV_ROUND_DOWN);
		fmt = AL_FORMAT_STEREO16;

		maxResampleSamples = av_rescale_rnd(AVBlockSize / sampleSize, dstRate, srcRate, AV_ROUND_UP);
		if ((res = av_samples_alloc_array_and_samples(&dstSamplesData, 0, AudioToChannels, maxResampleSamples, AudioToFormat, 0)) < 0) {
			LOG(("Audio Error: Unable to av_samples_alloc for file '%1', data size '%2', error %3, %4").arg(_file.name()).arg(_data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
			return false;
		}
	}
	if (position) {
		int64 ts = (position * fmtContext->streams[streamId]->time_base.den) / (_samplesFrequency * fmtContext->streams[streamId]->time_base.num);
		if (av_seek_frame(fmtContext, streamId, ts, AVSEEK_FLAG_ANY) < 0) {
			if (av_seek_frame(fmtContext, streamId, ts, 0) < 0) {
			}
		}
	}

	return true;
}
Exemple #25
0
int audio_decode_frame(VideoState *is) {
  int len1, data_size = 0;
  AVPacket *pkt = &is->audio_pkt;

  for(;;) {
    while(is->audio_pkt_size > 0) {
      int got_frame = 0;
      len1 = avcodec_decode_audio4(is->audio_st->codec, &is->audio_frame, &got_frame, pkt);
      if(len1 < 0) {
	/* if error, skip frame */
	is->audio_pkt_size = 0;
	break;
      }
      if (got_frame)
      {
          /*
          data_size = 
            av_samples_get_buffer_size
            (
                NULL, 
                is->audio_st->codec->channels,
                is->audio_frame.nb_samples,
                is->audio_st->codec->sample_fmt,
                1
            );
          memcpy(is->audio_buf, is->audio_frame.data[0], data_size);
          */
          data_size =av_samples_get_buffer_size
                  (
                      NULL,
                      is->audio_st->codec->channels,
                      is->audio_frame.nb_samples,
                      AV_SAMPLE_FMT_S16,
                      0
                  );
                if (!swr_ctx)
                {
                    swr_ctx = swr_alloc();
                    if (!swr_ctx)
                    {
                        printf("Could not allocate swr context\n");
                        exit(1);
                    }
                    /* set options */
                    av_opt_set_int(swr_ctx, "in_channel_layout", is->audio_st->codec->channel_layout, 0);
                    av_opt_set_int(swr_ctx, "in_sample_rate", is->audio_st->codec->sample_rate, 0);
                    av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", is->audio_st->codec->sample_fmt, 0);
                    av_opt_set_int(swr_ctx, "out_channel_layout", is->audio_st->codec->channel_layout, 0);
                    av_opt_set_int(swr_ctx, "out_sample_rate", is->audio_st->codec->sample_rate, 0);
                    av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
                    if (swr_init(swr_ctx) < 0)
                    {
                        printf("Failed to initialize the resampling context\n");
                        exit(1);
                    }
                    decode_buffer = (uint8_t*) malloc(data_size);
                }
                int ret = swr_convert(swr_ctx, &decode_buffer, is->audio_frame.nb_samples, (const uint8_t **) &is->audio_frame.data[0],
                                        is->audio_frame.nb_samples);
                if (ret < 0)
                {
                    printf("Error while converting\n");
                    break;
                }
                memcpy(is->audio_buf, decode_buffer, data_size);

      }
      is->audio_pkt_data += len1;
      is->audio_pkt_size -= len1;
      if(data_size <= 0) {
	/* No data yet, get more frames */
	continue;
      }
      /* We have data, return it and come back for more later */
      return data_size;
    }
    if(pkt->data)
      av_free_packet(pkt);

    if(is->quit) {
      return -1;
    }
    /* next packet */
    if(packet_queue_get(&is->audioq, pkt, 1) < 0) {
      return -1;
    }
    is->audio_pkt_data = pkt->data;
    is->audio_pkt_size = pkt->size;
  }
}
Exemple #26
0
static void open_audio(AVFormatContext *oc, AVCodec *codec, AVStream *st)
{
    AVCodecContext *c;
    int ret;

    c = st->codec;

    /* allocate and init a re-usable frame */
    audio_frame = av_frame_alloc();
    if (!audio_frame) {
        fprintf(stderr, "Could not allocate audio frame\n");
        exit(1);
    }

    /* open it */
    ret = avcodec_open2(c, codec, NULL);
    if (ret < 0) {
        fprintf(stderr, "Could not open audio codec: %s\n", av_err2str(ret));
        exit(1);
    }

    /* init signal generator */
    t     = 0;
    tincr = 2 * M_PI * 110.0 / c->sample_rate;
    /* increment frequency by 110 Hz per second */
    tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate;

    src_nb_samples = c->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE ?
        10000 : c->frame_size;

    ret = av_samples_alloc_array_and_samples(&src_samples_data, &src_samples_linesize, c->channels,
                                             src_nb_samples, AV_SAMPLE_FMT_S16, 0);
    if (ret < 0) {
        fprintf(stderr, "Could not allocate source samples\n");
        exit(1);
    }

    /* compute the number of converted samples: buffering is avoided
     * ensuring that the output buffer will contain at least all the
     * converted input samples */
    max_dst_nb_samples = src_nb_samples;

    /* create resampler context */
    if (c->sample_fmt != AV_SAMPLE_FMT_S16) {
        swr_ctx = swr_alloc();
        if (!swr_ctx) {
            fprintf(stderr, "Could not allocate resampler context\n");
            exit(1);
        }

        /* set options */
        av_opt_set_int       (swr_ctx, "in_channel_count",   c->channels,       0);
        av_opt_set_int       (swr_ctx, "in_sample_rate",     c->sample_rate,    0);
        av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt",      AV_SAMPLE_FMT_S16, 0);
        av_opt_set_int       (swr_ctx, "out_channel_count",  c->channels,       0);
        av_opt_set_int       (swr_ctx, "out_sample_rate",    c->sample_rate,    0);
        av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt",     c->sample_fmt,     0);

        /* initialize the resampling context */
        if ((ret = swr_init(swr_ctx)) < 0) {
            fprintf(stderr, "Failed to initialize the resampling context\n");
            exit(1);
        }

        ret = av_samples_alloc_array_and_samples(&dst_samples_data, &dst_samples_linesize, c->channels,
                                                 max_dst_nb_samples, c->sample_fmt, 0);
        if (ret < 0) {
            fprintf(stderr, "Could not allocate destination samples\n");
            exit(1);
        }
    } else {
        dst_samples_data = src_samples_data;
    }
    dst_samples_size = av_samples_get_buffer_size(NULL, c->channels, max_dst_nb_samples,
                                                  c->sample_fmt, 0);
}
Exemple #27
0
int frame_pusher_open(frame_pusher **o_fp, const char *path,
    int aud_samplerate, AVRational vid_framerate,
    int width, int height, int vid_bitrate)
{
    *o_fp = NULL;
    int ret;
    frame_pusher *fp = (frame_pusher *)av_malloc(sizeof(frame_pusher));

    // Guess the format
    AVOutputFormat *ofmt = av_guess_format(NULL, path, NULL);
    if (!ofmt) {
        ofmt = av_oformat_next(NULL);   // Use the first format available
        av_log(NULL, AV_LOG_WARNING, "Unsupported container format. Using %s instead.\n", ofmt->name);
        // TODO: Add the extension to the path.
    }
    av_log(NULL, AV_LOG_INFO, "Using format %s\n", ofmt->name);
    // Open output file
    AVIOContext *io_ctx;
    if ((ret = avio_open2(&io_ctx, path, AVIO_FLAG_WRITE, NULL, NULL)) < 0) return ret;
    // Create the format context
    fp->fmt_ctx = avformat_alloc_context();
    fp->fmt_ctx->oformat = ofmt;
    fp->fmt_ctx->pb = io_ctx;
    // > Create the streams. Here we simply create one for video and one for audio.
    // >> The audio stream
    AVCodec *aud_codec = avcodec_find_encoder(AV_CODEC_ID_AAC);
    fp->aud_stream = avformat_new_stream(fp->fmt_ctx, aud_codec);
    fp->aud_stream->id = 0;
    fp->aud_stream->codec->codec_id = AV_CODEC_ID_AAC;
    fp->aud_stream->codec->bit_rate = 64000;
    fp->aud_stream->codec->sample_rate = fp->aud_samplerate = aud_samplerate;
    // >>> http://stackoverflow.com/questions/22989838
    // >>> TODO: Add an option to set the codec and the sample format.
    fp->aud_stream->codec->sample_fmt = fp->aud_stream->codec->codec->sample_fmts[0];
    fp->aud_stream->codec->channel_layout = AV_CH_LAYOUT_STEREO;
    fp->aud_stream->codec->channels = 2;
    fp->aud_stream->codec->time_base = fp->aud_stream->time_base = (AVRational){1, aud_samplerate};
    // >> The video stream
    AVCodec *vid_codec = avcodec_find_encoder(AV_CODEC_ID_H264);
    fp->vid_stream = avformat_new_stream(fp->fmt_ctx, vid_codec);
    fp->vid_width = fp->vid_stream->codec->width = width;
    fp->vid_height = fp->vid_stream->codec->height = height;
    fp->vid_stream->id = 1;
    // >>> * ATTENTION: fp->vid_stream->codec is an (AVCodecContext *) rather than (AVCodec *)!
    fp->vid_stream->codec->codec_id = AV_CODEC_ID_H264;
    fp->vid_stream->codec->bit_rate = vid_bitrate > 0 ? vid_bitrate : 1200000;
    fp->vid_stream->codec->pix_fmt = AV_PIX_FMT_YUV420P;
    fp->vid_stream->codec->gop_size = 24;
    fp->vid_stream->codec->time_base = fp->vid_stream->time_base = (AVRational){vid_framerate.den, vid_framerate.num};
    // >> Enable experimental codecs such as AAC
    fp->aud_stream->codec->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
    fp->vid_stream->codec->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
    // >> Some formats want stream headers to be separate.
    // >> XXX: MPEG-4 doesn't have AVFMT_GLOBALHEADER in its format flags??
    //if (fp->fmt_ctx->flags & AVFMT_GLOBALHEADER)
        fp->aud_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
        fp->vid_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
    if ((ret = avcodec_open2(fp->aud_stream->codec, aud_codec, NULL)) < 0) return ret;
    if ((ret = avcodec_open2(fp->vid_stream->codec, vid_codec, NULL)) < 0) return ret;
    // Trigger a full initialization on the format context and write the header.
    avformat_write_header(fp->fmt_ctx, NULL);

    // Miscellaneous initializations
    fp->first_packet = 1;
    fp->last_aud_pts = fp->last_vid_pts = 0;
    fp->nb_aud_buffered_samples = 0;
    // > Video
    fp->vid_frame = av_frame_alloc();
    fp->pict_bufsize = avpicture_get_size(AV_PIX_FMT_YUV420P, width, height);
    fp->pict_buf = (uint8_t *)av_malloc(fp->pict_bufsize);
    // >> Assign the video frame with the allocated buffer
    avpicture_fill((AVPicture *)fp->vid_frame, fp->pict_buf, AV_PIX_FMT_YUV420P, width, height);
    fp->sws_ctx = sws_getContext(
        width, height, PIX_FMT_RGB24, width, height, AV_PIX_FMT_YUV420P,
        SWS_BILINEAR, NULL, NULL, NULL);
    // > Audio
    fp->aud_frame = av_frame_alloc();
    fp->aud_buf = av_frame_alloc();
    fp->aud_buf->format = fp->aud_frame->format = fp->aud_stream->codec->sample_fmt;
    fp->aud_buf->channel_layout = fp->aud_frame->channel_layout = fp->aud_stream->codec->channel_layout;
    fp->aud_buf->sample_rate = fp->aud_frame->sample_rate = fp->aud_stream->codec->sample_rate;
    if (aud_codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE) {
        fp->nb_aud_samples_per_frame = 4096;
        av_log(NULL, AV_LOG_INFO, "frame_pusher: codec has variable frame size capability\n");
    } else fp->nb_aud_samples_per_frame = fp->aud_stream->codec->frame_size;
    fp->aud_buf->nb_samples = fp->aud_frame->nb_samples = fp->nb_aud_samples_per_frame;
    av_log(NULL, AV_LOG_INFO, "frame_pusher: number of samples per frame = %d\n", fp->nb_aud_samples_per_frame);
    if ((ret = av_frame_get_buffer(fp->aud_frame, 0)) < 0) return ret;
    if ((ret = av_frame_get_buffer(fp->aud_buf, 0)) < 0) return ret;
    // >> The audio resampling context
    fp->swr_ctx = swr_alloc();
    if (!fp->swr_ctx) {
        av_log(NULL, AV_LOG_ERROR, "frame_pusher: Cannot initialize audio resampling library"
            "(possibly caused by insufficient memory)\n");
        return AVERROR_UNKNOWN;
    }
    av_opt_set_channel_layout(fp->swr_ctx, "in_channel_layout", fp->aud_stream->codec->channel_layout, 0);
    av_opt_set_channel_layout(fp->swr_ctx, "out_channel_layout", fp->aud_stream->codec->channel_layout, 0);
    av_opt_set_int(fp->swr_ctx, "in_sample_rate", fp->aud_stream->codec->sample_rate, 0);
    av_opt_set_int(fp->swr_ctx, "out_sample_rate", fp->aud_stream->codec->sample_rate, 0);
    av_opt_set_sample_fmt(fp->swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
    av_opt_set_sample_fmt(fp->swr_ctx, "out_sample_fmt", fp->aud_stream->codec->sample_fmt, 0);
    if ((ret = swr_init(fp->swr_ctx)) < 0) return ret;

    *o_fp = fp;
    return 0;
}
Exemple #28
0
int procAudioResampling(AVCodecContext * audio_dec_ctx,
	AVFrame * pAudioDecodeFrame,
	int out_sample_fmt,
	int out_channels,
	int out_sample_rate,
	uint8_t * audio_chunk)
{
	SwrContext * swr_ctx = NULL;
	int data_size = 0;
	int ret = 0;
	int64_t src_ch_layout = audio_dec_ctx->channel_layout;
	int64_t dst_ch_layout = AV_CH_LAYOUT_STEREO;
	int dst_nb_channels = 0;
	int dst_linesize = 0;
	int src_nb_samples = 0;
	int dst_nb_samples = 0;
	int max_dst_nb_samples = 0;
	uint8_t **dst_data = NULL;
	int resampled_data_size = 0;

	swr_ctx = swr_alloc();
	if (!swr_ctx)
	{
		LOGD("swr_alloc error \n");
		return -1;
	}

	src_ch_layout = (audio_dec_ctx->channels ==
		av_get_channel_layout_nb_channels(audio_dec_ctx->channel_layout)) ?
		audio_dec_ctx->channel_layout :
		av_get_default_channel_layout(audio_dec_ctx->channels);

	if (out_channels == 1)
	{
		dst_ch_layout = AV_CH_LAYOUT_MONO;
		//LOGD("dst_ch_layout: AV_CH_LAYOUT_MONO\n");
	}
	else if (out_channels == 2)
	{
		dst_ch_layout = AV_CH_LAYOUT_STEREO;
		//LOGD("dst_ch_layout: AV_CH_LAYOUT_STEREO\n");
	}
	else
	{
		dst_ch_layout = AV_CH_LAYOUT_SURROUND;
		//LOGD("dst_ch_layout: AV_CH_LAYOUT_SURROUND\n");
	}

	if (src_ch_layout <= 0)
	{
		LOGD("src_ch_layout error \n");
		return -1;
	}

	src_nb_samples = pAudioDecodeFrame->nb_samples;
	if (src_nb_samples <= 0)
	{
		LOGD("src_nb_samples error \n");
		return -1;
	}

	av_opt_set_int(swr_ctx, "in_channel_layout", src_ch_layout, 0);
	av_opt_set_int(swr_ctx, "in_sample_rate", audio_dec_ctx->sample_rate, 0);
	av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", audio_dec_ctx->sample_fmt, 0);

	av_opt_set_int(swr_ctx, "out_channel_layout", dst_ch_layout, 0);
	av_opt_set_int(swr_ctx, "out_sample_rate", out_sample_rate, 0);
	av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", (AVSampleFormat)out_sample_fmt, 0);

	if ((ret = swr_init(swr_ctx)) < 0) {
		LOGD("Failed to initialize the resampling context\n");
		return -1;
	}

	max_dst_nb_samples = dst_nb_samples = av_rescale_rnd(src_nb_samples,
		out_sample_rate, audio_dec_ctx->sample_rate, AV_ROUND_UP);
	if (max_dst_nb_samples <= 0)
	{
		LOGD("av_rescale_rnd error \n");
		return -1;
	}

	dst_nb_channels = av_get_channel_layout_nb_channels(dst_ch_layout);
	ret = av_samples_alloc_array_and_samples(&dst_data, &dst_linesize, dst_nb_channels,
		dst_nb_samples, (AVSampleFormat)out_sample_fmt, 0);
	if (ret < 0)
	{
		LOGD("av_samples_alloc_array_and_samples error \n");
		return -1;
	}


	dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, audio_dec_ctx->sample_rate) +
		src_nb_samples, out_sample_rate, audio_dec_ctx->sample_rate, AV_ROUND_UP);
	if (dst_nb_samples <= 0)
	{
		LOGD("av_rescale_rnd error \n");
		return -1;
	}
	if (dst_nb_samples > max_dst_nb_samples)
	{
		av_free(dst_data[0]);
		ret = av_samples_alloc(dst_data, &dst_linesize, dst_nb_channels,
			dst_nb_samples, (AVSampleFormat)out_sample_fmt, 1);
		max_dst_nb_samples = dst_nb_samples;
	}

	if (swr_ctx)
	{
		ret = swr_convert(swr_ctx, dst_data, dst_nb_samples,
			(const uint8_t **)pAudioDecodeFrame->data, pAudioDecodeFrame->nb_samples);
		if (ret < 0)
		{
			LOGD("swr_convert error \n");
			return -1;
		}

		resampled_data_size = av_samples_get_buffer_size(&dst_linesize, dst_nb_channels,
			ret, (AVSampleFormat)out_sample_fmt, 1);
		if (resampled_data_size < 0)
		{
			LOGD("av_samples_get_buffer_size error \n");
			return -1;
		}
	}
	else
	{
		LOGD("swr_ctx null error \n");
		return -1;
	}

	//LOGD("resampled_data_size:%d",resampled_data_size);
	memcpy(audio_chunk, dst_data[0], resampled_data_size);

	if (dst_data)
	{
		av_freep(&dst_data[0]);
	}
	av_freep(&dst_data);
	dst_data = NULL;

	if (swr_ctx)
	{
		swr_free(&swr_ctx);
	}
	return resampled_data_size;
}
Exemple #29
0
int main (int argc, char **argv){
    int ret = 0, got_frame;
    AVFormatContext *ofmt_ctx = NULL;
    AVOutputFormat *ofmt = NULL;
    


    uint8_t *sample_buf;
    
    
    if (argc != 4 && argc != 5) {
        fprintf(stderr, "input  1.source file:%s\n"
                "2.output_video\n"
                "3.output_audio\n"
                "4.mux video file(Optional)\n"
                "\n", argv[0]);
        exit(1);
    }
    
    src_filename = argv[1];
    video_dst_filename = argv[2];
    audio_dst_filename = argv[3];
    //optional mux to any type video
    if(argc == 5){
        out_filename = argv[4];
    }
    
    /* register all formats and codecs */
    av_register_all();
    //for network stream
    avformat_network_init();
    
    ret = init_input();
    if(ret){
        goto end;
    }


    ret = init_video_out_context();
    if(ret){
        goto end;
    }


    ret = init_audio_out_context(sample_buf);
    if(ret){
        goto end;
    }else{
        int aud_buffer_size;
        //alloc frame and packet
        AudFrame = av_frame_alloc();
        AudFrame->nb_samples     = AudCodecCtx->frame_size;
        AudFrame->format         = AudCodecCtx->sample_fmt;
        AudFrame->channel_layout = AudCodecCtx->channel_layout;
        
        aud_buffer_size = av_samples_get_buffer_size(NULL, AudCodecCtx->channels,AudCodecCtx->frame_size,AudCodecCtx->sample_fmt, 1);
        sample_buf = (uint8_t *)av_malloc(aud_buffer_size);
        avcodec_fill_audio_frame(AudFrame, AudCodecCtx->channels, AudCodecCtx->sample_fmt,(const uint8_t*)sample_buf, aud_buffer_size, 1);
        av_new_packet(&AudPkt,aud_buffer_size);
    }
    
    
    if(argc == 5){
        //alloc memory
        avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, out_filename);
        if (!ofmt_ctx) {
            printf( "Could not create output context\n");
            ret = AVERROR_UNKNOWN;
            return 1;
        }
        ofmt = ofmt_ctx->oformat;

        ret = init_output(ofmt_ctx);
        if(ret){
            printf("Init output ERROR\n");
            goto end;
        }
    }
    
    if (!(ofmt->flags & AVFMT_NOFILE)) {
        ret = avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE);
        if (ret < 0) {
            printf( "Could not open output file '%s'", out_filename);
            goto end;
        }
    }

    ret = avformat_write_header(ofmt_ctx, NULL);
    if (ret < 0) {
        printf( "Error occurred when opening output file\n");
        goto end;
    }
    
    //this will fill up by decoder(|read frame|->packet->|decoder|->frame)
    frame = av_frame_alloc();
    if (!frame) {
        fprintf(stderr, "Could not allocate frame\n");
        ret = AVERROR(ENOMEM);
        goto end;
    }
    
    if (video_stream)
        printf("Demuxing video from file '%s' into '%s'\n", src_filename, video_dst_filename);
    if (audio_stream)
        printf("Demuxing audio from file '%s' into '%s'\n", src_filename, audio_dst_filename);
    
    
    //Write video Header
    avformat_write_header(pFormatCtx,NULL);
    //Write audio Header
    avformat_write_header(AudFormatCtx,NULL);
    
    //alloc packet to get copy from pkt
    av_new_packet(&epkt,picture_size);
    
    /*setup the convert parameter
     *due to input sample format AV_SAMPLE_FMT_FLTP
     *can't be converted to AV_SAMPLE_FMT_S16
     *which only accepted by the aac encoder
     */
    swr = swr_alloc();
    av_opt_set_int(swr, "in_channel_layout",  audio_dec_ctx->channel_layout, 0);
    av_opt_set_int(swr, "out_channel_layout", AudCodecCtx->channel_layout,  0);
    av_opt_set_int(swr, "in_sample_rate",     audio_dec_ctx->sample_rate, 0);
    av_opt_set_int(swr, "out_sample_rate",    AudCodecCtx->sample_rate, 0);
    av_opt_set_sample_fmt(swr, "in_sample_fmt",  AV_SAMPLE_FMT_FLTP, 0);
    av_opt_set_sample_fmt(swr, "out_sample_fmt", AV_SAMPLE_FMT_S16,  0);
    swr_init(swr);
    
    
    
    
    /*start read frames from the file */
    while (av_read_frame(fmt_ctx, &pkt) >= 0) {
        //do demux & decode -> encode -> output h264 & aac file
        ret = decode_packet();

        if (ret < 0)
            break;
        if(argc == 5){
            remux_packet(ofmt_ctx,&pkt);
        }
        
        av_free_packet(&pkt);
    }
    
    /* flush cached frames */
    pkt.data = NULL;
    pkt.size = 0;
    
    
    //Flush Encoder
    int retfe = flush_encoder(pFormatCtx,0);
    if (retfe < 0) {
        printf("Flushing encoder failed\n");
        return -1;
    }
    
    //Flush Encoder
    ret = flush_encoder(pFormatCtx,0);
    if (ret < 0) {
        printf("Flushing encoder failed\n");
        return -1;
    }
    
    //Write video trailer
    av_write_trailer(pFormatCtx);
    
    //Write audio Trailer
    av_write_trailer(AudFormatCtx);
    
    //Write remux Trailer
    if(argc == 5){
        av_write_trailer(ofmt_ctx);
    }
    
    
    printf("Output succeeded!!!!\n");
    
    
    
    
    
    
    
    
    
end:
    //free remux
    if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
        avio_close(ofmt_ctx->pb);
    avformat_free_context(ofmt_ctx);
    
    //free audio
    if (audio_st){
        avcodec_close(audio_st->codec);
        av_free(AudFrame);
        av_free(sample_buf);
    }
    avio_close(AudFormatCtx->pb);
    avformat_free_context(AudFormatCtx);
    
    //free video
    if (video_st){
        avcodec_close(video_st->codec);
        av_free(pFrame);
        av_free(picture_buf);
    }
    avio_close(pFormatCtx->pb);  
    avformat_free_context(pFormatCtx);
    
    //free decode
    avcodec_close(video_dec_ctx);
    avcodec_close(audio_dec_ctx);
    avformat_close_input(&fmt_ctx);
    if (video_dst_file)
        fclose(video_dst_file);
    if (audio_dst_file)
        fclose(audio_dst_file);    
    av_frame_free(&frame);
    return ret < 0;
}
Exemple #30
0
int bl_audio_decode(
		char const * const filename,
		struct bl_song * const song) {
	int ret;
	// Contexts and libav variables
	AVPacket avpkt;
	AVFormatContext* context;
	int audio_stream;
	AVCodecContext* codec_context = NULL;
	AVCodec *codec = NULL;
	AVFrame *decoded_frame = NULL;
	struct SwrContext *swr_ctx;

	// Size of the samples
	uint64_t size = 0;

	// Dictionary to fetch tags
	AVDictionaryEntry *tags_dictionary;

	// Planar means channels are interleaved in data section
	// See MP3 vs FLAC for instance.
	int is_planar;

	// Pointer to beginning of music data
	int8_t *beginning;
	// Received frame holder
	int got_frame;
	// Position in the data buffer
	int index;
	// Initialize AV lib
	av_register_all();
	context = avformat_alloc_context();

	av_log_set_level(AV_LOG_QUIET);

	// Open input file
	if (avformat_open_input(&context, filename, NULL, NULL) < 0) {
		fprintf(stderr, "Couldn't open file: %s. Error %d encountered.\n", filename, errno);
		return BL_UNEXPECTED;
	}

	// Search for a valid stream
	if (avformat_find_stream_info(context, NULL) < 0) {
		fprintf(stderr, "Couldn't find stream information\n");
		return BL_UNEXPECTED;
	}

	// Get audio stream
	audio_stream = av_find_best_stream(context, AVMEDIA_TYPE_AUDIO, -1, -1, &codec, 0);
	if (audio_stream < 0) {
		fprintf(stderr, "Couldn't find a suitable audio stream\n");
		return BL_UNEXPECTED;
	}
	// Find associated codec
	codec_context = context->streams[audio_stream]->codec;
	if (!codec_context) {
		fprintf(stderr, "Codec not found!\n");
		return BL_UNEXPECTED;
	}
	if (avcodec_open2(codec_context, codec, NULL) < 0) {
		fprintf(stderr, "Could not open codec\n");
		return BL_UNEXPECTED;
	}

	// Fill song properties
	song->filename = malloc(strlen(filename) + 1);
	strcpy(song->filename, filename);

	song->sample_rate = codec_context->sample_rate;
	song->duration = (uint64_t)(context->duration) / ((uint64_t)AV_TIME_BASE);
	song->bitrate = context->bit_rate;
	song->not_s16 = 0;
	song->nb_bytes_per_sample = av_get_bytes_per_sample(codec_context->sample_fmt);
	song->channels = codec_context->channels;

	// Get number of samples
	size = (
		((uint64_t)(context->duration) * (uint64_t)song->sample_rate) /
		((uint64_t)AV_TIME_BASE)
		) *
		song->channels *
		song->nb_bytes_per_sample;

	// Estimated number of samples
	song->nSamples = (
		(
		((uint64_t)(context->duration) * (uint64_t)song->sample_rate) /
		((uint64_t)AV_TIME_BASE)
		) *
		song->channels
	);

	// Allocate sample_array
	if((song->sample_array = calloc(size, 1)) == NULL) {
		fprintf(stderr, "Could not allocate enough memory\n");
		return BL_UNEXPECTED;
	}

	beginning = song->sample_array;
	index = 0;

	// If the song is in a floating-point format or int32, prepare the conversion to int16
	if(codec_context->sample_fmt != AV_SAMPLE_FMT_S16 &&
		codec_context->sample_fmt != AV_SAMPLE_FMT_S16P) {
		song->not_s16 = 1;
		song->nb_bytes_per_sample = 2;
	
		swr_ctx = swr_alloc();
		av_opt_set_int(swr_ctx, "in_channel_layout", codec_context->channel_layout, 0);
		av_opt_set_int(swr_ctx, "in_sample_rate", codec_context->sample_rate, 0);
		av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", codec_context->sample_fmt, 0);

		av_opt_set_int(swr_ctx, "out_channel_layout", codec_context->channel_layout, 0);
		av_opt_set_int(swr_ctx, "out_sample_rate", codec_context->sample_rate, 0);
		av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
		if((ret = swr_init(swr_ctx)) < 0) {
			fprintf(stderr, "Could not allocate resampler context\n");
			return BL_UNEXPECTED;
		}
	}

    // Zero initialize tags
	song->artist = NULL;
	song->title = NULL;
	song->album = NULL;
	song->tracknumber = NULL;

	// Initialize tracknumber tag
	tags_dictionary = av_dict_get(context->metadata, "track", NULL, 0);
	if (tags_dictionary!= NULL) {
		song->tracknumber = malloc(strlen(tags_dictionary->value) + 1);
		strcpy(song->tracknumber, tags_dictionary->value);
		song->tracknumber[strcspn(song->tracknumber, "/")] = '\0';
	} 
	else {
		song->tracknumber = malloc(1 * sizeof(char));
		strcpy(song->tracknumber, "");
	}

    // Initialize title tag
    tags_dictionary = av_dict_get(context->metadata, "title", NULL, 0);
	if (tags_dictionary!= NULL) {
		song->title = malloc(strlen(tags_dictionary->value) + 1);
		strcpy(song->title, tags_dictionary->value);
	}
	else {
		song->title = malloc(12 * sizeof(char));
		strcpy(song->title, "<no title>");
	}

	// Initialize artist tag
	tags_dictionary = av_dict_get(context->metadata, "ARTIST", NULL, 0);
	if (tags_dictionary!= NULL) {
		song->artist= malloc(strlen(tags_dictionary->value) + 1);
		strcpy(song->artist, tags_dictionary->value);
	}
	else {
		song->artist= malloc(12 * sizeof(char));
		strcpy(song->artist, "<no artist>");
	}

	// Initialize album tag
	tags_dictionary = av_dict_get(context->metadata, "ALBUM", NULL, 0);
	if (tags_dictionary!= NULL) {
		song->album= malloc(strlen(tags_dictionary->value) + 1);
		strcpy(song->album, tags_dictionary->value);
	}
	else {
		song->album= malloc(11 * sizeof(char));
		strcpy(song->album, "<no album>");
	}

	// Initialize genre tag
	tags_dictionary = av_dict_get(context->metadata, "genre", NULL, 0);
	if (tags_dictionary!= NULL) {
		song->genre= malloc(strlen(tags_dictionary->value) + 1);
		strcpy(song->genre, tags_dictionary->value);
	}
	else {
		song->genre = malloc(11 * sizeof(char));
		strcpy(song->genre, "<no genre>");
	}

	// Planar means channels are not interleaved
	is_planar = av_sample_fmt_is_planar(codec_context->sample_fmt);

	// Read the whole data and copy them into a huge buffer
	av_init_packet(&avpkt);
	while(av_read_frame(context, &avpkt) >= 0) {
		if(avpkt.stream_index == audio_stream) {
			got_frame = 0;

			// If decoded frame has not been allocated yet
			if (!decoded_frame) {
				// Try to allocate it
				decoded_frame = av_frame_alloc();
				if(!decoded_frame) {
					fprintf(stderr, "Could not allocate audio frame\n");
					return BL_UNEXPECTED;
				}
			}
			else {
				// Else, unreference it and reset fields
				av_frame_unref(decoded_frame);
			}

			int length = avcodec_decode_audio4(codec_context,
				decoded_frame,
				&got_frame,
				&avpkt);
			if(length < 0) {
				avpkt.size = 0;
			}

			av_packet_unref(&avpkt);

			// Copy decoded data into a huge array
			if(got_frame) {
				size_t data_size = av_samples_get_buffer_size(
					NULL,
					codec_context->channels,
					decoded_frame->nb_samples,
					codec_context->sample_fmt,
				1);

				if((index * song->nb_bytes_per_sample + data_size) > size) {
					int8_t *ptr;
					ptr = realloc(beginning, size + data_size);
					if(ptr != NULL) {
						beginning = ptr;
						size += data_size;
						song->nSamples += data_size / song->nb_bytes_per_sample;
					}
					else
						break;
				}
				int8_t *p = beginning + (index * song->nb_bytes_per_sample);

				// If the song isn't in a 16-bit format, convert it to
				if(song->not_s16 == 1) {
					uint8_t **out_buffer;
					int buff_size;
					buff_size = av_samples_alloc_array_and_samples(&out_buffer, decoded_frame->linesize,
						song->channels, decoded_frame->nb_samples, AV_SAMPLE_FMT_S16, 0);
					ret = swr_convert(swr_ctx, out_buffer, buff_size,
						(const uint8_t**)decoded_frame->extended_data, decoded_frame->nb_samples);
					if(ret < 0) {
						fprintf(stderr, "Error while converting from floating-point to int\n");
						return BL_UNEXPECTED;
					}
					memcpy((index * song->nb_bytes_per_sample) + beginning,
						out_buffer[0], buff_size);
					av_freep(&out_buffer[0]);
					free(out_buffer);
					index += buff_size / song->nb_bytes_per_sample;
				}
				else if(1 == is_planar) {
					for (int i = 0;
						i < (decoded_frame->nb_samples * song->nb_bytes_per_sample);
						i += song->nb_bytes_per_sample) {
						for (int j = 0; j < codec_context->channels; ++j) {
							for (int k = 0; k < song->nb_bytes_per_sample; ++k) {
								*p = ((int8_t*)(decoded_frame->extended_data[j]))[i + k];
								++p;
							}
						}
					}
					index += data_size / song->nb_bytes_per_sample;
				}
				else if (0 == is_planar) {
					memcpy((index * song->nb_bytes_per_sample) + beginning,
						decoded_frame->extended_data[0],
						data_size);
					index += data_size / song->nb_bytes_per_sample;
				}
			}
		}
		else {
			// Dropping packets that do not belong to the audio stream
			// (such as album cover)
			av_packet_unref(&avpkt);
		}
	}
	song->sample_array = beginning;

	// Free memory
	avpkt.data = NULL;
	avpkt.size = 0;

	// Use correct number of samples after decoding
	song->nSamples = index; 
	
	// Read the end of audio, as precognized in http://ffmpeg.org/pipermail/libav-user/2015-August/008433.html
	do {
		avcodec_decode_audio4(codec_context, decoded_frame, &got_frame, &avpkt);
	} while(got_frame);
	// Free memory
	if(song->not_s16)
		swr_free(&swr_ctx);
	avcodec_close(codec_context);
	av_frame_unref(decoded_frame);
	# if LIBAVUTIL_VERSION_MAJOR > 51
	av_frame_free(&decoded_frame);
	#endif
	av_packet_unref(&avpkt);
	avformat_close_input(&context);

	return BL_OK;
}