/*
 * Initially based on gst-omx/omx/gstomxvideodec.c
 *
 * Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
 *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
 *
 * Copyright (C) 2012, Collabora Ltd.
 *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
 *
 * Copyright (C) 2012, Rafaël Carré <funman@videolanorg>
 *
 * Copyright (C) 2015, Sebastian Dröge <sebastian@centricular.com>
 *
 * Copyright (C) 2014-2015, Collabora Ltd.
 *   Author: Matthieu Bouron <matthieu.bouron@gcollabora.com>
 *
 * Copyright (C) 2015, Edward Hervey
 *   Author: Edward Hervey <bilboed@gmail.com>
 *
 * Copyright (C) 2015, Matthew Waters <matthew@centricular.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation
 * version 2.1 of the License.
 *
 * 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
 *
 */

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

#include <gst/gst.h>
#include <gst/gl/gl.h>
#include <gst/video/gstvideometa.h>
#include <gst/video/gstvideoaffinetransformationmeta.h>
#include <gst/video/gstvideopool.h>
#include <string.h>

#ifdef HAVE_ORC
#include <orc/orc.h>
#else
#define orc_memcpy memcpy
#endif

#include "gstamcvideodec.h"
#include "gstamc-constants.h"

GST_DEBUG_CATEGORY_STATIC (gst_amc_video_dec_debug_category);
#define GST_CAT_DEFAULT gst_amc_video_dec_debug_category

#define GST_VIDEO_DECODER_ERROR_FROM_ERROR(el, err) G_STMT_START { \
  gchar *__dbg = g_strdup (err->message);                               \
  GstVideoDecoder *__dec = GST_VIDEO_DECODER (el);                      \
  GST_WARNING_OBJECT (el, "error: %s", __dbg);                          \
  _gst_video_decoder_error (__dec, 1,                                   \
    err->domain, err->code,                                             \
    NULL, __dbg, __FILE__, GST_FUNCTION, __LINE__);                     \
  g_clear_error (&err); \
} G_STMT_END

#if GLIB_SIZEOF_VOID_P == 8
#define JLONG_TO_GST_AMC_VIDEO_DEC(value) (GstAmcVideoDec *)(value)
#define GST_AMC_VIDEO_DEC_TO_JLONG(value) (jlong)(value)
#else
#define JLONG_TO_GST_AMC_VIDEO_DEC(value) (GstAmcVideoDec *)(jint)(value)
#define GST_AMC_VIDEO_DEC_TO_JLONG(value) (jlong)(jint)(value)
#endif

typedef struct _BufferIdentification BufferIdentification;
struct _BufferIdentification
{
  guint64 timestamp;
};

struct gl_sync_result
{
  gint refcount;
  gint64 frame_available_ts;
  gboolean updated;             /* only every call update_tex_image once */
  gboolean released;            /* only every call release_output_buffer once */
  gboolean rendered;            /* whether the release resulted in a render */
};

static struct gl_sync_result *
_gl_sync_result_ref (struct gl_sync_result *result)
{
  g_assert (result != NULL);

  g_atomic_int_inc (&result->refcount);

  GST_TRACE ("gl_sync result %p ref", result);

  return result;
}

static void
_gl_sync_result_unref (struct gl_sync_result *result)
{
  g_assert (result != NULL);

  GST_TRACE ("gl_sync result %p unref", result);

  if (g_atomic_int_dec_and_test (&result->refcount)) {
    GST_TRACE ("freeing gl_sync result %p", result);
    g_free (result);
  }
}

struct gl_sync
{
  gint refcount;
  GstAmcVideoDec *sink;         /* back reference for statistics, lock, cond, etc */
  gint buffer_idx;              /* idx of the AMC buffer we should render */
  GstBuffer *buffer;            /* back reference to the buffer */
  GstGLMemory *oes_mem;         /* where amc is rendering into. The same for every gl_sync */
  GstAmcSurface *surface;       /* java wrapper for where amc is rendering into */
  guint gl_frame_no;            /* effectively the frame id */
  gint64 released_ts;           /* microseconds from g_get_monotonic_time() */
  struct gl_sync_result *result;
};

static struct gl_sync *
_gl_sync_ref (struct gl_sync *sync)
{
  g_assert (sync != NULL);

  g_atomic_int_inc (&sync->refcount);

  GST_TRACE ("gl_sync %p ref", sync);

  return sync;
}

static void
_gl_sync_unref (struct gl_sync *sync)
{
  g_assert (sync != NULL);

  GST_TRACE ("gl_sync %p unref", sync);

  if (g_atomic_int_dec_and_test (&sync->refcount)) {
    GST_TRACE ("freeing gl_sync %p", sync);

    _gl_sync_result_unref (sync->result);

    g_object_unref (sync->surface);
    gst_memory_unref ((GstMemory *) sync->oes_mem);

    g_free (sync);
  }
}

static gint
_queue_compare_gl_sync (gconstpointer a, gconstpointer b)
{
  const struct gl_sync *sync = a;
  guint frame = GPOINTER_TO_INT (b);

  return sync->gl_frame_no - frame;
}

static GList *
_find_gl_sync_for_frame (GstAmcVideoDec * dec, guint frame)
{
  return g_queue_find_custom (dec->gl_queue, GINT_TO_POINTER (frame),
      (GCompareFunc) _queue_compare_gl_sync);
}

static void
_attach_mem_to_context (GstGLContext * context, GstAmcVideoDec * self)
{
  GST_TRACE_OBJECT (self, "attaching texture %p id %u to current context",
      self->surface->texture, self->oes_mem->tex_id);
  if (!gst_amc_surface_texture_attach_to_gl_context (self->surface->texture,
          self->oes_mem->tex_id, &self->gl_error)) {
    GST_ERROR_OBJECT (self, "Failed to attach texture to the GL context");
    GST_ELEMENT_ERROR_FROM_ERROR (self, self->gl_error);
  } else {
    self->gl_mem_attached = TRUE;
  }
}

static void
_dettach_mem_from_context (GstGLContext * context, GstAmcVideoDec * self)
{
  if (self->surface) {
    guint tex_id = self->oes_mem ? self->oes_mem->tex_id : 0;

    GST_TRACE_OBJECT (self, "detaching texture %p id %u from current context",
        self->surface->texture, tex_id);

    if (!gst_amc_surface_texture_detach_from_gl_context (self->surface->texture,
            &self->gl_error)) {
      GST_ERROR_OBJECT (self, "Failed to attach texture to the GL context");
      GST_ELEMENT_ERROR_FROM_ERROR (self, self->gl_error);
    }
  }
  self->gl_mem_attached = FALSE;
}

static BufferIdentification *
buffer_identification_new (GstClockTime timestamp)
{
  BufferIdentification *id = g_slice_new (BufferIdentification);

  id->timestamp = timestamp;

  return id;
}

static void
buffer_identification_free (BufferIdentification * id)
{
  g_slice_free (BufferIdentification, id);
}

/* prototypes */
static void gst_amc_video_dec_finalize (GObject * object);

static GstStateChangeReturn
gst_amc_video_dec_change_state (GstElement * element,
    GstStateChange transition);
static void gst_amc_video_dec_set_context (GstElement * element,
    GstContext * context);

static gboolean gst_amc_video_dec_open (GstVideoDecoder * decoder);
static gboolean gst_amc_video_dec_close (GstVideoDecoder * decoder);
static gboolean gst_amc_video_dec_start (GstVideoDecoder * decoder);
static gboolean gst_amc_video_dec_stop (GstVideoDecoder * decoder);
static gboolean gst_amc_video_dec_set_format (GstVideoDecoder * decoder,
    GstVideoCodecState * state);
static gboolean gst_amc_video_dec_flush (GstVideoDecoder * decoder);
static GstFlowReturn gst_amc_video_dec_handle_frame (GstVideoDecoder * decoder,
    GstVideoCodecFrame * frame);
static GstFlowReturn gst_amc_video_dec_finish (GstVideoDecoder * decoder);
static gboolean gst_amc_video_dec_decide_allocation (GstVideoDecoder * bdec,
    GstQuery * query);
static gboolean gst_amc_video_dec_src_query (GstVideoDecoder * bdec,
    GstQuery * query);

static GstFlowReturn gst_amc_video_dec_drain (GstAmcVideoDec * self);
static gboolean gst_amc_video_dec_check_codec_config (GstAmcVideoDec * self);
static void
gst_amc_video_dec_on_frame_available (JNIEnv * env, jobject thiz,
    long long context, jobject surfaceTexture);

enum
{
  PROP_0
};

/* class initialization */

static void gst_amc_video_dec_class_init (GstAmcVideoDecClass * klass);
static void gst_amc_video_dec_init (GstAmcVideoDec * self);
static void gst_amc_video_dec_base_init (gpointer g_class);

static GstVideoDecoderClass *parent_class = NULL;

GType
gst_amc_video_dec_get_type (void)
{
  static volatile gsize type = 0;

  if (g_once_init_enter (&type)) {
    GType _type;
    static const GTypeInfo info = {
      sizeof (GstAmcVideoDecClass),
      gst_amc_video_dec_base_init,
      NULL,
      (GClassInitFunc) gst_amc_video_dec_class_init,
      NULL,
      NULL,
      sizeof (GstAmcVideoDec),
      0,
      (GInstanceInitFunc) gst_amc_video_dec_init,
      NULL
    };

    _type = g_type_register_static (GST_TYPE_VIDEO_DECODER, "GstAmcVideoDec",
        &info, 0);

    GST_DEBUG_CATEGORY_INIT (gst_amc_video_dec_debug_category, "amcvideodec", 0,
        "Android MediaCodec video decoder");

    g_once_init_leave (&type, _type);
  }
  return type;
}

static const gchar *
caps_to_mime (GstCaps * caps)
{
  GstStructure *s;
  const gchar *name;

  s = gst_caps_get_structure (caps, 0);
  if (!s)
    return NULL;

  name = gst_structure_get_name (s);

  if (strcmp (name, "video/mpeg") == 0) {
    gint mpegversion;

    if (!gst_structure_get_int (s, "mpegversion", &mpegversion))
      return NULL;

    if (mpegversion == 4)
      return "video/mp4v-es";
    else if (mpegversion == 1 || mpegversion == 2)
      return "video/mpeg2";
  } else if (strcmp (name, "video/x-h263") == 0) {
    return "video/3gpp";
  } else if (strcmp (name, "video/x-h264") == 0) {
    return "video/avc";
  } else if (strcmp (name, "video/x-h265") == 0) {
    return "video/hevc";
  } else if (strcmp (name, "video/x-vp8") == 0) {
    return "video/x-vnd.on2.vp8";
  } else if (strcmp (name, "video/x-vp9") == 0) {
    return "video/x-vnd.on2.vp9";
  } else if (strcmp (name, "video/x-divx") == 0) {
    return "video/mp4v-es";
  }

  return NULL;
}

