Domanda

I am attempting to take the api-example.c which reads in a file using fread to instead use memcpy (or the like) as I have loaded the file I wish to decode & encode into a different codec in a std::vector<char>. (Due to I read it to memory from a compressed archive to memory). Any suggestions or examples on how I could achieve this?

Original api-example http://svn.perian.org/ffmpeg/libavcodec/api-example.c

My current "progress" http://pastebin.com/Ag0KfEsg

È stato utile?

Soluzione

Got a solution here http://pastebin.com/HsDUX8jp

void AudioLibav::DecodeAudio(std::vector<char> *inputAudio)
{

//Wasteful?
avcodec_register_all();

unsigned int audioVectorPosition = 0;

AVCodec *codec;
AVCodecContext *codecContext = NULL;
int length;
FILE *memoutfile;
uint8_t memBuffer[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
AVPacket memPkt;
AVFrame *decoded_frame_mem = NULL;

av_init_packet(&memPkt);

printf("Audio decoding\n");

/* find the mpeg audio decoder */
codec = avcodec_find_decoder(AV_CODEC_ID_PCM_S16LE);
if (!codec)
{
    fprintf(stderr, "codec not found\n");
    exit(1);
}

codecContext = avcodec_alloc_context3(codec);

#warning Bad assumption
codecContext->channels = 2;

/* open it */
if (avcodec_open2(codecContext, codec, NULL) < 0) {
    fprintf(stderr, "could not open codec\n");
    exit(1);
}

memoutfile = fopen("testrawmem", "wb");
if (!memoutfile) {
    av_free(codecContext);
    exit(1);
}

/* decode until eof */
memPkt.data = memBuffer;
memPkt.size = AUDIO_INBUF_SIZE;
memcpy(memBuffer, &inputAudio->at(0), AUDIO_INBUF_SIZE);

inputAudioVectorPosition = AUDIO_INBUF_SIZE;

while (memPkt.size > 0)
{
    int got_frame_mem = 0;

    if(!decoded_frame_mem)
    {
        if (!(decoded_frame_mem = avcodec_alloc_frame()))
        {
            fprintf(stderr, "out of memory\n");
            exit(1);
        }
    }
    else
    {
                    avcodec_get_frame_defaults(decoded_frame_mem);
    }

    length = avcodec_decode_audio4(codecContext, decoded_frame_mem, &got_frame_mem, &memPkt);

    if (length < 0)
    {
        fprintf(stderr, "Error while decoding\n");
        exit(1);
    }
    if(got_frame_mem )
    {
        int data_size_mem = av_samples_get_buffer_size(NULL, codecContext->channels, decoded_frame_mem->nb_samples, codecContext->sample_fmt, 1);


        fwrite(decoded_frame_mem->data[0], 1, data_size_mem, memoutfile);
    }

    memPkt.size -= length;
    memPkt.data += length;

    if(memPkt.size < AUDIO_REFILL_THRESH)
    {
        memmove(memBuffer, memPkt.data, memPkt.size);
        memPkt.data = memBuffer;
        //std::cout << "Mempacket data: " << memPkt.data << "   MemPacket size: " << memPkt.size << "    memAUDIO BUFF - size: " << AUDIO_INBUF_SIZE - memPkt.size;
        if((inputAudio->size() - inputAudioVectorPosition) < (AUDIO_INBUF_SIZE - memPkt.size))
        {
            memcpy( (memPkt.data + memPkt.size) , &inputAudio->at(inputAudioVectorPosition), (inputAudio->size() - inputAudioVectorPosition));
            inputAudioVectorPosition = inputAudio->size() - 1;
            #warning Bad Assumption?
            //memlen = AUDIO_INBUF_SIZE - memPkt.size;
            length = 0;
        }
        else
        {
            memcpy( (memPkt.data + memPkt.size) , &inputAudio->at(inputAudioVectorPosition), AUDIO_INBUF_SIZE - memPkt.size);
            inputAudioVectorPosition = inputAudioVectorPosition + (AUDIO_INBUF_SIZE - memPkt.size);
            length = AUDIO_INBUF_SIZE - memPkt.size;
        }

        if(length > 0)
        {
            memPkt.size += length;
        }

    }

}

fclose(memoutfile);

avcodec_close(codecContext);
av_free(codecContext);
avcodec_free_frame(&decoded_frame_mem);

}

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top