/*
 * GStreamer
 * Copyright (C) 2013 Fluendo S.L. <support@fluendo.com>
 *    Authors: Andoni Morales Alastruey <amorales@fluendo.com>
 * Copyright (C) 2014 Collabora Ltd.
 *    Authors: Matthieu Bouron <matthieu.bouron@collabora.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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/**
 * SECTION:element-plugin
 *
 * Read and decode samples from AVFoundation assets using the AVFAssetReader API
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 -v -m avfassetsrc uri="file://movie.mp4" ! autovideosink
 * ]|
 * </refsect2>
 */

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include "avfassetsrc.h"
#include "coremediabuffer.h"

GST_DEBUG_CATEGORY_STATIC (gst_avf_asset_src_debug);
#define GST_CAT_DEFAULT gst_avf_asset_src_debug

#define CMTIME_TO_GST_TIME(x) \
    (x.value == 0 ? 0 : (guint64)(x.value * GST_SECOND / x.timescale));
#define GST_AVF_ASSET_SRC_LOCK(x) (g_mutex_lock (&x->lock));
#define GST_AVF_ASSET_SRC_UNLOCK(x) (g_mutex_unlock (&x->lock));
#define MEDIA_TYPE_TO_STR(x) \
    (x == GST_AVF_ASSET_READER_MEDIA_TYPE_AUDIO ? "audio" : "video")
#define AVF_ASSET_READER_HAS_AUDIO(x) \
    ([self->reader hasMediaType:GST_AVF_ASSET_READER_MEDIA_TYPE_AUDIO])
#define AVF_ASSET_READER_HAS_VIDEO(x) \
    ([self->reader hasMediaType:GST_AVF_ASSET_READER_MEDIA_TYPE_VIDEO])
#define OBJC_CALLOUT_BEGIN() \
   NSAutoreleasePool *pool; \
   \
   pool = [[NSAutoreleasePool alloc] init]
#define OBJC_CALLOUT_END() \
  [pool release]

enum
{
  PROP_0,
  PROP_URI
};

static GstStaticPadTemplate audio_factory = GST_STATIC_PAD_TEMPLATE ("audio",
    GST_PAD_SRC,
    GST_PAD_SOMETIMES,
    GST_STATIC_CAPS ("audio/x-raw, "
        "format = (string) F32LE, "
        "rate = " GST_AUDIO_RATE_RANGE ", "
        "channels = (int) [1, 2], "
        "layout = (string) interleaved"
    )
);

static GstStaticPadTemplate video_factory = GST_STATIC_PAD_TEMPLATE ("video",
    GST_PAD_SRC,
    GST_PAD_SOMETIMES,
    GST_STATIC_CAPS ("video/x-raw, "
        "format = (string) NV12, "
        "framerate = " GST_VIDEO_FPS_RANGE ", "
        "width = " GST_VIDEO_SIZE_RANGE ", "
        "height = " GST_VIDEO_SIZE_RANGE
    )
);

static void gst_avf_asset_src_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_avf_asset_src_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void gst_avf_asset_src_dispose (GObject *object);

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

static gboolean gst_avf_asset_src_query (GstPad *pad, GstObject * parent, GstQuery *query);
static gboolean gst_avf_asset_src_event (GstPad *pad, GstObject * parent, GstEvent *event);
static gboolean gst_avf_asset_src_send_event (GstAVFAssetSrc *self,
    GstEvent *event);

static void gst_avf_asset_src_read_audio (GstAVFAssetSrc *self);
static void gst_avf_asset_src_read_video (GstAVFAssetSrc *self);
static void gst_avf_asset_src_start (GstAVFAssetSrc *self);
static void gst_avf_asset_src_stop (GstAVFAssetSrc *self);
static gboolean gst_avf_asset_src_start_reading (GstAVFAssetSrc *self);
static void gst_avf_asset_src_stop_reading (GstAVFAssetSrc *self);
static void gst_avf_asset_src_stop_all (GstAVFAssetSrc *self);
static void gst_avf_asset_src_uri_handler_init (gpointer g_iface,
    gpointer iface_data);

static void
_do_init (GType avf_assetsrc_type)
{
  static const GInterfaceInfo urihandler_info = {
    gst_avf_asset_src_uri_handler_init,
    NULL,
    NULL
  };

  g_type_add_interface_static (avf_assetsrc_type, GST_TYPE_URI_HANDLER,
      &urihandler_info);
  GST_DEBUG_CATEGORY_INIT (gst_avf_asset_src_debug, "avfassetsrc",
      0, "avfassetsrc element");
}

G_DEFINE_TYPE_WITH_CODE (GstAVFAssetSrc, gst_avf_asset_src, GST_TYPE_ELEMENT,
    _do_init (g_define_type_id));


/* GObject vmethod implementations */