static void
gst_amc_video_dec_base_init (gpointer g_class)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
  GstAmcVideoDecClass *amcvideodec_class = GST_AMC_VIDEO_DEC_CLASS (g_class);
  const GstAmcCodecInfo *codec_info;
  GstPadTemplate *templ;
  GstCaps *sink_caps, *src_caps, *all_src_caps;
  gchar *longname;

  codec_info =
      g_type_get_qdata (G_TYPE_FROM_CLASS (g_class), gst_amc_codec_info_quark);
  /* This happens for the base class and abstract subclasses */
  if (!codec_info)
    return;

  amcvideodec_class->codec_info = codec_info;

  gst_amc_codec_info_to_caps (codec_info, &sink_caps, &src_caps);

  all_src_caps =
      gst_caps_from_string ("video/x-raw(" GST_CAPS_FEATURE_MEMORY_GL_MEMORY
      "), format = (string) RGBA, texture-target = (string) external-oes");

  if (codec_info->gl_output_only) {
    gst_caps_unref (src_caps);
  } else {
    gst_caps_append (all_src_caps, src_caps);
  }

  /* Add pad templates */
  templ =
      gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, sink_caps);
  gst_element_class_add_pad_template (element_class, templ);
  gst_caps_unref (sink_caps);

  templ =
      gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, all_src_caps);
  gst_element_class_add_pad_template (element_class, templ);
  gst_caps_unref (all_src_caps);

  longname = g_strdup_printf ("Android MediaCodec %s", codec_info->name);
  gst_element_class_set_metadata (element_class,
      codec_info->name,
      "Codec/Decoder/Video",
      longname, "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
  g_free (longname);
}

static void
gst_amc_video_dec_class_init (GstAmcVideoDecClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  GstVideoDecoderClass *videodec_class = GST_VIDEO_DECODER_CLASS (klass);

  parent_class = g_type_class_peek_parent (klass);

  gobject_class->finalize = gst_amc_video_dec_finalize;

  element_class->change_state =
      GST_DEBUG_FUNCPTR (gst_amc_video_dec_change_state);
  element_class->set_context =
      GST_DEBUG_FUNCPTR (gst_amc_video_dec_set_context);

  videodec_class->start = GST_DEBUG_FUNCPTR (gst_amc_video_dec_start);
  videodec_class->stop = GST_DEBUG_FUNCPTR (gst_amc_video_dec_stop);
  videodec_class->open = GST_DEBUG_FUNCPTR (gst_amc_video_dec_open);
  videodec_class->close = GST_DEBUG_FUNCPTR (gst_amc_video_dec_close);
  videodec_class->flush = GST_DEBUG_FUNCPTR (gst_amc_video_dec_flush);
  videodec_class->set_format = GST_DEBUG_FUNCPTR (gst_amc_video_dec_set_format);
  videodec_class->handle_frame =
      GST_DEBUG_FUNCPTR (gst_amc_video_dec_handle_frame);
  videodec_class->finish = GST_DEBUG_FUNCPTR (gst_amc_video_dec_finish);
  videodec_class->decide_allocation =
      GST_DEBUG_FUNCPTR (gst_amc_video_dec_decide_allocation);
  videodec_class->src_query = GST_DEBUG_FUNCPTR (gst_amc_video_dec_src_query);
}

static void
gst_amc_video_dec_init (GstAmcVideoDec * self)
{
  gst_video_decoder_set_packetized (GST_VIDEO_DECODER (self), TRUE);
  gst_video_decoder_set_needs_format (GST_VIDEO_DECODER (self), TRUE);

  g_mutex_init (&self->drain_lock);
  g_cond_init (&self->drain_cond);

  g_mutex_init (&self->gl_lock);
  g_cond_init (&self->gl_cond);

  self->gl_queue = g_queue_new ();
}

static gboolean
gst_amc_video_dec_open (GstVideoDecoder * decoder)
{
  GstAmcVideoDec *self = GST_AMC_VIDEO_DEC (decoder);
  GstAmcVideoDecClass *klass = GST_AMC_VIDEO_DEC_GET_CLASS (self);
  GError *err = NULL;

  GST_DEBUG_OBJECT (self, "Opening decoder");

  self->codec = gst_amc_codec_new (klass->codec_info->name, &err);
  if (!self->codec) {
    GST_ELEMENT_ERROR_FROM_ERROR (self, err);
    return FALSE;
  }
  self->codec_config = AMC_CODEC_CONFIG_NONE;

  self->started = FALSE;
  self->flushing = TRUE;

  GST_DEBUG_OBJECT (self, "Opened decoder");

  return TRUE;
}

static gboolean
gst_amc_video_dec_close (GstVideoDecoder * decoder)
{
  GstAmcVideoDec *self = GST_AMC_VIDEO_DEC (decoder);

  GST_DEBUG_OBJECT (self, "Closing decoder");

  if (self->downstream_supports_gl
      && self->codec_config == AMC_CODEC_CONFIG_WITH_SURFACE) {
    g_mutex_lock (&self->gl_lock);
    GST_INFO_OBJECT (self, "shutting down gl queue pushed %u ready %u "
        "released %u", self->gl_pushed_frame_count, self->gl_ready_frame_count,
        self->gl_released_frame_count);

    g_queue_free_full (self->gl_queue, (GDestroyNotify) _gl_sync_unref);
    self->gl_queue = g_queue_new ();
    g_mutex_unlock (&self->gl_lock);

    if (self->gl_mem_attached)
      gst_gl_context_thread_add (self->gl_context,
          (GstGLContextThreadFunc) _dettach_mem_from_context, self);
  }
  self->gl_pushed_frame_count = 0;
  self->gl_ready_frame_count = 0;
  self->gl_released_frame_count = 0;
  self->gl_last_rendered_frame = 0;

  if (self->surface) {
    gst_object_unref (self->surface);
    self->surface = NULL;
  }

  if (self->listener) {
    JNIEnv *env = gst_amc_jni_get_env ();
    GError *err = NULL;

    if (!gst_amc_jni_call_void_method (env, &err, self->listener,
            self->set_context_id, GST_AMC_VIDEO_DEC_TO_JLONG (NULL))) {
      GST_ERROR_OBJECT (self, "Failed to unset back pointer on the listener. "
          "crashes/hangs may ensue: %s", err ? err->message : "Unknown");
      GST_ELEMENT_ERROR_FROM_ERROR (self, err);
    }

    gst_amc_jni_object_unref (env, self->listener);
  }
  self->listener = NULL;

  if (self->codec) {
    GError *err = NULL;

    gst_amc_codec_release (self->codec, &err);
    if (err)
      GST_ELEMENT_WARNING_FROM_ERROR (self, err);

    gst_amc_codec_free (self->codec);
  }

  self->started = FALSE;
  self->flushing = TRUE;
  self->downstream_supports_gl = FALSE;

  self->codec = NULL;
  self->codec_config = AMC_CODEC_CONFIG_NONE;

  GST_DEBUG_OBJECT (self, "Freeing GL context: %" GST_PTR_FORMAT,
      self->gl_context);
  if (self->gl_context) {
    gst_object_unref (self->gl_context);
    self->gl_context = NULL;
  }

  if (self->oes_mem) {
    gst_memory_unref ((GstMemory *) self->oes_mem);
    self->oes_mem = NULL;
  }

  if (self->gl_display) {
    gst_object_unref (self->gl_display);
    self->gl_display = NULL;
  }

  if (self->other_gl_context) {
    gst_object_unref (self->other_gl_context);
    self->other_gl_context = NULL;
  }

  GST_DEBUG_OBJECT (self, "Closed decoder");

  return TRUE;
}

static void
gst_amc_video_dec_finalize (GObject * object)
{
  GstAmcVideoDec *self = GST_AMC_VIDEO_DEC (object);

  g_mutex_clear (&self->drain_lock);
  g_cond_clear (&self->drain_cond);

  g_mutex_clear (&self->gl_lock);
  g_cond_clear (&self->gl_cond);

  if (self->gl_queue) {
    g_queue_free_full (self->gl_queue, (GDestroyNotify) _gl_sync_unref);
    self->gl_queue = NULL;
  }

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

static void
gst_amc_video_dec_set_context (GstElement * element, GstContext * context)
{
  GstAmcVideoDec *self = GST_AMC_VIDEO_DEC (element);

  gst_gl_handle_set_context (element, context, &self->gl_display,
      &self->other_gl_context);

  GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
}

static GstStateChangeReturn
gst_amc_video_dec_change_state (GstElement * element, GstStateChange transition)
{
  GstAmcVideoDec *self;
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
  GError *err = NULL;

  g_return_val_if_fail (GST_IS_AMC_VIDEO_DEC (element),
      GST_STATE_CHANGE_FAILURE);
  self = GST_AMC_VIDEO_DEC (element);

  GST_DEBUG_OBJECT (element, "changing state: %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:
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      self->downstream_flow_ret = GST_FLOW_OK;
      self->draining = FALSE;
      self->started = FALSE;
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      self->flushing = TRUE;
      if (self->started) {
        gst_amc_codec_flush (self->codec, &err);
        if (err)
          GST_ELEMENT_WARNING_FROM_ERROR (self, err);
      }
      g_mutex_lock (&self->drain_lock);
      self->draining = FALSE;
      g_cond_broadcast (&self->drain_cond);
      g_mutex_unlock (&self->drain_lock);
      break;
    default:
      break;
  }

  if (ret == GST_STATE_CHANGE_FAILURE)
    return ret;

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

  if (ret == GST_STATE_CHANGE_FAILURE)
    return ret;

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      self->downstream_flow_ret = GST_FLOW_FLUSHING;
      self->started = FALSE;
      break;
    default:
      break;
  }

  return ret;
}

#define MAX_FRAME_DIST_TIME  (5 * GST_SECOND)
#define MAX_FRAME_DIST_FRAMES (100)

static GstVideoCodecFrame *
_find_nearest_frame (GstAmcVideoDec * self, GstClockTime reference_timestamp)
{
  GList *l, *best_l = NULL;
  GList *finish_frames = NULL;
  GstVideoCodecFrame *best = NULL;
  guint64 best_timestamp = 0;
  guint64 best_diff = G_MAXUINT64;
  BufferIdentification *best_id = NULL;
  GList *frames;

  frames = gst_video_decoder_get_frames (GST_VIDEO_DECODER (self));

  for (l = frames; l; l = l->next) {
    GstVideoCodecFrame *tmp = l->data;
    BufferIdentification *id = gst_video_codec_frame_get_user_data (tmp);
    guint64 timestamp, diff;

    /* This happens for frames that were just added but
     * which were not passed to the component yet. Ignore
     * them here!
     */
    if (!id)
      continue;

    timestamp = id->timestamp;

    if (timestamp > reference_timestamp)
      diff = timestamp - reference_timestamp;
    else
      diff = reference_timestamp - timestamp;

    if (best == NULL || diff < best_diff) {
      best = tmp;
      best_timestamp = timestamp;
      best_diff = diff;
      best_l = l;
      best_id = id;

      /* For frames without timestamp we simply take the first frame */
      if ((reference_timestamp == 0 && !GST_CLOCK_TIME_IS_VALID (timestamp))
          || diff == 0)
        break;
    }
  }

  if (best_id) {
    for (l = frames; l && l != best_l; l = l->next) {
      GstVideoCodecFrame *tmp = l->data;
      BufferIdentification *id = gst_video_codec_frame_get_user_data (tmp);
      guint64 diff_time, diff_frames;

      if (id->timestamp > best_timestamp)
        break;

      if (id->timestamp == 0 || best_timestamp == 0)
        diff_time = 0;
      else
        diff_time = best_timestamp - id->timestamp;
      diff_frames = best->system_frame_number - tmp->system_frame_number;

      if (diff_time > MAX_FRAME_DIST_TIME
          || diff_frames > MAX_FRAME_DIST_FRAMES) {
        finish_frames =
            g_list_prepend (finish_frames, gst_video_codec_frame_ref (tmp));
      }
    }
  }

  if (finish_frames) {
    g_warning ("%s: Too old frames, bug in decoder -- please file a bug",
        GST_ELEMENT_NAME (self));
    for (l = finish_frames; l; l = l->next) {
      gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), l->data);
    }
  }

  if (best)
    gst_video_codec_frame_ref (best);

  g_list_foreach (frames, (GFunc) gst_video_codec_frame_unref, NULL);
  g_list_free (frames);

  return best;
}

