/*
 * 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_static_pad_template (gstelement_class, &audio_factory);
  gst_element_class_add_static_pad_template (gstelement_class, &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_FLOW_ERROR (self, 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;
  gboolean ret = FALSE;

  OBJC_CALLOUT_BEGIN ();
  str = [NSString stringWithUTF8String: uri];
  url = [[NSURL alloc] initWithString: str];
  asset = [AVAsset assetWithURL: url];

  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", 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;

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

  str = [NSString stringWithUTF8String: uri];
  url = [[NSURL alloc] initWithString: str];
  asset = [[AVAsset assetWithURL: url] retain];

  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, NULL);
  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
