int audio_decode_frame(VideoState *is, double *pts_ptr) { /* For example with wma audio package size can be like 100 000 bytes */ long len1, data_size = 0; AVPacket *pkt = &is->audio_pkt; double pts; int n = 0; #ifdef __RESAMPLER__ long resample_size = 0; #endif 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 ); #ifdef __RESAMPLER__ if(is->audio_need_resample == 1) { resample_size = audio_tutorial_resample(is, &is->audio_frame); if( resample_size > 0 ) { memcpy(is->audio_buf, is->pResampledOut, resample_size); memset(is->pResampledOut, 0x00, resample_size); } } else { #endif memcpy(is->audio_buf, is->audio_frame.data[0], data_size); #ifdef __RESAMPLER__ } #endif } is->audio_pkt_data += len1; is->audio_pkt_size -= len1; if(data_size <= 0) { /* No data yet, get more frames */ continue; } pts = is->audio_clock; *pts_ptr = pts; n = 2 * is->audio_st->codec->channels; #ifdef __RESAMPLER__ /* If you just return original data_size you will suffer for clicks because you don't have that much data in queue incoming so return resampled size. */ if(is->audio_need_resample == 1) { is->audio_clock += (double)resample_size / (double)(n * is->audio_st->codec->sample_rate); return resample_size; } else { #endif /* We have data, return it and come back for more later */ is->audio_clock += (double)data_size / (double)(n * is->audio_st->codec->sample_rate); return data_size; #ifdef __RESAMPLER__ } #endif } 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; } if(pkt->data == flush_pkt.data) { avcodec_flush_buffers(is->audio_st->codec); continue; } is->audio_pkt_data = pkt->data; is->audio_pkt_size = pkt->size; /* if update, update the audio clock w/pts */ if(pkt->pts != AV_NOPTS_VALUE) { is->audio_clock = av_q2d(is->audio_st->time_base) * pkt->pts; } } }
int audio_decode_frame(VideoState *is, double *pts_ptr) { int len1, data_size = 0, n; AVPacket *pkt = &is->audio_pkt; double pts; for(;;) { while(is->audio_pkt_size > 0) { int got_frame = 0; int resample_size = 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 ); #ifdef __RESAMPLER__ if(is->audio_need_resample == 1) { resample_size = audio_tutorial_resample(is, &is->audio_frame); if( resample_size > 0 ) { memcpy(is->audio_buf, is->pResampledOut, resample_size); memset(is->pResampledOut, 0x00, resample_size); } } else { #endif memcpy(is->audio_buf, is->audio_frame.data[0], data_size); #ifdef __RESAMPLER__ } #endif } is->audio_pkt_data += len1; is->audio_pkt_size -= len1; if(data_size <= 0) { /* No data yet, get more frames */ continue; } pts = is->audio_clock; *pts_ptr = pts; n = 2 * is->audio_st->codec->channels; is->audio_clock += (double)data_size / (double)(n * is->audio_st->codec->sample_rate); /* 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; } if(pkt->data == flush_pkt.data) { avcodec_flush_buffers(is->audio_st->codec); continue; } is->audio_pkt_data = pkt->data; is->audio_pkt_size = pkt->size; /* if update, update the audio clock w/pts */ if(pkt->pts != AV_NOPTS_VALUE) { is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts; } } }