static gboolean
gst_amc_video_dec_check_codec_config (GstAmcVideoDec * self)
{
  gboolean ret = (self->codec_config == AMC_CODEC_CONFIG_NONE
      || (self->codec_config == AMC_CODEC_CONFIG_WITH_SURFACE
          && self->downstream_supports_gl)
      || (self->codec_config == AMC_CODEC_CONFIG_WITHOUT_SURFACE
          && !self->downstream_supports_gl));

  if (!ret) {
    GST_ERROR_OBJECT
        (self,
        "Codec configuration (%d) is not compatible with downstream which %s support GL output",
        self->codec_config, self->downstream_supports_gl ? "does" : "does not");
  }

  return ret;
}

static gboolean
gst_amc_video_dec_set_src_caps (GstAmcVideoDec * self, GstAmcFormat * format)
{
  GstVideoCodecState *output_state;
  const gchar *mime;
  gint color_format, width, height;
  gint stride, slice_height;
  gint crop_left, crop_right;
  gint crop_top, crop_bottom;
  GstVideoFormat gst_format;
  GstAmcVideoDecClass *klass = GST_AMC_VIDEO_DEC_GET_CLASS (self);
  GError *err = NULL;
  gboolean ret;

  if (!gst_amc_format_get_int (format, "color-format", &color_format, &err) ||
      !gst_amc_format_get_int (format, "width", &width, &err) ||
      !gst_amc_format_get_int (format, "height", &height, &err)) {
    GST_ERROR_OBJECT (self, "Failed to get output format metadata: %s",
        err->message);
    g_clear_error (&err);
    return FALSE;
  }

  if (!gst_amc_format_get_int (format, "stride", &stride, &err) ||
      !gst_amc_format_get_int (format, "slice-height", &slice_height, &err)) {
    GST_ERROR_OBJECT (self, "Failed to get stride and slice-height: %s",
        err->message);
    g_clear_error (&err);
    return FALSE;
  }

  if (!gst_amc_format_get_int (format, "crop-left", &crop_left, &err) ||
      !gst_amc_format_get_int (format, "crop-right", &crop_right, &err) ||
      !gst_amc_format_get_int (format, "crop-top", &crop_top, &err) ||
      !gst_amc_format_get_int (format, "crop-bottom", &crop_bottom, &err)) {
    GST_ERROR_OBJECT (self, "Failed to get crop rectangle: %s", err->message);
    g_clear_error (&err);
    return FALSE;
  }

  if (width == 0 || height == 0) {
    GST_ERROR_OBJECT (self, "Height or width not set");
    return FALSE;
  }

  if (crop_bottom)
    height = height - (height - crop_bottom - 1);
  if (crop_top)
    height = height - crop_top;

  if (crop_right)
    width = width - (width - crop_right - 1);
  if (crop_left)
    width = width - crop_left;

  mime = caps_to_mime (self->input_state->caps);
  if (!mime) {
    GST_ERROR_OBJECT (self, "Failed to convert caps to mime");
    return FALSE;
  }

  if (self->codec_config == AMC_CODEC_CONFIG_WITH_SURFACE) {
    gst_format = GST_VIDEO_FORMAT_RGBA;
  } else {
    gst_format =
        gst_amc_color_format_to_video_format (klass->codec_info, mime,
        color_format);
  }

  if (gst_format == GST_VIDEO_FORMAT_UNKNOWN) {
    GST_ERROR_OBJECT (self, "Unknown color format 0x%08x", color_format);
    return FALSE;
  }

  output_state = gst_video_decoder_set_output_state (GST_VIDEO_DECODER (self),
      gst_format, width, height, self->input_state);

  /* FIXME: Special handling for multiview, untested */
  if (color_format == COLOR_QCOM_FormatYVU420SemiPlanar32mMultiView) {
    gst_video_multiview_video_info_change_mode (&output_state->info,
        GST_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM, GST_VIDEO_MULTIVIEW_FLAGS_NONE);
  }

  memset (&self->color_format_info, 0, sizeof (self->color_format_info));
  if (self->codec_config == AMC_CODEC_CONFIG_WITH_SURFACE) {
    if (output_state->caps)
      gst_caps_unref (output_state->caps);
    output_state->caps = gst_video_info_to_caps (&output_state->info);
    gst_caps_set_features (output_state->caps, 0,
        gst_caps_features_new (GST_CAPS_FEATURE_MEMORY_GL_MEMORY, NULL));
    gst_caps_set_simple (output_state->caps, "texture-target", G_TYPE_STRING,
        "external-oes", NULL);
    GST_DEBUG_OBJECT (self, "Configuring for Surface output");

    /* The width/height values are used in other places for
     * checking if the resolution changed. Set everything
     * that makes sense here
     */
    self->color_format_info.color_format = COLOR_FormatAndroidOpaque;
    self->color_format_info.width = width;
    self->color_format_info.height = height;
    self->color_format_info.crop_left = crop_left;
    self->color_format_info.crop_right = crop_right;
    self->color_format_info.crop_top = crop_top;
    self->color_format_info.crop_bottom = crop_bottom;

    goto out;
  }

  self->format = gst_format;
  self->width = width;
  self->height = height;
  if (!gst_amc_color_format_info_set (&self->color_format_info,
          klass->codec_info, mime, color_format, width, height, stride,
          slice_height, crop_left, crop_right, crop_top, crop_bottom)) {
    GST_ERROR_OBJECT (self, "Failed to set up GstAmcColorFormatInfo");
    return FALSE;
  }

  GST_DEBUG_OBJECT (self,
      "Color format info: {color_format=%d (0x%08x), width=%d, height=%d, "
      "stride=%d, slice-height=%d, crop-left=%d, crop-top=%d, "
      "crop-right=%d, crop-bottom=%d, frame-size=%d}",
      self->color_format_info.color_format,
      self->color_format_info.color_format, self->color_format_info.width,
      self->color_format_info.height, self->color_format_info.stride,
      self->color_format_info.slice_height, self->color_format_info.crop_left,
      self->color_format_info.crop_top, self->color_format_info.crop_right,
      self->color_format_info.crop_bottom, self->color_format_info.frame_size);

out:
  ret = gst_video_decoder_negotiate (GST_VIDEO_DECODER (self));

  gst_video_codec_state_unref (output_state);
  self->input_state_changed = FALSE;

  return ret;
}

static gboolean
gst_amc_video_dec_fill_buffer (GstAmcVideoDec * self, GstAmcBuffer * buf,
    const GstAmcBufferInfo * buffer_info, GstBuffer * outbuf)
{
  GstVideoCodecState *state =
      gst_video_decoder_get_output_state (GST_VIDEO_DECODER (self));
  GstVideoInfo *info = &state->info;
  gboolean ret = FALSE;

  if (self->color_format_info.color_format == COLOR_FormatAndroidOpaque)
    return FALSE;

  ret =
      gst_amc_color_format_copy (&self->color_format_info, buf, buffer_info,
      info, outbuf, COLOR_FORMAT_COPY_OUT);

  gst_video_codec_state_unref (state);
  return ret;
}

static const gfloat yflip_matrix[16] = {
  1.0f, 0.0f, 0.0f, 0.0f,
  0.0f, -1.0f, 0.0f, 0.0f,
  0.0f, 0.0f, 1.0f, 0.0f,
  0.0f, 1.0f, 0.0f, 1.0f
};

static void
_amc_gl_set_sync (GstGLSyncMeta * sync_meta, GstGLContext * context)
{
}

static void
_gl_sync_release_buffer (struct gl_sync *sync, gboolean render)
{
  GError *error = NULL;

  if (!sync->result->released) {
    sync->released_ts = g_get_monotonic_time ();

    if ((gint) (sync->sink->gl_released_frame_count -
            sync->sink->gl_ready_frame_count) > 0) {
      guint diff =
          sync->sink->gl_released_frame_count -
          sync->sink->gl_ready_frame_count - 1u;
      sync->sink->gl_ready_frame_count += diff;
      GST_LOG ("gl_sync %p possible \'on_frame_available\' listener miss "
          "detected, attempting to work around.  Jumping forward %u "
          "frames for frame %u", sync, diff, sync->gl_frame_no);
    }

    GST_TRACE ("gl_sync %p release_output_buffer idx %u frame %u render %s",
        sync, sync->buffer_idx, sync->gl_frame_no, render ? "TRUE" : "FALSE");

    /* Release the frame into the surface */
    sync->sink->gl_released_frame_count++;
    if (!render) {
      /* Advance the ready counter ourselves if we aren't going to render
       * and therefore receive a listener callback */
      sync->sink->gl_ready_frame_count++;
    }

    if (!gst_amc_codec_release_output_buffer (sync->sink->codec,
            sync->buffer_idx, render, &error)) {
      GST_ERROR_OBJECT (sync->sink,
          "gl_sync %p Failed to render buffer, index %d frame %u", sync,
          sync->buffer_idx, sync->gl_frame_no);
      goto out;
    }
    sync->result->released = TRUE;
    sync->result->rendered = render;
  }

out:
  if (error) {
    if (sync->sink->gl_error == NULL)
      sync->sink->gl_error = error;
    else
      g_clear_error (&error);
  }
}

static void
_gl_sync_release_next_buffer (struct gl_sync *sync, gboolean render)
{
  GList *l;

  if ((l = _find_gl_sync_for_frame (sync->sink, sync->gl_frame_no + 1))) {
    struct gl_sync *next = l->data;

    _gl_sync_release_buffer (next, render);
  } else {
    GST_TRACE ("gl_sync %p no next frame available", sync);
  }
}

/* caller should remove from the gl_queue after calling this function.
 * _gl_sync_release_buffer must be called before this function */
