[PATCH 13/43] audio/dsound: convert to QOM lifecycle methods

marcandre.lureau@redhat.com posted 43 patches 1 week, 6 days ago
Maintainers: Gerd Hoffmann <kraxel@redhat.com>, Christian Schoenebeck <qemu_oss@crudebyte.com>, "Marc-André Lureau" <marcandre.lureau@redhat.com>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>, Thomas Huth <huth@tuxfamily.org>, Alexandre Ratchov <alex@caoua.org>, Laurent Vivier <laurent@vivier.eu>, Manos Pitsidianakis <manos.pitsidianakis@linaro.org>, "Michael S. Tsirkin" <mst@redhat.com>, Alistair Francis <alistair@alistair23.me>, "Edgar E. Iglesias" <edgar.iglesias@gmail.com>, Peter Maydell <peter.maydell@linaro.org>
[PATCH 13/43] audio/dsound: convert to QOM lifecycle methods
Posted by marcandre.lureau@redhat.com 1 week, 6 days ago
From: Marc-André Lureau <marcandre.lureau@redhat.com>

Migrate the DirectSound audio backend from the legacy driver init/fini
callbacks to proper QOM realize and finalize methods.

The dsound struct fields are now embedded directly in the AudioDsound
QOM object instead of being allocated separately as drv_opaque. This
allows accessing the backend state through proper QOM type casting
with AUDIO_DSOUND() rather than casting drv_opaque pointers.

The DirectSound and DirectSoundCapture COM objects are now managed
through the QOM lifecycle, with initialization in realize and cleanup
in finalize.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 audio/dsound_template.h |  9 ++---
 audio/dsoundaudio.c     | 87 +++++++++++++++++++----------------------
 2 files changed, 45 insertions(+), 51 deletions(-)

