/* GStreamer
 * Copyright (C) 2011 David Schleef <ds@entropywave.com>
 * Copyright (C) 2014 Sebastian Dröge <sebastian@centricular.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Suite 500,
 * Boston, MA 02110-1335, USA.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "gstdecklinkaudiosink.h"

GST_DEBUG_CATEGORY_STATIC (gst_decklink_audio_sink_debug);
#define GST_CAT_DEFAULT gst_decklink_audio_sink_debug

// Ringbuffer implementation

#define GST_TYPE_DECKLINK_AUDIO_SINK_RING_BUFFER \
  (gst_decklink_audio_sink_ringbuffer_get_type())
#define GST_DECKLINK_AUDIO_SINK_RING_BUFFER(obj) \
  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DECKLINK_AUDIO_SINK_RING_BUFFER,GstDecklinkAudioSinkRingBuffer))
#define GST_DECKLINK_AUDIO_SINK_RING_BUFFER_CAST(obj) \
  ((GstDecklinkAudioSinkRingBuffer*) obj)
#define GST_DECKLINK_AUDIO_SINK_RING_BUFFER_CLASS(klass) \
  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DECKLINK_AUDIO_SINK_RING_BUFFER,GstDecklinkAudioSinkRingBufferClass))
#define GST_DECKLINK_AUDIO_SINK_RING_BUFFER_CAST_GET_CLASS(obj) \
  (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_DECKLINK_AUDIO_SINK_RING_BUFFER,GstDecklinkAudioSinkRingBufferClass))
#define GST_IS_DECKLINK_AUDIO_SINK_RING_BUFFER(obj) \
  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DECKLINK_AUDIO_SINK_RING_BUFFER))
#define GST_IS_DECKLINK_AUDIO_SINK_RING_BUFFER_CLASS(klass) \
  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DECKLINK_AUDIO_SINK_RING_BUFFER))

typedef struct _GstDecklinkAudioSinkRingBuffer GstDecklinkAudioSinkRingBuffer;
typedef struct _GstDecklinkAudioSinkRingBufferClass
    GstDecklinkAudioSinkRingBufferClass;

struct _GstDecklinkAudioSinkRingBuffer
{
  GstAudioRingBuffer object;

  GstDecklinkOutput *output;
  GstDecklinkAudioSink *sink;

  GMutex clock_id_lock;
  GstClockID clock_id;
};

struct _GstDecklinkAudioSinkRingBufferClass
{
  GstAudioRingBufferClass parent_class;
};

GType gst_decklink_audio_sink_ringbuffer_get_type (void);

static void gst_decklink_audio_sink_ringbuffer_finalize (GObject * object);

static void gst_decklink_audio_sink_ringbuffer_clear_all (GstAudioRingBuffer *
    rb);
static guint gst_decklink_audio_sink_ringbuffer_delay (GstAudioRingBuffer * rb);
static gboolean gst_decklink_audio_sink_ringbuffer_start (GstAudioRingBuffer *
    rb);
static gboolean gst_decklink_audio_sink_ringbuffer_pause (GstAudioRingBuffer *
    rb);
static gboolean gst_decklink_audio_sink_ringbuffer_stop (GstAudioRingBuffer *
    rb);
static gboolean gst_decklink_audio_sink_ringbuffer_acquire (GstAudioRingBuffer *
    rb, GstAudioRingBufferSpec * spec);
static gboolean gst_decklink_audio_sink_ringbuffer_release (GstAudioRingBuffer *
    rb);
static gboolean
gst_decklink_audio_sink_ringbuffer_open_device (GstAudioRingBuffer * rb);
static gboolean
gst_decklink_audio_sink_ringbuffer_close_device (GstAudioRingBuffer * rb);

#define ringbuffer_parent_class gst_decklink_audio_sink_ringbuffer_parent_class
G_DEFINE_TYPE (GstDecklinkAudioSinkRingBuffer,
    gst_decklink_audio_sink_ringbuffer, GST_TYPE_AUDIO_RING_BUFFER);

static void
    gst_decklink_audio_sink_ringbuffer_class_init
    (GstDecklinkAudioSinkRingBufferClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstAudioRingBufferClass *gstringbuffer_class =
      GST_AUDIO_RING_BUFFER_CLASS (klass);

  gobject_class->finalize = gst_decklink_audio_sink_ringbuffer_finalize;

  gstringbuffer_class->open_device =
      GST_DEBUG_FUNCPTR (gst_decklink_audio_sink_ringbuffer_open_device);
  gstringbuffer_class->close_device =
      GST_DEBUG_FUNCPTR (gst_decklink_audio_sink_ringbuffer_close_device);
  gstringbuffer_class->acquire =
      GST_DEBUG_FUNCPTR (gst_decklink_audio_sink_ringbuffer_acquire);
  gstringbuffer_class->release =
      GST_DEBUG_FUNCPTR (gst_decklink_audio_sink_ringbuffer_release);
  gstringbuffer_class->start =
      GST_DEBUG_FUNCPTR (gst_decklink_audio_sink_ringbuffer_start);
  gstringbuffer_class->pause =
      GST_DEBUG_FUNCPTR (gst_decklink_audio_sink_ringbuffer_pause);
  gstringbuffer_class->resume =
      GST_DEBUG_FUNCPTR (gst_decklink_audio_sink_ringbuffer_start);
  gstringbuffer_class->stop =
      GST_DEBUG_FUNCPTR (gst_decklink_audio_sink_ringbuffer_stop);
  gstringbuffer_class->delay =
      GST_DEBUG_FUNCPTR (gst_decklink_audio_sink_ringbuffer_delay);
  gstringbuffer_class->clear_all =
      GST_DEBUG_FUNCPTR (gst_decklink_audio_sink_ringbuffer_clear_all);
}

static void
gst_decklink_audio_sink_ringbuffer_init (GstDecklinkAudioSinkRingBuffer * self)
{
  g_mutex_init (&self->clock_id_lock);
}

static void
gst_decklink_audio_sink_ringbuffer_finalize (GObject * object)
{
  GstDecklinkAudioSinkRingBuffer *self =
      GST_DECKLINK_AUDIO_SINK_RING_BUFFER_CAST (object);

  gst_object_unref (self->sink);
  self->sink = NULL;
  g_mutex_clear (&self->clock_id_lock);

  G_OBJECT_CLASS (ringbuffer_parent_class)->finalize (object);
}

class GStreamerAudioOutputCallback:public IDeckLinkAudioOutputCallback
{
public:
  GStreamerAudioOutputCallback (GstDecklinkAudioSinkRingBuffer * ringbuffer)
  :IDeckLinkAudioOutputCallback (), m_refcount (1)
  {
    m_ringbuffer =
        GST_DECKLINK_AUDIO_SINK_RING_BUFFER_CAST (gst_object_ref (ringbuffer));
    g_mutex_init (&m_mutex);
  }

  virtual HRESULT QueryInterface (REFIID, LPVOID *)
  {
    return E_NOINTERFACE;
  }

  virtual ULONG AddRef (void)
  {
    ULONG ret;

    g_mutex_lock (&m_mutex);
    m_refcount++;
    ret = m_refcount;
    g_mutex_unlock (&m_mutex);

    return ret;
  }

  virtual ULONG Release (void)
  {
    ULONG ret;

    g_mutex_lock (&m_mutex);
    m_refcount--;
    ret = m_refcount;
    g_mutex_unlock (&m_mutex);

    if (ret == 0) {
      delete this;
    }

    return ret;
  }

  virtual ~ GStreamerAudioOutputCallback () {
    gst_object_unref (m_ringbuffer);
    g_mutex_clear (&m_mutex);
  }

  virtual HRESULT RenderAudioSamples (bool preroll)
  {
    guint8 *ptr;
    gint seg;
    gint len;
    gint bpf;
    guint written, written_sum;
    HRESULT res;
    const GstAudioRingBufferSpec *spec =
        &GST_AUDIO_RING_BUFFER_CAST (m_ringbuffer)->spec;
    guint delay, max_delay;

    GST_LOG_OBJECT (m_ringbuffer->sink, "Writing audio samples (preroll: %d)",
        preroll);

    delay =
        gst_audio_ring_buffer_delay (GST_AUDIO_RING_BUFFER_CAST (m_ringbuffer));
    max_delay = MAX ((spec->segtotal * spec->segsize) / 2, spec->segsize);
    max_delay /= GST_AUDIO_INFO_BPF (&spec->info);
    if (delay > max_delay) {
      GstClock *clock =
          gst_element_get_clock (GST_ELEMENT_CAST (m_ringbuffer->sink));
      GstClockTime wait_time;
      GstClockID clock_id;
      GstClockReturn clock_ret;

      GST_DEBUG_OBJECT (m_ringbuffer->sink, "Delay %u > max delay %u", delay,
          max_delay);

      wait_time =
          gst_util_uint64_scale (delay - max_delay, GST_SECOND,
          GST_AUDIO_INFO_RATE (&spec->info));
      GST_DEBUG_OBJECT (m_ringbuffer->sink, "Waiting for %" GST_TIME_FORMAT,
          GST_TIME_ARGS (wait_time));
      wait_time += gst_clock_get_time (clock);

      g_mutex_lock (&m_ringbuffer->clock_id_lock);
      if (!GST_AUDIO_RING_BUFFER_CAST (m_ringbuffer)->acquired) {
        GST_DEBUG_OBJECT (m_ringbuffer->sink,
            "Ringbuffer not acquired anymore");
        g_mutex_unlock (&m_ringbuffer->clock_id_lock);
        gst_object_unref (clock);
        return S_OK;
      }
      clock_id = gst_clock_new_single_shot_id (clock, wait_time);
      m_ringbuffer->clock_id = clock_id;
      g_mutex_unlock (&m_ringbuffer->clock_id_lock);
      gst_object_unref (clock);

      clock_ret = gst_clock_id_wait (clock_id, NULL);

      g_mutex_lock (&m_ringbuffer->clock_id_lock);
      gst_clock_id_unref (clock_id);
      m_ringbuffer->clock_id = NULL;
      g_mutex_unlock (&m_ringbuffer->clock_id_lock);

      if (clock_ret == GST_CLOCK_UNSCHEDULED) {
        GST_DEBUG_OBJECT (m_ringbuffer->sink, "Flushing");
        return S_OK;
      }
    }

    if (!gst_audio_ring_buffer_prepare_read (GST_AUDIO_RING_BUFFER_CAST
            (m_ringbuffer), &seg, &ptr, &len)) {
      GST_WARNING_OBJECT (m_ringbuffer->sink, "No segment available");
      return E_FAIL;
    }

    bpf =
        GST_AUDIO_INFO_BPF (&GST_AUDIO_RING_BUFFER_CAST (m_ringbuffer)->
        spec.info);
    len /= bpf;
    GST_LOG_OBJECT (m_ringbuffer->sink,
        "Write audio samples: %p size %d segment: %d", ptr, len, seg);

    written_sum = 0;
    do {
      res =
          m_ringbuffer->output->output->ScheduleAudioSamples (ptr, len,
          0, 0, &written);
      len -= written;
      ptr += written * bpf;
      written_sum += written;
    } while (len > 0 && res == S_OK);

    GST_LOG_OBJECT (m_ringbuffer->sink, "Wrote %u samples: 0x%08x", written_sum,
        res);

    gst_audio_ring_buffer_clear (GST_AUDIO_RING_BUFFER_CAST (m_ringbuffer),
        seg);
    gst_audio_ring_buffer_advance (GST_AUDIO_RING_BUFFER_CAST (m_ringbuffer),
        1);

    return res;
  }

private:
  GstDecklinkAudioSinkRingBuffer * m_ringbuffer;
  GMutex m_mutex;
  gint m_refcount;
};

static void
gst_decklink_audio_sink_ringbuffer_clear_all (GstAudioRingBuffer * rb)
{
  GstDecklinkAudioSinkRingBuffer *self =
      GST_DECKLINK_AUDIO_SINK_RING_BUFFER_CAST (rb);

  GST_DEBUG_OBJECT (self->sink, "Flushing");

  if (self->output)
    self->output->output->FlushBufferedAudioSamples ();
}

static guint
gst_decklink_audio_sink_ringbuffer_delay (GstAudioRingBuffer * rb)
{
  GstDecklinkAudioSinkRingBuffer *self =
      GST_DECKLINK_AUDIO_SINK_RING_BUFFER_CAST (rb);
  guint ret = 0;

  if (self->output) {
    if (self->output->output->GetBufferedAudioSampleFrameCount (&ret) != S_OK)
      ret = 0;
  }

  GST_DEBUG_OBJECT (self->sink, "Delay: %u", ret);

  return ret;
}

#if 0
static gboolean
in_same_pipeline (GstElement * a, GstElement * b)
{
  GstObject *root = NULL, *tmp;
  gboolean ret = FALSE;

  tmp = gst_object_get_parent (GST_OBJECT_CAST (a));
  while (tmp != NULL) {
    if (root)
      gst_object_unref (root);
    root = tmp;
    tmp = gst_object_get_parent (root);
  }

  ret = root && gst_object_has_ancestor (GST_OBJECT_CAST (b), root);

  if (root)
    gst_object_unref (root);

  return ret;
}
#endif

static gboolean
gst_decklink_audio_sink_ringbuffer_start (GstAudioRingBuffer * rb)
{
  GstDecklinkAudioSinkRingBuffer *self =
      GST_DECKLINK_AUDIO_SINK_RING_BUFFER_CAST (rb);
  GstElement *videosink = NULL;
  gboolean ret = TRUE;

  // Check if there is a video sink for this output too and if it
  // is actually in the same pipeline
  g_mutex_lock (&self->output->lock);
  if (self->output->videosink)
    videosink = GST_ELEMENT_CAST (gst_object_ref (self->output->videosink));
  g_mutex_unlock (&self->output->lock);

  if (!videosink) {
    GST_ELEMENT_ERROR (self->sink, STREAM, FAILED,
        (NULL), ("Audio sink needs a video sink for its operation"));
    ret = FALSE;
  }
  // FIXME: This causes deadlocks sometimes  
#if 0
  else if (!in_same_pipeline (GST_ELEMENT_CAST (self->sink), videosink)) {
    GST_ELEMENT_ERROR (self->sink, STREAM, FAILED,
        (NULL), ("Audio sink and video sink need to be in the same pipeline"));
    ret = FALSE;
  }
#endif

  if (videosink)
    gst_object_unref (videosink);
  return ret;
}

static gboolean
gst_decklink_audio_sink_ringbuffer_pause (GstAudioRingBuffer * rb)
{
  return TRUE;
}

static gboolean
gst_decklink_audio_sink_ringbuffer_stop (GstAudioRingBuffer * rb)
{
  return TRUE;
}

static gboolean
gst_decklink_audio_sink_ringbuffer_acquire (GstAudioRingBuffer * rb,
    GstAudioRingBufferSpec * spec)
{
  GstDecklinkAudioSinkRingBuffer *self =
      GST_DECKLINK_AUDIO_SINK_RING_BUFFER_CAST (rb);
  HRESULT ret;
  BMDAudioSampleType sample_depth;

  GST_DEBUG_OBJECT (self->sink, "Acquire");

  if (spec->info.finfo->format == GST_AUDIO_FORMAT_S16LE) {
    sample_depth = bmdAudioSampleType16bitInteger;
  } else {
    sample_depth = bmdAudioSampleType32bitInteger;
  }

  ret = self->output->output->EnableAudioOutput (bmdAudioSampleRate48kHz,
      sample_depth, 2, bmdAudioOutputStreamContinuous);
  if (ret != S_OK) {
    GST_WARNING_OBJECT (self->sink, "Failed to enable audio output 0x%08x",
        ret);
    return FALSE;
  }

  ret =
      self->output->
      output->SetAudioCallback (new GStreamerAudioOutputCallback (self));
  if (ret != S_OK) {
    GST_WARNING_OBJECT (self->sink,
        "Failed to set audio output callback 0x%08x", ret);
    return FALSE;
  }

  spec->segsize =
      (spec->latency_time * GST_AUDIO_INFO_RATE (&spec->info) /
      G_USEC_PER_SEC) * GST_AUDIO_INFO_BPF (&spec->info);
  spec->segtotal = spec->buffer_time / spec->latency_time;
  // set latency to one more segment as we need some headroom
  spec->seglatency = spec->segtotal + 1;

  rb->size = spec->segtotal * spec->segsize;
  rb->memory = (guint8 *) g_malloc0 (rb->size);

  return TRUE;
}

static gboolean
gst_decklink_audio_sink_ringbuffer_release (GstAudioRingBuffer * rb)
{
  GstDecklinkAudioSinkRingBuffer *self =
      GST_DECKLINK_AUDIO_SINK_RING_BUFFER_CAST (rb);

  GST_DEBUG_OBJECT (self->sink, "Release");

  if (self->output) {
    g_mutex_lock (&self->clock_id_lock);
    if (self->clock_id)
      gst_clock_id_unschedule (self->clock_id);
    g_mutex_unlock (&self->clock_id_lock);

    g_mutex_lock (&self->output->lock);
    self->output->audio_enabled = FALSE;
    if (self->output->start_scheduled_playback && self->output->videosink)
      self->output->start_scheduled_playback (self->output->videosink);
    g_mutex_unlock (&self->output->lock);

    self->output->output->DisableAudioOutput ();
  }
  // free the buffer
  g_free (rb->memory);
  rb->memory = NULL;

  return TRUE;
}

static gboolean
gst_decklink_audio_sink_ringbuffer_open_device (GstAudioRingBuffer * rb)
{
  GstDecklinkAudioSinkRingBuffer *self =
      GST_DECKLINK_AUDIO_SINK_RING_BUFFER_CAST (rb);

  GST_DEBUG_OBJECT (self->sink, "Open device");

  self->output =
      gst_decklink_acquire_nth_output (self->sink->device_number,
      GST_ELEMENT_CAST (self), TRUE);
  if (!self->output) {
    GST_ERROR_OBJECT (self, "Failed to acquire output");
    return FALSE;
  }

  gst_decklink_output_set_audio_clock (self->output,
      GST_AUDIO_BASE_SINK_CAST (self->sink)->provided_clock);

  return TRUE;
}

static gboolean
gst_decklink_audio_sink_ringbuffer_close_device (GstAudioRingBuffer * rb)
{
  GstDecklinkAudioSinkRingBuffer *self =
      GST_DECKLINK_AUDIO_SINK_RING_BUFFER_CAST (rb);

  GST_DEBUG_OBJECT (self->sink, "Close device");

  if (self->output) {
    gst_decklink_output_set_audio_clock (self->output, NULL);
    gst_decklink_release_nth_output (self->sink->device_number,
        GST_ELEMENT_CAST (self), TRUE);
    self->output = NULL;
  }

  return TRUE;
}

enum
{
  PROP_0,
  PROP_DEVICE_NUMBER
};

static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS
    ("audio/x-raw, format={S16LE,S32LE}, channels=2, rate=48000, "
        "layout=interleaved")
    );

static void gst_decklink_audio_sink_set_property (GObject * object,
    guint property_id, const GValue * value, GParamSpec * pspec);
static void gst_decklink_audio_sink_get_property (GObject * object,
    guint property_id, GValue * value, GParamSpec * pspec);
static void gst_decklink_audio_sink_finalize (GObject * object);

static GstStateChangeReturn gst_decklink_audio_sink_change_state (GstElement *
    element, GstStateChange transition);

static GstAudioRingBuffer
    * gst_decklink_audio_sink_create_ringbuffer (GstAudioBaseSink * absink);

#define parent_class gst_decklink_audio_sink_parent_class
G_DEFINE_TYPE (GstDecklinkAudioSink, gst_decklink_audio_sink,
    GST_TYPE_AUDIO_BASE_SINK);

static void
gst_decklink_audio_sink_class_init (GstDecklinkAudioSinkClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  GstAudioBaseSinkClass *audiobasesink_class =
      GST_AUDIO_BASE_SINK_CLASS (klass);

  gobject_class->set_property = gst_decklink_audio_sink_set_property;
  gobject_class->get_property = gst_decklink_audio_sink_get_property;
  gobject_class->finalize = gst_decklink_audio_sink_finalize;

  element_class->change_state =
      GST_DEBUG_FUNCPTR (gst_decklink_audio_sink_change_state);

  audiobasesink_class->create_ringbuffer =
      GST_DEBUG_FUNCPTR (gst_decklink_audio_sink_create_ringbuffer);

  g_object_class_install_property (gobject_class, PROP_DEVICE_NUMBER,
      g_param_spec_int ("device-number", "Device number",
          "Output device instance to use", 0, G_MAXINT, 0,
          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
              G_PARAM_CONSTRUCT)));

  gst_element_class_add_static_pad_template (element_class, &sink_template);

  gst_element_class_set_static_metadata (element_class, "Decklink Audio Sink",
      "Audio/Sink", "Decklink Sink", "David Schleef <ds@entropywave.com>, "
      "Sebastian Dröge <sebastian@centricular.com>");

  GST_DEBUG_CATEGORY_INIT (gst_decklink_audio_sink_debug, "decklinkaudiosink",
      0, "debug category for decklinkaudiosink element");
}

static void
gst_decklink_audio_sink_init (GstDecklinkAudioSink * self)
{
  self->device_number = 0;

  // 25.000ms latency time seems to be needed at least,
  // everything below can cause drop-outs
  // TODO: This is probably related to the video mode that
  // is selected, but not directly it seems. Choosing the
  // duration of a frame does not work.
  GST_AUDIO_BASE_SINK_CAST (self)->latency_time = 25000;
}

void
gst_decklink_audio_sink_set_property (GObject * object, guint property_id,
    const GValue * value, GParamSpec * pspec)
{
  GstDecklinkAudioSink *self = GST_DECKLINK_AUDIO_SINK_CAST (object);

  switch (property_id) {
    case PROP_DEVICE_NUMBER:
      self->device_number = g_value_get_int (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
}

void
gst_decklink_audio_sink_get_property (GObject * object, guint property_id,
    GValue * value, GParamSpec * pspec)
{
  GstDecklinkAudioSink *self = GST_DECKLINK_AUDIO_SINK_CAST (object);

  switch (property_id) {
    case PROP_DEVICE_NUMBER:
      g_value_set_int (value, self->device_number);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
}

void
gst_decklink_audio_sink_finalize (GObject * object)
{
  G_OBJECT_CLASS (parent_class)->finalize (object);
}

static GstStateChangeReturn
gst_decklink_audio_sink_change_state (GstElement * element,
    GstStateChange transition)
{
  GstDecklinkAudioSink *self = GST_DECKLINK_AUDIO_SINK_CAST (element);
  GstDecklinkAudioSinkRingBuffer *buf =
      GST_DECKLINK_AUDIO_SINK_RING_BUFFER_CAST (GST_AUDIO_BASE_SINK_CAST
      (self)->ringbuffer);
  GstStateChangeReturn ret;

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
  if (ret == GST_STATE_CHANGE_FAILURE)
    return ret;

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      g_mutex_lock (&buf->output->lock);
      buf->output->audio_enabled = TRUE;
      if (buf->output->start_scheduled_playback && buf->output->videosink)
        buf->output->start_scheduled_playback (buf->output->videosink);
      g_mutex_unlock (&buf->output->lock);
      break;
    default:
      break;
  }

  return ret;
}

static GstAudioRingBuffer *
gst_decklink_audio_sink_create_ringbuffer (GstAudioBaseSink * absink)
{
  GstAudioRingBuffer *ret;

  GST_DEBUG_OBJECT (absink, "Creating ringbuffer");

  ret =
      GST_AUDIO_RING_BUFFER_CAST (g_object_new
      (GST_TYPE_DECKLINK_AUDIO_SINK_RING_BUFFER, NULL));

  GST_DECKLINK_AUDIO_SINK_RING_BUFFER_CAST (ret)->sink =
      (GstDecklinkAudioSink *) gst_object_ref (absink);

  return ret;
}
