How can obtain audioData from oboe::FifoBuffer with the callback #2152
-
This is what i have tried, but no audio sound is played. //decodes audio and writes uint8_t* to Fifobuffer called "Buff"
void getPcmData(AVFormatContext *formatCtx, AVPacket *packet, AVCodecContext *decoder_ctx, AVFrame *frame, SwrContext *swr_context, int *stream_index,oboe::FifoBuffer &Buff) {
while (av_read_frame(formatCtx, packet) >= 0) {
if (packet->stream_index == *stream_index) {
int ret = avcodec_send_packet(decoder_ctx, packet);
if (ret < 0) {
std::cerr << "Error sending packet for decoding\n";
return;
}
ret = avcodec_receive_frame(decoder_ctx, frame);
while (ret>=0){
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
return;
} else if (ret < 0) {
std::cerr << "Error during decoding\n";
return;
}
uint8_t **converted_data = NULL;
av_samples_alloc_array_and_samples(&converted_data, NULL, 2, frame->nb_samples, AV_SAMPLE_FMT_FLT, 0);
int convert_ret = swr_convert(swr_context,converted_data, frame->nb_samples, (const uint8_t **)frame->data, frame->nb_samples);
if (convert_ret < 0) {
std::cerr << "Error during resampling\n";
return;
}
Buff.write(converted_data[0],frame->nb_samples);
//av_freep(&converted_data[0]);
}
}
av_packet_unref(packet);
}
}
// my callback ....
class MyCallback : public oboe::AudioStreamCallback{
public:
MyCallback(oboe::FifoBuffer &buff) : mBuff(buff){}
oboe::DataCallbackResult onAudioReady(oboe::AudioStream *media,void *audioData, int32_t numFrames) override{
mBuff.read(audioData,numFrames);
return oboe::DataCallbackResult::Continue;
}
// some more code here ...
}
int main(){
// some ffmpeg code ...
uint32_t bytesPerFrame = 4;
uint32_t CapacityInFrames = totalFrames(formatCtx);
oboe::FifoBuffer buff(bytesPerFrame,CapacityInFrames);
std::thread t([&](){
getPcmData(formatCtx, packet, decoder_ctx, frame, swr_context, &stream_index,buff);
});
t.detach();
MyCallback audioCallback(buff);
oboe::AudioStreamBuilder builder;
builder.setCallback(&audioCallback);
builder.setFormat(oboe::AudioFormat::Float);
builder.setChannelCount(oboe::ChannelCount::Stereo);
builder.setSampleRate(48000);
oboe::AudioStream *mediaStream=nullptr;
oboe::Result result = builder.openStream(&mediaStream);
if(result != oboe::Result::OK){
std::cerr<<"failed to create stream\n";
return -1;
}
result=mediaStream->start();
if(result != oboe::Result::OK){
std::cerr << "failed to start stream\n";
return -1;
}
std::this_thread::sleep_for(std::chrono::minutes(1));
//cleanUp code
} |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
I see several problems here: Your function getPcmData() does not seem to wait for room in the FIFO. So it just runs full speed until all the data is read. If the FIFO. If the FIFO is full then the data will be dropped. If you want to stream data to Oboe then you should check to see if there is enough room in the buffer for the data to be written. Then sleep until there is room. You are allocating the buffer to be the totalFrames. If you are simply going to read the entire file into one array then you don't need a FIFO. But if you plan on streaming a large amount of data then just allocate enough to avoid buffer underflows. You set bytesPerFrame = 4 but then you allocate a stream with stereo-float. That would be 8 bytes per stream. Instead of sleeping for 1 minute. I recommend sleeping for 500 msec in a loop and printing the framesWritten and framesRead for the mBuff. Then you can see if the data is being written or read. |
Beta Was this translation helpful? Give feedback.
I see several problems here:
Your function getPcmData() does not seem to wait for room in the FIFO. So it just runs full speed until all the data is read. If the FIFO. If the FIFO is full then the data will be dropped. If you want to stream data to Oboe then you should check to see if there is enough room in the buffer for the data to be written. Then sleep until there is room.
You are allocating the buffer to be the totalFrames. If you are simply going to read the entire file into one array then you don't need a FIFO. But if you plan on streaming a large amount of data then just allocate enough to avoid buffer underflows.
You set bytesPerFrame = 4 but then you allocate a stream with ster…