예제 #1
0
	implementation(size_t output_channels, size_t input_channels, size_t output_sample_rate, size_t input_sample_rate, AVSampleFormat output_sample_format, AVSampleFormat input_sample_format)
		: output_channels_(output_channels)
		, output_sample_format_(output_sample_format)
		, input_channels_(input_channels)
		, input_sample_format_(input_sample_format)
	{
		if(input_channels		!= output_channels || 
		   input_sample_rate	!= output_sample_rate ||
		   input_sample_format	!= output_sample_format)
		{	
			auto resampler = av_audio_resample_init(output_channels,		input_channels,
													output_sample_rate,		input_sample_rate,
													output_sample_format,	input_sample_format,
													16, 10, 0, 0.8);

			buffer2_.resize(AVCODEC_MAX_AUDIO_FRAME_SIZE*2);

			char sample_fmt_string[200];
			av_get_sample_fmt_string(sample_fmt_string, 200, input_sample_format);

			CASPAR_LOG(warning) << L"[audio-resampler]"		
								<< L" sample-rate: "	<< input_sample_rate 
								<< L" channels: "		<< input_channels 
								<< L" sample-fmt: "		<< widen(sample_fmt_string);

			if(resampler)
				resampler_.reset(resampler, audio_resample_close);
			else
				BOOST_THROW_EXCEPTION(caspar_exception());
		}		
	}