static void
_gl_sync_render_unlocked (struct gl_sync *sync)
{
  GstVideoAffineTransformationMeta *af_meta;
  GError *error = NULL;
  gfloat matrix[16];
  gint64 ts = 0;

  GST_TRACE ("gl_sync %p result %p render (updated:%u)", sync, sync->result,
      sync->result->updated);

  if (sync->result->updated || !sync->result->rendered)
    return;

  /* FIXME: if this ever starts returning valid values we should attempt
   * to use it */
  if (!gst_amc_surface_texture_get_timestamp (sync->surface->texture, &ts,
          &error)) {
    GST_ERROR_OBJECT (sync->sink, "Failed to update texture image");
    GST_ELEMENT_ERROR_FROM_ERROR (sync->sink, error);
    goto out;
  }
  GST_TRACE ("gl_sync %p rendering timestamp before update %" G_GINT64_FORMAT,
      sync, ts);

  GST_TRACE ("gl_sync %p update_tex_image", sync);
  if (!gst_amc_surface_texture_update_tex_image (sync->surface->texture,
          &error)) {
    GST_ERROR_OBJECT (sync->sink, "Failed to update texture image");
    GST_ELEMENT_ERROR_FROM_ERROR (sync->sink, error);
    goto out;
  }
  GST_TRACE ("gl_sync result %p updated", sync->result);
  sync->result->updated = TRUE;
  sync->sink->gl_last_rendered_frame = sync->gl_frame_no;

  if (!gst_amc_surface_texture_get_timestamp (sync->surface->texture, &ts,
          &error)) {
    GST_ERROR_OBJECT (sync->sink, "Failed to update texture image");
    GST_ELEMENT_ERROR_FROM_ERROR (sync->sink, error);
    goto out;
  }
  GST_TRACE ("gl_sync %p rendering timestamp after update %" G_GINT64_FORMAT,
      sync, ts);

  af_meta = gst_buffer_get_video_affine_transformation_meta (sync->buffer);
  if (!af_meta) {
    GST_WARNING ("Failed to retreive the transformation meta from the "
        "gl_sync %p buffer %p", sync, sync->buffer);
  } else if (gst_amc_surface_texture_get_transform_matrix (sync->surface->
          texture, matrix, &error)) {

    gst_video_affine_transformation_meta_apply_matrix (af_meta, matrix);
    gst_video_affine_transformation_meta_apply_matrix (af_meta, yflip_matrix);
  }

  GST_LOG ("gl_sync %p successfully updated SurfaceTexture %p into "
      "OES texture %u", sync, sync->surface->texture, sync->oes_mem->tex_id);

out:
  if (error) {
    if (sync->sink->gl_error == NULL)
      sync->sink->gl_error = error;
    else
      g_clear_error (&error);
  }

  _gl_sync_release_next_buffer (sync, TRUE);
}

static gboolean
_amc_gl_possibly_wait_for_gl_sync (struct gl_sync *sync, gint64 end_time)
{
  GST_TRACE ("gl_sync %p waiting for frame %u current %u updated %u ", sync,
      sync->gl_frame_no, sync->sink->gl_ready_frame_count,
      sync->result->updated);

  if ((gint) (sync->sink->gl_last_rendered_frame - sync->gl_frame_no) > 0) {
    GST_ERROR ("gl_sync %p unsuccessfully waited for frame %u. out of order "
        "wait detected", sync, sync->gl_frame_no);
    return FALSE;
  }

  /* The number of frame callbacks (gl_ready_frame_count) is not a direct
   * relationship with the number of pushed buffers (gl_pushed_frame_count)
   * or even, the number of released buffers (gl_released_frame_count)
   * as, from the frameworks/native/include/gui/ConsumerBase.h file,
   *
   *    "...frames that are queued while in asynchronous mode only trigger the
   *    callback if no previous frames are pending."
   *
   * As a result, we need to advance the ready counter somehow ourselves when
   * such events happen. There is no reliable way of knowing when/if the frame
   * listener is going to fire.  The only uniqueu identifier,
   * SurfaceTexture::get_timestamp seems to always return 0.
   *
   * The maximum queue size as defined in
   * frameworks/native/include/gui/BufferQueue.h
   * is 32 of which a maximum of 30 can be acquired at a time so we picked a
   * number less than that to wait for before updating the ready frame count.
   */

  while (!sync->result->updated
      && (gint) (sync->sink->gl_ready_frame_count - sync->gl_frame_no) < 0) {
    /* The time limit is need otherwise when amc decides to not emit the
     * frame listener (say, on orientation changes) we don't wait foreever */
    if (end_time == -1 || !g_cond_wait_until (&sync->sink->gl_cond,
            &sync->sink->gl_lock, end_time)) {
      GST_LOG ("gl_sync %p unsuccessfully waited for frame %u", sync,
          sync->gl_frame_no);
      return FALSE;
    }
  }
  GST_LOG ("gl_sync %p successfully waited for frame %u", sync,
      sync->gl_frame_no);

  return TRUE;
}

static gboolean
_amc_gl_iterate_queue_unlocked (GstGLSyncMeta * sync_meta, gboolean wait)
{
  struct gl_sync *sync = sync_meta->data;
  struct gl_sync *tmp;
  gboolean ret = TRUE;
  gint64 end_time;

  while ((tmp = g_queue_peek_head (sync->sink->gl_queue))) {
    /* skip frames that are ahead of the current wait frame */
    if ((gint) (sync->gl_frame_no - tmp->gl_frame_no) < 0) {
      GST_TRACE ("gl_sync %p frame %u is ahead of gl_sync %p frame %u", tmp,
          tmp->gl_frame_no, sync, sync->gl_frame_no);
      break;
    }

    _gl_sync_release_buffer (tmp, wait);

    /* Frames are currently pushed in order and waits need to be performed
     * in the same order */

    end_time = wait ? 30 * G_TIME_SPAN_MILLISECOND + tmp->released_ts : -1;
    if (!_amc_gl_possibly_wait_for_gl_sync (tmp, end_time))
      ret = FALSE;

    _gl_sync_render_unlocked (tmp);

    g_queue_pop_head (tmp->sink->gl_queue);
    _gl_sync_unref (tmp);
  }

  return ret;
}

struct gl_wait
{
  GstGLSyncMeta *sync_meta;
  gboolean ret;
};

static void
_amc_gl_wait_gl (GstGLContext * context, struct gl_wait *wait)
{
  struct gl_sync *sync = wait->sync_meta->data;

  g_mutex_lock (&sync->sink->gl_lock);
  wait->ret = _amc_gl_iterate_queue_unlocked (wait->sync_meta, TRUE);
  g_mutex_unlock (&sync->sink->gl_lock);
}

static void
_amc_gl_wait (GstGLSyncMeta * sync_meta, GstGLContext * context)
{
  struct gl_sync *sync = sync_meta->data;
  struct gl_wait wait;

  wait.sync_meta = sync_meta;
  wait.ret = FALSE;
  gst_gl_context_thread_add (context,
      (GstGLContextThreadFunc) _amc_gl_wait_gl, &wait);

  if (!wait.ret)
    GST_WARNING ("gl_sync %p could not wait for frame, took too long", sync);
}

static void
_amc_gl_copy (GstGLSyncMeta * src, GstBuffer * sbuffer, GstGLSyncMeta * dest,
    GstBuffer * dbuffer)
{
  struct gl_sync *sync = src->data;
  struct gl_sync *tmp;

  tmp = g_new0 (struct gl_sync, 1);

  GST_TRACE ("copying gl_sync %p to %p", sync, tmp);

  g_mutex_lock (&sync->sink->gl_lock);

  tmp->refcount = 1;
  tmp->sink = sync->sink;
  tmp->buffer = dbuffer;
  tmp->oes_mem = (GstGLMemory *) gst_memory_ref ((GstMemory *) sync->oes_mem);
  tmp->surface = g_object_ref (sync->surface);
  tmp->gl_frame_no = sync->gl_frame_no;
  tmp->released_ts = sync->released_ts;
  tmp->result = sync->result;
  _gl_sync_result_ref (tmp->result);
  dest->data = tmp;

  g_mutex_unlock (&sync->sink->gl_lock);
}

static void
_amc_gl_render_on_free (GstGLContext * context, GstGLSyncMeta * sync_meta)
{
  struct gl_sync *sync = sync_meta->data;

  g_mutex_lock (&sync->sink->gl_lock);
  /* just render as many frames as we have */
  _amc_gl_iterate_queue_unlocked (sync_meta, FALSE);
  g_mutex_unlock (&sync->sink->gl_lock);
}

static void
_amc_gl_free (GstGLSyncMeta * sync_meta, GstGLContext * context)
{
  struct gl_sync *sync = sync_meta->data;

  /* The wait render queue inside android is not very deep so when we drop
   * frames we need to signal that we have rendered them if we have any chance
   * of keeping up between the decoder, the android GL queue and downstream
   * OpenGL. If we don't do this, once we start dropping frames downstream,
   * it is very near to impossible for the pipeline to catch up. */
  gst_gl_context_thread_add (context,
      (GstGLContextThreadFunc) _amc_gl_render_on_free, sync_meta);
  _gl_sync_unref (sync);
}