static void
gst_avf_asset_src_class_init (GstAVFAssetSrcClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;

  gst_element_class_set_static_metadata (gstelement_class,
    "Source and decoder for AVFoundation assets",
    "Source/Codec",
    "Read and decode samples from AVFoundation assets using the AVFAssetReader API",
    "Andoni Morales Alastruey amorales@fluendo.com");

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&audio_factory));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&video_factory));

  gobject_class->set_property = gst_avf_asset_src_set_property;
  gobject_class->get_property = gst_avf_asset_src_get_property;
  gobject_class->dispose = gst_avf_asset_src_dispose;

  /**
   * GstAVFAssetSrc:uri
   *
   * URI of the asset to read
   *
   **/
  g_object_class_install_property (gobject_class, PROP_URI,
      g_param_spec_string ("uri", "Asset URI",
          "URI of the asset to read", NULL,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
          GST_PARAM_MUTABLE_READY));

  gstelement_class->change_state = gst_avf_asset_src_change_state;

}

static void
gst_avf_asset_src_init (GstAVFAssetSrc * self)
{
  self->selected_audio_track = 0;
  self->selected_video_track = 0;
  self->last_audio_pad_ret = GST_FLOW_OK;
  self->last_video_pad_ret = GST_FLOW_OK;
  g_mutex_init (&self->lock);
}

static void
gst_avf_asset_src_dispose (GObject *object)
{
  GstAVFAssetSrc *self = GST_AVF_ASSET_SRC (object);

  if (self->uri != NULL) {
    g_free (self->uri);
    self->uri = NULL;
  }

  if (self->seek_event) {
    gst_event_unref (self->seek_event);
    self->seek_event = NULL;
  }
}

