Example #1
0
void LibavReader::setupDecoder_() {
	int ret = -1;
	for( std::size_t i = 0 ; i < this->pFormatContext_->nb_streams; ++i ) {
		if( this->pFormatContext_->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO ) {
			ret = i;
			break;
		}
	}
	if( ret == -1 ) {
		throw CodecError( "LibavReader: Find no audio stream!", __FILE__, __LINE__ );
	}
	this->pStream_ = this->pFormatContext_->streams[ret];
	AVCodecContext * pCC = this->pStream_->codec;
	// getting codec information
	this->setBitRate( pCC->bit_rate );

	// setup sample format
	AudioFormat format;
	format.setFrequency( 44100 );
	format.setChannels( pCC->channels );
	switch( pCC->channels ) {
	case 1:
		this->setChannelLayout( LayoutMono );
		break;
	case 2:
		this->setChannelLayout( LayoutStereo );
		break;
	default:
		this->setChannelLayout( LayoutNative );
	}
	format.setSampleType( AudioFormat::SignedInt );
	format.setSampleSize( 16 );
	this->setAudioFormat( format );

	AVCodec * pC = avcodec_find_decoder( pCC->codec_id );
	if( pC == NULL ) {
		throw CodecError( tr( "find no decoder" ), __FILE__, __LINE__ );
	}

	if( avcodec_open2( pCC, pC, NULL ) < 0 ) {
		throw CodecError( tr( "can not open decoder" ), __FILE__, __LINE__ );
	}
	this->pCodecContext_.reset( pCC, avcodec_close );

	// resampling
	if( pCC->channel_layout > 0 || format.frequency() != pCC->sample_rate || pCC->sample_fmt != AV_SAMPLE_FMT_S16 ) {
		auto rsc = av_audio_resample_init( format.channels(), pCC->channels, format.frequency(), pCC->sample_rate, AV_SAMPLE_FMT_S16, pCC->sample_fmt, 16, 10, 0, 0.8 );
		if( !rsc ) {
			throw CodecError( QObject::tr( "ReSampleContext open failed" ), __FILE__, __LINE__ );
		}
		this->pArContext_.reset( rsc, []( ReSampleContext * p )->void {
			audio_resample_close( p );
		} );
	}
}