最近在移植ffmpeg到android,今天花了大半天的时间终于把ffmpeg移植到linux下面,下一步就是移植到android框架中,这里关于ffmpeg的音频操作,和视频有很大的区别,话不多说,直接上代码。代码有点乱,调试了很长时间。
#include <stdlib.h>
#include <stdio.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef struct
{
char chChunkID[4];
int nChunkSize;
}XCHUNKHEADER;
typedef struct
{
short nFormatTag;
short nChannels;
int nSamplesPerSec;
int nAvgBytesPerSec;
short nBlockAlign;
short nBitsPerSample;
}WAVEFORMAT;
typedef struct
{
short nFormatTag;
short nChannels;
int nSamplesPerSec;
int nAvgBytesPerSec;
short nBlockAlign;
short nBitsPerSample;
short nExSize;
}WAVEFORMATX;
typedef struct
{
char chRiffID[4];
int nRiffSize;
char chRiffFormat[4];
}RIFFHEADER;
typedef struct
{
char chFmtID[4];
int nFmtSize;
WAVEFORMAT wf;
}FMTBLOCK;
void WriteWAVEFileHeader(FILE* fpwave, int len)
{
RIFFHEADER riff;
FMTBLOCK fmt;
XCHUNKHEADER chunk;
WAVEFORMATX wfx;
char tag[10] = "";
// 1. ÐŽRIFFÍ·
strcpy(tag, "RIFF");
memcpy(riff.chRiffID, tag, 4);
riff.nRiffSize = 4 // WAVE
+ sizeof(XCHUNKHEADER) // fmt
+ sizeof(WAVEFORMATX) // WAVEFORMATX
+ sizeof(XCHUNKHEADER) // DATA
+ len*sizeof(char); //
strcpy(tag, "WAVE");
memcpy(riff.chRiffFormat, tag, 4);
fwrite(&riff, 1, sizeof(RIFFHEADER), fpwave);
// 2. ÐŽFMT¿é
strcpy(tag, "fmt ");
memcpy(chunk.chChunkID, tag, 4);
chunk.nChunkSize = sizeof(WAVEFORMATX);
fwrite(&chunk, 1, sizeof(XCHUNKHEADER), fpwave);
memset(&wfx, 0, sizeof(WAVEFORMATX));
wfx.nFormatTag = 1;
wfx.nChannels = 2; //
wfx.nSamplesPerSec = 44100; // 8khz
wfx.nAvgBytesPerSec = 176400;
wfx.nBlockAlign = 2;
wfx.nBitsPerSample = 16; // 16λ
fwrite(&wfx, 1, sizeof(WAVEFORMATX), fpwave);
// 3. ÐŽdata¿éÍ·
strcpy(tag, "data");
memcpy(chunk.chChunkID, tag, 4);
//chunk.nChunkSize = 2319*18432*sizeof(char);
chunk.nChunkSize = len*sizeof(char);
fwrite(&chunk, 1, sizeof(XCHUNKHEADER), fpwave);
}
int main(int argc, char *argv[])
{
char * file_path="/home/lost/Desktop/test.ape";
char * out_file_path="/home/lost/Desktop/456.wav";
AVFormatContext *pFormatCtx;
int i;
int len;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVPacket packet;
uint8_t * decompressed_audio_buf;
int videoStream=-1;
int audioStream = -1;
FILE * file_out;
int sample_len = 0;
// Open video file
av_register_all();
if(av_open_input_file(&pFormatCtx,file_path , NULL, 0, NULL)!=0)
{
printf("Open error/n");
return -1; // Couldn't open file
}
// Retrieve stream information
if(av_find_stream_info(pFormatCtx)<0)
{
printf("Find info error/n");
return -1; // Couldn't find stream informatio
}
// Dump information about file onto standard error
dump_format(pFormatCtx, 0,file_path, 0);
// Find the first video stream
for(i=0; i<pFormatCtx->nb_streams; i++)
if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO) {
videoStream=i;
break;
}
if(videoStream==-1)
{
printf("can not find a vedio stream/n");
//return -1; // Didn't find a video stream
}
for(i=0; i<pFormatCtx->nb_streams; i++)
if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_AUDIO) {
audioStream=i;
break;
}
if(audioStream==-1)
{
printf("can not find a audio stream/n");
//return -1; // Didn't find a video stream
}
// Get a pointer to the codec context for the audio stream
pCodecCtx=pFormatCtx->streams[audioStream]->codec;
// Find the decoder for the audio stream
pCodec = avcodec_find_decoder (pCodecCtx->codec_id);
if (pCodec == NULL)
{
printf("Can not find the codec/n");
return -1; // Codec not found
}
// Open codec
if (avcodec_open (pCodecCtx, pCodec) < 0){
printf("Open codec failed/n");
return -1; // Could not open codec
}
printf ("pCodecCtx->sample_rate:%d, audioStream:%d/n", (pCodecCtx)->sample_rate, audioStream);
file_out = fopen(out_file_path,"wb");
WriteWAVEFileHeader(file_out,0);
i = 0;
decompressed_audio_buf= malloc((AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2);
len = (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2;
//len = (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2;
av_init_packet(&packet);
int len_not_codec =0;
char * data;
while (av_read_frame(pFormatCtx, &packet) >= 0)
{
//printf("haha,packet size = %d/n", packet.size);
len_not_codec = packet.size;
data = packet.data;
while (len_not_codec>0) {
len = (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2;
i = avcodec_decode_audio2(pCodecCtx, (int16_t *)decompressed_audio_buf,
&len,data,len_not_codec );
printf("haha,frame size = %d/n,packet skip %d", len,i);
if(i<0)
{
printf("error skip/n");
break;
}
data += i;
len_not_codec -= i;
if(len<0)
{
printf("not data ,skip/n");
continue;
}
fwrite((char *)decompressed_audio_buf, 1, len, file_out);
}
if(packet.data)
av_free_packet(&packet);
}
avcodec_close(pCodecCtx);
av_close_input_file(pFormatCtx);
fseek(file_out,0,SEEK_SET);
WriteWAVEFileHeader(file_out,sample_len);
fclose(file_out);
printf("haha/n");
}
转:Android上ffmpeg移植(1)
最新推荐文章于 2024-09-10 15:14:28 发布