Файл WAV, закодированный с помощью FFMPEG, имеет проблемы с кодеками при воспроизведении с использованием VLC Player. - PullRequest
2 голосов
/ 07 сентября 2011

Я хочу преобразовать необработанные данные PCM (взятые с микрофона Android Phone) в файл libGSM Wave.После кодирования в файл проигрыватель VLC показывает правильную информацию и длительность кодека, но не может воспроизвести содержимое.Пожалуйста, помогите мне понять, что я делаю неправильно.

Ниже приведен мой код для кодирования и написания заголовка:

void EncodeTest(uint8_t *audioData, size_t audioSize)
{
    AVCodecContext  *audioCodec;
    AVCodec *codec;
    uint8_t *buf;    int bufSize, frameBytes;
    __android_log_print(ANDROID_LOG_INFO, DEBUG_TAG,"Lets encode :%u with size %d\n",(int)audioData, (int)audioSize);
    //Set up audio encoder
    codec = avcodec_find_encoder(CODEC_ID_GSM);
    if (codec == NULL){
        __android_log_print(ANDROID_LOG_ERROR, DEBUG_TAG,"ERROR:: Unable to find encoder(CODEC_ID_GSM)");
        codec = avcodec_find_encoder(CODEC_ID_GSM);
        if (codec == NULL){
            __android_log_print(ANDROID_LOG_ERROR, DEBUG_TAG,"ERROR:: Unable to find encoder(CODEC_ID_GSM)");
            return;
        }
    }
    audioCodec                  = avcodec_alloc_context();
    audioCodec->channels        = 1;
    audioCodec->sample_rate     = 8000;
    audioCodec->sample_fmt      = SAMPLE_FMT_S16;
    audioCodec->bit_rate        = 13200;
    audioCodec->priv_data       = gsm_create();

    switch(audioCodec->codec_id) {
        case CODEC_ID_GSM:
            audioCodec->frame_size = GSM_FRAME_SIZE;
            audioCodec->block_align = GSM_BLOCK_SIZE;
            int one = 1;
            gsm_option(audioCodec->priv_data, GSM_OPT_WAV49, &one);
            break;
        case CODEC_ID_GSM_MS: {
            int one = 1;
            gsm_option(audioCodec->priv_data, GSM_OPT_WAV49, &one);
            audioCodec->frame_size = 2*GSM_FRAME_SIZE;
            audioCodec->block_align = GSM_MS_BLOCK_SIZE;
        }
    }
    audioCodec->coded_frame= avcodec_alloc_frame();
    audioCodec->coded_frame->key_frame= 1;
    audioCodec->time_base       = (AVRational){1,  audioCodec->sample_rate};
    audioCodec->codec_type      = CODEC_TYPE_AUDIO;

    if (avcodec_open(audioCodec, codec) < 0){
        __android_log_print(ANDROID_LOG_ERROR, DEBUG_TAG,"ERROR:: Unable to avcodec_open");
        return;
    }

    bufSize     = FF_MIN_BUFFER_SIZE * 10;
    buf         = (uint8_t *)malloc(bufSize);
    if (buf == NULL) return;
    frameBytes = audioCodec->frame_size * audioCodec->channels * 2;
    FILE *fileWrite = fopen(FILE_NAME,"w+b");
    if(NULL == fileWrite){
        __android_log_print(ANDROID_LOG_ERROR, DEBUG_TAG,"ERROR:: Unable to open file for reading.");
    }
    /*Write wave header*/
    WriteWav(fileWrite, 32505);/*Just for test*/

    /*Lets encode raw packet and write into file after header.*/
    __android_log_print(ANDROID_LOG_INFO, DEBUG_TAG,"Lets Encode Actual Bytes");
    int nChunckSize = 0;
    while (audioSize >= frameBytes)
    {
        int packetSize;

        packetSize = avcodec_encode_audio(audioCodec, buf, bufSize, (short *)audioData);
        __android_log_print(ANDROID_LOG_INFO, DEBUG_TAG,"Encoder returned %d bytes of data\n", packetSize);
        nChunckSize += packetSize;
        audioData += frameBytes;
        audioSize -= frameBytes;
        if(NULL != fileWrite){
            fwrite(buf, packetSize, 1, fileWrite);
        }
        else{
            __android_log_print(ANDROID_LOG_ERROR, DEBUG_TAG,"Unable to open file for writting... NULL");
        }
    }
    if(NULL != fileWrite){
        fclose(fileWrite);
    }
    __android_log_print(ANDROID_LOG_INFO, DEBUG_TAG,"----- Done with nChunckSize: %d --- ",nChunckSize);
     __android_log_print(ANDROID_LOG_INFO, DEBUG_TAG,"*****************************");
    wavReadnDisplayHeader(FILE_NAME);
    __android_log_print(ANDROID_LOG_INFO, DEBUG_TAG,"*****************************");
    wavReadnDisplayHeader("/sdcard/Voicemail2.wav");
}

Запись заголовка:

/** Writes WAV headers */
void WriteWav(FILE *f, long int bytes)
{
    /* quick and dirty */
    fwrite("RIFF",sizeof(char),4,f);                /*  0-3 */      //RIFF
    PutNum(bytes+44-8,f,1,4);                       /*  4-7 */      //ChunkSize
    fwrite("WAVEfmt ",sizeof(char),8,f);            /*  8-15 */     //WAVE Header + FMT header
    PutNum(16,f,1,4);                               /* 16-19 */     //Size of the fmt chunk
    PutNum(49,f,1,2);                                /* 20-21 */     //Audio format, 49=libgsm wave, 1=PCM,6=mulaw,7=alaw, 257=IBM Mu-Law, 258=IBM A-Law, 259=ADPCM
    PutNum(1,f,1,2);                                /* 22-23 */     //Number of channels 1=Mono 2=Sterio
    PutNum(8000,f,1,4);                             /* 24-27 */     //Sampling Frequency in Hz 
    PutNum(2*8000,f,1,4);                           /* 28-31 */     //bytes per second /Sample/persec
    PutNum(2,f,1,2);                                /* 32-33 */     // 2=16-bit mono, 4=16-bit stereo 
    PutNum(16,f,1,2);                                /* 34-35 */     // Number of bits per sample
    fwrite("data",sizeof(char),4,f);                /* 36-39 */     
    PutNum(bytes,f,1,4);                            /* 40-43 */     //Sampled data length  
}

Пожалуйста, помогите ....

...