static void
gst_avf_asset_src_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstAVFAssetSrc *self = GST_AVF_ASSET_SRC (object);

  switch (prop_id) {
    case PROP_URI:
      g_free (self->uri);
      self->uri = g_value_dup_string (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_avf_asset_src_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstAVFAssetSrc *self = GST_AVF_ASSET_SRC (object);

  switch (prop_id) {
    case PROP_URI:
      g_value_set_string (value, self->uri);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static GstStateChangeReturn
gst_avf_asset_src_change_state (GstElement * element, GstStateChange transition)
{
  GstAVFAssetSrc *self = GST_AVF_ASSET_SRC (element);
  GstStateChangeReturn ret;
  GError *error;

  GST_DEBUG ("%s => %s",
      gst_element_state_get_name (GST_STATE_TRANSITION_CURRENT (transition)),
      gst_element_state_get_name (GST_STATE_TRANSITION_NEXT (transition)));

  OBJC_CALLOUT_BEGIN ();
  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY: {
      self->state = GST_AVF_ASSET_SRC_STATE_STOPPED;
      self->reader = [[GstAVFAssetReader alloc] initWithURI:self->uri:&error];
      if (error) {
        GST_ELEMENT_ERROR (element, RESOURCE, FAILED, ("AVFAssetReader error"),
            ("%s", error->message));
        g_error_free (error);
        gst_avf_asset_src_stop_all (self);
        return GST_STATE_CHANGE_FAILURE;
      }
      break;
    }
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      gst_avf_asset_src_start (self);
      gst_avf_asset_src_start_reading (self);
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (gst_avf_asset_src_parent_class)->change_state (element, transition);

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_avf_asset_src_stop_reading (self);
      gst_avf_asset_src_stop (self);
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      [self->reader release];
      break;
    default:
      break;
  }
  OBJC_CALLOUT_END ();
  return ret;
}

static GstCaps *
gst_avf_asset_src_get_caps(GstAVFAssetSrc * self, GstPad * pad, GstCaps * filter)
{
  GstCaps * caps;

  caps = gst_pad_get_current_caps (pad);
  if (!caps) {
    caps = gst_pad_get_pad_template_caps (pad);
  }

  if (filter) {
    GstCaps *intersection = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (caps);
    caps = intersection;
  }

  return caps;
}

static gboolean
gst_avf_asset_src_query (GstPad *pad, GstObject * parent, GstQuery *query)
{
    gboolean ret = FALSE;
    GstCaps *caps;
    GstAVFAssetSrc *self = GST_AVF_ASSET_SRC (parent);

    switch (GST_QUERY_TYPE (query)) {
      case GST_QUERY_URI:
        gst_query_set_uri (query, self->uri);
        ret = TRUE;
        break;
      case GST_QUERY_DURATION:
        gst_query_set_duration (query, GST_FORMAT_TIME, self->reader.duration);
        ret = TRUE;
        break;
      case GST_QUERY_POSITION:
        gst_query_set_position (query, GST_FORMAT_TIME, self->reader.position);
        ret = TRUE;
        break;
      case GST_QUERY_SEEKING: {
        GstFormat fmt;
        gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
        if (fmt == GST_FORMAT_TIME) {
          gst_query_set_seeking (query, GST_FORMAT_TIME, TRUE, 0, self->reader.duration);
          ret = TRUE;
        }
        break;
      }
      case GST_QUERY_CAPS: {
        GstCaps *filter = NULL;
        gst_query_parse_caps (query, &filter);
        caps = gst_avf_asset_src_get_caps (self, pad, filter);
        gst_query_set_caps_result (query, caps);
        ret = TRUE;
        break;
      }
      default:
        ret = FALSE;
        break;
    }

    return ret;
}

static gboolean
gst_avf_asset_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstAVFAssetSrc *self;
  gboolean res = TRUE;
  GError *error = NULL;

  OBJC_CALLOUT_BEGIN ();
  self = GST_AVF_ASSET_SRC (gst_pad_get_parent_element (pad));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEEK: {
      GstFormat format;
      GstSeekFlags flags;
      gdouble rate;
      GstSeekType start_type, stop_type;
      gint64 start, stop;
      GstSegment segment;

      GST_DEBUG ("Processing SEEK event");

      GST_AVF_ASSET_SRC_LOCK (self);
      if (self->seek_event && gst_event_get_seqnum (event) ==
          gst_event_get_seqnum (self->seek_event)) {
        GST_AVF_ASSET_SRC_UNLOCK (self);
        break;
      }
      self->seek_event = gst_event_ref (event);
      GST_AVF_ASSET_SRC_UNLOCK (self);

      /* pause tasks before re-acquiring the object's lock */
      gst_avf_asset_src_stop_reading (self);
      GST_AVF_ASSET_SRC_LOCK (self);

      gst_event_parse_seek (event, &rate, &format, &flags, &start_type,
          &start, &stop_type, &stop);

      if (rate < 0) {
        GST_WARNING ("Negative rates are not supported yet");
        GST_AVF_ASSET_SRC_UNLOCK (self);
        res = FALSE;
        break;
      }

      if (format != GST_FORMAT_TIME || start_type == GST_SEEK_TYPE_NONE) {
        GST_AVF_ASSET_SRC_UNLOCK(self);
        gst_avf_asset_src_start_reading (self);
        res = FALSE;
        break;
      }
      if (stop_type == GST_SEEK_TYPE_NONE) {
        stop = GST_CLOCK_TIME_NONE;
      }
      gst_avf_asset_src_send_event (self, gst_event_new_flush_start ());
      [self->reader seekTo: start: stop: &error];

      gst_segment_init (&segment, GST_FORMAT_TIME);
      segment.rate = rate;
      segment.start = start;
      segment.stop = stop;
      segment.position = start;

      gst_avf_asset_src_send_event (self, gst_event_new_flush_stop (TRUE));
      gst_avf_asset_src_send_event (self, gst_event_new_segment (&segment));

      if (error != NULL) {
        GST_ELEMENT_ERROR (self, RESOURCE, SEEK,
            ("AVFAssetReader seek failed"), ("%s", error->message));
        g_error_free(error);
        res = FALSE;
      }
      GST_AVF_ASSET_SRC_UNLOCK (self);
      gst_event_unref (event);

      /* start tasks after releasing the object's lock */
      gst_avf_asset_src_start_reading (self);
      break;
    }
    default:
      res = gst_pad_event_default (pad, parent, event);
      break;
  }

  gst_object_unref (self);
  OBJC_CALLOUT_END ();
  return res;
}

static GstFlowReturn
gst_avf_asset_src_send_start_stream (GstAVFAssetSrc * self, GstPad * pad)
{
  GstEvent *event;
  gchar *stream_id;
  GstFlowReturn ret;

  stream_id = gst_pad_create_stream_id (pad, GST_ELEMENT_CAST (self), NULL);
  GST_DEBUG_OBJECT (self, "Pushing STREAM START");
  event = gst_event_new_stream_start (stream_id);
  gst_event_set_group_id (event, gst_util_group_id_next ());

  ret = gst_pad_push_event (pad, event);
  g_free (stream_id);

  return ret;
}

static GstFlowReturn
gst_avf_asset_src_combine_flows (GstAVFAssetSrc * self, GstAVFAssetReaderMediaType type,
    GstFlowReturn ret)
{
  gboolean has_other_pad;
  GstFlowReturn last_other_pad_ret;

  GST_AVF_ASSET_SRC_LOCK (self);
  if (type == GST_AVF_ASSET_READER_MEDIA_TYPE_AUDIO) {
    self->last_audio_pad_ret = ret;
    has_other_pad = AVF_ASSET_READER_HAS_VIDEO (ret);
    last_other_pad_ret = self->last_video_pad_ret;
  } else if (type == GST_AVF_ASSET_READER_MEDIA_TYPE_VIDEO) {
    self->last_video_pad_ret = ret;
    has_other_pad = AVF_ASSET_READER_HAS_AUDIO (ret);
    last_other_pad_ret = self->last_audio_pad_ret;
  } else {
    GST_ERROR ("Unsupported media type");
    ret = GST_FLOW_ERROR;
    goto exit;
  }

  if (!has_other_pad || ret != GST_FLOW_NOT_LINKED)
    goto exit;

  ret = last_other_pad_ret;

exit:
  GST_AVF_ASSET_SRC_UNLOCK (self);
  return ret;
}

