19,469
社区成员
发帖
与我相关
我的任务
分享
char *outfilename="D:/cvsroot/ffmpeg/ffmpegDecodeAndEncode/Debug/3.pcm";
FILE* pcm;
pcm = fopen(outfilename,"wb");
av_register_all();
AVFrame* frame = avcodec_alloc_frame();
if (!frame)
{
printf( "Error allocating the frame" );
return 1;
}
AVFormatContext* formatContext = NULL;
//if (avformat_open_input(&formatContext, "D:/cvsroot/ffmpeg/ffmpegDecodeAndEncode/Debug/1.mp3", NULL, NULL) != 0)
if (avformat_open_input(&formatContext, "D:/cvsroot/ffmpeg/ffmpegDecodeAndEncode/Debug/1.amr", NULL, NULL) != 0)
{
av_free(frame);
printf( "Error opening the file" );
return 1;
}
if (avformat_find_stream_info(formatContext, NULL) < 0)
{
av_free(frame);
av_close_input_file(formatContext);
printf( "Error finding the stream info" );
return 1;
}
AVStream* audioStream = NULL;
for (unsigned int i = 0; i < formatContext->nb_streams; ++i)
{
if (formatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
{
audioStream = formatContext->streams[i];
break;
}
}
if (audioStream == NULL)
{
av_free(frame);
av_close_input_file(formatContext);
printf( "Could not find any audio stream in the file" );
return 1;
}
AVCodecContext* codecContext = audioStream->codec;
codecContext->codec = avcodec_find_decoder(codecContext->codec_id);
if (codecContext->codec == NULL)
{
av_free(frame);
av_close_input_file(formatContext);
printf( "Couldn't find a proper decoder" );
return 1;
}
else if (avcodec_open2(codecContext, codecContext->codec, NULL) != 0)
{
av_free(frame);
av_close_input_file(formatContext);
printf( "Couldn't open the context with the decoder" );
return 1;
}
SwrContext* swrContext = NULL;
swrContext = swr_alloc_set_opts(swrContext,
codecContext->channel_layout, // out channel layout
codecContext->sample_fmt, // out sample format
codecContext->sample_rate, // out sample rate
codecContext->channel_layout, // in channel layout
codecContext->sample_fmt, // in sample format
codecContext->sample_rate, // in sample rate
0, // log offset
NULL); // log context
swr_init(swrContext);
if(codecContext->sample_fmt==AV_SAMPLE_FMT_S16)
{
swrContext = swr_alloc_set_opts(swrContext,
codecContext->channel_layout,
AV_SAMPLE_FMT_S16P,
codecContext->sample_rate,
codecContext->channel_layout,
AV_SAMPLE_FMT_S16,
codecContext->sample_rate,
0,
0);
if(swr_init(swrContext)<0)
{
printf("swr_init() for AV_SAMPLE_FMT_S16P fail");
return 0;
}
}
else if(codecContext->sample_fmt==AV_SAMPLE_FMT_FLT)
{
swrContext = swr_alloc_set_opts(swrContext,
codecContext->channel_layout,
AV_SAMPLE_FMT_S16P,
codecContext->sample_rate,
codecContext->channel_layout,
AV_SAMPLE_FMT_FLT,
codecContext->sample_rate,
0,
0);
if(swr_init(swrContext)<0)
{
printf("swr_init() for AV_SAMPLE_FMT_S16P fail");
return 0;
}
}
if (!swrContext)
{
av_free(frame);
avcodec_close(codecContext);
av_close_input_file(formatContext);
printf( "Couldn't allocate and set the resampling context" );
return 1;
}
printf(" bit_rate = %d \r\n", codecContext->bit_rate);
printf(" sample_rate = %d \r\n", codecContext->sample_rate);
printf(" channels = %d \r\n", codecContext->channels);
printf(" code_name = %s \r\n", codecContext->codec->name);
int bufSize = av_samples_get_buffer_size(NULL, codecContext->channels, codecContext->sample_rate, codecContext->sample_fmt, 0);
uint8_t* buf = new uint8_t[bufSize];
AVPacket packet;
av_init_packet(&packet);
int packetCount = 0;
int decodedFrameCount = 0;
static uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
uint8_t *out[]={audio_buf};
uint8_t *pktdata;
int pktsize,flush_complete=0;
while (av_read_frame(formatContext, &packet) == 0)
{
++packetCount;
if (packet.stream_index == audioStream->index)
{
pktdata = packet.data;
pktsize = packet.size;
int frameFinished = 0;
avcodec_decode_audio4(codecContext, frame, &frameFinished, &packet);
if (frameFinished)
{
pktsize -= len;
pktdata += len;
int data_size = av_samples_get_buffer_size(NULL,codecContext->channels,frame->nb_samples,codecContext->sample_fmt, 1);
/*****************************************************
以下代码使用swr_convert函数进行转换,但是转换后的文件连mp3到pcm文件都不能播放了,所以注释了
const uint8_t *in[] = {frame->data[0]};
int len=swr_convert(swrContext,out,sizeof(audio_buf)/codecContext->channels/av_get_bytes_per_sample(AV_SAMPLE_FMT_S16P),
in,frame->linesize[0]/codecContext->channels/av_get_bytes_per_sample(codecContext->sample_fmt));
len=len*codecContext->channels*av_get_bytes_per_sample(AV_SAMPLE_FMT_S16P);
if (len < 0) {
fprintf(stderr, "audio_resample() failed\n");
break;
}
if (len == sizeof(audio_buf) / codecContext->channels / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16P)) {
fprintf(stderr, "warning: audio buffer is probably too small\n");
swr_init(swrContext);
}
*****************************************************/
char *data = (char *)malloc(data_size);
short *sample_buffer = (short *)frame->data[0];
for (int i = 0; i < data_size/2; i++)
{
data[i*2] = (char)(sample_buffer[i/2] & 0xFF);
data[i*2+1] = (char)((sample_buffer[i/2] >>8) & 0xFF);
}
fwrite(data, data_size, 1, pcm);
fflush(pcm);
}
}
av_free_packet(&packet);
}
delete [] buf;
swr_free(&swrContext);
av_free(frame);
avcodec_close(codecContext);
av_close_input_file(formatContext);
fclose(pcm);
short *data = (char *)malloc(frame->nb_samples);
short *sample_buffer = (short *)frame->data[0];
short *sample_buffer1=(short*)frame->data[1];
for (int i = 0; i < frame->nb_samples; i++)
{
data[i*2] = sample_buffer[i];
data[i*2+1] = sample_buffer1[i];
}