static void
gst_amc_video_dec_loop (GstAmcVideoDec * self)
{
  GstVideoCodecFrame *frame;
  GstFlowReturn flow_ret = GST_FLOW_OK;
  GstClockTimeDiff deadline;
  gboolean is_eos;
  GstAmcBuffer *buf;
  GstAmcBufferInfo buffer_info;
  gint idx;
  GError *err = NULL;
  gboolean release_buffer = TRUE;

  GST_VIDEO_DECODER_STREAM_LOCK (self);

retry:
  /*if (self->input_state_changed) {
     idx = INFO_OUTPUT_FORMAT_CHANGED;
     } else { */
  GST_DEBUG_OBJECT (self, "Waiting for available output buffer");
  GST_VIDEO_DECODER_STREAM_UNLOCK (self);
  /* Wait at most 100ms here, some codecs don't fail dequeueing if
   * the codec is flushing, causing deadlocks during shutdown */
  idx =
      gst_amc_codec_dequeue_output_buffer (self->codec, &buffer_info, 100000,
      &err);
  GST_VIDEO_DECODER_STREAM_LOCK (self);
  /*} */

  GST_DEBUG_OBJECT (self, "dequeueOutputBuffer() returned %d (0x%x)", idx, idx);

  if (idx < 0) {
    if (self->flushing) {
      g_clear_error (&err);
      goto flushing;
    }

    switch (idx) {
      case INFO_OUTPUT_BUFFERS_CHANGED:
        /* Handled internally */
        g_assert_not_reached ();
        break;
      case INFO_OUTPUT_FORMAT_CHANGED:{
        GstAmcFormat *format;
        gchar *format_string;

        GST_DEBUG_OBJECT (self, "Output format has changed");

        format = gst_amc_codec_get_output_format (self->codec, &err);
        if (!format)
          goto format_error;

        format_string = gst_amc_format_to_string (format, &err);
        if (!format) {
          gst_amc_format_free (format);
          goto format_error;
        }
        GST_DEBUG_OBJECT (self, "Got new output format: %s", format_string);
        g_free (format_string);

        if (!gst_amc_video_dec_set_src_caps (self, format)) {
          gst_amc_format_free (format);
          goto format_error;
        }
        gst_amc_format_free (format);

        goto retry;
      }
      case INFO_TRY_AGAIN_LATER:
        GST_DEBUG_OBJECT (self, "Dequeueing output buffer timed out");
        goto retry;
      case G_MININT:
        GST_ERROR_OBJECT (self, "Failure dequeueing output buffer");
        goto dequeue_error;
      default:
        g_assert_not_reached ();
        break;
    }

    goto retry;
  }

  GST_DEBUG_OBJECT (self,
      "Got output buffer at index %d: offset %d size %d time %" G_GINT64_FORMAT
      " flags 0x%08x", idx, buffer_info.offset, buffer_info.size,
      buffer_info.presentation_time_us, buffer_info.flags);

  buf = gst_amc_codec_get_output_buffer (self->codec, idx, &err);
  if (err) {
    if (self->flushing) {
      g_clear_error (&err);
      goto flushing;
    }
    goto failed_to_get_output_buffer;
  }

  if (self->codec_config != AMC_CODEC_CONFIG_WITH_SURFACE && !buf)
    goto got_null_output_buffer;

  frame =
      _find_nearest_frame (self,
      gst_util_uint64_scale (buffer_info.presentation_time_us, GST_USECOND, 1));

  is_eos = ! !(buffer_info.flags & BUFFER_FLAG_END_OF_STREAM);

  if (frame
      && (deadline =
          gst_video_decoder_get_max_decode_time (GST_VIDEO_DECODER (self),
              frame)) < 0) {
    GST_WARNING_OBJECT (self,
        "Frame is too late, dropping (deadline %" GST_STIME_FORMAT ")",
        GST_STIME_ARGS (deadline));
    flow_ret = gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame);
  } else if (frame && self->codec_config == AMC_CODEC_CONFIG_WITH_SURFACE) {
    GstBuffer *outbuf;
    GstGLSyncMeta *sync_meta;
    GstVideoCodecState *state;
    struct gl_sync *sync;
    gboolean first_buffer = FALSE;

    g_mutex_lock (&self->gl_lock);
    if (self->gl_error) {
      GST_ELEMENT_ERROR_FROM_ERROR (self, self->gl_error);
      g_mutex_unlock (&self->gl_lock);
      goto gl_output_error;
    }
    g_mutex_unlock (&self->gl_lock);

    outbuf = gst_buffer_new ();

    state = gst_video_decoder_get_output_state (GST_VIDEO_DECODER (self));

    if (!self->oes_mem) {
      GstGLBaseMemoryAllocator *base_mem_alloc;
      GstGLVideoAllocationParams *params;

      base_mem_alloc =
          GST_GL_BASE_MEMORY_ALLOCATOR (gst_allocator_find
          (GST_GL_MEMORY_ALLOCATOR_NAME));

      params = gst_gl_video_allocation_params_new (self->gl_context, NULL,
          &state->info, 0, NULL, GST_GL_TEXTURE_TARGET_EXTERNAL_OES,
          GST_GL_RGBA);

      self->oes_mem = (GstGLMemory *) gst_gl_base_memory_alloc (base_mem_alloc,
          (GstGLAllocationParams *) params);
      gst_gl_allocation_params_free ((GstGLAllocationParams *) params);
      gst_object_unref (base_mem_alloc);

      gst_gl_context_thread_add (self->gl_context,
          (GstGLContextThreadFunc) _attach_mem_to_context, self);

      first_buffer = TRUE;
    }

    gst_video_codec_state_unref (state);

    gst_buffer_append_memory (outbuf,
        gst_memory_ref ((GstMemory *) self->oes_mem));

    sync = g_new0 (struct gl_sync, 1);
    sync->refcount = 1;
    sync->sink = self;
    sync->buffer = outbuf;
    sync->surface = g_object_ref (self->surface);
    sync->oes_mem =
        (GstGLMemory *) gst_memory_ref ((GstMemory *) self->oes_mem);
    sync->buffer_idx = idx;
    sync->result = g_new0 (struct gl_sync_result, 1);
    sync->result->refcount = 1;
    sync->result->updated = FALSE;

    GST_TRACE ("new gl_sync %p result %p", sync, sync->result);

    sync_meta = gst_buffer_add_gl_sync_meta_full (self->gl_context, outbuf,
        sync);
    sync_meta->set_sync = _amc_gl_set_sync;
    sync_meta->wait = _amc_gl_wait;
    sync_meta->wait_cpu = _amc_gl_wait;
    sync_meta->copy = _amc_gl_copy;
    sync_meta->free = _amc_gl_free;

    /* The meta needs to be created now:
     * Later (in _gl_sync_render_unlocked) the buffer will be locked.
     */
    gst_buffer_add_video_affine_transformation_meta (outbuf);

    g_mutex_lock (&self->gl_lock);

    self->gl_pushed_frame_count++;
    sync->gl_frame_no = self->gl_pushed_frame_count;
    g_queue_push_tail (self->gl_queue, _gl_sync_ref (sync));

    if (first_buffer) {
      _gl_sync_release_buffer (sync, TRUE);
      if (self->gl_error) {
        gst_buffer_unref (outbuf);
        g_mutex_unlock (&self->gl_lock);
        goto gl_output_error;
      }
    }
    g_mutex_unlock (&self->gl_lock);

    GST_DEBUG_OBJECT (self, "push GL frame %u", sync->gl_frame_no);
    frame->output_buffer = outbuf;
    flow_ret = gst_video_decoder_finish_frame (GST_VIDEO_DECODER (self), frame);

    release_buffer = FALSE;
  } else if (self->codec_config == AMC_CODEC_CONFIG_WITHOUT_SURFACE && !frame
      && buffer_info.size > 0) {
    GstBuffer *outbuf;

    /* This sometimes happens at EOS or if the input is not properly framed,
     * let's handle it gracefully by allocating a new buffer for the current
     * caps and filling it
     */
    GST_ERROR_OBJECT (self, "No corresponding frame found");

    outbuf =
        gst_video_decoder_allocate_output_buffer (GST_VIDEO_DECODER (self));

    if (!gst_amc_video_dec_fill_buffer (self, buf, &buffer_info, outbuf)) {
      gst_buffer_unref (outbuf);
      if (!gst_amc_codec_release_output_buffer (self->codec, idx, FALSE, &err))
        GST_ERROR_OBJECT (self, "Failed to release output buffer index %d",
            idx);
      if (err && !self->flushing)
        GST_ELEMENT_WARNING_FROM_ERROR (self, err);
      g_clear_error (&err);
      gst_amc_buffer_free (buf);
      buf = NULL;
      goto invalid_buffer;
    }

    GST_BUFFER_PTS (outbuf) =
        gst_util_uint64_scale (buffer_info.presentation_time_us, GST_USECOND,
        1);
    flow_ret = gst_pad_push (GST_VIDEO_DECODER_SRC_PAD (self), outbuf);
  } else if (self->codec_config == AMC_CODEC_CONFIG_WITHOUT_SURFACE && frame
      && buffer_info.size > 0) {
    if ((flow_ret =
            gst_video_decoder_allocate_output_frame (GST_VIDEO_DECODER (self),
                frame)) != GST_FLOW_OK) {
      GST_ERROR_OBJECT (self, "Failed to allocate buffer");
      if (!gst_amc_codec_release_output_buffer (self->codec, idx, FALSE, &err))
        GST_ERROR_OBJECT (self, "Failed to release output buffer index %d",
            idx);
      if (err && !self->flushing)
        GST_ELEMENT_WARNING_FROM_ERROR (self, err);
      g_clear_error (&err);
      gst_amc_buffer_free (buf);
      buf = NULL;
      goto flow_error;
    }

    if (!gst_amc_video_dec_fill_buffer (self, buf, &buffer_info,
            frame->output_buffer)) {
      gst_buffer_replace (&frame->output_buffer, NULL);
      gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame);
      if (!gst_amc_codec_release_output_buffer (self->codec, idx, FALSE, &err))
        GST_ERROR_OBJECT (self, "Failed to release output buffer index %d",
            idx);
      if (err && !self->flushing)
        GST_ELEMENT_WARNING_FROM_ERROR (self, err);
      g_clear_error (&err);
      gst_amc_buffer_free (buf);
      buf = NULL;
      goto invalid_buffer;
    }

    flow_ret = gst_video_decoder_finish_frame (GST_VIDEO_DECODER (self), frame);
  } else if (frame != NULL) {
    flow_ret = gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame);
  }

  if (buf) {
    gst_amc_buffer_free (buf);
    buf = NULL;
  }

  if (release_buffer) {
    if (!gst_amc_codec_release_output_buffer (self->codec, idx, FALSE, &err)) {
      if (self->flushing) {
        g_clear_error (&err);
        goto flushing;
      }
      goto failed_release;
    }
  }

  if (is_eos || flow_ret == GST_FLOW_EOS) {
    GST_VIDEO_DECODER_STREAM_UNLOCK (self);
    g_mutex_lock (&self->drain_lock);
    if (self->draining) {
      GST_DEBUG_OBJECT (self, "Drained");
      self->draining = FALSE;
      g_cond_broadcast (&self->drain_cond);
    } else if (flow_ret == GST_FLOW_OK) {
      GST_DEBUG_OBJECT (self, "Component signalled EOS");
      flow_ret = GST_FLOW_EOS;
    }
    g_mutex_unlock (&self->drain_lock);
    GST_VIDEO_DECODER_STREAM_LOCK (self);
  } else {
    GST_DEBUG_OBJECT (self, "Finished frame: %s", gst_flow_get_name (flow_ret));
  }

  self->downstream_flow_ret = flow_ret;

  if (flow_ret != GST_FLOW_OK)
    goto flow_error;

  GST_VIDEO_DECODER_STREAM_UNLOCK (self);

  return;

dequeue_error:
  {
    GST_ELEMENT_ERROR_FROM_ERROR (self, err);
    gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), gst_event_new_eos ());
    gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self));
    self->downstream_flow_ret = GST_FLOW_ERROR;
    GST_VIDEO_DECODER_STREAM_UNLOCK (self);
    g_mutex_lock (&self->drain_lock);
    self->draining = FALSE;
    g_cond_broadcast (&self->drain_cond);
    g_mutex_unlock (&self->drain_lock);
    return;
  }

format_error:
  {
    if (err)
      GST_ELEMENT_ERROR_FROM_ERROR (self, err);
    else
      GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
          ("Failed to handle format"));
    gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), gst_event_new_eos ());
    gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self));
    self->downstream_flow_ret = GST_FLOW_ERROR;
    GST_VIDEO_DECODER_STREAM_UNLOCK (self);
    g_mutex_lock (&self->drain_lock);
    self->draining = FALSE;
    g_cond_broadcast (&self->drain_cond);
    g_mutex_unlock (&self->drain_lock);
    return;
  }