static gboolean
gst_ffmpegaudioresample_set_caps (GstBaseTransform * trans, GstCaps * incaps,
    GstCaps * outcaps)
{
  GstFFMpegAudioResample *resample = GST_FFMPEGAUDIORESAMPLE (trans);
  GstStructure *instructure = gst_caps_get_structure (incaps, 0);
  GstStructure *outstructure = gst_caps_get_structure (outcaps, 0);

  GST_LOG_OBJECT (resample, "incaps:%" GST_PTR_FORMAT, incaps);

  GST_LOG_OBJECT (resample, "outcaps:%" GST_PTR_FORMAT, outcaps);

  if (!gst_structure_get_int (instructure, "channels", &resample->in_channels))
    return FALSE;
  if (!gst_structure_get_int (instructure, "rate", &resample->in_rate))
    return FALSE;

  if (!gst_structure_get_int (outstructure, "channels",
          &resample->out_channels))
    return FALSE;
  if (!gst_structure_get_int (outstructure, "rate", &resample->out_rate))
    return FALSE;

  /* FIXME : Allow configuring the various resampling properties */
#define TAPS 16
  resample->res =
      av_audio_resample_init (resample->out_channels, resample->in_channels,
      resample->out_rate, resample->in_rate,
      AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16, TAPS, 10, 0, 0.8);
  if (resample->res == NULL)
    return FALSE;

  return TRUE;
}
예제 #3
0
FFwrapper::AudioResampler::AudioResampler(int in_ch, int in_rate, enum SampleFormat in_fmt, int out_ch, int out_rate) 
    : buf(NULL), buf_size(0), ctx(NULL) {

    ctx = av_audio_resample_init(
        out_ch, in_ch, out_rate, in_rate,       /* in, out parameters */
        SAMPLE_FMT_S16, in_fmt,         /* output, input formats */
        16, 10, 0, 0.8                          /* filter length, log2 phase count, linear?, cutoff */
    );

    if (!ctx) {
        throw AllocationError("audio resampling context");
    }
}
예제 #4
0
AudioBufferPtr AudioDecoderThread::resampleAudio(char* pDecodedData, int framesDecoded,
        int currentSampleFormat)
{
    if (!m_pResampleContext) {
#ifdef LIBAVRESAMPLE_VERSION
        m_pResampleContext = avresample_alloc_context();
        av_opt_set_int(m_pResampleContext, "in_channel_layout",
                av_get_default_channel_layout(m_pStream->codec->channels), 0);
        av_opt_set_int(m_pResampleContext, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0);
        av_opt_set_int(m_pResampleContext, "in_sample_rate", m_InputSampleRate, 0);
        av_opt_set_int(m_pResampleContext, "out_sample_rate", m_AP.m_SampleRate, 0);
        av_opt_set_int(m_pResampleContext, "in_sample_fmt",
                (AVSampleFormat)currentSampleFormat, 0);
        av_opt_set_int(m_pResampleContext, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
        int err = avresample_open(m_pResampleContext);
        AVG_ASSERT(err >= 0);
#else
        m_pResampleContext = av_audio_resample_init(m_AP.m_Channels, 
                m_pStream->codec->channels, m_AP.m_SampleRate, m_InputSampleRate,
                AV_SAMPLE_FMT_S16, (AVSampleFormat)currentSampleFormat, 16, 10, 0, 0.8);
#endif
        AVG_ASSERT(m_pResampleContext);
    }
#ifdef LIBAVRESAMPLE_VERSION
    uint8_t *pResampledData;
    int leftoverSamples = avresample_available(m_pResampleContext);
    int framesAvailable = leftoverSamples +
            av_rescale_rnd(avresample_get_delay(m_pResampleContext) +
                    framesDecoded, m_AP.m_SampleRate, m_InputSampleRate, AV_ROUND_UP);
    av_samples_alloc(&pResampledData, 0, 2, framesAvailable,
            AV_SAMPLE_FMT_S16, 0);
    int framesResampled = avresample_convert(m_pResampleContext, &pResampledData, 0, 
            framesAvailable, (uint8_t**)&pDecodedData, 0, framesDecoded);
    AudioBufferPtr pBuffer(new AudioBuffer(framesResampled, m_AP));
    memcpy(pBuffer->getData(), pResampledData, 
            framesResampled*m_AP.m_Channels*sizeof(short));
    av_freep(&pResampledData);
#else
    short pResampledData[AVCODEC_MAX_AUDIO_FRAME_SIZE/2];
    int framesResampled = audio_resample(m_pResampleContext, pResampledData,
            (short*)pDecodedData, framesDecoded);
    AudioBufferPtr pBuffer(new AudioBuffer(framesResampled, m_AP));
    memcpy(pBuffer->getData(), pResampledData, 
            framesResampled*m_AP.m_Channels*sizeof(short));
#endif
    return pBuffer;
}
예제 #5
0
파일: playvid.c 프로젝트: edy555/openlase
int av_aud_init(char *file)
{
	int i;
    AVDictionary *opts = NULL; 

	av_register_all();

    if(avformat_open_input(&pAFormatCtx, file, NULL, &opts)!=0)
        return -1;

	if (av_find_stream_info(pAFormatCtx)<0)
		return -1;

	audioStream=-1;
	for (i=0; i<pAFormatCtx->nb_streams; i++)
		if (pAFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO)
		{
			audioStream=i;
			break;
		}
	if (audioStream==-1)
		return -1;

	pACodecCtx=pAFormatCtx->streams[audioStream]->codec;

	pACodec=avcodec_find_decoder(pACodecCtx->codec_id);
	if (pACodec==NULL)
		return -1;

	if (avcodec_open(pACodecCtx, pACodec)<0)
		return -1;

	resampler = av_audio_resample_init(2, pACodecCtx->channels,
									   48000, pACodecCtx->sample_rate,
									   AV_SAMPLE_FMT_FLT, pACodecCtx->sample_fmt,
									   16, 10, 0, 0.8);

	if (!resampler)
		return -1;

	buffered_samples = 0;

	return 0;
}
예제 #6
0
bool
AudioResamplerFfmpeg::init(AVCodecContext* ctx) {
    if ((ctx->sample_rate != 44100) ||
#if defined(HAVE_SWRESAMPLE_H) || defined(HAVE_AVRESAMPLE_H)
        (ctx->sample_fmt != AV_SAMPLE_FMT_S16) ||
#endif
        (ctx->channels != 2)) {
        if (! _context) {
#ifdef HAVE_SWRESAMPLE_H
            _context = swr_alloc();
#elif HAVE_AVRESAMPLE_H
            _context = avresample_alloc_context();
#else
            _context = av_audio_resample_init(2, ctx->channels,
                44100, ctx->sample_rate,
                AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16,
                16, 10, 0, 0.8);
#endif
#if defined(HAVE_SWRESAMPLE_H) || defined(HAVE_AVRESAMPLE_H)
            av_opt_set_int(_context, "in_channel_layout",
                av_get_default_channel_layout(ctx->channels), 0);
            av_opt_set_int(_context, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0);
            av_opt_set_int(_context, "in_sample_rate", ctx->sample_rate, 0);
            av_opt_set_int(_context, "out_sample_rate", 44100, 0);
            av_opt_set_int(_context, "in_sample_fmt", ctx->sample_fmt, 0);
            av_opt_set_int(_context, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
#endif
#ifdef HAVE_SWRESAMPLE_H
            swr_init(_context);
#elif HAVE_AVRESAMPLE_H
            avresample_open(_context);
#endif
        }
        return true;
    }
    return false;
}
예제 #7
0
KeyFinder::AudioData* LibAvDecoder::decodeFile(const QString& filePath, const int maxDuration){

  QMutexLocker codecMutexLocker(&codecMutex); // mutex the preparatory section of this method

  AVCodec *codec = NULL;
  AVFormatContext *fCtx = NULL;
  AVCodecContext *cCtx = NULL;
  AVDictionary* dict = NULL;

  // convert filepath
#ifdef Q_OS_WIN
  const wchar_t* filePathWc = reinterpret_cast<const wchar_t*>(filePath.constData());
  const char* filePathCh = utf16_to_utf8(filePathWc);
#else
  QByteArray encodedPath = QFile::encodeName(filePath);
  const char* filePathCh = encodedPath;
#endif

  // open file
  int openInputResult = avformat_open_input(&fCtx, filePathCh, NULL, NULL);
  if(openInputResult != 0){
    throw KeyFinder::Exception(GuiStrings::getInstance()->libavCouldNotOpenFile(openInputResult).toLocal8Bit().constData());
  }

  if(avformat_find_stream_info(fCtx, NULL) < 0){
    av_close_input_file(fCtx);
    throw KeyFinder::Exception(GuiStrings::getInstance()->libavCouldNotFindStreamInformation().toLocal8Bit().constData());
  }
  int audioStream = -1;
  for(int i=0; i<(signed)fCtx->nb_streams; i++){
    if(fCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO){
      audioStream = i;
      break;
    }
  }
  if(audioStream == -1){
    av_close_input_file(fCtx);
    throw KeyFinder::Exception(GuiStrings::getInstance()->libavCouldNotFindAudioStream().toLocal8Bit().constData());
  }

  // Determine duration
  int durationSeconds = fCtx->duration / AV_TIME_BASE;
  int durationMinutes = durationSeconds / 60;
  // First condition is a hack for bizarre overestimation of some MP3s
  if(durationMinutes < 720 && durationSeconds > maxDuration * 60){
    av_close_input_file(fCtx);
    throw KeyFinder::Exception(GuiStrings::getInstance()->durationExceedsPreference(durationMinutes, durationSeconds % 60, maxDuration).toLocal8Bit().constData());
  }

  // Determine stream codec
  cCtx = fCtx->streams[audioStream]->codec;
  codec = avcodec_find_decoder(cCtx->codec_id);
  if(codec == NULL){
    av_close_input_file(fCtx);
    throw KeyFinder::Exception(GuiStrings::getInstance()->libavUnsupportedCodec().toLocal8Bit().constData());
  }

  // Open codec
  int codecOpenResult = avcodec_open2(cCtx, codec, &dict);
  if(codecOpenResult < 0){
    av_close_input_file(fCtx);
    throw KeyFinder::Exception(GuiStrings::getInstance()->libavCouldNotOpenCodec(codec->long_name, codecOpenResult).toLocal8Bit().constData());
  }

  ReSampleContext* rsCtx = av_audio_resample_init(
        cCtx->channels, cCtx->channels,
        cCtx->sample_rate, cCtx->sample_rate,
        AV_SAMPLE_FMT_S16, cCtx->sample_fmt,
        0, 0, 0, 0);
  if(rsCtx == NULL){
    avcodec_close(cCtx);
    av_close_input_file(fCtx);
    throw KeyFinder::Exception(GuiStrings::getInstance()->libavCouldNotCreateResampleContext().toLocal8Bit().constData());
  }

  qDebug("Decoding %s (%s, %d)", filePathCh, av_get_sample_fmt_name(cCtx->sample_fmt), cCtx->sample_rate);

  codecMutexLocker.unlock();

  // Prep buffer
  KeyFinder::AudioData *audio = new KeyFinder::AudioData();
  audio->setFrameRate(cCtx->sample_rate);
  audio->setChannels(cCtx->channels);
  // Decode stream
  AVPacket avpkt;
  int badPacketCount = 0;
  int badPacketThreshold = 100;
  while(true){
    av_init_packet(&avpkt);
    if(av_read_frame(fCtx, &avpkt) < 0)
      break;
    if(avpkt.stream_index == audioStream){
      try{
        int result = decodePacket(cCtx, rsCtx, &avpkt, audio);
        if(result != 0){
          if(badPacketCount < badPacketThreshold){
            badPacketCount++;
          }else{
            avcodec_close(cCtx);
            av_close_input_file(fCtx);
            throw KeyFinder::Exception(GuiStrings::getInstance()->libavTooManyBadPackets(badPacketThreshold).toLocal8Bit().constData());
          }
        }
      }catch(KeyFinder::Exception& e){
        throw e;
      }
    }
    av_free_packet(&avpkt);
  }

  codecMutexLocker.relock();
  audio_resample_close(rsCtx);
  int codecCloseResult = avcodec_close(cCtx);
  if(codecCloseResult < 0){
    qCritical("Error closing audio codec: %s (%d)", codec->long_name, codecCloseResult);
  }
  codecMutexLocker.unlock();

  av_close_input_file(fCtx);
  return audio;
}
예제 #8
0
KeyFinder::AudioData* LibAvDecoder::decodeFile(const QString& filePath){

  QMutexLocker codecMutexLocker(&codecMutex); // mutex the preparatory section of this method

  AVCodec *codec = NULL;
  AVFormatContext *fCtx = NULL;
  AVCodecContext *cCtx = NULL;
  AVDictionary* dict = NULL;

  // convert filepath
#ifdef Q_OS_WIN
  const wchar_t* filePathWc = reinterpret_cast<const wchar_t*>(filePath.constData());
  const char* filePathCh = utf16_to_utf8(filePathWc);
#else
  QByteArray encodedPath = QFile::encodeName(filePath);
  const char* filePathCh = encodedPath;
#endif

  // open file
  int openInputResult = avformat_open_input(&fCtx, filePathCh, NULL, NULL);
  if(openInputResult != 0){
    std::ostringstream ss;
    ss << "Could not open audio file (" << openInputResult << ")";
    throw KeyFinder::Exception(ss.str());
  }

  if(avformat_find_stream_info(fCtx,NULL) < 0){
    throw KeyFinder::Exception("Could not find stream information");
  }
  int audioStream = -1;
  for(int i=0; i<(signed)fCtx->nb_streams; i++){
    if(fCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO){
      audioStream = i;
      break;
    }
  }
  if(audioStream == -1){
    throw KeyFinder::Exception("Could not find an audio stream");
  }

  // Determine stream codec
  cCtx = fCtx->streams[audioStream]->codec;
  codec = avcodec_find_decoder(cCtx->codec_id);
  if(codec == NULL){
    throw KeyFinder::Exception("Audio stream has unsupported codec");
  }

  // Open codec
  int codecOpenResult = avcodec_open2(cCtx, codec, &dict);
  if(codecOpenResult < 0){
    std::ostringstream ss;
    ss << "Could not open audio codec: " << codec->long_name << " (" << codecOpenResult << ")";
    throw KeyFinder::Exception(ss.str());
  }

  ReSampleContext* rsCtx = av_audio_resample_init(
        cCtx->channels, cCtx->channels,
        cCtx->sample_rate, cCtx->sample_rate,
        AV_SAMPLE_FMT_S16, cCtx->sample_fmt,
        0, 0, 0, 0);
  if(rsCtx == NULL){
    throw KeyFinder::Exception("Could not create ReSampleContext");
  }

  qDebug("Decoding %s (%s, %d)", filePathCh, av_get_sample_fmt_name(cCtx->sample_fmt), cCtx->sample_rate);

  codecMutexLocker.unlock();

  // Prep buffer
  KeyFinder::AudioData *audio = new KeyFinder::AudioData();
  audio->setFrameRate(cCtx->sample_rate);
  audio->setChannels(cCtx->channels);
  // Decode stream
  AVPacket avpkt;
  int badPacketCount = 0;
  while(true){
    av_init_packet(&avpkt);
    if(av_read_frame(fCtx, &avpkt) < 0)
      break;
    if(avpkt.stream_index == audioStream){
      try{
        int result = decodePacket(cCtx, rsCtx, &avpkt, audio);
        if(result != 0){
          if(badPacketCount < 100){
            badPacketCount++;
          }else{
            throw KeyFinder::Exception("100 bad packets");
          }
        }
      }catch(KeyFinder::Exception& e){
        throw e;
      }
    }
    av_free_packet(&avpkt);
  }

  codecMutexLocker.relock();
  audio_resample_close(rsCtx);
  int codecCloseResult = avcodec_close(cCtx);
  if(codecCloseResult < 0){
    qCritical("Error closing audio codec: %s (%d)", codec->long_name, codecCloseResult);
  }
  codecMutexLocker.unlock();

  av_close_input_file(fCtx);
  return audio;
}
예제 #9
0
int AudioConvertFunc(const char *outfilename,int sample_rate,int channels,int sec,const char *inputfilename,HWND mParentHwnd,UINT mMsg)
{
	AVCodec *aCodec =NULL;
	AVPacket *packet = NULL;
	AVFormatContext *pFormatCtx =NULL;
    AVCodecContext *aCodecCtx= NULL;
	ReSampleContext* ResampleCtx=NULL;
	AVFrame *decoded_frame = NULL;
	int datasize;
	//int tempcount = 0;
	//long total_out_size=0;
	int64_t total_in_convert_size = 0;
	int audioConvertProgress = 0;
	int tempAudioConvertProgress;
	unsigned int i;
	int len, ret, buffer_size, count, audio_stream_index = -1, totle_samplenum = 0;

	FILE *outfile = NULL;// *infile;
	head_pama pt;

	int16_t *audio_buffer = NULL;
	int16_t *resamplebuff = NULL;
	int ResampleChange=0;
	int ChannelsChange=0;
	int tempret;

	packet = (AVPacket*)malloc(sizeof(AVPacket));
	if (packet==NULL)
	{
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)(-1));
		return -1;
	}
	packet->data=NULL;

	buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE * 100;
	audio_buffer = (int16_t *)av_malloc(buffer_size);
	if (audio_buffer==NULL)
	{
		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)(-2));
		return -2;
	}
	
	av_register_all();

	av_init_packet(packet);