static void
gst_avf_asset_src_read_data (GstAVFAssetSrc *self, GstPad *pad,
    GstAVFAssetReaderMediaType type)
{
  GstBuffer *buf;
  GstFlowReturn ret, combined_ret;
  GError *error;

  OBJC_CALLOUT_BEGIN ();

  GST_AVF_ASSET_SRC_LOCK (self);
  if (self->state != GST_AVF_ASSET_SRC_STATE_READING) {
    GST_AVF_ASSET_SRC_UNLOCK (self);
    goto exit;
  }

  buf = [self->reader nextBuffer:type:&error];
  GST_AVF_ASSET_SRC_UNLOCK (self);

  if (buf == NULL) {
    if (error != NULL) {
      GST_ELEMENT_ERROR (self, RESOURCE, READ, ("Error reading next buffer"),
          ("%s", error->message));
      g_error_free (error);

      gst_avf_asset_src_combine_flows (self, type, GST_FLOW_ERROR);
      gst_pad_pause_task (pad);
      goto exit;
    }

    gst_pad_push_event (pad, gst_event_new_eos ());
    gst_avf_asset_src_combine_flows (self, type, GST_FLOW_EOS);
    gst_pad_pause_task (pad);
    goto exit;
  }

  ret = gst_pad_push (pad, buf);
  combined_ret = gst_avf_asset_src_combine_flows (self, type, ret);

  if (ret != GST_FLOW_OK) {
    GST_WARNING ("Error pushing %s buffer on pad %" GST_PTR_FORMAT
        ", reason %s", MEDIA_TYPE_TO_STR (type), pad, gst_flow_get_name (ret));

    if (ret == GST_FLOW_EOS) {
      gst_pad_push_event (pad, gst_event_new_eos ());
    }

    if (combined_ret != GST_FLOW_OK) {
      GST_ELEMENT_ERROR (self, STREAM, FAILED, ("Internal data stream error."),
          ("stream stopped reason %s", gst_flow_get_name (ret)));
    }

    gst_pad_pause_task (pad);
  }

exit:
  OBJC_CALLOUT_END ();
}

static void
gst_avf_asset_src_read_audio (GstAVFAssetSrc *self)
{
  gst_avf_asset_src_read_data (self, self->audiopad,
      GST_AVF_ASSET_READER_MEDIA_TYPE_AUDIO);
}

static void
gst_avf_asset_src_read_video (GstAVFAssetSrc *self)
{
  gst_avf_asset_src_read_data (self, self->videopad,
      GST_AVF_ASSET_READER_MEDIA_TYPE_VIDEO);
}

static gboolean
gst_avf_asset_src_start_reader (GstAVFAssetSrc * self)
{
  GError *error = NULL;
  gboolean ret = TRUE;

  OBJC_CALLOUT_BEGIN ();

  [self->reader start: &error];
  if (error != NULL) {
    GST_ELEMENT_ERROR (self, RESOURCE, FAILED,
        ("AVFAssetReader could not start reading"), ("%s", error->message));
    g_error_free (error);
    ret = FALSE;
    goto exit;
  }

exit:
  OBJC_CALLOUT_END ();
  return ret;
}

static gboolean
gst_avf_asset_src_send_event (GstAVFAssetSrc *self, GstEvent *event)
{
  gboolean ret = TRUE;

  OBJC_CALLOUT_BEGIN ();

  if (AVF_ASSET_READER_HAS_VIDEO (self)) {
    ret |= gst_pad_push_event (self->videopad, gst_event_ref (event));
  }
  if (AVF_ASSET_READER_HAS_AUDIO (self)) {
    ret |= gst_pad_push_event (self->audiopad, gst_event_ref (event));
  }

  gst_event_unref (event);
  OBJC_CALLOUT_END ();
  return ret;
}

