static void mp_media_next_audio(mp_media_t *m) { struct mp_decode *d = &m->a; struct obs_source_audio audio = {0}; AVFrame *f = d->frame; if (!mp_media_can_play_frame(m, d)) return; d->frame_ready = false; if (!m->a_cb) return; for (size_t i = 0; i < MAX_AV_PLANES; i++) audio.data[i] = f->data[i]; audio.samples_per_sec = f->sample_rate * m->speed / 100; audio.speakers = convert_speaker_layout(f->channels); audio.format = convert_sample_format(f->format); audio.frames = f->nb_samples; audio.timestamp = m->base_ts + d->frame_pts - m->start_ts + m->play_sys_ts - base_sys_ts; if (audio.format == AUDIO_FORMAT_UNKNOWN) return; m->a_cb(m->opaque, &audio); }
bool ffmpeg_decode_audio(struct ffmpeg_decode *decode, uint8_t *data, size_t size, struct obs_source_audio *audio, bool *got_output) { AVPacket packet = {0}; int got_frame = false; int ret = 0; *got_output = false; copy_data(decode, data, size); av_init_packet(&packet); packet.data = decode->packet_buffer; packet.size = (int)size; if (!decode->frame) { decode->frame = av_frame_alloc(); if (!decode->frame) return false; } if (data && size) ret = avcodec_send_packet(decode->decoder, &packet); if (ret == 0) ret = avcodec_receive_frame(decode->decoder, decode->frame); got_frame = (ret == 0); if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN)) ret = 0; if (ret < 0) return false; else if (!got_frame) return true; for (size_t i = 0; i < MAX_AV_PLANES; i++) audio->data[i] = decode->frame->data[i]; audio->samples_per_sec = decode->frame->sample_rate; audio->format = convert_sample_format(decode->frame->format); audio->speakers = convert_speaker_layout((uint8_t)decode->decoder->channels); audio->frames = decode->frame->nb_samples; if (audio->format == AUDIO_FORMAT_UNKNOWN) return false; *got_output = true; return true; }
int ffmpeg_decode_audio(struct ffmpeg_decode *decode, uint8_t *data, size_t size, struct obs_source_audio *audio, bool *got_output) { AVPacket packet = {0}; int got_frame = false; int len; *got_output = false; copy_data(decode, data, size); av_init_packet(&packet); packet.data = decode->packet_buffer; packet.size = (int)size; if (!decode->frame) { decode->frame = av_frame_alloc(); if (!decode->frame) return -1; } len = avcodec_decode_audio4(decode->decoder, decode->frame, &got_frame, &packet); if (len <= 0 || !got_frame) return len; for (size_t i = 0; i < MAX_AV_PLANES; i++) audio->data[i] = decode->frame->data[i]; audio->samples_per_sec = decode->frame->sample_rate; audio->speakers = (enum speaker_layout)decode->decoder->channels; audio->format = convert_sample_format(decode->frame->format); audio->frames = decode->frame->nb_samples; if (audio->format == AUDIO_FORMAT_UNKNOWN) return 0; *got_output = true; return len; }