我正在尝试使用api-example.c,它使用fread读取文件而不是使用memcpy(或类似),因为我已经加载了我想解码的文件&amp;编码为std::vector<char>
中的不同编解码器。 (由于我从压缩存档到内存将其读入内存)。关于如何实现这一目标的任何建议或例子?
原始api-example http://svn.perian.org/ffmpeg/libavcodec/api-example.c
我目前的“进步” http://pastebin.com/Ag0KfEsg
答案 0 :(得分:0)
在这里找到解决方案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);
}