<commit_before>/*
 * Mex - a media explorer
 *
 * Copyright © 2010, 2011 Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU Lesser General Public License,
 * version 2.1, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses>
 */


#include "mex-content-tile.h"

#include "mex-download-queue.h"
#include "mex-program.h"

#include "mex-utils.h"
#include <string.h>

#include <clutter-gst/clutter-gst.h>

static void mex_content_view_iface_init (MexContentViewIface *iface);
static void mx_focusable_iface_init (MxFocusableIface *iface);

G_DEFINE_TYPE_WITH_CODE (MexContentTile, mex_content_tile, MEX_TYPE_TILE,
                         G_IMPLEMENT_INTERFACE (MEX_TYPE_CONTENT_VIEW, mex_content_view_iface_init)
                         G_IMPLEMENT_INTERFACE (MX_TYPE_FOCUSABLE, mx_focusable_iface_init))

#define CONTENT_TILE_PRIVATE(o) \
  (G_TYPE_INSTANCE_GET_PRIVATE ((o), MEX_TYPE_CONTENT_TILE, MexContentTilePrivate))

enum
{
  PROP_THUMB_WIDTH = 1,
  PROP_THUMB_HEIGHT
};

struct _MexContentTilePrivate
{
  MexContent *content;
  guint changed_id;

  MexModel *model;

  ClutterActor *image;
  ClutterActor *video_preview;

  gint thumb_height;
  gint thumb_width;

  guint start_video_preview;
  guint stop_video_preview;

  gpointer download_id;

  guint thumbnail_loaded : 1;
  guint image_set        : 1;
};

enum
{
  FOCUS_IN,
  FOCUS_OUT,

  LAST_SIGNAL
};

static gulong signals[LAST_SIGNAL] = { 0, };

static gboolean
_stop_video_preview (MexContentTile *self)
{
  MexContentTilePrivate *priv = MEX_CONTENT_TILE (self)->priv;

  if (priv->start_video_preview > 0)
    g_source_remove (priv->start_video_preview);

  /* video never started */
  if (mx_bin_get_child (MX_BIN (self)) == priv->image)
    return FALSE;

  if (!priv->video_preview)
    return FALSE;

  clutter_media_set_playing (CLUTTER_MEDIA (priv->video_preview), FALSE);
  mx_bin_set_child (MX_BIN (self), priv->image);
  /* After setting the child the old child is killed off so NULL this to
   *  help with checks
   */
  priv->video_preview = NULL;


  return FALSE;
}

static void
_stop_video_eos (ClutterMedia *media, MexContentTile *self)
{
  _stop_video_preview (self);
}

static gboolean
_start_video_preview (MexContentTile *self)
{
  MexContentTilePrivate *priv = self->priv;

  const gchar *mimetype, *uri;
  mimetype = mex_content_get_metadata (priv->content,
                                       MEX_CONTENT_METADATA_MIMETYPE);

  if ((mimetype) && strncmp (mimetype, "video/", 6) != 0)
    return FALSE;

  if (!(uri = mex_content_get_metadata (priv->content,
                                        MEX_CONTENT_METADATA_STREAM)))
    return FALSE;

  priv->video_preview = clutter_gst_video_texture_new ();

  clutter_gst_video_texture_set_idle_material (CLUTTER_GST_VIDEO_TEXTURE (priv->video_preview),
                                               NULL);
  g_signal_connect (priv->video_preview, "eos",
                    G_CALLBACK (_stop_video_eos),
                    self);

  clutter_actor_set_opacity (priv->video_preview, 0);

  g_object_ref (priv->image);
  mx_bin_set_child (MX_BIN (self), priv->video_preview);


  clutter_actor_animate (priv->video_preview, CLUTTER_LINEAR, 500,
                         "opacity", 0xff, NULL);

  clutter_actor_set_size (priv->video_preview,
                          (gfloat)priv->thumb_width,
                          (gfloat)priv->thumb_height);

  clutter_media_set_uri (CLUTTER_MEDIA (priv->video_preview), uri);
  clutter_media_set_audio_volume (CLUTTER_MEDIA (priv->video_preview), 0.0);
  clutter_media_set_playing (CLUTTER_MEDIA (priv->video_preview), TRUE);

  if (priv->stop_video_preview <= 0)
    priv->stop_video_preview =
      g_timeout_add_seconds (180, (GSourceFunc)_stop_video_preview, self);

  return FALSE;
}

static MxFocusable*
mex_content_tile_accept_focus (MxFocusable *focusable,
                               MxFocusHint  hint)
{
  MexContentTilePrivate *priv = MEX_CONTENT_TILE (focusable)->priv;

  clutter_actor_grab_key_focus (CLUTTER_ACTOR (focusable));

  priv->start_video_preview =
    g_timeout_add_seconds (1, (GSourceFunc)_start_video_preview,
                           MEX_CONTENT_TILE (focusable));

  g_signal_emit (focusable, signals[FOCUS_IN], 0);

  return focusable;
}