static void
gst_avf_asset_src_start (GstAVFAssetSrc *self)
{
  GstSegment segment;

  OBJC_CALLOUT_BEGIN ();
  if (self->state == GST_AVF_ASSET_SRC_STATE_STARTED) {
    goto exit;
  }

  GST_DEBUG_OBJECT (self, "Creating pads and starting reader");

  gst_segment_init (&segment, GST_FORMAT_TIME);
  segment.duration = self->reader.duration;

  /* We call AVFAssetReader's startReading when the pads are linked
   * and no outputs can be added afterwards, so the tracks must be
   * selected before adding any of the new pads */
  if (AVF_ASSET_READER_HAS_AUDIO (self)) {
    [self->reader selectTrack: GST_AVF_ASSET_READER_MEDIA_TYPE_AUDIO:
        self->selected_audio_track];
  }
  if (AVF_ASSET_READER_HAS_VIDEO (self)) {
    [self->reader selectTrack: GST_AVF_ASSET_READER_MEDIA_TYPE_VIDEO:
         self->selected_video_track];
  }

  if (AVF_ASSET_READER_HAS_AUDIO (self)) {
    self->audiopad = gst_pad_new_from_static_template (&audio_factory, "audio");
    gst_pad_set_query_function (self->audiopad,
        gst_avf_asset_src_query);
    gst_pad_set_event_function(self->audiopad,
        gst_avf_asset_src_event);
    gst_pad_use_fixed_caps (self->audiopad);
    gst_pad_set_active (self->audiopad, TRUE);
    gst_avf_asset_src_send_start_stream (self, self->audiopad);
    gst_pad_set_caps (self->audiopad,
        [self->reader getCaps: GST_AVF_ASSET_READER_MEDIA_TYPE_AUDIO]);
    gst_pad_push_event (self->audiopad, gst_event_new_caps (
        [self->reader getCaps: GST_AVF_ASSET_READER_MEDIA_TYPE_AUDIO]));
    gst_pad_push_event (self->audiopad, gst_event_new_segment (&segment));
    gst_element_add_pad (GST_ELEMENT (self), self->audiopad);
  }
  if (AVF_ASSET_READER_HAS_VIDEO (self)) {
    self->videopad = gst_pad_new_from_static_template (&video_factory, "video");
    gst_pad_set_query_function (self->videopad,
        gst_avf_asset_src_query);
    gst_pad_set_event_function(self->videopad,
        gst_avf_asset_src_event);
    gst_pad_use_fixed_caps (self->videopad);
    gst_pad_set_active (self->videopad, TRUE);
    gst_avf_asset_src_send_start_stream (self, self->videopad);
    gst_pad_set_caps (self->videopad,
        [self->reader getCaps: GST_AVF_ASSET_READER_MEDIA_TYPE_VIDEO]);
    gst_pad_push_event (self->videopad, gst_event_new_caps (
        [self->reader getCaps: GST_AVF_ASSET_READER_MEDIA_TYPE_VIDEO]));
    gst_pad_push_event (self->videopad, gst_event_new_segment (&segment));
    gst_element_add_pad (GST_ELEMENT (self), self->videopad);
  }
  gst_element_no_more_pads (GST_ELEMENT (self));

  self->state = GST_AVF_ASSET_SRC_STATE_STARTED;

exit:
  OBJC_CALLOUT_END ();
}

static void
gst_avf_asset_src_stop (GstAVFAssetSrc *self)
{
  gboolean has_audio, has_video;
  OBJC_CALLOUT_BEGIN();

  if (self->state == GST_AVF_ASSET_SRC_STATE_STOPPED) {
    goto exit;
  }

  GST_DEBUG ("Stopping tasks and removing pads");

  has_audio = AVF_ASSET_READER_HAS_AUDIO (self);
  has_video = AVF_ASSET_READER_HAS_VIDEO (self);
  [self->reader stop];

  if (has_audio) {
    gst_pad_stop_task (self->audiopad);
    gst_element_remove_pad (GST_ELEMENT (self), self->audiopad);
  }
  if (has_video) {
    gst_pad_stop_task (self->videopad);
    gst_element_remove_pad (GST_ELEMENT (self), self->videopad);
  }

  self->state = GST_AVF_ASSET_SRC_STATE_STOPPED;

exit:
  OBJC_CALLOUT_END ();
}

static gboolean
gst_avf_asset_src_start_reading (GstAVFAssetSrc *self)
{
  gboolean ret = TRUE;

  if (self->state != GST_AVF_ASSET_SRC_STATE_STARTED) {
    goto exit;
  }

  GST_DEBUG_OBJECT (self, "Start reading");

  if ((ret = gst_avf_asset_src_start_reader (self)) != TRUE) {
    goto exit;
  }

  if (AVF_ASSET_READER_HAS_AUDIO (self)) {
    ret = gst_pad_start_task (self->audiopad, (GstTaskFunction)gst_avf_asset_src_read_audio, self, NULL);
    if (!ret) {
      GST_ERROR ("Failed to start audio task");
      goto exit;
    }
  }

  if (AVF_ASSET_READER_HAS_VIDEO (self)) {
    ret = gst_pad_start_task (self->videopad, (GstTaskFunction)gst_avf_asset_src_read_video, self, NULL);
    if (!ret) {
      GST_ERROR ("Failed to start video task");
      goto exit;
    }
  }

  self->state = GST_AVF_ASSET_SRC_STATE_READING;

exit:
  return ret;
}

