/*
 * 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) \
    ([GST_AVF_ASSET_SRC_READER(self) hasMediaType:GST_AVF_ASSET_READER_MEDIA_TYPE_AUDIO])
#define AVF_ASSET_READER_HAS_VIDEO(x) \
    ([GST_AVF_ASSET_SRC_READER(self) hasMediaType:GST_AVF_ASSET_READER_MEDIA_TYPE_VIDEO])

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

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY: {
      self->state = GST_AVF_ASSET_SRC_STATE_STOPPED;
      if (!self->uri) {
        GST_ELEMENT_ERROR (element, RESOURCE, NOT_FOUND,
            ("\"uri\" property not set"), (NULL));
        gst_avf_asset_src_stop_all (self);
        return GST_STATE_CHANGE_FAILURE;
      }
      self->reader = (__bridge_retained gpointer)([[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:
      CFBridgingRelease(self->reader);
      break;
    default:
      break;
  }
  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, GST_AVF_ASSET_SRC_READER(self).duration);
        ret = TRUE;
        break;
      case GST_QUERY_POSITION:
        gst_query_set_position (query, GST_FORMAT_TIME, GST_AVF_ASSET_SRC_READER(self).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, GST_AVF_ASSET_SRC_READER(self).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;

  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 ());
      [GST_AVF_ASSET_SRC_READER(self) 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);
  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;


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

  buf = [GST_AVF_ASSET_SRC_READER(self) 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);
        return;
    }

    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);
    return;
  }

  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);
  }

}

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;


  [GST_AVF_ASSET_SRC_READER(self) 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:
  return ret;
}

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


  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);
  return ret;
}

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

  if (self->state == GST_AVF_ASSET_SRC_STATE_STARTED) {
    return;
  }

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

  gst_segment_init (&segment, GST_FORMAT_TIME);
  segment.duration = GST_AVF_ASSET_SRC_READER(self).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)) {
    [GST_AVF_ASSET_SRC_READER(self) selectTrack: GST_AVF_ASSET_READER_MEDIA_TYPE_AUDIO:
        self->selected_audio_track];
  }
  if (AVF_ASSET_READER_HAS_VIDEO (self)) {
    [GST_AVF_ASSET_SRC_READER(self) 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,
        [GST_AVF_ASSET_SRC_READER(self) getCaps: GST_AVF_ASSET_READER_MEDIA_TYPE_AUDIO]);
    gst_pad_push_event (self->audiopad, gst_event_new_caps (
        [GST_AVF_ASSET_SRC_READER(self) 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,
        [GST_AVF_ASSET_SRC_READER(self) getCaps: GST_AVF_ASSET_READER_MEDIA_TYPE_VIDEO]);
    gst_pad_push_event (self->videopad, gst_event_new_caps (
        [GST_AVF_ASSET_SRC_READER(self) 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;
}

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

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

  GST_DEBUG ("Stopping tasks and removing pads");

  has_audio = AVF_ASSET_READER_HAS_AUDIO (self);
  has_video = AVF_ASSET_READER_HAS_VIDEO (self);
  [GST_AVF_ASSET_SRC_READER(self) 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;
}

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;

  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);
  }
  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 = nil;
  audio_track = nil;
  video_tracks = nil;
  audio_tracks = nil;
  reader = nil;
}

- (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]);

    return;
  }

  audio_tracks = [asset tracksWithMediaType:AVMediaTypeAudio];
  video_tracks = [asset tracksWithMediaType:AVMediaTypeVideo];
  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];

  if (!asset.playable) {
    *error = g_error_new (GST_AVF_ASSET_SRC_ERROR, GST_AVF_ASSET_ERROR_NOT_PLAYABLE,
        "Media is not playable");
    asset = nil;
    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 * __strong *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];
  [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
{
  [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;
}

- (void) dealloc
{
  asset = nil;
  [self releaseReader];

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

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

@end