#if 0
	/**********尝试分解av_open_input_file函数*************/
	int ret = 0;
	
	AVFormatParameters ap = { 0 };
	AVDictionary *tmp = NULL;
	AVInputFormat *fmt = NULL;
	AVDictionary **options = NULL;
	if (!pFormatCtx && !(pFormatCtx = avformat_alloc_context()))
		return AVERROR(ENOMEM);
	if (fmt)
		pFormatCtx->iformat = fmt;

	if (options)
		av_dict_copy(&tmp, *options, 0);

	if ((ret = av_opt_set_dict(pFormatCtx, &tmp)) < 0)
		goto fail;
	
	AVDictionary *tmp = NULL;

	if (!pFormatCtx && !(pFormatCtx = avformat_alloc_context()))
		return AVERROR(ENOMEM);

	int ret;
	AVProbeData pd = {inputfilename, NULL, 0};

	if (pFormatCtx->pb) {
		pFormatCtx->flags |= AVFMT_FLAG_CUSTOM_IO;
		if (!pFormatCtx->iformat)
			return av_probe_input_buffer(pFormatCtx->pb, &pFormatCtx->iformat, inputfilename, pFormatCtx, 0, 0);
		else if (pFormatCtx->iformat->flags & AVFMT_NOFILE)
			av_log(pFormatCtx, AV_LOG_WARNING, "Custom AVIOContext makes no sense and "
			"will be ignored with AVFMT_NOFILE format.\n");
		return 0;
	}

	if ( (pFormatCtx->iformat && pFormatCtx->iformat->flags & AVFMT_NOFILE) ||
		(!pFormatCtx->iformat && (pFormatCtx->iformat = av_probe_input_format(&pd, 0))))
		return 0;

	URLContext *h;
	int err;

	err = ffurl_open(&h, inputfilename, AVIO_RDONLY);
	if (err < 0)
		return err;
	err = ffio_fdopen(pFormatCtx, h);
	if (err < 0) {
		ffurl_close(h);
		return err;
	}

	if (pFormatCtx->iformat)
		return 0;
	av_probe_input_buffer(pFormatCtx->pb, &pFormatCtx->iformat, inputfilename, pFormatCtx, 0, 0);


	if (pFormatCtx->iformat->flags & AVFMT_NEEDNUMBER) {
		if (!av_filename_number_test(inputfilename)) {
			ret = AVERROR(EINVAL);
			goto fail;
		}
	}

	pFormatCtx->duration = pFormatCtx->start_time = AV_NOPTS_VALUE;
	av_strlcpy(pFormatCtx->filename, inputfilename ? inputfilename : "", sizeof(pFormatCtx->filename));

	/* allocate private data */
	if (pFormatCtx->iformat->priv_data_size > 0) {
		if (!(pFormatCtx->priv_data = av_mallocz(pFormatCtx->iformat->priv_data_size))) {
			ret = AVERROR(ENOMEM);
			goto fail;
		}
		if (pFormatCtx->iformat->priv_class) {
			*(const AVClass**)pFormatCtx->priv_data = pFormatCtx->iformat->priv_class;
			av_opt_set_defaults(pFormatCtx->priv_data);
			if ((ret = av_opt_set_dict(pFormatCtx->priv_data, &tmp)) < 0)
				goto fail;
		}
	}

	/* e.g. AVFMT_NOFILE formats will not have a AVIOContext */
	if (pFormatCtx->pb)
		ff_id3v2_read(pFormatCtx, ID3v2_DEFAULT_MAGIC);

	if (!(pFormatCtx->flags&AVFMT_FLAG_PRIV_OPT) && pFormatCtx->iformat->read_header)
		if ((ret = pFormatCtx->iformat->read_header(pFormatCtx, &ap)) < 0)
			goto fail;

	if (!(pFormatCtx->flags&AVFMT_FLAG_PRIV_OPT) && pFormatCtx->pb && !pFormatCtx->data_offset)
		pFormatCtx->data_offset = avio_tell(pFormatCtx->pb);

	pFormatCtx->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;

	if (options) {
		av_dict_free(options);
		*options = tmp;
	}
	return 0;

fail:
	av_dict_free(&tmp);
	if (pFormatCtx->pb && !(pFormatCtx->flags & AVFMT_FLAG_CUSTOM_IO))
		avio_close(pFormatCtx->pb);
	avformat_free_context(pFormatCtx);
	pFormatCtx = NULL;
	return ret;

	return err;
	/**********尝试分解av_open_input_file函数*************/
	//pFormatCtx = avformat_alloc_context();