static MxFocusable*
mex_content_tile_move_focus (MxFocusable      *focusable,
                             MxFocusDirection  direction,<commit_msg>content-tile: Disable audio sink in video preview<commit_after>/*
 * Mex - a media explorer
 *
 * Copyright © 2010, 2011 Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU Lesser General Public License,
 * version 2.1, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses>
 */


#include "mex-content-tile.h"

#include "mex-download-queue.h"
#include "mex-program.h"

#include "mex-utils.h"
#include <string.h>

#include <clutter-gst/clutter-gst.h>

static void mex_content_view_iface_init (MexContentViewIface *iface);
static void mx_focusable_iface_init (MxFocusableIface *iface);

G_DEFINE_TYPE_WITH_CODE (MexContentTile, mex_content_tile, MEX_TYPE_TILE,
                         G_IMPLEMENT_INTERFACE (MEX_TYPE_CONTENT_VIEW, mex_content_view_iface_init)
                         G_IMPLEMENT_INTERFACE (MX_TYPE_FOCUSABLE, mx_focusable_iface_init))

#define CONTENT_TILE_PRIVATE(o) \
  (G_TYPE_INSTANCE_GET_PRIVATE ((o), MEX_TYPE_CONTENT_TILE, MexContentTilePrivate))

enum
{
  PROP_THUMB_WIDTH = 1,
  PROP_THUMB_HEIGHT
};

struct _MexContentTilePrivate
{
  MexContent *content;
  guint changed_id;

  MexModel *model;

  ClutterActor *image;
  ClutterActor *video_preview;

  gint thumb_height;
  gint thumb_width;

  guint start_video_preview;
  guint stop_video_preview;

  gpointer download_id;

  guint thumbnail_loaded : 1;
  guint image_set        : 1;
};

enum
{
  FOCUS_IN,
  FOCUS_OUT,

  LAST_SIGNAL
};

static gulong signals[LAST_SIGNAL] = { 0, };

static gboolean
_stop_video_preview (MexContentTile *self)
{
  MexContentTilePrivate *priv = MEX_CONTENT_TILE (self)->priv;

  if (priv->start_video_preview > 0)
    g_source_remove (priv->start_video_preview);

  /* video never started */
  if (mx_bin_get_child (MX_BIN (self)) == priv->image)
    return FALSE;

  if (!priv->video_preview)
    return FALSE;

  clutter_media_set_playing (CLUTTER_MEDIA (priv->video_preview), FALSE);
  mx_bin_set_child (MX_BIN (self), priv->image);
  /* After setting the child the old child is killed off so NULL this to
   *  help with checks
   */
  priv->video_preview = NULL;


  return FALSE;
}

static void
_stop_video_eos (ClutterMedia *media, MexContentTile *self)
{
  _stop_video_preview (self);
}

static gboolean
_start_video_preview (MexContentTile *self)
{
  MexContentTilePrivate *priv = self->priv;
  GstElement *pipeline;
  gint gst_flags;

  const gchar *mimetype, *uri;
  mimetype = mex_content_get_metadata (priv->content,
                                       MEX_CONTENT_METADATA_MIMETYPE);

  if ((mimetype) && strncmp (mimetype, "video/", 6) != 0)
    return FALSE;

  if (!(uri = mex_content_get_metadata (priv->content,
                                        MEX_CONTENT_METADATA_STREAM)))
    return FALSE;

  priv->video_preview = clutter_gst_video_texture_new ();

  pipeline = clutter_gst_video_texture_get_pipeline (priv->video_preview);
  g_object_get (G_OBJECT (pipeline), "flags", &gst_flags, NULL);

  gst_flags = 1;//GST_PLAY_FLAG_VIDEO;

  g_object_set (G_OBJECT (pipeline), "flags", gst_flags, NULL);


  clutter_gst_video_texture_set_idle_material (CLUTTER_GST_VIDEO_TEXTURE (priv->video_preview),
                                               NULL);
  g_signal_connect (priv->video_preview, "eos",
                    G_CALLBACK (_stop_video_eos),
                    self);

  clutter_actor_set_opacity (priv->video_preview, 0);

  g_object_ref (priv->image);
  mx_bin_set_child (MX_BIN (self), priv->video_preview);


  clutter_actor_animate (priv->video_preview, CLUTTER_LINEAR, 500,
                         "opacity", 0xff, NULL);

  clutter_actor_set_size (priv->video_preview,
                          (gfloat)priv->thumb_width,
                          (gfloat)priv->thumb_height);

  clutter_media_set_uri (CLUTTER_MEDIA (priv->video_preview), uri);
  clutter_media_set_playing (CLUTTER_MEDIA (priv->video_preview), TRUE);

  if (priv->stop_video_preview <= 0)
    priv->stop_video_preview =
      g_timeout_add_seconds (180, (GSourceFunc)_stop_video_preview, self);

  return FALSE;
}

static MxFocusable*
mex_content_tile_accept_focus (MxFocusable *focusable,
                               MxFocusHint  hint)
{
  MexContentTilePrivate *priv = MEX_CONTENT_TILE (focusable)->priv;

  clutter_actor_grab_key_focus (CLUTTER_ACTOR (focusable));

  priv->start_video_preview =
    g_timeout_add_seconds (1, (GSourceFunc)_start_video_preview,
                           MEX_CONTENT_TILE (focusable));

  g_signal_emit (focusable, signals[FOCUS_IN], 0);

  return focusable;
}

static MxFocusable*
mex_content_tile_move_focus (MxFocusable      *focusable,
                             MxFocusDirection  direction,
{'fraction_non_alphanumeric': 0.0893854748603352, 'fraction_numerical': 0.005885873902633679, 'mean_word_length': 3.515765765765766, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 67, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4295778', 'n_tokens_mistral': 3440, 'n_tokens_neox': 3307, 'n_words': 752}