diff --git a/audio/dsound_template.h b/audio/dsound_template.h
index 0678f2de38b..7979773eb86 100644
--- a/audio/dsound_template.h
+++ b/audio/dsound_template.h
@@ -72,7 +72,7 @@ static int glue (dsound_lock_, TYPE) (
     DWORD *blen1p,
     DWORD *blen2p,
     int entire,
-    dsound *s
+    AudioDsound *s
     )
 {
     HRESULT hr;
@@ -166,7 +166,7 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
 {
     int err;
     HRESULT hr;
-    dsound *s = drv_opaque;
+    AudioDsound *s = AUDIO_DSOUND(hw->s);
     WAVEFORMATEX wfx;
     struct audsettings obt_as;
 #ifdef DSBTYPE_IN
@@ -174,13 +174,13 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
     DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
     DSCBUFFERDESC bd;
     DSCBCAPS bc;
-    AudiodevPerDirectionOptions *pdo = s->dev->u.dsound.in;
+    AudiodevPerDirectionOptions *pdo = hw->s->dev->u.dsound.in;
 #else
     const char *typ = "DAC";
     DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
     DSBUFFERDESC bd;
     DSBCAPS bc;
-    AudiodevPerDirectionOptions *pdo = s->dev->u.dsound.out;
+    AudiodevPerDirectionOptions *pdo = hw->s->dev->u.dsound.out;
 #endif
 
     if (!s->FIELD2) {
@@ -256,7 +256,6 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
     }
     hw->size_emul = bc.dwBufferBytes;
     hw->samples = bc.dwBufferBytes / hw->info.bytes_per_frame;
-    ds->s = s;
 
 #ifdef DEBUG_DSOUND
     dolog ("caps %ld, desc %ld\n",
diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c
index 3de6a3dee9c..4ecf2ade003 100644
--- a/audio/dsoundaudio.c
+++ b/audio/dsoundaudio.c
@@ -45,40 +45,30 @@
 #define TYPE_AUDIO_DSOUND "audio-dsound"
 OBJECT_DECLARE_SIMPLE_TYPE(AudioDsound, AUDIO_DSOUND)
 
+static AudioBackendClass *audio_dsound_parent_class;
+
 struct AudioDsound {
     AudioMixengBackend parent;
+
+    LPDIRECTSOUND dsound;
+    LPDIRECTSOUNDCAPTURE dsound_capture;
+    struct audsettings settings;
 };
 
 static struct audio_driver dsound_audio_driver;
 
-static void audio_dsound_class_init(ObjectClass *klass, const void *data)
-{
-    AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_CLASS(klass);
-
-    k->driver = &dsound_audio_driver;
-}
-
 /* #define DEBUG_DSOUND */
 
-typedef struct {
-    LPDIRECTSOUND dsound;
-    LPDIRECTSOUNDCAPTURE dsound_capture;
-    struct audsettings settings;
-    Audiodev *dev;
-} dsound;
-
 typedef struct {
     HWVoiceOut hw;
     LPDIRECTSOUNDBUFFER dsound_buffer;
     bool first_time;
-    dsound *s;
 } DSoundVoiceOut;
 
 typedef struct {
     HWVoiceIn hw;
     LPDIRECTSOUNDCAPTUREBUFFER dsound_capture_buffer;
     bool first_time;
-    dsound *s;
 } DSoundVoiceIn;
 
 static const char *dserror(HRESULT hr)
@@ -276,7 +266,7 @@ static void print_wave_format (WAVEFORMATEX *wfx)
 }
 #endif
 
-static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb, dsound *s)
+static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb, AudioDsound *s)
 {
     HRESULT hr;
 
@@ -295,7 +285,7 @@ static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb, dsound *s)
 #undef DSBTYPE_IN
 
 static int dsound_get_status_out (LPDIRECTSOUNDBUFFER dsb, DWORD *statusp,
-                                  dsound *s)
+                                  AudioDsound *s)
 {
     HRESULT hr;
 
@@ -328,7 +318,7 @@ static int dsound_get_status_in (LPDIRECTSOUNDCAPTUREBUFFER dscb,
 }
 
 static void dsound_clear_sample (HWVoiceOut *hw, LPDIRECTSOUNDBUFFER dsb,
-                                 dsound *s)
+                                 AudioDsound *s)
 {
     int err;
     LPVOID p1, p2;
@@ -372,9 +362,9 @@ static void dsound_enable_out(HWVoiceOut *hw, bool enable)
 {
     HRESULT hr;
     DWORD status;
+    AudioDsound *s = AUDIO_DSOUND(hw->s);
     DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
     LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer;
-    dsound *s = ds->s;
 
     if (!dsb) {
         dolog ("Attempt to control voice without a buffer\n");
@@ -450,7 +440,7 @@ static void *dsound_get_buffer_out(HWVoiceOut *hw, size_t *size)
     assert(req_size > 0);
 
     err = dsound_lock_out(dsb, &hw->info, hw->pos_emul, req_size, &ret, NULL,
-                          &act_size, NULL, false, ds->s);
+                          &act_size, NULL, false, AUDIO_DSOUND(hw->s));
     if (err) {
         dolog("Failed to lock buffer\n");
         *size = 0;
@@ -553,7 +543,7 @@ static void *dsound_get_buffer_in(HWVoiceIn *hw, size_t *size)
     }
 
     err = dsound_lock_in(dscb, &hw->info, hw->pos_emul, req_size, &ret, NULL,
-                         &act_size, NULL, false, ds->s);
+                         &act_size, NULL, false, AUDIO_DSOUND(hw->s));
     if (err) {
         dolog("Failed to lock buffer\n");
         *size = 0;
@@ -577,13 +567,12 @@ static void dsound_put_buffer_in(HWVoiceIn *hw, void *buf, size_t len)
     hw->pos_emul = (hw->pos_emul + len) % hw->size_emul;
 }
 
-static void dsound_audio_fini (void *opaque)
+static void audio_dsound_finalize(Object *obj)
 {
+    AudioDsound *s = AUDIO_DSOUND(obj);
     HRESULT hr;
-    dsound *s = opaque;
 
     if (!s->dsound) {
-        g_free(s);
         return;
     }
 
@@ -594,7 +583,6 @@ static void dsound_audio_fini (void *opaque)
     s->dsound = NULL;
 
     if (!s->dsound_capture) {
-        g_free(s);
         return;
     }
 
@@ -603,18 +591,21 @@ static void dsound_audio_fini (void *opaque)
         dsound_logerr (hr, "Could not release DirectSoundCapture\n");
     }
     s->dsound_capture = NULL;
-
-    g_free(s);
 }
 
