Vlc producer

good morning

am trying to create a vlc producer. i have been able to get the video working, but the audio is not working. it’s cracking massively. any help to get the audio working will be much appreciated.

below is a sample code. the full source is also attached

libvlc_video_set_callbacks(media_player, video_lock, NULL, video_display, this);
libvlc_video_set_format(media_player, “RV32”, format_desc.width, format_desc.height, format_desc.width * 4);

    libvlc_audio_set_callbacks(media_player, audio_play, NULL, NULL, NULL, NULL, this);
    libvlc_audio_set_format(media_player, "S32N", format_desc.audio_sample_rate, 2);

struct FrameContext
{
uint8_t* data;
AVPixelFormat video_format;
AVSampleFormat audio_format;
int line_size;
int width;
int height;
int64_t pts;
int nb_samples;
int channels;
int sample_rate;
vlc_producer* producer;
bool valid;
};

std::queue video_data_;
std::queue audio_data_;

void* vlc_producer::video_lock(void* data, void** planes)
{
vlc_producer* producer = static_cast<vlc_producer*>(data);
*planes = producer->pixel_data;
return NULL;
}

void vlc_producer::audio_play(void* data, const void* samples, unsigned count, int64_t pts)
{
vlc_producer* producer = static_cast<vlc_producer*>(data);

int      size   = count;
uint8_t* buffer = new uint8_t[size];
memcpy(buffer, samples, size);

FrameContext                frame_context;
frame_context.data         = buffer;
frame_context.nb_samples = count/2;
frame_context.pts        = pts;
frame_context.channels     = 2;
frame_context.sample_rate  = producer->format_desc_.audio_sample_rate;
frame_context.audio_format = AVSampleFormat::AV_SAMPLE_FMT_S32;

std::lock_guard<std::mutex> lock(producer->audio_frames_mutex_);
producer->audio_data_.push(frame_context);

}

void vlc_producer::video_display(void* data, void* picture)
{
vlc_producer* producer = static_cast<vlc_producer*>(data);

FrameContext frame_context;
frame_context.data         = producer->pixel_data;
frame_context.height       = producer->format_desc_.height;
frame_context.width        = producer->format_desc_.width;
frame_context.video_format = AVPixelFormat::AV_PIX_FMT_BGRA;
frame_context.line_size    = producer->format_desc_.width * 4;

std::lock_guard<std::mutex> lock(producer->video_frames_mutex_);
producer->video_data_.push(frame_context);

}

bool vlc_producer::try_pop(FrameContext& video_frame, FrameContext& audio_frame )
{
{
std::lock_guardstd::mutex lock(video_frames_mutex_);
if (!video_data_.empty()) {
video_frame = video_data_.front();
video_frame.valid = true;
video_data_.pop();
}
}

{
    std::lock_guard<std::mutex> lock(audio_frames_mutex_);
    if (!audio_data_.empty()) {
        audio_frame       = audio_data_.front();
        audio_frame.valid = true;
        audio_data_.pop();
    }
}

return video_frame.valid;

}

core::draw_frame vlc_producer::receive_impl(const core::video_field field, int nb_samples)
{
FrameContext video_frame;
FrameContext audio_frame;

if (try_pop(video_frame, audio_frame)) {
    std::shared_ptr<AVFrame> av_frame(av_frame_alloc(), [](AVFrame* frame) { av_frame_free(&frame); });
    std::shared_ptr<AVFrame> a_frame(av_frame_alloc(), [](AVFrame* frame) { av_frame_free(&frame); });

    av_frame->data[0]     = video_frame.data;
    av_frame->linesize[0] = video_frame.line_size;
    av_frame->format      = video_frame.video_format;
    av_frame->width       = video_frame.width;
    av_frame->height      = video_frame.height;

    if (audio_frame.valid) {
        a_frame->channels         = audio_frame.channels;
        a_frame->format           = audio_frame.audio_format;
        a_frame->sample_rate      = audio_frame.sample_rate;
        a_frame->nb_samples       = audio_frame.nb_samples;
        a_frame->data[0]          = audio_frame.data;
        a_frame->pts              = audio_frame.pts;
        a_frame->interlaced_frame = false;
        a_frame->channel_layout   = av_get_default_channel_layout(a_frame->channels);
    } 

    auto mframe = ffmpeg::make_frame(this, *(frame_factory_.get()), std::move(av_frame), std::move(a_frame));

    delete[] audio_frame.data;
    //delete[] video_frame.data;
    last_frame_ = core::draw_frame(std::move(mframe));
}

return last_frame_;

}

vlc_producer.cpp.html (6.2 KB)
vlc_producer.h.html (2.8 KB)