我正在尝试使用使用 fread 读取文件的 api-example.c 来代替使用 memcpy (或类似的),因为我已将我希望解码和编码的文件加载到std::vector<char>
. (由于我将它从压缩存档读取到内存中)。关于如何实现这一目标的任何建议或示例?
原始 api-example http://svn.perian.org/ffmpeg/libavcodec/api-example.c
我目前的“进展” http://pastebin.com/Ag0KfEsg
我正在尝试使用使用 fread 读取文件的 api-example.c 来代替使用 memcpy (或类似的),因为我已将我希望解码和编码的文件加载到std::vector<char>
. (由于我将它从压缩存档读取到内存中)。关于如何实现这一目标的任何建议或示例?
原始 api-example http://svn.perian.org/ffmpeg/libavcodec/api-example.c
我目前的“进展” http://pastebin.com/Ag0KfEsg
在这里得到了解决方案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);
}