failed_release:
  {
    GST_VIDEO_DECODER_ERROR_FROM_ERROR (self, err);
    gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), gst_event_new_eos ());
    gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self));
    self->downstream_flow_ret = GST_FLOW_ERROR;
    GST_VIDEO_DECODER_STREAM_UNLOCK (self);
    g_mutex_lock (&self->drain_lock);
    self->draining = FALSE;
    g_cond_broadcast (&self->drain_cond);
    g_mutex_unlock (&self->drain_lock);
    return;
  }
flushing:
  {
    GST_DEBUG_OBJECT (self, "Flushing -- stopping task");
    gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self));
    self->downstream_flow_ret = GST_FLOW_FLUSHING;
    GST_VIDEO_DECODER_STREAM_UNLOCK (self);
    return;
  }

flow_error:
  {
    if (flow_ret == GST_FLOW_EOS) {
      GST_DEBUG_OBJECT (self, "EOS");
      gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self),
          gst_event_new_eos ());
      gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self));
    } else if (flow_ret < GST_FLOW_EOS) {
      GST_ELEMENT_FLOW_ERROR (self, flow_ret);
      gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self),
          gst_event_new_eos ());
      gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self));
    } else if (flow_ret == GST_FLOW_FLUSHING) {
      GST_DEBUG_OBJECT (self, "Flushing -- stopping task");
      gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self));
    }
    GST_VIDEO_DECODER_STREAM_UNLOCK (self);
    g_mutex_lock (&self->drain_lock);
    self->draining = FALSE;
    g_cond_broadcast (&self->drain_cond);
    g_mutex_unlock (&self->drain_lock);
    return;
  }

failed_to_get_output_buffer:
  {
    GST_VIDEO_DECODER_ERROR_FROM_ERROR (self, err);
    gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), gst_event_new_eos ());
    gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self));
    self->downstream_flow_ret = GST_FLOW_ERROR;
    GST_VIDEO_DECODER_STREAM_UNLOCK (self);
    g_mutex_lock (&self->drain_lock);
    self->draining = FALSE;
    g_cond_broadcast (&self->drain_cond);
    g_mutex_unlock (&self->drain_lock);
    return;
  }

got_null_output_buffer:
  {
    GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
        ("Got no output buffer"));
    gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), gst_event_new_eos ());
    gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self));
    self->downstream_flow_ret = GST_FLOW_ERROR;
    GST_VIDEO_DECODER_STREAM_UNLOCK (self);
    g_mutex_lock (&self->drain_lock);
    self->draining = FALSE;
    g_cond_broadcast (&self->drain_cond);
    g_mutex_unlock (&self->drain_lock);
    return;
  }

invalid_buffer:
  {
    GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
        ("Invalid sized input buffer"));
    gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), gst_event_new_eos ());
    gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self));
    self->downstream_flow_ret = GST_FLOW_NOT_NEGOTIATED;
    GST_VIDEO_DECODER_STREAM_UNLOCK (self);
    g_mutex_lock (&self->drain_lock);
    self->draining = FALSE;
    g_cond_broadcast (&self->drain_cond);
    g_mutex_unlock (&self->drain_lock);
    return;
  }
gl_output_error:
  {
    if (buf) {
      gst_amc_buffer_free (buf);
      buf = NULL;
    }
    gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), gst_event_new_eos ());
    gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self));
    self->downstream_flow_ret = GST_FLOW_NOT_NEGOTIATED;
    GST_VIDEO_DECODER_STREAM_UNLOCK (self);
    g_mutex_lock (&self->drain_lock);
    self->draining = FALSE;
    g_cond_broadcast (&self->drain_cond);
    g_mutex_unlock (&self->drain_lock);
    return;
  }
}

static gboolean
gst_amc_video_dec_start (GstVideoDecoder * decoder)
{
  GstAmcVideoDec *self;

  self = GST_AMC_VIDEO_DEC (decoder);
  self->last_upstream_ts = 0;
  self->drained = TRUE;
  self->downstream_flow_ret = GST_FLOW_OK;
  self->started = FALSE;
  self->flushing = TRUE;

  return TRUE;
}

static gboolean
gst_amc_video_dec_stop (GstVideoDecoder * decoder)
{
  GstAmcVideoDec *self;
  GError *err = NULL;

  self = GST_AMC_VIDEO_DEC (decoder);
  GST_DEBUG_OBJECT (self, "Stopping decoder");
  self->flushing = TRUE;
  if (self->started) {
    gst_amc_codec_flush (self->codec, &err);
    if (err)
      GST_ELEMENT_WARNING_FROM_ERROR (self, err);
    gst_amc_codec_stop (self->codec, &err);
    if (err)
      GST_ELEMENT_WARNING_FROM_ERROR (self, err);
    self->started = FALSE;
  }
  gst_pad_stop_task (GST_VIDEO_DECODER_SRC_PAD (decoder));

  self->downstream_flow_ret = GST_FLOW_FLUSHING;
  self->drained = TRUE;
  g_mutex_lock (&self->drain_lock);
  self->draining = FALSE;
  g_cond_broadcast (&self->drain_cond);
  g_mutex_unlock (&self->drain_lock);
  g_free (self->codec_data);
  self->codec_data_size = 0;
  if (self->input_state)
    gst_video_codec_state_unref (self->input_state);
  self->input_state = NULL;
  GST_DEBUG_OBJECT (self, "Stopped decoder");
  return TRUE;
}

static jobject
gst_amc_video_dec_new_on_frame_available_listener (GstAmcVideoDec * decoder,
    JNIEnv * env, GError ** err)
{
  jobject listener = NULL;
  jclass listener_cls = NULL;
  jmethodID constructor_id = 0;

  JNINativeMethod amcOnFrameAvailableListener = {
    "native_onFrameAvailable",
    "(JLandroid/graphics/SurfaceTexture;)V",
    (void *) gst_amc_video_dec_on_frame_available,
  };

  listener_cls =
      gst_amc_jni_get_application_class (env,
      "org/freedesktop/gstreamer/androidmedia/GstAmcOnFrameAvailableListener",
      err);
  if (!listener_cls) {
    return FALSE;
  }

  (*env)->RegisterNatives (env, listener_cls, &amcOnFrameAvailableListener, 1);
  if ((*env)->ExceptionCheck (env)) {
    (*env)->ExceptionClear (env);
    goto done;
  }

  constructor_id =
      gst_amc_jni_get_method_id (env, err, listener_cls, "<init>", "()V");
  if (!constructor_id) {
    goto done;
  }

  decoder->set_context_id =
      gst_amc_jni_get_method_id (env, err, listener_cls, "setContext", "(J)V");
  if (!decoder->set_context_id) {
    goto done;
  }

  listener =
      gst_amc_jni_new_object (env, err, TRUE, listener_cls, constructor_id);
  if (!listener) {
    goto done;
  }

  if (!gst_amc_jni_call_void_method (env, err, listener,
          decoder->set_context_id, GST_AMC_VIDEO_DEC_TO_JLONG (decoder))) {
    gst_amc_jni_object_unref (env, listener);
    listener = NULL;
  }

done:
  gst_amc_jni_object_unref (env, listener_cls);

  return listener;
}