static void
gst_avf_asset_src_stop_reading (GstAVFAssetSrc * self)
{
  if (self->state != GST_AVF_ASSET_SRC_STATE_READING) {
    return;
  }

  GST_DEBUG_OBJECT (self, "Stop reading");

  if (AVF_ASSET_READER_HAS_AUDIO (self)) {
    gst_pad_pause_task (self->audiopad);
  }
  if (AVF_ASSET_READER_HAS_VIDEO (self)) {
    gst_pad_pause_task (self->videopad);
  }

  self->state = GST_AVF_ASSET_SRC_STATE_STARTED;
}

static void
gst_avf_asset_src_stop_all (GstAVFAssetSrc *self)
{
  GST_AVF_ASSET_SRC_LOCK (self);
  gst_avf_asset_src_stop_reading (self);
  gst_avf_asset_src_stop (self);
  GST_AVF_ASSET_SRC_UNLOCK (self);
}

static GQuark
gst_avf_asset_src_error_quark (void)
{
  static GQuark q;              /* 0 */

  if (G_UNLIKELY (q == 0)) {
      q = g_quark_from_static_string ("avfasset-src-error-quark");
  }
  return q;
}

static GstURIType
gst_avf_asset_src_uri_get_type (GType type)
{
  return GST_URI_SRC;
}

static const gchar * const *
gst_avf_asset_src_uri_get_protocols (GType type)
{
  static const gchar * const protocols[] = { "file", "ipod-library", NULL };

  return protocols;
}

static gchar *
gst_avf_asset_src_uri_get_uri (GstURIHandler * handler)
{
  GstAVFAssetSrc *self = GST_AVF_ASSET_SRC (handler);

  return g_strdup (self->uri);
}

static gboolean
gst_avf_asset_src_uri_set_uri (GstURIHandler * handler, const gchar * uri, GError **error)
{
  GstAVFAssetSrc *self = GST_AVF_ASSET_SRC (handler);
  NSString *str;
  NSURL *url;
  AVAsset *asset;
  gchar *escaped_uri;
  gboolean ret = FALSE;

  OBJC_CALLOUT_BEGIN ();
  escaped_uri = g_uri_escape_string (uri, ":/", TRUE);
  str = [NSString stringWithUTF8String: escaped_uri];
  url = [[NSURL alloc] initWithString: str];
  asset = [AVAsset assetWithURL: url];
  g_free (escaped_uri);

  if (asset.playable) {
    ret = TRUE;
    g_free (self->uri);
    self->uri = g_strdup (uri);
  } else {
    g_set_error (error, GST_URI_ERROR, GST_URI_ERROR_BAD_URI,
        "Invalid URI '%s' for avfassetsrc", self->uri);
  }
  OBJC_CALLOUT_END ();
  return ret;
}

static void
gst_avf_asset_src_uri_handler_init (gpointer g_iface, gpointer iface_data)
{
  GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;

  iface->get_type = gst_avf_asset_src_uri_get_type;
  iface->get_protocols = gst_avf_asset_src_uri_get_protocols;
  iface->get_uri = gst_avf_asset_src_uri_get_uri;
  iface->set_uri = gst_avf_asset_src_uri_set_uri;
}

@implementation GstAVFAssetReader

@synthesize duration;
@synthesize position;

