转:Android上ffmpeg移植(1)

最近在移植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");

}

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值