static gboolean
gst_amc_video_dec_set_format (GstVideoDecoder * decoder,
    GstVideoCodecState * state)
{
  GstAmcVideoDec *self;
  GstAmcVideoDecClass *klass;
  GstAmcFormat *format;
  const gchar *mime;
  gboolean is_format_change = FALSE;
  gboolean needs_disable = FALSE;
  gchar *format_string;
  guint8 *codec_data = NULL;
  gsize codec_data_size = 0;
  GError *err = NULL;
  jobject jsurface = NULL;

  self = GST_AMC_VIDEO_DEC (decoder);
  klass = GST_AMC_VIDEO_DEC_GET_CLASS (self);

  GST_DEBUG_OBJECT (self, "Setting new caps %" GST_PTR_FORMAT, state->caps);

  /* Check if the caps change is a real format change or if only irrelevant
   * parts of the caps have changed or nothing at all.
   */
  is_format_change |= self->color_format_info.width != state->info.width;
  is_format_change |= self->color_format_info.height != state->info.height;
  if (state->codec_data) {
    GstMapInfo cminfo;

    gst_buffer_map (state->codec_data, &cminfo, GST_MAP_READ);
    codec_data = g_memdup (cminfo.data, cminfo.size);
    codec_data_size = cminfo.size;

    is_format_change |= (!self->codec_data
        || self->codec_data_size != codec_data_size
        || memcmp (self->codec_data, codec_data, codec_data_size) != 0);
    gst_buffer_unmap (state->codec_data, &cminfo);
  } else if (self->codec_data) {
    is_format_change |= TRUE;
  }

  needs_disable = self->started;

  /* If the component is not started and a real format change happens
   * we have to restart the component. If no real format change
   * happened we can just exit here.
   */
  if (needs_disable && !is_format_change) {
    g_free (codec_data);
    codec_data = NULL;
    codec_data_size = 0;

    /* Framerate or something minor changed */
    self->input_state_changed = TRUE;
    if (self->input_state)
      gst_video_codec_state_unref (self->input_state);
    self->input_state = gst_video_codec_state_ref (state);
    GST_DEBUG_OBJECT (self,
        "Already running and caps did not change the format");
    return TRUE;
  }

  if (needs_disable && is_format_change) {
    gst_amc_video_dec_drain (self);
    GST_VIDEO_DECODER_STREAM_UNLOCK (self);
    gst_amc_video_dec_stop (GST_VIDEO_DECODER (self));
    GST_VIDEO_DECODER_STREAM_LOCK (self);
    gst_amc_video_dec_close (GST_VIDEO_DECODER (self));
    if (!gst_amc_video_dec_open (GST_VIDEO_DECODER (self))) {
      GST_ERROR_OBJECT (self, "Failed to open codec again");
      return FALSE;
    }

    if (!gst_amc_video_dec_start (GST_VIDEO_DECODER (self))) {
      GST_ERROR_OBJECT (self, "Failed to start codec again");
    }
  }
  /* srcpad task is not running at this point */
  if (self->input_state)
    gst_video_codec_state_unref (self->input_state);
  self->input_state = NULL;

  g_free (self->codec_data);
  self->codec_data = codec_data;
  self->codec_data_size = codec_data_size;

  mime = caps_to_mime (state->caps);
  if (!mime) {
    GST_ERROR_OBJECT (self, "Failed to convert caps to mime");
    return FALSE;
  }

  format =
      gst_amc_format_new_video (mime, state->info.width, state->info.height,
      &err);
  if (!format) {
    GST_ERROR_OBJECT (self, "Failed to create video format");
    GST_ELEMENT_ERROR_FROM_ERROR (self, err);
    return FALSE;
  }

  /* FIXME: This buffer needs to be valid until the codec is stopped again */
  if (self->codec_data) {
    gst_amc_format_set_buffer (format, "csd-0", self->codec_data,
        self->codec_data_size, &err);
    if (err)
      GST_ELEMENT_WARNING_FROM_ERROR (self, err);
  }

  {
    gboolean downstream_supports_gl = FALSE;
    GstVideoDecoder *decoder = GST_VIDEO_DECODER (self);
    GstPad *src_pad = GST_VIDEO_DECODER_SRC_PAD (decoder);
    GstCaps *templ_caps = gst_pad_get_pad_template_caps (src_pad);
    GstCaps *downstream_caps = gst_pad_peer_query_caps (src_pad, templ_caps);

    gst_caps_unref (templ_caps);

    if (downstream_caps) {
      guint i, n;
      GstStaticCaps static_caps =
          GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
          (GST_CAPS_FEATURE_MEMORY_GL_MEMORY, "RGBA"));
      GstCaps *gl_memory_caps = gst_static_caps_get (&static_caps);

      GST_DEBUG_OBJECT (self, "Available downstream caps: %" GST_PTR_FORMAT,
          downstream_caps);

      /* Check if downstream caps supports
       * video/x-raw(memory:GLMemory),format=RGBA */
      n = gst_caps_get_size (downstream_caps);
      for (i = 0; i < n; i++) {
        GstCaps *caps = NULL;
        GstStructure *structure = gst_caps_get_structure (downstream_caps, i);
        GstCapsFeatures *features = gst_caps_get_features (downstream_caps, i);

        caps = gst_caps_new_full (gst_structure_copy (structure), NULL);
        if (!caps)
          continue;

        gst_caps_set_features (caps, 0, gst_caps_features_copy (features));

        if (gst_caps_can_intersect (caps, gl_memory_caps)) {
          downstream_supports_gl = TRUE;
        }

        gst_caps_unref (caps);
        if (downstream_supports_gl)
          break;
      }

      gst_caps_unref (gl_memory_caps);

      /* If video/x-raw(memory:GLMemory),format=RGBA is supported,
       * update the video decoder output state accordingly and negotiate */
      if (downstream_supports_gl) {
        GstVideoCodecState *output_state = NULL;
        GstVideoCodecState *prev_output_state = NULL;

        prev_output_state = gst_video_decoder_get_output_state (decoder);

        output_state =
            gst_video_decoder_set_output_state (decoder, GST_VIDEO_FORMAT_RGBA,
            state->info.width, state->info.height, state);

        if (output_state->caps) {
          gst_caps_unref (output_state->caps);
        }

        output_state->caps = gst_video_info_to_caps (&output_state->info);
        gst_caps_set_features (output_state->caps, 0,
            gst_caps_features_new (GST_CAPS_FEATURE_MEMORY_GL_MEMORY, NULL));

        /* gst_amc_video_dec_decide_allocation will update
         * self->downstream_supports_gl */
        if (!gst_video_decoder_negotiate (decoder)) {
          GST_ERROR_OBJECT (self, "Failed to negotiate");

          /* Rollback output state changes */
          if (prev_output_state) {
            output_state->info = prev_output_state->info;
            gst_caps_replace (&output_state->caps, prev_output_state->caps);
          } else {
            gst_video_info_init (&output_state->info);
            gst_caps_replace (&output_state->caps, NULL);
          }
        }
        if (prev_output_state) {
          gst_video_codec_state_unref (prev_output_state);
        }
      }

      gst_caps_unref (downstream_caps);
    }
  }

  GST_INFO_OBJECT (self, "GL output: %s",
      self->downstream_supports_gl ? "enabled" : "disabled");

  if (klass->codec_info->gl_output_only && !self->downstream_supports_gl) {
    GST_ERROR_OBJECT (self,
        "Codec only supports GL output but downstream does not");
    return FALSE;
  }

  if (self->downstream_supports_gl && self->surface) {
    jsurface = self->surface->jobject;
  } else if (self->downstream_supports_gl && !self->surface) {
    int ret = TRUE;
    JNIEnv *env = NULL;
    GstAmcSurfaceTexture *surface_texture = NULL;

    env = gst_amc_jni_get_env ();
    surface_texture = gst_amc_surface_texture_new (&err);
    if (!surface_texture) {
      GST_ELEMENT_ERROR_FROM_ERROR (self, err);
      return FALSE;
    }

    if (self->listener) {
      if (!gst_amc_jni_call_void_method (env, &err, self->listener,
              self->set_context_id, GST_AMC_VIDEO_DEC_TO_JLONG (NULL))) {
        ret = FALSE;
        goto done;
      }

      gst_amc_jni_object_unref (env, self->listener);
    }
    self->listener =
        gst_amc_video_dec_new_on_frame_available_listener (self, env, &err);
    if (!self->listener) {
      ret = FALSE;
      goto done;
    }

    if (!gst_amc_surface_texture_set_on_frame_available_listener
        (surface_texture, self->listener, &err)) {
      ret = FALSE;
      goto done;
    }

    self->surface = gst_amc_surface_new (surface_texture, &err);
    jsurface = self->surface->jobject;

  done:
    g_object_unref (surface_texture);
    if (!ret) {
      GST_ELEMENT_ERROR_FROM_ERROR (self, err);
      return FALSE;
    }
  }

  format_string = gst_amc_format_to_string (format, &err);
  if (err)
    GST_ELEMENT_WARNING_FROM_ERROR (self, err);
  GST_DEBUG_OBJECT (self, "Configuring codec with format: %s",
      GST_STR_NULL (format_string));
  g_free (format_string);

  if (!gst_amc_codec_configure (self->codec, format, jsurface, 0, &err)) {
    GST_ERROR_OBJECT (self, "Failed to configure codec");
    GST_ELEMENT_ERROR_FROM_ERROR (self, err);
    return FALSE;
  }
  if (jsurface) {
    self->codec_config = AMC_CODEC_CONFIG_WITH_SURFACE;
  } else {
    self->codec_config = AMC_CODEC_CONFIG_WITHOUT_SURFACE;
  }

  gst_amc_format_free (format);

  if (!gst_amc_codec_start (self->codec, &err)) {
    GST_ERROR_OBJECT (self, "Failed to start codec");
    GST_ELEMENT_ERROR_FROM_ERROR (self, err);
    return FALSE;
  }

  self->started = TRUE;
  self->input_state = gst_video_codec_state_ref (state);
  self->input_state_changed = TRUE;

  /* Start the srcpad loop again */
  self->flushing = FALSE;
  self->downstream_flow_ret = GST_FLOW_OK;
  gst_pad_start_task (GST_VIDEO_DECODER_SRC_PAD (self),
      (GstTaskFunction) gst_amc_video_dec_loop, decoder, NULL);

  return TRUE;
}

static gboolean
gst_amc_video_dec_flush (GstVideoDecoder * decoder)
{
  GstAmcVideoDec *self;
  GError *err = NULL;

  self = GST_AMC_VIDEO_DEC (decoder);

  GST_DEBUG_OBJECT (self, "Flushing decoder");

  if (!self->started) {
    GST_DEBUG_OBJECT (self, "Codec not started yet");
    return TRUE;
  }

  self->flushing = TRUE;
  /* Wait until the srcpad loop is finished,
   * unlock GST_VIDEO_DECODER_STREAM_LOCK to prevent deadlocks
   * caused by using this lock from inside the loop function */
  GST_VIDEO_DECODER_STREAM_UNLOCK (self);
  GST_PAD_STREAM_LOCK (GST_VIDEO_DECODER_SRC_PAD (self));
  GST_PAD_STREAM_UNLOCK (GST_VIDEO_DECODER_SRC_PAD (self));
  GST_VIDEO_DECODER_STREAM_LOCK (self);
  gst_amc_codec_flush (self->codec, &err);
  if (err)
    GST_ELEMENT_WARNING_FROM_ERROR (self, err);
  self->flushing = FALSE;

  /* Start the srcpad loop again */
  self->last_upstream_ts = 0;
  self->drained = TRUE;
  self->downstream_flow_ret = GST_FLOW_OK;
  gst_pad_start_task (GST_VIDEO_DECODER_SRC_PAD (self),
      (GstTaskFunction) gst_amc_video_dec_loop, decoder, NULL);

  GST_DEBUG_OBJECT (self, "Flushed decoder");

  return TRUE;
}

static GstFlowReturn
gst_amc_video_dec_handle_frame (GstVideoDecoder * decoder,
    GstVideoCodecFrame * frame)
{
  GstAmcVideoDec *self;
  gint idx;
  GstAmcBuffer *buf;
  GstAmcBufferInfo buffer_info;
  guint offset = 0;
  GstClockTime timestamp, duration, timestamp_offset = 0;
  GstMapInfo minfo;
  GError *err = NULL;

  memset (&minfo, 0, sizeof (minfo));

  self = GST_AMC_VIDEO_DEC (decoder);

  GST_DEBUG_OBJECT (self, "Handling frame");

  if (!self->started) {
    GST_ERROR_OBJECT (self, "Codec not started yet");
    gst_video_codec_frame_unref (frame);
    return GST_FLOW_NOT_NEGOTIATED;
  }

  if (self->flushing)
    goto flushing;

  if (self->downstream_flow_ret != GST_FLOW_OK)
    goto downstream_error;

  timestamp = frame->pts;
  duration = frame->duration;

  gst_buffer_map (frame->input_buffer, &minfo, GST_MAP_READ);

  while (offset < minfo.size) {
    /* Make sure to release the base class stream lock, otherwise
     * _loop() can't call _finish_frame() and we might block forever
     * because no input buffers are released */
    GST_VIDEO_DECODER_STREAM_UNLOCK (self);
    /* Wait at most 100ms here, some codecs don't fail dequeueing if
     * the codec is flushing, causing deadlocks during shutdown */
    idx = gst_amc_codec_dequeue_input_buffer (self->codec, 100000, &err);
    GST_VIDEO_DECODER_STREAM_LOCK (self);

    if (idx < 0) {
      if (self->flushing || self->downstream_flow_ret == GST_FLOW_FLUSHING) {
        g_clear_error (&err);
        goto flushing;
      }

      switch (idx) {
        case INFO_TRY_AGAIN_LATER:
          GST_DEBUG_OBJECT (self, "Dequeueing input buffer timed out");
          continue;             /* next try */
          break;
        case G_MININT:
          GST_ERROR_OBJECT (self, "Failed to dequeue input buffer");
          goto dequeue_error;
        default:
          g_assert_not_reached ();
          break;
      }

      continue;
    }

    if (self->flushing) {
      memset (&buffer_info, 0, sizeof (buffer_info));
      gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info, NULL);
      goto flushing;
    }

    if (self->downstream_flow_ret != GST_FLOW_OK) {
      memset (&buffer_info, 0, sizeof (buffer_info));
      gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info, &err);
      if (err && !self->flushing)
        GST_ELEMENT_WARNING_FROM_ERROR (self, err);
      g_clear_error (&err);
      goto downstream_error;
    }

    /* Now handle the frame */

    /* Copy the buffer content in chunks of size as requested
     * by the port */
    buf = gst_amc_codec_get_input_buffer (self->codec, idx, &err);
    if (err)
      goto failed_to_get_input_buffer;
    else if (!buf)
      goto got_null_input_buffer;

    memset (&buffer_info, 0, sizeof (buffer_info));
    buffer_info.offset = 0;
    buffer_info.size = MIN (minfo.size - offset, buf->size);
    gst_amc_buffer_set_position_and_limit (buf, NULL, buffer_info.offset,
        buffer_info.size);

    orc_memcpy (buf->data, minfo.data + offset, buffer_info.size);

    gst_amc_buffer_free (buf);
    buf = NULL;

    /* Interpolate timestamps if we're passing the buffer
     * in multiple chunks */
    if (offset != 0 && duration != GST_CLOCK_TIME_NONE) {
      timestamp_offset = gst_util_uint64_scale (offset, duration, minfo.size);
    }

    if (timestamp != GST_CLOCK_TIME_NONE) {
      buffer_info.presentation_time_us =
          gst_util_uint64_scale (timestamp + timestamp_offset, 1, GST_USECOND);
      self->last_upstream_ts = timestamp + timestamp_offset;
    }
    if (duration != GST_CLOCK_TIME_NONE)
      self->last_upstream_ts += duration;

    if (offset == 0) {
      BufferIdentification *id =
          buffer_identification_new (timestamp + timestamp_offset);
      if (GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame))
        buffer_info.flags |= BUFFER_FLAG_SYNC_FRAME;
      gst_video_codec_frame_set_user_data (frame, id,
          (GDestroyNotify) buffer_identification_free);
    }

    offset += buffer_info.size;
    GST_DEBUG_OBJECT (self,
        "Queueing buffer %d: size %d time %" G_GINT64_FORMAT
        " flags 0x%08x", idx, buffer_info.size,
        buffer_info.presentation_time_us, buffer_info.flags);
    if (!gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info,
            &err)) {
      if (self->flushing) {
        g_clear_error (&err);
        goto flushing;
      }
      goto queue_error;
    }
    self->drained = FALSE;
  }

  gst_buffer_unmap (frame->input_buffer, &minfo);
  gst_video_codec_frame_unref (frame);

  return self->downstream_flow_ret;