- (NSDictionary *) capsToAudioSettings
{
  gint depth;
  gboolean isFloat;
  GstAudioInfo info;

  if (!gst_caps_is_fixed (audio_caps))
    return NULL;

  gst_audio_info_from_caps (&info, audio_caps);
  isFloat = GST_AUDIO_INFO_IS_FLOAT(&info);
  depth = GST_AUDIO_INFO_DEPTH(&info);

  return [NSDictionary dictionaryWithObjectsAndKeys:
      [NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey,
      [NSNumber numberWithFloat:info.rate], AVSampleRateKey,
      [NSNumber numberWithInt:info.channels], AVNumberOfChannelsKey,
      //[NSData dataWithBytes:&channelLayout length:sizeof(AudioChannelLayout)],
      //AVChannelLayoutKey,
      [NSNumber numberWithInt:depth], AVLinearPCMBitDepthKey,
      [NSNumber numberWithBool:isFloat],AVLinearPCMIsFloatKey,
      [NSNumber numberWithBool:NO], AVLinearPCMIsNonInterleaved,
      [NSNumber numberWithBool:NO], AVLinearPCMIsBigEndianKey,
      nil];
}

- (void) releaseReader
{
  [video_track release];
  [audio_track release];
  [video_tracks release];
  [audio_tracks release];
  [reader release];
}

- (void) initReader: (GError **) error
{
  NSError *nserror;

  reader = [[AVAssetReader alloc] initWithAsset:asset error:&nserror];
  if (nserror != NULL) {
    GST_ERROR ("Error initializing reader: %s",
        [nserror.description UTF8String]);
    *error = g_error_new (GST_AVF_ASSET_SRC_ERROR, GST_AVF_ASSET_ERROR_INIT, "%s",
        [nserror.description UTF8String]);
    [asset release];
    [reader release];
    return;
  }

  audio_tracks = [[asset tracksWithMediaType:AVMediaTypeAudio] retain];
  video_tracks = [[asset tracksWithMediaType:AVMediaTypeVideo] retain];
  reader.timeRange = CMTimeRangeMake(kCMTimeZero, asset.duration);
  GST_INFO ("Found %lu video tracks and %lu audio tracks",
      (unsigned long)[video_tracks count], (unsigned long)[audio_tracks count]);
}

- (id) initWithURI:(gchar*)uri : (GError **)error;
{
  NSString *str;
  NSURL *url;
  gchar *escaped_uri;

  GST_INFO ("Initializing AVFAssetReader with uri:%s", uri);
  *error = NULL;

  escaped_uri = g_uri_escape_string (uri, ":/", TRUE);
  str = [NSString stringWithUTF8String: escaped_uri];
  url = [[NSURL alloc] initWithString: str];
  asset = [[AVAsset assetWithURL: url] retain];
  g_free (escaped_uri);

  if (!asset.playable) {
    *error = g_error_new (GST_AVF_ASSET_SRC_ERROR, GST_AVF_ASSET_ERROR_NOT_PLAYABLE,
        "Media is not playable");
    [asset release];
    return nil;
  }

  selected_audio_track = -1;
  selected_video_track = -1;
  reading = FALSE;
  position = 0;
  duration = CMTIME_TO_GST_TIME (asset.duration);

  /* FIXME: use fixed caps here until we found a way to determine
   * the native audio format */
  audio_caps = gst_caps_from_string ("audio/x-raw, "
      "format=F32LE, rate=44100, channels=2, layout=interleaved");

  [self initReader: error];
  if (*error) {
    return nil;
  }

  self = [super init];
  return self;
}

- (bool) selectTrack: (GstAVFAssetReaderMediaType) type : (gint) index
{
  NSArray *tracks;
  AVAssetTrack *track;
  AVAssetReaderOutput **output;
  NSDictionary *settings;
  NSString *mediaType;
  gint *selected_track;

  GST_INFO ("Selecting %s track %d", MEDIA_TYPE_TO_STR(type), index);

  if (type == GST_AVF_ASSET_READER_MEDIA_TYPE_AUDIO) {
    mediaType = AVMediaTypeAudio;
    selected_track = &selected_audio_track;
    output = &audio_track;
    settings = [self capsToAudioSettings];
  } else if (type == GST_AVF_ASSET_READER_MEDIA_TYPE_VIDEO) {
    mediaType = AVMediaTypeVideo;
    selected_track = &selected_video_track;
    output = &video_track;
    settings = [NSDictionary dictionaryWithObjectsAndKeys:
        [NSNumber numberWithInt:
        kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange],
        kCVPixelBufferPixelFormatTypeKey, nil];
  } else {
    return FALSE;
  }

  tracks = [asset tracksWithMediaType:mediaType];
  if ([tracks count] == 0 || [tracks count] < index + 1) {
    return FALSE;
  }

  track = [tracks objectAtIndex:index];
  *selected_track = index;
  *output  = [AVAssetReaderTrackOutput
      assetReaderTrackOutputWithTrack:track
      outputSettings:settings];
  [*output retain];
  [reader addOutput:*output];
  return TRUE;
}

- (void) start: (GError **)error
{
  if (reading)
    return;

  if (![reader startReading]) {
    *error = g_error_new (GST_AVF_ASSET_SRC_ERROR, GST_AVF_ASSET_ERROR_START,
        "%s", [reader.error.description UTF8String]);
    reading = FALSE;
    return;
  }
  reading = TRUE;
}

- (void) stop
{
  [self->reader cancelReading];
  reading = FALSE;
}

- (bool) hasMediaType: (GstAVFAssetReaderMediaType) type
{
  if (type == GST_AVF_ASSET_READER_MEDIA_TYPE_AUDIO) {
    return [audio_tracks count] != 0;
  }
  if (type == GST_AVF_ASSET_READER_MEDIA_TYPE_VIDEO) {
    return [video_tracks count] != 0;
  }
  return FALSE;
}

- (void) seekTo: (guint64) startTS : (guint64) stopTS : (GError **) error
{
  CMTime startTime = kCMTimeZero, stopTime = kCMTimePositiveInfinity;

  if (startTS != GST_CLOCK_TIME_NONE) {
    startTime = CMTimeMake (startTS, GST_SECOND);
  }
  if (stopTS != GST_CLOCK_TIME_NONE) {
    stopTime = CMTimeMake (stopTS, GST_SECOND);
  }

  /* AVFAssetReader needs to be recreated before changing the
   * timerange property */
  [self stop];
  [self releaseReader];
  [self initReader: error];
  if (*error) {
    return;
  }

  GST_DEBUG ("Seeking to start:%" GST_TIME_FORMAT " stop:%" GST_TIME_FORMAT,
      GST_TIME_ARGS(startTS), GST_TIME_ARGS(stopTS));

  reader.timeRange = CMTimeRangeMake(startTime, stopTime);
  [self selectTrack: GST_AVF_ASSET_READER_MEDIA_TYPE_AUDIO:selected_audio_track];
  [self selectTrack: GST_AVF_ASSET_READER_MEDIA_TYPE_VIDEO:selected_video_track];
  [self start: error];
}

- (GstBuffer *) nextBuffer: (GstAVFAssetReaderMediaType) type : (GError **) error
{
  CMSampleBufferRef cmbuf;
  AVAssetReaderTrackOutput *areader = NULL;
  GstCaps *caps;
  GstBuffer *buf;
  CMTime dur, ts;

  GST_LOG ("Reading %s next buffer", MEDIA_TYPE_TO_STR (type));
  if (type == GST_AVF_ASSET_READER_MEDIA_TYPE_AUDIO && audio_track != NULL) {
    areader = audio_track;
    caps = audio_caps;
  } else if (type == GST_AVF_ASSET_READER_MEDIA_TYPE_VIDEO &&
      video_track != NULL) {
    areader = video_track;
    caps = video_caps;
  }

  if (areader == NULL) {
    return NULL;
  }

  *error = NULL;
  cmbuf = [areader copyNextSampleBuffer];
  if (cmbuf == NULL) {
    if (reader.error != NULL) {
      *error = g_error_new (GST_AVF_ASSET_SRC_ERROR, GST_AVF_ASSET_ERROR_READ,
          "%s", [reader.error.description UTF8String]);
    }
    /* EOS */
    return NULL;
  }

  buf = gst_core_media_buffer_new (cmbuf, FALSE);
  CFRelease (cmbuf);
  if (buf == NULL)
    return NULL;
  /* cmbuf is now retained by buf (in meta) */
  dur = CMSampleBufferGetDuration (cmbuf);
  ts = CMSampleBufferGetPresentationTimeStamp (cmbuf);
  if (dur.value != 0) {
    GST_BUFFER_DURATION (buf) = CMTIME_TO_GST_TIME (dur);
  }
  GST_BUFFER_TIMESTAMP (buf) = CMTIME_TO_GST_TIME (ts);
  GST_LOG ("Copying next %s buffer ts:%" GST_TIME_FORMAT " dur:%"
      GST_TIME_FORMAT, MEDIA_TYPE_TO_STR (type),
      GST_TIME_ARGS(GST_BUFFER_TIMESTAMP (buf)),
      GST_TIME_ARGS(GST_BUFFER_DURATION (buf)));
  if (GST_BUFFER_TIMESTAMP (buf) > position) {
    position = GST_BUFFER_TIMESTAMP (buf);
  }
  return buf;
}

- (GstCaps *) getCaps: (GstAVFAssetReaderMediaType) type
{
  GstCaps *caps = NULL;
  AVAssetTrack *track;

  if (type == GST_AVF_ASSET_READER_MEDIA_TYPE_AUDIO) {
    caps = gst_caps_ref (audio_caps);
    GST_INFO ("Using audio caps: %" GST_PTR_FORMAT, caps);
  } else if (type == GST_AVF_ASSET_READER_MEDIA_TYPE_VIDEO) {
    gint fr_n, fr_d;

    track = [video_tracks objectAtIndex: selected_video_track];
    gst_util_double_to_fraction(track.nominalFrameRate, &fr_n, &fr_d);
    caps = gst_caps_new_simple ("video/x-raw",
        "format", G_TYPE_STRING, "NV12",
        "width", G_TYPE_INT, (int) track.naturalSize.width,
        "height", G_TYPE_INT, (int) track.naturalSize.height,
        "framerate", GST_TYPE_FRACTION, fr_n, fr_d, NULL);
    GST_INFO ("Using video caps: %" GST_PTR_FORMAT, caps);
    video_caps = gst_caps_ref (caps);
  }

  return caps;
}

- (oneway void) release
{
  [asset release];

  [self releaseReader];

  if (audio_caps != NULL) {
    gst_caps_unref (audio_caps);
  }

  if (video_caps != NULL) {
    gst_caps_unref (audio_caps);
  }
}

@end