-static void *dsound_audio_init(Audiodev *dev, Error **errp)
+static bool
+audio_dsound_realize(AudioBackend *abe, Audiodev *dev, Error **errp)
 {
+    AudioDsound *s = AUDIO_DSOUND(abe);
     HRESULT hr;
-    dsound *s = g_new0(dsound, 1);
     AudiodevDsoundOptions *dso;
 
     assert(dev->driver == AUDIODEV_DRIVER_DSOUND);
-    s->dev = dev;
+
+    if (!audio_dsound_parent_class->realize(abe, dev, errp)) {
+        return false;
+    }
+
     dso = &dev->u.dsound;
 
     if (!dso->has_latency) {
@@ -625,8 +616,7 @@ static void *dsound_audio_init(Audiodev *dev, Error **errp)
     hr = CoInitialize (NULL);
     if (FAILED (hr)) {
         dserror_set(errp, hr, "Could not initialize COM");
-        dsound_audio_fini(s);
-        return NULL;
+        return false;
     }
 
     hr = CoCreateInstance (
@@ -638,15 +628,13 @@ static void *dsound_audio_init(Audiodev *dev, Error **errp)
         );
     if (FAILED (hr)) {
         dserror_set(errp, hr, "Could not create DirectSound instance");
-        dsound_audio_fini(s);
-        return NULL;
+        return false;
     }
 
     hr = IDirectSound_Initialize (s->dsound, NULL);
     if (FAILED (hr)) {
         dserror_set(errp, hr, "Could not initialize DirectSound");
-        dsound_audio_fini(s);
-        return NULL;
+        return false;
     }
 
     hr = CoCreateInstance (
@@ -658,15 +646,13 @@ static void *dsound_audio_init(Audiodev *dev, Error **errp)
         );
     if (FAILED (hr)) {
         dserror_set(errp, hr, "Could not create DirectSoundCapture instance");
-        dsound_audio_fini(s);
-        return NULL;
+        return false;
     }
 
     hr = IDirectSoundCapture_Initialize (s->dsound_capture, NULL);
     if (FAILED(hr)) {
         dserror_set(errp, hr, "Could not initialize DirectSoundCapture");
-        dsound_audio_fini(s);
-        return NULL;
+        return false;
     }
 
     hr = IDirectSound_SetCooperativeLevel (
@@ -676,11 +662,10 @@ static void *dsound_audio_init(Audiodev *dev, Error **errp)
     );
     if (FAILED(hr)) {
         dserror_set(errp, hr, "Could not set cooperative level");
-        dsound_audio_fini(s);
-        return NULL;
+        return false;
     }
 
-    return s;
+    return true;
 }
 
 static struct audio_pcm_ops dsound_pcm_ops = {
@@ -702,8 +687,6 @@ static struct audio_pcm_ops dsound_pcm_ops = {
 
 static struct audio_driver dsound_audio_driver = {
     .name           = "dsound",
-    .init           = dsound_audio_init,
-    .fini           = dsound_audio_fini,
     .pcm_ops        = &dsound_pcm_ops,
     .max_voices_out = INT_MAX,
     .max_voices_in  = 1,
@@ -711,11 +694,23 @@ static struct audio_driver dsound_audio_driver = {
     .voice_size_in  = sizeof (DSoundVoiceIn)
 };
 
+static void audio_dsound_class_init(ObjectClass *klass, const void *data)
+{
+    AudioBackendClass *b = AUDIO_BACKEND_CLASS(klass);
+    AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_CLASS(klass);
+
+    audio_dsound_parent_class = AUDIO_BACKEND_CLASS(object_class_get_parent(klass));
+
+    b->realize = audio_dsound_realize;
+    k->driver = &dsound_audio_driver;
+}
+
 static const TypeInfo audio_dsound_info = {
     .name = TYPE_AUDIO_DSOUND,
     .parent = TYPE_AUDIO_MIXENG_BACKEND,
     .instance_size = sizeof(AudioDsound),
     .class_init = audio_dsound_class_init,
+    .instance_finalize = audio_dsound_finalize,
 };
 
 static void register_audio_dsound(void)
-- 
2.52.0