downstream_error:
  {
    GST_ERROR_OBJECT (self, "Downstream returned %s",
        gst_flow_get_name (self->downstream_flow_ret));
    if (minfo.data)
      gst_buffer_unmap (frame->input_buffer, &minfo);
    gst_video_codec_frame_unref (frame);
    return self->downstream_flow_ret;
  }
failed_to_get_input_buffer:
  {
    GST_ELEMENT_ERROR_FROM_ERROR (self, err);
    if (minfo.data)
      gst_buffer_unmap (frame->input_buffer, &minfo);
    gst_video_codec_frame_unref (frame);
    return GST_FLOW_ERROR;
  }
got_null_input_buffer:
  {
    GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
        ("Got no input buffer"));
    if (minfo.data)
      gst_buffer_unmap (frame->input_buffer, &minfo);
    gst_video_codec_frame_unref (frame);
    return GST_FLOW_ERROR;
  }
dequeue_error:
  {
    GST_ELEMENT_ERROR_FROM_ERROR (self, err);
    if (minfo.data)
      gst_buffer_unmap (frame->input_buffer, &minfo);
    gst_video_codec_frame_unref (frame);
    return GST_FLOW_ERROR;
  }
queue_error:
  {
    GST_VIDEO_DECODER_ERROR_FROM_ERROR (self, err);
    if (minfo.data)
      gst_buffer_unmap (frame->input_buffer, &minfo);
    gst_video_codec_frame_unref (frame);
    return GST_FLOW_ERROR;
  }
flushing:
  {
    GST_DEBUG_OBJECT (self, "Flushing -- returning FLUSHING");
    if (minfo.data)
      gst_buffer_unmap (frame->input_buffer, &minfo);
    gst_video_codec_frame_unref (frame);
    return GST_FLOW_FLUSHING;
  }
}

static GstFlowReturn
gst_amc_video_dec_finish (GstVideoDecoder * decoder)
{
  GstAmcVideoDec *self;

  self = GST_AMC_VIDEO_DEC (decoder);

  return gst_amc_video_dec_drain (self);
}

static GstFlowReturn
gst_amc_video_dec_drain (GstAmcVideoDec * self)
{
  GstFlowReturn ret;
  gint idx;
  GError *err = NULL;

  GST_DEBUG_OBJECT (self, "Draining codec");
  if (!self->started) {
    GST_DEBUG_OBJECT (self, "Codec not started yet");
    return GST_FLOW_OK;
  }

  /* Don't send drain buffer twice, this doesn't work */
  if (self->drained) {
    GST_DEBUG_OBJECT (self, "Codec is drained already");
    return GST_FLOW_OK;
  }

  /* Make sure to release the base class stream lock, otherwise
   * _loop() can't call _finish_frame() and we might block forever
   * because no input buffers are released */
  GST_VIDEO_DECODER_STREAM_UNLOCK (self);
  /* Send an EOS buffer to the component and let the base
   * class drop the EOS event. We will send it later when
   * the EOS buffer arrives on the output port.
   * Wait at most 0.5s here. */
  idx = gst_amc_codec_dequeue_input_buffer (self->codec, 500000, &err);
  GST_VIDEO_DECODER_STREAM_LOCK (self);

  if (idx >= 0) {
    GstAmcBuffer *buf;
    GstAmcBufferInfo buffer_info;

    buf = gst_amc_codec_get_input_buffer (self->codec, idx, &err);
    if (buf) {
      GST_VIDEO_DECODER_STREAM_UNLOCK (self);
      g_mutex_lock (&self->drain_lock);
      self->draining = TRUE;

      memset (&buffer_info, 0, sizeof (buffer_info));
      buffer_info.size = 0;
      buffer_info.presentation_time_us =
          gst_util_uint64_scale (self->last_upstream_ts, 1, GST_USECOND);
      buffer_info.flags |= BUFFER_FLAG_END_OF_STREAM;

      gst_amc_buffer_set_position_and_limit (buf, NULL, 0, 0);
      gst_amc_buffer_free (buf);
      buf = NULL;

      if (gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info,
              &err)) {
        GST_DEBUG_OBJECT (self, "Waiting until codec is drained");
        g_cond_wait (&self->drain_cond, &self->drain_lock);
        GST_DEBUG_OBJECT (self, "Drained codec");
        ret = GST_FLOW_OK;
      } else {
        GST_ERROR_OBJECT (self, "Failed to queue input buffer");
        if (self->flushing) {
          g_clear_error (&err);
          ret = GST_FLOW_FLUSHING;
        } else {
          GST_ELEMENT_WARNING_FROM_ERROR (self, err);
          ret = GST_FLOW_ERROR;
        }
      }

      self->drained = TRUE;
      self->draining = FALSE;
      g_mutex_unlock (&self->drain_lock);
      GST_VIDEO_DECODER_STREAM_LOCK (self);
    } else {
      GST_ERROR_OBJECT (self, "Failed to get buffer for EOS: %d", idx);
      if (err)
        GST_ELEMENT_WARNING_FROM_ERROR (self, err);
      ret = GST_FLOW_ERROR;
    }
  } else {
    GST_ERROR_OBJECT (self, "Failed to acquire buffer for EOS: %d", idx);
    if (err)
      GST_ELEMENT_WARNING_FROM_ERROR (self, err);
    ret = GST_FLOW_ERROR;
  }

  return ret;
}

static gboolean
gst_amc_video_dec_src_query (GstVideoDecoder * bdec, GstQuery * query)
{
  GstAmcVideoDec *self = GST_AMC_VIDEO_DEC (bdec);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_CONTEXT:
    {
      if (gst_gl_handle_context_query ((GstElement *) self, query,
              self->gl_display, self->gl_context, self->other_gl_context))
        return TRUE;
      break;
    }
    default:
      break;
  }

  return GST_VIDEO_DECODER_CLASS (parent_class)->src_query (bdec, query);
}

static gboolean
_caps_are_rgba_with_gl_memory (GstCaps * caps)
{
  GstVideoInfo info;
  GstCapsFeatures *features;

  if (!caps)
    return FALSE;

  if (!gst_video_info_from_caps (&info, caps))
    return FALSE;

  if (info.finfo->format != GST_VIDEO_FORMAT_RGBA)
    return FALSE;

  if (!(features = gst_caps_get_features (caps, 0)))
    return FALSE;

  return gst_caps_features_contains (features,
      GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
}

static gboolean
_find_local_gl_context (GstAmcVideoDec * self)
{
  if (gst_gl_query_local_gl_context (GST_ELEMENT (self), GST_PAD_SRC,
          &self->gl_context))
    return TRUE;
  return FALSE;
}

static gboolean
gst_amc_video_dec_decide_allocation (GstVideoDecoder * bdec, GstQuery * query)
{
  GstAmcVideoDec *self = GST_AMC_VIDEO_DEC (bdec);
  gboolean need_pool = FALSE;
  GstCaps *caps = NULL;
//  GError *error = NULL;

  if (!GST_VIDEO_DECODER_CLASS (parent_class)->decide_allocation (bdec, query))
    return FALSE;

  self->downstream_supports_gl = FALSE;
  gst_query_parse_allocation (query, &caps, &need_pool);
  if (_caps_are_rgba_with_gl_memory (caps)) {

    if (!gst_gl_ensure_element_data (self, &self->gl_display,
            &self->other_gl_context))
      return FALSE;

    if (!_find_local_gl_context (self))
      goto out;
#if 0
    if (!self->gl_context) {
      GST_OBJECT_LOCK (self->gl_display);
      do {
        if (self->gl_context) {
          gst_object_unref (self->gl_context);
          self->gl_context = NULL;
        }
        /* just get a GL context.  we don't care */
        self->gl_context =
            gst_gl_display_get_gl_context_for_thread (self->gl_display, NULL);
        if (!self->gl_context) {
          if (!gst_gl_display_create_context (self->gl_display,
                  self->other_gl_context, &self->gl_context, &error)) {
            GST_OBJECT_UNLOCK (mix->display);
            goto context_error;
          }
        }
      } while (!gst_gl_display_add_context (self->gl_display,
              self->gl_context));
      GST_OBJECT_UNLOCK (self->gl_display);
    }
#endif

    self->downstream_supports_gl = TRUE;
  }

out:
  return gst_amc_video_dec_check_codec_config (self);
#if 0
context_error:
  {
    GST_ELEMENT_ERROR (self, RESOURCE, NOT_FOUND, ("%s", error->message),
        (NULL));
    g_clear_error (&error);
    return FALSE;
  }
#endif
}

static void
gst_amc_video_dec_on_frame_available (JNIEnv * env, jobject thiz,
    long long context, jobject surfaceTexture)
{
  GstAmcVideoDec *self = JLONG_TO_GST_AMC_VIDEO_DEC (context);

  /* apparently we can be called after the decoder has been closed */
  if (!self)
    return;

  g_mutex_lock (&self->gl_lock);
  self->gl_ready_frame_count++;
  GST_LOG_OBJECT (self, "frame %u available", self->gl_ready_frame_count);
  g_cond_broadcast (&self->gl_cond);
  g_mutex_unlock (&self->gl_lock);
}
