Re: [Ffmpeg-devel] Using libavformat and libavcodec(help me Martin Böhme)

Chang Min Jeon jcm1981
Tue May 31 17:23:05 CEST 2005


On 5/31/05, M?ns Rullg?rd <mru at inprovide.com> wrote:
> Chang Min Jeon <jcm1981 at gmail.com> writes:
> 
> > hello, I'm student in South Korea.
> 
> KAIST, by any chance?
> 
> > I read Martin B?hme's article about using libavcodec and libavformat
> > in ffmpeg doc.
> >
> > So I can read video frame from video file, Wow amazing.~
> >
> > Now I'm trying to read audio stream.
> >
> > How to read raw audio stream from video file ?
> >
> > //find the first audio stream.
> >
> >  m_nAudioStream = -1;
> >
> >  for(j=0; j<m_pFormatCtx->nb_streams; j++)
> >   if(m_pFormatCtx->streams[j]->codec.codec_type == CODEC_TYPE_AUDIO)
> >   {
> >    m_nAudioStream =j;
> >    break;
> >   }
> >
> > // didn't find a video stream
> >  if(m_nAudioStream==-1)
> >   return -1;
> >
> >  // get a pointer to the codec context for the audio stream.
> >  m_pAudioCtx=&m_pFormatCtx->streams[m_nAudioStream]->codec;
> >
> > // fine the decoder for the audio stream
> >  pAudioCodec=avcodec_find_decoder(m_pAudioCtx->codec_id);
> >  if(pAudioCodec==NULL)
> >   return -1;
> >
> > // open audio codec
> >
> >  if(avcodec_open(m_pAudioCtx, pAudioCodec) <0)
> >   return -1;
> 
> Looking good so far.
> 
> AVPacket packet;
> 
> /* you must already be doing this for the video */
> if(av_read_frame(m_pFormatCtx, &packet) < 0)
>    /* error */
> 
> Check packet.stream_index to see where it belongs.  If you can decode
> video you're already doing it right, just add some code for decoding
> audio:
> 
> int16_t *audio_out;
> int outsize;
> int decoded;
> 
> audio_out = malloc(something reasonable);
> 
> decoded = avcodec_decode_audio(m_pAudioCtx, audio_out, &outsize,
>                               packet.data, packet.size);
> if(decoded < 0)
>    /* error */
> 
> /* do something with decoded audio */
> 
> avcodec_decode_audio() returns the number of encoded bytes that have
> been used.  If this value is smaller than the packet size, you'll have
> to keep calling it until the packet has been used up.
> 
> It's quite similar to decoding video.
> 
> --
> M?ns Rullg?rd
> mru at inprovide.com
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at mplayerhq.hu
> http://mplayerhq.hu/mailman/listinfo/ffmpeg-devel
> 
Thank you reply
I read a source about audio_decode_example.

So I reference example source . I write following line.

First of all, Sound device initilizing.

int CVideoView::InitSound()
{

	// Sound Device Option
	if((m_nFD = open("/dev/dsp", O_RDWR, 0)) == -1)
	{
		perror("OSS: Error Opening Device\n");
		return -1;
	}
    
	//Sound Duplex Option
	if(ioctl(m_nFD, SNDCTL_DSP_SETDUPLEX, 0) == -1)
	{
		perror("SOUND_PCM_SETDUPLEX");
		return -1;
	}

	m_nFormat = AFMT_S16_LE;
	/* Inform the sound card of the audio format */
	if(ioctl(m_nFD, SNDCTL_DSP_SETFMT, &m_nFormat) == -1)
	{
		perror("SOUND_PCM_SETFMT");
		return -1;
	}
	m_nChannels = m_pAudioCtx->channels;
	// Sound Stereo Option
	if(ioctl(m_nFD, SNDCTL_DSP_CHANNELS, &m_nChannels) == -1)
	{
		perror("SOUND_PCM_CHANNELS");
		return -1;
	}
	
	m_nRate = m_pAudioCtx->sample_rate;
	/* Set the DSP playback rate, sampling rate of the raw PCM audio*/
	if(ioctl(m_nFD, SNDCTL_DSP_SPEED, &m_nRate) == -1)
	{
		perror("SOUND_PCM_SPEED");
		return -1;
	}

	return 0;
    
}

m_outbuf is allocated when constructor had been generated.
m_outbuf =  (uint8_t *)malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);

 * GetNextAudio function is similar with GetNextFrame

bool CVideoView::GetNextAudio(AVFormatContext *pFormatCtx,
AVCodecContext *pAudioCtx, int audioStream)
{
	static AVPacket Apacket;
	static int audioRemaining=0;
	static bool aFirstTime=true;
	int audioDecoded;
	int audioFinished;
	
	uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE], *inbuf_ptr;
	
	memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
	
	inbuf_ptr = inbuf;

	if(aFirstTime)
	{
		aFirstTime=false;
		Apacket.data=NULL;
	}
	
			
	while(true)
	{
		while(audioRemaining > 0)	
		{
			audioDecoded = avcodec_decode_audio(m_pAudioCtx, (short *)m_outbuf,
&audioFinished, inbuf_ptr, audioRemaining);
			if(audioDecoded < 0)
			{
				fprintf(stderr, "Error while decoding audio\n");
				return false;
			}
			if(audioFinished > 0)
			{
				write(m_nFD, m_outbuf, audioFinished);
			}
				
			audioRemaining -=audioDecoded;
			inbuf_ptr +=audioDecoded;
			

			if(audioFinished)
				return true;
		}
		
		do
		{
			if(Apacket.data!=NULL)
				av_free_packet(&Apacket);
				
			if(av_read_packet(pFormatCtx, &Apacket) < 0)
				goto loop_exit;
		} while(Apacket.stream_index!=audioStream);
		
		audioRemaining = Apacket.size;
	}
	
	loop_exit:
	
	
		audioDecoded = avcodec_decode_audio(m_pAudioCtx, (short *)m_outbuf,
&audioFinished, inbuf_ptr, audioRemaining);
		
		if(Apacket.data!=NULL)
			av_free_packet(&Apacket);
			
		return audioFinished!=0;
			
}

Problem - app is running. Video is displayed very well. But audio
output is not correct.

app with Gtkmm





More information about the ffmpeg-devel mailing list