#endif
	ret = av_open_input_file(&pFormatCtx, inputfilename, NULL,0, NULL);

	if(ret < 0)
	{
		if (audio_buffer!=NULL)
		{
			av_free(audio_buffer);
			audio_buffer=NULL;
		}
		
		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		if (pFormatCtx!=NULL)
		{
			av_close_input_file(pFormatCtx);
			pFormatCtx=NULL;
		}
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)1);
		return 1;  
	}

	ret = av_find_stream_info(pFormatCtx);

	if( ret < 0)
	{
		if (audio_buffer!=NULL)
		{
			av_free(audio_buffer);
			audio_buffer=NULL;
		}

		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		if (pFormatCtx!=NULL)
		{
			av_close_input_file(pFormatCtx);
			pFormatCtx=NULL;
		}
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)2);
		return 2;
	}

	audio_stream_index=-1;
	for(i=0; i< (signed)pFormatCtx->nb_streams; i++)
	{

		if(pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO && audio_stream_index < 0)
		{
			audio_stream_index = i;
			break;
		}
	}

	if(audio_stream_index == -1)
	{
		if (audio_buffer!=NULL)
		{
			av_free(audio_buffer);
			audio_buffer=NULL;
		}

		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		if (pFormatCtx!=NULL)
		{
			av_close_input_file(pFormatCtx);
			pFormatCtx=NULL;
		}
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)3);
		return 3;
	}

	aCodecCtx = pFormatCtx->streams[audio_stream_index]->codec;
	if (aCodecCtx==NULL)
	{
		if (audio_buffer!=NULL)
		{
			av_free(audio_buffer);
			audio_buffer=NULL;
		}

		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		if (pFormatCtx!=NULL)
		{
			av_close_input_file(pFormatCtx);
			pFormatCtx=NULL;
		}
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)4);
		return 4;
	}
	aCodec = avcodec_find_decoder(aCodecCtx->codec_id);
	if(!aCodec) 
	{
		if (audio_buffer!=NULL)
		{
			av_free(audio_buffer);
			audio_buffer=NULL;
		}

		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		if (pFormatCtx!=NULL)
		{
			av_close_input_file(pFormatCtx);
			pFormatCtx=NULL;
		}
		/*if (aCodecCtx!=NULL)
		{
			avcodec_close(aCodecCtx);
			aCodecCtx=NULL;
		}*/
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)5);
		return 5;
	}
	//resample init
	if (channels==0)
	{
		channels=aCodecCtx->channels;
	}
	if (sample_rate==0)
	{
		sample_rate=aCodecCtx->sample_rate;
	}
	//if (aCodecCtx->channels!=channels)
	//{
	//	ChannelsChange=1;
	//	ResampleChange=1;
	//}
	if (aCodecCtx->sample_rate!=sample_rate||aCodecCtx->channels!=channels)
	{
		ResampleChange=1;
	}
	if (ResampleChange==1)
	{
		ResampleCtx = av_audio_resample_init(channels,aCodecCtx->channels,sample_rate,aCodecCtx->sample_rate,SAMPLE_FMT_S16,SAMPLE_FMT_S16,16,10,0,1.0);
		if (ResampleCtx==NULL)
		{
			if (audio_buffer!=NULL)
			{
				av_free(audio_buffer);
				audio_buffer=NULL;
			}

			if (packet->data!=NULL)
			{
				av_free_packet(packet);
				packet->data=NULL;
			}
			if (packet!=NULL)
			{
				free(packet);
				packet=NULL;
			}
			if (pFormatCtx!=NULL)
			{
				av_close_input_file(pFormatCtx);
				pFormatCtx=NULL;
			}
			/*if (aCodecCtx!=NULL)
			{
				avcodec_close(aCodecCtx);
				aCodecCtx=NULL;
			}*/
			ResampleChange=0;
			PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)6);
			return 6;
		}
		resamplebuff=(int16_t *)malloc(buffer_size);
		if (resamplebuff==NULL)
		{
			if (audio_buffer!=NULL)
			{
				av_free(audio_buffer);
				audio_buffer=NULL;
			}

			if (packet->data!=NULL)
			{
				av_free_packet(packet);
				packet->data=NULL;
			}
			if (packet!=NULL)
			{
				free(packet);
				packet=NULL;
			}
			if (pFormatCtx!=NULL)
			{
				av_close_input_file(pFormatCtx);
				pFormatCtx=NULL;
			}
			/*if (aCodecCtx!=NULL)
			{
				avcodec_close(aCodecCtx);
				aCodecCtx=NULL;
			}*/
			
			if (ResampleChange==1&&ResampleCtx!=NULL)
			{
				audio_resample_close(ResampleCtx);
				ResampleCtx=NULL;
			}
			PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)7);
			return 7;
		}
	}
	//
	datasize=sec*sample_rate;
	if(avcodec_open(aCodecCtx, aCodec)<0)
	{
		if (audio_buffer!=NULL)
		{
			av_free(audio_buffer);
			audio_buffer=NULL;
		}

		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		if (pFormatCtx!=NULL)
		{
			av_close_input_file(pFormatCtx);
			pFormatCtx=NULL;
		}
		if (aCodecCtx!=NULL)
		{
			avcodec_close(aCodecCtx);
			aCodecCtx=NULL;
		}

		if (ResampleChange==1&&ResampleCtx!=NULL&&resamplebuff!=NULL)
		{
			audio_resample_close(ResampleCtx);
			ResampleCtx=NULL;
			free(resamplebuff);
			resamplebuff=NULL;
		}
		ResampleChange=0;
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)8);
		return 8;
	}

	pt.bits = 16;
	pt.channels = channels;
	pt.rate = sample_rate;

	outfile = fopen(outfilename, "wb");
	if (!outfile) 
	{
		if (audio_buffer!=NULL)
		{
			av_free(audio_buffer);
			audio_buffer=NULL;
		}

		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		if (pFormatCtx!=NULL)
		{
			av_close_input_file(pFormatCtx);
			pFormatCtx=NULL;
		}
		if (aCodecCtx!=NULL)
		{
			avcodec_close(aCodecCtx);
			aCodecCtx=NULL;
		}

		if (ResampleChange==1&&ResampleCtx!=NULL&&resamplebuff!=NULL)
		{
			audio_resample_close(ResampleCtx);
			ResampleCtx=NULL;
			free(resamplebuff);
			resamplebuff=NULL;
		}
		ResampleChange=0;
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)9);
		return 9;
	}

	fseek(outfile,44,SEEK_SET);
    while(av_read_frame(pFormatCtx, packet) >= 0) 
	{
		CheckMessageQueue();
	    if(packet->stream_index == audio_stream_index)
	    {
			//while(packet->size > 0)
			//{
				buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE * 100;
				len = avcodec_decode_audio3(aCodecCtx, audio_buffer, &buffer_size, packet);

				if (len < 0) 
				{
					break;
				}

				if(buffer_size > 0)
				{
					//resample
					if (ResampleChange==1)
					{
						int samples=buffer_size/ ((aCodecCtx->channels) * 2);
						int resamplenum= 0;
						resamplenum = audio_resample(ResampleCtx, 
							resamplebuff, 
							audio_buffer, 
							samples);
						count = fwrite(resamplebuff, 2*channels, resamplenum, outfile);
					}
					
					else
					{
						count = fwrite(audio_buffer, 2*aCodecCtx->channels, buffer_size/((aCodecCtx->channels)*2), outfile);
					}
					totle_samplenum += count;
				}
				//tempcount++;
				//total_out_size += count*2*aCodecCtx->channels;
				total_in_convert_size += packet->size;
				tempAudioConvertProgress = 100*total_in_convert_size/(pFormatCtx->file_size);
				if(tempAudioConvertProgress != audioConvertProgress)
				{
					if(tempAudioConvertProgress == 100)
						tempAudioConvertProgress = 99;
					audioConvertProgress = tempAudioConvertProgress;
					tempret = PostMessage(mParentHwnd,mMsg,DECING_TAG,audioConvertProgress);
				}
				if (packet->data!=NULL)
				{
					av_free_packet(packet);
					packet->data=NULL;
				}
				//packet->size -= len;
				//packet->data += len;
			//}
			if (datasize!=0&&totle_samplenum>=datasize)
			{
				break;
			}
	    }
	}
	audioConvertProgress = 100;
	PostMessage(mParentHwnd,mMsg,DECING_TAG,audioConvertProgress);
	fseek(outfile,0,SEEK_SET);
	wav_write_header(outfile, pt, totle_samplenum);
	
	if (outfile!=NULL)
	{
		fclose(outfile);
		outfile=NULL;
	}
    
	if (audio_buffer!=NULL)
	{
		av_free(audio_buffer);
		audio_buffer=NULL;
	}
	
	if (aCodecCtx!=NULL)
	{
		avcodec_close(aCodecCtx);
		aCodecCtx=NULL;
	}
	
	if (packet!=NULL)
	{
		free(packet);//
		packet=NULL;
	}
	
	if (pFormatCtx!=NULL)
	{
		av_close_input_file(pFormatCtx);
		pFormatCtx=NULL;
	}
	
	if (ResampleChange==1)
	{
		if (resamplebuff!=NULL)
		{
			free(resamplebuff);
			resamplebuff=NULL;
		}
		if (ResampleCtx!=NULL)
		{
			audio_resample_close(ResampleCtx);
			ResampleCtx=NULL;
		}
	}
	if (totle_samplenum<=sample_rate*5)
	{
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)10);
		return 10;
	}
	PostMessage(mParentHwnd,mMsg,FINISH_TAG,NULL);
	return 0;
}
예제 #10
0
int AudioConvertFunc_Buffer(const short *pcmbuffer,int sample_rate,int channels,int sec,const char *inputfilename,int *pcmbuff_size)
{
	AVCodec *aCodec =NULL;
	AVPacket *packet = NULL;
	AVFormatContext *pFormatCtx =NULL;
    AVCodecContext *aCodecCtx= NULL;
	ReSampleContext* ResampleCtx=NULL;
	AVFrame *decoded_frame = NULL;
	int datasize;

	unsigned int i;
	int len, ret, buffer_size, audio_stream_index = -1, totle_samplenum = 0;

	////1.FILE *outfile = NULL;// *infile;
	

	head_pama pt;

	int16_t *audio_buffer = NULL;
	int16_t *resamplebuff = NULL;
	int ResampleChange=0;
	int ChannelsChange=0;
	int totalsize=0;

	packet = (AVPacket*)malloc(sizeof(AVPacket));
	if (packet==NULL)
	{
		return -1;
	}
	packet->data=NULL;

	buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE * 100;
	audio_buffer = (int16_t *)av_malloc(buffer_size);
	if (audio_buffer==NULL)
	{
		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		
		return -2;
	}
	
	av_register_all();

	av_init_packet(packet);

	//pFormatCtx = avformat_alloc_context();
	ret = av_open_input_file(&pFormatCtx, inputfilename, NULL,0, NULL);

	if(ret < 0)
	{
		if (audio_buffer!=NULL)
		{
			av_free(audio_buffer);
			audio_buffer=NULL;
		}
		
		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		if (pFormatCtx!=NULL)
		{
			av_close_input_file(pFormatCtx);
			pFormatCtx=NULL;
		}
		
		return 1;  
	}

	ret = av_find_stream_info(pFormatCtx);

	if( ret < 0)
	{
		if (audio_buffer!=NULL)
		{
			av_free(audio_buffer);
			audio_buffer=NULL;
		}

		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		if (pFormatCtx!=NULL)
		{
			av_close_input_file(pFormatCtx);
			pFormatCtx=NULL;
		}

		return 2;
	}

	audio_stream_index=-1;
	for(i=0; i< (signed)pFormatCtx->nb_streams; i++)
	{

		if(pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO && audio_stream_index < 0)
		{
			audio_stream_index = i;
			break;
		}
	}

	if(audio_stream_index == -1)
	{
		if (audio_buffer!=NULL)
		{
			av_free(audio_buffer);
			audio_buffer=NULL;
		}

		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		if (pFormatCtx!=NULL)
		{
			av_close_input_file(pFormatCtx);
			pFormatCtx=NULL;
		}

		return 3;
	}

	aCodecCtx = pFormatCtx->streams[audio_stream_index]->codec;
	if (aCodecCtx==NULL)
	{
		if (audio_buffer!=NULL)
		{
			av_free(audio_buffer);
			audio_buffer=NULL;
		}

		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		if (pFormatCtx!=NULL)
		{
			av_close_input_file(pFormatCtx);
			pFormatCtx=NULL;
		}
		return 4;
	}
	aCodec = avcodec_find_decoder(aCodecCtx->codec_id);
	if(!aCodec) 
	{
		if (audio_buffer!=NULL)
		{
			av_free(audio_buffer);
			audio_buffer=NULL;
		}

		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		if (pFormatCtx!=NULL)
		{
			av_close_input_file(pFormatCtx);
			pFormatCtx=NULL;
		}
		/*if (aCodecCtx!=NULL)
		{
			avcodec_close(aCodecCtx);
			aCodecCtx=NULL;
		}*/
		return 5;
	}
	//resample init
	if (channels==0)
	{
		channels=aCodecCtx->channels;
	}
	if (sample_rate==0)
	{
		sample_rate=aCodecCtx->sample_rate;
	}
	//if (aCodecCtx->channels!=channels)
	//{
	//	ChannelsChange=1;
	//	ResampleChange=1;
	//}
	if (aCodecCtx->sample_rate!=sample_rate||aCodecCtx->channels!=channels)
	{
		ResampleChange=1;
	}
	if (ResampleChange==1)
	{
		ResampleCtx = av_audio_resample_init(channels,aCodecCtx->channels,sample_rate,aCodecCtx->sample_rate,SAMPLE_FMT_S16,SAMPLE_FMT_S16,16,10,0,1.0);
		if (ResampleCtx==NULL)
		{
			if (audio_buffer!=NULL)
			{
				av_free(audio_buffer);
				audio_buffer=NULL;
			}

			if (packet->data!=NULL)
			{
				av_free_packet(packet);
				packet->data=NULL;
			}
			if (packet!=NULL)
			{
				free(packet);
				packet=NULL;
			}
			if (pFormatCtx!=NULL)
			{
				av_close_input_file(pFormatCtx);
				pFormatCtx=NULL;
			}
			/*if (aCodecCtx!=NULL)
			{
				avcodec_close(aCodecCtx);
				aCodecCtx=NULL;
			}*/
			ResampleChange=0;
			return 6;
		}
		resamplebuff=(int16_t *)malloc(buffer_size);
		if (resamplebuff==NULL)
		{
			if (audio_buffer!=NULL)
			{
				av_free(audio_buffer);
				audio_buffer=NULL;
			}

			if (packet->data!=NULL)
			{
				av_free_packet(packet);
				packet->data=NULL;
			}
			if (packet!=NULL)
			{
				free(packet);
				packet=NULL;
			}
			if (pFormatCtx!=NULL)
			{
				av_close_input_file(pFormatCtx);
				pFormatCtx=NULL;
			}
			/*if (aCodecCtx!=NULL)
			{
				avcodec_close(aCodecCtx);
				aCodecCtx=NULL;
			}*/
			
			if (ResampleChange==1&&ResampleCtx!=NULL)
			{
				audio_resample_close(ResampleCtx);
				ResampleCtx=NULL;
			}
			return 7;
		}
	}
	//
	datasize=sec*sample_rate;
	if(avcodec_open(aCodecCtx, aCodec)<0)
	{
		if (audio_buffer!=NULL)
		{
			av_free(audio_buffer);
			audio_buffer=NULL;
		}

		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		if (pFormatCtx!=NULL)
		{
			av_close_input_file(pFormatCtx);
			pFormatCtx=NULL;
		}
		if (aCodecCtx!=NULL)
		{
			avcodec_close(aCodecCtx);
			aCodecCtx=NULL;
		}

		if (ResampleChange==1&&ResampleCtx!=NULL&&resamplebuff!=NULL)
		{
			audio_resample_close(ResampleCtx);
			ResampleCtx=NULL;
			free(resamplebuff);
			resamplebuff=NULL;
		}
		ResampleChange=0;
		return 8;
	}

	pt.bits = 16;
	pt.channels = channels;
	pt.rate = sample_rate;

	////2.outfile = fopen(outfilename, "wb");
	

	////3.outfile pcmbuffer
	if (!pcmbuffer) 
	{
		if (audio_buffer!=NULL)
		{
			av_free(audio_buffer);
			audio_buffer=NULL;
		}

		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		if (pFormatCtx!=NULL)
		{
			av_close_input_file(pFormatCtx);
			pFormatCtx=NULL;
		}
		if (aCodecCtx!=NULL)
		{
			avcodec_close(aCodecCtx);
			aCodecCtx=NULL;
		}

		if (ResampleChange==1&&ResampleCtx!=NULL&&resamplebuff!=NULL)
		{
			audio_resample_close(ResampleCtx);
			ResampleCtx=NULL;
			free(resamplebuff);
			resamplebuff=NULL;
		}
		ResampleChange=0;
		return 9;
	}

	////4.fseek(outfile,44,SEEK_SET);


    while(av_read_frame(pFormatCtx, packet) >= 0) 
	{
		CheckMessageQueue();
	    if(packet->stream_index == audio_stream_index)
	    {
			//while(packet->size > 0)
			//{
				buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE * 100;
				len = avcodec_decode_audio3(aCodecCtx, audio_buffer, &buffer_size, packet);

				if (len < 0) 
				{
					break;
				}

				if(buffer_size > 0)
				{
					//resample
					
					if (ResampleChange==1)
					{
						int samples=buffer_size/ ((aCodecCtx->channels) * 2);
						int resamplenum= 0;
						
						resamplenum = audio_resample(ResampleCtx, 
							resamplebuff, 
							audio_buffer, 
							samples);
						////5.count = fwrite(resamplebuff, 2*channels, resamplenum, outfile);
						memcpy((char*)(pcmbuffer+totalsize/2),resamplebuff,2*channels*resamplenum);
						totalsize+=2*channels*resamplenum;
						totle_samplenum+=resamplenum;
					}
					
					else
					{
						////6.count = fwrite(audio_buffer, 2*aCodecCtx->channels, buffer_size/((aCodecCtx->channels)*2), outfile);
						
						memcpy((char*)(pcmbuffer+totalsize/2),audio_buffer,2*channels*buffer_size/((aCodecCtx->channels)*2));
						totalsize+=2*channels*buffer_size/((aCodecCtx->channels)*2);
						totle_samplenum+=buffer_size/ ((aCodecCtx->channels) * 2);
						
					}
					////totle_samplenum += count;
					if(totalsize>=2*channels*(sample_rate*sec))
					{   
						*pcmbuff_size=totalsize/2/channels;
						break;
					}


				}
				if (packet->data!=NULL)
				{
					av_free_packet(packet);
					packet->data=NULL;
				}
				//packet->size -= len;
				//packet->data += len;
			//}
			if (datasize!=0&&totle_samplenum>=datasize)
			{
				break;
			}
	    }
	}
    
	if (audio_buffer!=NULL)
	{
		av_free(audio_buffer);
		audio_buffer=NULL;
	}
	
	if (aCodecCtx!=NULL)
	{
		avcodec_close(aCodecCtx);
		aCodecCtx=NULL;
	}
	
	if (packet!=NULL)
	{
		free(packet);//
		packet=NULL;
	}
	
	if (pFormatCtx!=NULL)
	{
		av_close_input_file(pFormatCtx);
		pFormatCtx=NULL;
	}
	
	if (ResampleChange==1)
	{
		if (resamplebuff!=NULL)
		{
			free(resamplebuff);
			resamplebuff=NULL;
		}
		if (ResampleCtx!=NULL)
		{
			audio_resample_close(ResampleCtx);
			ResampleCtx=NULL;
		}
	}
	if (totle_samplenum<=sample_rate*5)
	{
		return 10;
	}
	return 0;
}
// Initialize resampler
//
// Generic
//     ::new(src_channels, src_rate, src_format, dst_format)							- Change sample format
//     ::new(src_channels, src_rate, src_format, dst_rate, dst_format)					- Change sample rate and format
//     ::new(src_channels, src_rate, src_format, dst_channels, dst_rate, dst_format)	- Change channel count, sample rate, and format
//
// From Object
//     ::new(source, dst_format)														- Change sample format
//     ::new(source, dst_rate, dst_format)												- Change sample rate and format
//     ::new(source, dst_channels, dst_rate, dst_format)								- Change channel count, sample rate, and format
VALUE audio_resampler_initialize(int argc, VALUE * argv, VALUE self) {
	AudioResamplerInternal * internal;
	Data_Get_Struct(self, AudioResamplerInternal, internal);

	if (argc && TYPE(argv[0]) == T_FIXNUM) {
		// Called generic form
		if      (argc < 4)	rb_raise(rb_eArgError, "Missing argument(s)");
		else if (argc > 6)	rb_raise(rb_eArgError, "Too many arguments");

		internal->src_channels 	= NUM2INT(argv[0]);
		internal->src_rate		= NUM2INT(argv[1]);
		internal->src_format	= symbol_to_av_sample_format(argv[2]);

		argc -= 3;
		argv += 3;
	}
	else {
		// Called with object
		if 		(argc < 2)	rb_raise(rb_eArgError, "Missing argument(s)");
		else if (argc > 4)	rb_raise(rb_eArgError, "Too many arguments");

		internal->src_channels 	= NUM2INT(rb_funcall(argv[0], rb_intern("channels"), 0));
		internal->src_rate		= NUM2INT(rb_funcall(argv[0], rb_intern("rate"), 0));
		internal->src_format	= symbol_to_av_sample_format(rb_funcall(argv[0], rb_intern("format"), 0));

		argc -= 1;
		argv += 1;
	}

	internal->dst_channels	= internal->src_channels;
	internal->dst_rate		= internal->src_rate;
	internal->dst_format	= internal->src_format;

	switch (argc) {
		case 1: {
			// Change sample format
			internal->dst_format = symbol_to_av_sample_format(argv[0]);
			break;
		}
		case 2: {
			// Change sample rate and format
			internal->dst_rate = NUM2INT(argv[0]);
			internal->dst_format = symbol_to_av_sample_format(argv[1]);
			break;
		}
		case 3: {
			// Change channel count, sample rate, and sampleformat
			internal->dst_channels = NUM2INT(argv[0]);
			internal->dst_rate = NUM2INT(argv[1]);
			internal->dst_format = symbol_to_av_sample_format(argv[2]);
			break;
		}
	}

	if (internal->src_format == AV_SAMPLE_FMT_NONE) rb_raise(rb_eArgError, "Unknown input sample format");
	if (internal->dst_format == AV_SAMPLE_FMT_NONE) rb_raise(rb_eArgError, "Unknown output sample format");

	// Create audio resampler
	internal->context = av_audio_resample_init(internal->dst_channels,
									  		   internal->src_channels,
									  		   internal->dst_rate,
									  		   internal->src_rate,
									  		   internal->dst_format,
									  		   internal->src_format,
										  	   0,
									  		   0,
									  		   1,
									  		   0.0);
	if (!internal->context)
		rb_raise(rb_eRuntimeError, "Failed to create resampling context");

	return self;
}
예제 #12
0
파일: filter_avresample.c 프로젝트: aib/mlt
static int resample_get_audio( mlt_frame frame, void **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples )
{
	// Get the filter service
	mlt_filter filter = mlt_frame_pop_audio( frame );

	// Get the filter properties
	mlt_properties filter_properties = MLT_FILTER_PROPERTIES( filter );

	mlt_service_lock( MLT_FILTER_SERVICE( filter ) );

	// Get the resample information
	int output_rate = mlt_properties_get_int( filter_properties, "frequency" );
	int16_t *sample_buffer = mlt_properties_get_data( filter_properties, "buffer", NULL );

	// Obtain the resample context if it exists
	ReSampleContext *resample = mlt_properties_get_data( filter_properties, "audio_resample", NULL );

	// If no resample frequency is specified, default to requested value
	if ( output_rate == 0 )
		output_rate = *frequency;

	// Get the producer's audio
	int error = mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples );
	if ( error ) return error;

	// Return now if no work to do
	if ( output_rate != *frequency )
	{
		// Will store number of samples created
		int used = 0;

		mlt_log_debug( MLT_FILTER_SERVICE(filter), "channels %d samples %d frequency %d -> %d\n",
			*channels, *samples, *frequency, output_rate );

		// Do not convert to s16 unless we need to change the rate
		if ( *format != mlt_audio_s16 )
		{
			*format = mlt_audio_s16;
			mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples );
		}

		// Create a resampler if nececessary
		if ( resample == NULL || *frequency != mlt_properties_get_int( filter_properties, "last_frequency" ) )
		{
			// Create the resampler
			resample = av_audio_resample_init( *channels, *channels, output_rate, *frequency,
				AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16, 16, 10, 0, 0.8 );

			// And store it on properties
			mlt_properties_set_data( filter_properties, "audio_resample", resample, 0, ( mlt_destructor )audio_resample_close, NULL );

			// And remember what it was created for
			mlt_properties_set_int( filter_properties, "last_frequency", *frequency );
		}

		mlt_service_unlock( MLT_FILTER_SERVICE( filter ) );

		// Resample the audio
		used = audio_resample( resample, sample_buffer, *buffer, *samples );
		int size = used * *channels * sizeof( int16_t );

		// Resize if necessary
		if ( used > *samples )
		{
			*buffer = mlt_pool_realloc( *buffer, size );
			mlt_frame_set_audio( frame, *buffer, *format, size, mlt_pool_release );
		}

		// Copy samples
		memcpy( *buffer, sample_buffer, size );

		// Update output variables
		*samples = used;
		*frequency = output_rate;
	}
	else
	{
		mlt_service_unlock( MLT_FILTER_SERVICE( filter ) );
	}

	return error;
}
예제 #13
0
int main(int argc, char* argv[])
{
	AVFormatContext* in_fctx;	
	AVCodecContext* in_cctx;
	AVCodec* in_codec;
	const char* in_filename;
	const char* out_filename;
	char* decoded_buf;
	char* output_buf;
	char* resample_buf;
	char* before_encoding_buf;
	int ret = 0;

	if (argc != 3)
	{
		printf("./audio_convertor input ouput\n");
		return -1;
	}
	//in_filename = "../input/input.aac";
	//out_filename = "output/aac2mp3.mp3";
	in_filename = argv[1];
	out_filename = argv[2];
	decoded_buf = (char*)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
	output_buf = (char*)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
	resample_buf = (char*)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE); 
	before_encoding_buf = (char*)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE); 

	avcodec_register_all();
	av_register_all();

	in_fctx = avformat_alloc_context();

	ret = av_open_input_file(&in_fctx, in_filename, NULL, 0, NULL);
	if ( ret != 0 )
	{
		printf("open input audio file[%s] fail\n", in_filename);
		return -1;
	}

	ret = av_find_stream_info(in_fctx);
	if ( ret < 0 )
	{
		printf("find stream in audio file[%s] fail\n", in_filename);
		return -1;
	}

	dump_format(in_fctx, 0, in_filename, 0);

	//这里我们假设,如果一个文件包含多个音频流,
	//只对第一个音频流做转码,而对于视频流则忽略
	int i;
	int ast_index = -1;
	for (i = 0; i<(int)in_fctx->nb_streams; ++i)
	{
		if (in_fctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
		{
			ast_index = i;
			break;
		}
	}
	if (ast_index == -1)
	{
		printf("there is not any audio stream in file[%s]\n", in_filename);
		return 0;
	}
	else
	{
		printf("find audio stream in file[%s]\n", in_filename);
	}
	
	in_cctx = in_fctx->streams[ast_index]->codec;
	//in_cctx->codec_id = CODEC_ID_GSM;
	in_codec = avcodec_find_decoder(in_cctx->codec_id);
	if (!in_codec)
	{
		printf("find decoder for codec_id[%d] fail, file[%s]\n", in_cctx->codec_id, in_filename);
		return -1;
	}
	ret = avcodec_open(in_cctx, in_codec);
	if (ret >= 0)
	{
		printf("open codec[name:%s] for stream[idx:%d] of file[%s]\n", in_codec->name, ast_index, in_filename);
	}

	// 输出部分初始化
	AVOutputFormat* out_fmt;
	AVFormatContext* out_fctx;
	AVCodecContext* out_cctx = NULL;

	out_fmt = av_guess_format(NULL, out_filename, NULL);
	if (!out_fmt)
	{
		printf("Could not deduce output format from file extension: using MPEG-3.\n");
		out_fmt = av_guess_format("mp3", NULL, NULL);
	}
	if (!out_fmt)
	{
		fprintf(stderr, "Could not find suitable output format\n");
		exit(1);
	}

	out_fctx = avformat_alloc_context();
	if (!out_fctx)
	{
		fprintf(stderr, "avformat_alloc_context fail\n");
		exit(1);
	}
	out_fctx->oformat = out_fmt;

	out_cctx = output_decode_init(in_cctx, out_fctx, out_fmt->audio_codec);
	if (!out_cctx)
	{
		fprintf(stderr, "output_codec_init fail\n");
		exit(1);
	}
	/* set the output parameters (must be done even if no parameters). */
	if (av_set_parameters(out_fctx, NULL) < 0) 
	{
		fprintf(stderr, "Invalid output format parameters\n");
		exit(1);
	}
	dump_format(out_fctx, 0, out_filename, 1);

	output_decode_open(out_cctx);

	/* open the output file */
	if (!(out_fmt->flags & AVFMT_NOFILE)) 
	{
		if (url_fopen(&out_fctx->pb, out_filename, URL_WRONLY) < 0)
		{
			fprintf(stderr, "Could not open '%s'\n", out_filename);
			exit(1);
		}
	}
	/* write the stream header, if any */
	if(av_write_header(out_fctx) < 0)
	{
		fprintf(stderr, "Could not write header for output file\n");
		return -1;
	}

	int decoded_size;
	AVPacket in_packet;
	AVPacket out_packet;
	ReSampleContext *rs_ctx = NULL;
	/*
	参考链接:http://hi.baidu.com/wg_wang/item/34396781d20b4b1ec316270b
	两点需要注意:
	(1) 从输入文件中按帧读取数据,解码,按照输出文件的要求,编码,并按帧写入到输出文件中。
	在这里,由于sample_rate和channels可能不同,需要对音频数据进行重采样。
	(2) 由于不同编码类型对一帧音频的数据要求不同,可能需要将输入数据保存起来,直到够输出的编码使用,
	或者,一帧的输入数据可能需要被多次输出。
	这样,要求初始化重采样以及libavutil提供的fifo(libavutils/fifo.h声明)以临时保存数据。
	举个例子:aac的frame_size=1024,mp3的frame_size=1152。若不用这个fifo,则生成的mp3文件是有问题的
	*/
	// 设置从采样
	rs_ctx = av_audio_resample_init(
				out_cctx->channels, in_cctx->channels,
				out_cctx->sample_rate, in_cctx->sample_rate,
				out_cctx->sample_fmt, in_cctx->sample_fmt,
				16, 10, 0, 0.8);

	AVFifoBuffer *iofifo;
	iofifo = av_fifo_alloc(AVCODEC_MAX_AUDIO_FRAME_SIZE*2);
	av_init_packet(&in_packet);
	av_init_packet(&out_packet);

	while (av_read_frame(in_fctx, &in_packet) >= 0)
	{
		while (in_packet.size > 0)
		{
			int used_size;
			decoded_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
			used_size = avcodec_decode_audio3(in_cctx, (int16_t *)decoded_buf, &decoded_size, &in_packet);
			if (used_size < 0)
			{
				printf("avcodec_decode_audio3 fail\n");
				exit(1);
			}
			int bs, frame_bytes;

			bs = audio_resample(rs_ctx, (short *)resample_buf, (short *)decoded_buf, decoded_size/(in_cctx->channels*g_in_bytes));
			ret = av_fifo_generic_write(iofifo, (uint8_t *)resample_buf, bs*out_cctx->channels*g_out_bytes, NULL);
			//ret = av_fifo_generic_write(iofifo, (uint8_t *)decoded_buf, in_cctx->frame_size*in_cctx->channels*g_out_bytes, NULL);

			frame_bytes = out_cctx->frame_size * g_out_bytes * out_cctx->channels;
			while(av_fifo_size(iofifo) >= frame_bytes)
			{
				ret = av_fifo_generic_read(iofifo, before_encoding_buf, frame_bytes, NULL);
				out_packet.size = avcodec_encode_audio(out_cctx, (uint8_t*)output_buf, frame_bytes, (short *)before_encoding_buf);
				out_packet.data = (uint8_t *)output_buf;
				av_write_frame(out_fctx, &out_packet);
			}

			in_packet.size -= used_size;
			in_packet.data += used_size;
		}
	}
	/* write the trailer, if any */
	av_write_trailer(out_fctx);
	if (!(out_fmt->flags & AVFMT_NOFILE)) {
		/* close the output file */
		url_fclose(out_fctx->pb);
	}
}
예제 #14
0
int decoder_init(PlayerCtx *ctx, const char *file)
{
	int i;

	memset(ctx, 0, sizeof(*ctx));

	ctx->video_idx = -1;
	ctx->audio_idx = -1;
	ctx->cur_seekid = 1;
	ctx->a_cur_pts = 0;

	AVInputFormat *format = NULL;
	if (!strncmp(file, "x11grab://", 10)) {
		printf("Using X11Grab\n");
		format = av_find_input_format("x11grab");
		file += 10;
	}

	if (av_open_input_file(&ctx->fmt_ctx, file, NULL, 0, NULL) != 0) {
		printf("Couldn't open input file %s\n", file);
		return -1;
	}

	if (av_find_stream_info(ctx->fmt_ctx) < 0) {
		printf("Couldn't get stream info\n");
		return -1;
	}

	ctx->duration = ctx->fmt_ctx->duration/(double)AV_TIME_BASE;

	pthread_mutex_init(&ctx->seek_mutex, NULL);
	pthread_cond_init(&ctx->seek_cond, NULL);

	for (i = 0; i < ctx->fmt_ctx->nb_streams; i++) {
		switch (ctx->fmt_ctx->streams[i]->codec->codec_type) {
			case AVMEDIA_TYPE_VIDEO:
				if (ctx->video_idx == -1)
					ctx->video_idx = i;
				break;
			case AVMEDIA_TYPE_AUDIO:
				if (ctx->audio_idx == -1)
					ctx->audio_idx = i;
				break;
			default:
				break;
		}
	}

	if (ctx->video_idx == -1) {
		printf("No video streams\n");
		return -1;
	}

	if (ctx->audio_idx != -1) {
		ctx->a_stream = ctx->fmt_ctx->streams[ctx->audio_idx];
		ctx->a_codec_ctx = ctx->a_stream->codec;
		ctx->a_codec = avcodec_find_decoder(ctx->a_codec_ctx->codec_id);
		if (ctx->a_codec == NULL) {
			return -1;
			printf("No audio codec\n");
		}
		if (avcodec_open(ctx->a_codec_ctx, ctx->a_codec) < 0) {
			printf("Failed to open audio codec\n");
			return -1;
		}

		printf("Audio srate: %d\n", ctx->a_codec_ctx->sample_rate);

		ctx->a_ch = 2;
		if (ctx->a_codec_ctx->channels > 2)
			ctx->a_ch = ctx->a_codec_ctx->channels;

		ctx->a_resampler = av_audio_resample_init(ctx->a_ch, ctx->a_codec_ctx->channels,
								SAMPLE_RATE, ctx->a_codec_ctx->sample_rate,
								SAMPLE_FMT_S16, ctx->a_codec_ctx->sample_fmt,
								16, 10, 0, 0.8);
		if (!ctx->a_resampler)
			return -1;

		ctx->a_ratio = SAMPLE_RATE/(double)ctx->a_codec_ctx->sample_rate;

		ctx->a_stride = av_get_bits_per_sample_fmt(ctx->a_codec_ctx->sample_fmt) / 8;
		ctx->a_stride *= ctx->a_codec_ctx->channels;

		ctx->a_ibuf = malloc(ctx->a_stride * AVCODEC_MAX_AUDIO_FRAME_SIZE);
		ctx->a_rbuf = malloc(ctx->a_ch * sizeof(short) * AVCODEC_MAX_AUDIO_FRAME_SIZE * (ctx->a_ratio * 1.1));
		ctx->a_buf_len = AUDIO_BUF*SAMPLE_RATE;
		ctx->a_buf = malloc(sizeof(*ctx->a_buf) * ctx->a_buf_len);

		pthread_mutex_init(&ctx->a_buf_mutex, NULL);
		pthread_cond_init(&ctx->a_buf_not_full, NULL);
		pthread_cond_init(&ctx->a_buf_not_empty, NULL);
	}

	ctx->v_stream = ctx->fmt_ctx->streams[ctx->video_idx];
	ctx->v_codec_ctx = ctx->v_stream->codec;
	ctx->width = ctx->v_codec_ctx->width;
	ctx->height = ctx->v_codec_ctx->height;

	ctx->v_codec = avcodec_find_decoder(ctx->v_codec_ctx->codec_id);
	if (ctx->v_codec == NULL) {
		printf("No video codec\n");
		return -1;
	}

	if (avcodec_open(ctx->v_codec_ctx, ctx->v_codec) < 0) {
		printf("Failed to open video codec\n");
		return -1;
	}

	ctx->v_pkt_pts = AV_NOPTS_VALUE;
    ctx->v_faulty_pts = ctx->v_faulty_dts = 0;
    ctx->v_last_pts = ctx->v_last_dts = INT64_MIN;

	ctx->v_codec_ctx->get_buffer = hack_get_buffer;
    ctx->v_codec_ctx->release_buffer = hack_release_buffer;
	ctx->v_codec_ctx->opaque = ctx;

	ctx->v_frame = avcodec_alloc_frame();
	ctx->v_buf_len = VIDEO_BUF;

	pthread_mutex_init(&ctx->v_buf_mutex, NULL);
	pthread_cond_init(&ctx->v_buf_not_full, NULL);
	pthread_cond_init(&ctx->v_buf_not_empty, NULL);

	if (pthread_create(&ctx->decoder_thread, NULL, decoder_thread, ctx) != 0)
		return -1;

	return 0;
}