[mythtv] Audio Update - Another patch
Jesper Sörensen
jesper at datapartner.se
Sat Oct 23 11:53:54 UTC 2004
Ed Wildgoose wrote:
> Here is a link to the latest version of my audio patch. This is an
> interim version and is not for cvs, but mainly so that David and
> Jesper can check what I have done versus their stuff.
Thanks! Getting some problems here:
g++ -c -pipe -Wall -W -g -D_REENTRANT -D_GNU_SOURCE
-D_FILE_OFFSET_BITS=64 -DPREFIX=\"/usr\" -DMMX -DCONFIG_VIDEO4LINUX
-DUSING_OSS -DUSING_DVB -DQT_THREAD_SUPPORT -DQT_SHARED -DQT_NO_DEBUG
-I/usr/share/qt3/mkspecs/default -I. -I../../libs -I../../libs/libmyth
-I../../libs/libmythtv -I../../libs/libavcodec -I../../libs/libavformat
-I/usr/include -I/usr/local/include -I/usr/include/qt3 -o transcode.o
transcode.cpp
transcode.cpp: In member function `int Transcode::TranscodeFile(char*,
char*,
QString, bool, bool, bool, QString)':
transcode.cpp:276: error: cannot allocate an object of type `
AudioReencodeBuffer'
transcode.cpp:276: error: because the following virtual functions are
abstract:
../../libs/libmyth/audiooutput.h:50: error: virtual int
AudioOutput::GetVolumeChannel(int)
../../libs/libmyth/audiooutput.h:51: error: virtual void
AudioOutput::SetVolumeChannel(int, int)
make[3]: *** [transcode.o] Error 1
> Jesper could you check that I have your core audio patches included
> correctly.
If you mean my little Alsa patch, it is *not* included in your
patch/files. It's attached to this e-mail in case you lost it or if
someone else would like to take a look at it.
Apply with "patch -p2 -s -i alsa_crash_fix.patch" or similar.
What it does, in short:
- Fixes NULL device crash
- Handle errors better (don't close the device!)
- Various logging/debugging changes and some minor cleanup
Tested with Linux 2.6.8.1 and Alsa lib 1.0.6a or something like that.
Works fine on my Revo.
Please note: This patch is against Ed's patch - it probably won't work
against CVS.
Rgds,
Jesper
-------------- next part --------------
--- cvs.old/mythtv/libs/libmyth/audiooutputalsa.cpp 2004-10-11 17:48:54.000000000 +0200
+++ cvs/mythtv/libs/libmyth/audiooutputalsa.cpp 2004-10-11 23:16:21.000000000 +0200
@@ -29,19 +29,11 @@
bool AudioOutputALSA::OpenDevice()
{
- snd_pcm_t *new_pcm_handle;
snd_pcm_format_t format;
unsigned int buffer_time = 500000, period_time = 100000;
-
int err;
- new_pcm_handle = pcm_handle;
pcm_handle = NULL;
-
-// if (new_pcm_handle != NULL)
-// snd_pcm_hw_free(new_pcm_handle);
-
-
numbadioctls = 0;
err = snd_pcm_open(&pcm_handle, audiodevice,
@@ -49,7 +41,7 @@
if (err < 0)
{
- Error(QString("snd_pcm_open(%1) error %2")
+ Error(QString("snd_pcm_open(%1): %2")
.arg(audiodevice).arg(snd_strerror(err)));
}
@@ -58,7 +50,7 @@
snd_pcm_uframes_t avail = 0;
snd_pcm_hw_params_t *hw_params;
if ((err = snd_pcm_hw_params_malloc(&hw_params)) < 0) {
- Error(QString("cannot allocate hardware parameter structure (%1)")
+ Error(QString("snd_pcm_hw_params_malloc: %1")
.arg(snd_strerror(err)));
}
snd_pcm_hw_params_current(pcm_handle, hw_params);
@@ -87,8 +79,7 @@
period_time);
if (err < 0)
{
- snd_pcm_close(pcm_handle);
- pcm_handle = NULL;
+ CloseDevice();
return false;
}
@@ -108,21 +99,25 @@
void AudioOutputALSA::WriteAudio(unsigned char *aubuf, int size)
{
- if (pcm_handle == NULL)
- return;
-
unsigned char *tmpbuf;
int lw = 0;
int frames = size / audio_bytes_per_sample;
+ if (pcm_handle == NULL)
+ {
+ VERBOSE(VB_IMPORTANT, QString("WriteAudio() called with pcm_handle == NULL!"));
+ return;
+ }
+
tmpbuf = aubuf;
- VERBOSE(VB_AUDIO, QString("Preparing %1 bytes (%2 frames) in WriteAudio")
+ VERBOSE(VB_AUDIO, QString("WriteAudio: Preparing %1 bytes (%2 frames)")
.arg(size).arg(frames));
while (frames > 0)
{
lw = snd_pcm_mmap_writei(pcm_handle, tmpbuf, frames);
+
if (lw >= 0)
{
frames -= lw;
@@ -130,34 +125,53 @@
}
else if (lw == -EAGAIN)
{
- VERBOSE(VB_AUDIO, QString("Soundcard is blocked. Waiting for card to become ready"));
+ VERBOSE(VB_AUDIO, QString("WriteAudio: device is blocked - waiting"));
+
snd_pcm_wait(pcm_handle, 10);
}
- else if (lw == -EPIPE &&
- snd_pcm_state(pcm_handle) == SND_PCM_STATE_XRUN &&
- snd_pcm_prepare(pcm_handle) == 0)
+ else if (lw == -EPIPE)
{
- VERBOSE(VB_AUDIO, "WriteAudio: xrun (buffer underrun)");
- continue;
+ VERBOSE(VB_IMPORTANT, "WriteAudio: buffer underrun");
+
+ if ((lw = snd_pcm_prepare(pcm_handle)) < 0)
+ {
+ Error(QString("WriteAudio: unable to recover from xrun: %1")
+ .arg(snd_strerror(lw)));
+ return;
+ }
}
- else if (lw == -EPIPE &&
- snd_pcm_state(pcm_handle) == SND_PCM_STATE_SUSPENDED)
+ else if (lw == -ESTRPIPE)
{
- VERBOSE(VB_AUDIO, "WriteAudio: suspended");
+ VERBOSE(VB_IMPORTANT, "WriteAudio: device is suspended");
while ((lw = snd_pcm_resume(pcm_handle)) == -EAGAIN)
usleep(200);
- if (lw < 0 && (lw = snd_pcm_prepare(pcm_handle)) == 0)
- continue;
+ if (lw < 0)
+ {
+ VERBOSE(VB_IMPORTANT, "WriteAudio: resume failed");
+
+ if ((lw = snd_pcm_prepare(pcm_handle)) < 0)
+ {
+ Error(QString("WriteAudio: unable to recover from suspend: %1")
+ .arg(snd_strerror(lw)));
+ return;
+ }
+ }
}
+ else if (lw == -EBADFD)
+ {
+ VERBOSE(VB_IMPORTANT, QString("WriteAudio: device is in a bad state (state = %1)").arg(snd_pcm_state(pcm_handle)));
- if (lw < 0)
+ return;
+ }
+ else
{
- Error(QString("snd_pcm_mmap_writei(%1,frames=%2) error %3: %4")
- .arg(audiodevice).arg(frames).arg(snd_strerror(lw)));
- snd_pcm_close(pcm_handle);
- pcm_handle = NULL;
+ VERBOSE(VB_IMPORTANT, QString("snd_pcm_mmap_writei: %3 (%4)")
+ .arg(snd_strerror(lw)).arg(lw));
+ VERBOSE(VB_IMPORTANT, QString("WriteAudio: snd_pcm_state == %1").arg(snd_pcm_state(pcm_handle)));
+
+ // CloseDevice();
return;
}
}
@@ -168,6 +182,13 @@
int err;
snd_pcm_uframes_t soundcard_buffer = 0;
snd_pcm_hw_params_t *hw_params;
+
+ if (pcm_handle == NULL)
+ {
+ VERBOSE(VB_IMPORTANT, QString("getBufferedOnSoundcard() called with pcm_handle == NULL!"));
+ return 0;
+ }
+
if ((err = snd_pcm_hw_params_malloc(&hw_params)) < 0) {
Error(QString("cannot allocate hardware parameter structure (%1)")
.arg(snd_strerror(err)));
@@ -188,12 +209,15 @@
int err = 0;
if (pcm_handle == NULL)
- return 0;
+ {
+ VERBOSE(VB_IMPORTANT, QString("getSpaceOnSoundcard() called with pcm_handle == NULL!"));
+ return 0;
+ }
snd_pcm_uframes_t soundcard_buffer = 0; // total buffer on soundcard
snd_pcm_hw_params_t *hw_params;
if ((err = snd_pcm_hw_params_malloc(&hw_params)) < 0) {
- Error(QString("cannot allocate hardware parameter structure (%1)")
+ Error(QString("snd_pcm_hw_params_malloc: %1")
.arg(snd_strerror(err)));
}
snd_pcm_hw_params_current(pcm_handle, hw_params);
@@ -207,7 +231,7 @@
// make sure that we are actually in the running state otherwise
// snd_pcm_delay return is meaningless
if (snd_pcm_state(pcm_handle) < SND_PCM_STATE_RUNNING)
- VERBOSE(VB_IMPORTANT, QString("Not in the running state, state=%1")
+ VERBOSE(VB_AUDIO, QString("Not in the running state, state=%1")
.arg(snd_pcm_state(pcm_handle)));
// Free space is the total buffer minus the frames waiting to be written
@@ -249,6 +273,12 @@
"rate=%3, buffer_time=%4, period_time=%5")
.arg(format).arg(channels).arg(rate).arg(buffer_time).arg(period_time));
+ if (pcm_handle == NULL)
+ {
+ VERBOSE(VB_IMPORTANT, QString("SetParameters() called with pcm_handle == NULL!"));
+ return 0;
+ }
+
snd_pcm_hw_params_alloca(¶ms);
snd_pcm_sw_params_alloca(&swparams);
More information about the mythtv-dev
mailing list