Fix invalid channel layout (0x0) in audio processor and add playback diagnostics
- Add FixChannelLayout() helper to AudioProcessor::Open() to fall back to a default native channel layout when the input/output layout is unspecified, custom, or has a zero mask. This prevents FFmpeg's abuffer/aformat filters from rejecting 'channel_layouts=0x0' on Linux. - Log audio processor open parameters, viewer audio queue state, and AudioManager::PushToOutput device/stream status to help diagnose silent playback on Linux.
This commit is contained in:
@@ -601,6 +601,14 @@ void ViewerWidget::UpdateAudioProcessor()
|
||||
.toString()
|
||||
.toStdString()));
|
||||
|
||||
qDebug() << "ViewerWidget::UpdateAudioProcessor: from sample_rate="
|
||||
<< ap.sample_rate() << "channels=" << ap.channel_count()
|
||||
<< "layout_mask=0x" << Qt::hex << ap.channel_layout().u.mask
|
||||
<< "to sample_rate=" << packed.sample_rate()
|
||||
<< "channels=" << packed.channel_count()
|
||||
<< "layout_mask=0x" << packed.channel_layout().u.mask
|
||||
<< Qt::dec;
|
||||
|
||||
audio_processor_.Open(
|
||||
ap, packed, (playback_speed_ == 0) ? 1 : std::abs(playback_speed_));
|
||||
}
|
||||
@@ -844,9 +852,14 @@ void ViewerWidget::QueueNextAudioBuffer()
|
||||
// Clamp queue end by zero and the audio length
|
||||
queue_end = std::clamp(queue_end, rational(0),
|
||||
GetConnectedNode()->GetAudioLength());
|
||||
qDebug() << "ViewerWidget::QueueNextAudioBuffer: time="
|
||||
<< audio_playback_queue_time_.toDouble() << "end="
|
||||
<< queue_end.toDouble()
|
||||
<< "audio_length=" << GetConnectedNode()->GetAudioLength().toDouble();
|
||||
if ((playback_speed_ > 0 && queue_end <= audio_playback_queue_time_) ||
|
||||
(playback_speed_ < 0 && queue_end >= audio_playback_queue_time_)) {
|
||||
// This will queue nothing, so stop the loop here
|
||||
qDebug() << "ViewerWidget::QueueNextAudioBuffer: nothing to queue";
|
||||
if (prequeuing_audio_) {
|
||||
DecrementPrequeuedAudio();
|
||||
}
|
||||
@@ -865,6 +878,8 @@ void ViewerWidget::QueueNextAudioBuffer()
|
||||
|
||||
void ViewerWidget::ReceivedAudioBufferForPlayback()
|
||||
{
|
||||
qDebug() << "ViewerWidget::ReceivedAudioBufferForPlayback: queue_size="
|
||||
<< audio_playback_queue_.size();
|
||||
while (!audio_playback_queue_.empty() &&
|
||||
audio_playback_queue_.front()->HasResult()) {
|
||||
RenderTicketWatcher *watcher = audio_playback_queue_.front();
|
||||
@@ -872,6 +887,10 @@ void ViewerWidget::ReceivedAudioBufferForPlayback()
|
||||
|
||||
if (watcher->HasResult()) {
|
||||
SampleBuffer samples = watcher->Get().value<SampleBuffer>();
|
||||
qDebug() << "ViewerWidget::ReceivedAudioBufferForPlayback: got buffer"
|
||||
<< "allocated=" << samples.is_allocated()
|
||||
<< "sample_count=" << samples.sample_count()
|
||||
<< "channels=" << samples.audio_params().channel_count();
|
||||
if (samples.is_allocated()) {
|
||||
// If the samples must be reversed, reverse them now
|
||||
if (playback_speed_ < 0) {
|
||||
@@ -881,12 +900,17 @@ void ViewerWidget::ReceivedAudioBufferForPlayback()
|
||||
// Convert to packed data for audio output
|
||||
AudioProcessor::Buffer buf;
|
||||
int r = audio_processor_.Convert(samples.to_raw_ptrs().data(),
|
||||
samples.sample_count(), &buf);
|
||||
samples.sample_count(), &buf);
|
||||
qDebug() << "ViewerWidget::ReceivedAudioBufferForPlayback: Convert"
|
||||
<< "returned=" << r << "buf_size=" << buf.size();
|
||||
|
||||
// TempoProcessor may have emptied the array
|
||||
if (r >= 0) {
|
||||
if (!buf.empty()) {
|
||||
const QByteArray &pack = buf.at(0);
|
||||
qDebug() << "ViewerWidget::ReceivedAudioBufferForPlayback: pushing"
|
||||
<< pack.size() << "bytes prequeuing="
|
||||
<< prequeuing_audio_;
|
||||
if (prequeuing_audio_) {
|
||||
// Add to prequeued audio buffer
|
||||
prequeued_audio_.append(pack);
|
||||
@@ -1124,11 +1148,15 @@ void ViewerWidget::PlayInternal(int speed, bool in_to_out_only)
|
||||
}
|
||||
|
||||
AudioParams ap = GetConnectedNode()->GetAudioParams();
|
||||
qDebug() << "ViewerWidget::PlayInternal: audio params valid=" << ap.is_valid()
|
||||
<< "channel_count=" << ap.channel_count();
|
||||
if (ap.is_valid() && ap.channel_count() != 0) {
|
||||
UpdateAudioProcessor();
|
||||
|
||||
// Verify audio processor output params are valid before using them
|
||||
AudioParams output_params = audio_processor_.to();
|
||||
qDebug() << "ViewerWidget::PlayInternal: audio processor output params valid="
|
||||
<< output_params.is_valid();
|
||||
if (!output_params.is_valid()) {
|
||||
qWarning()
|
||||
<< "Audio processor output params are invalid, skipping audio playback";
|
||||
@@ -1142,6 +1170,8 @@ void ViewerWidget::PlayInternal(int speed, bool in_to_out_only)
|
||||
prequeuing_audio_ =
|
||||
prequeue_count; // Queue two buffers ahead of time
|
||||
audio_playback_queue_time_ = GetConnectedNode()->GetPlayhead();
|
||||
qDebug() << "ViewerWidget::PlayInternal: prequeuing audio start time="
|
||||
<< audio_playback_queue_time_.toDouble();
|
||||
for (int i = 0; i < prequeue_count; i++) {
|
||||
QueueNextAudioBuffer();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user