<commit_before>/*
 * stream.c - Source for TpStreamEngineStream
 * Copyright (C) 2006 Collabora Ltd.
 * Copyright (C) 2006 Nokia Corporation
 *
 * 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; either
 * version 2.1 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
 * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
 */

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

#include <string.h>

#include <libtelepathy/tp-conn.h>
#include <libtelepathy/tp-helpers.h>
#include <libtelepathy/tp-interfaces.h>
#include <libtelepathy/tp-media-stream-handler-gen.h>

#include <farsight/farsight-session.h>
#include <farsight/farsight-stream.h>
#include <farsight/farsight-transport.h>

#include <gst/interfaces/xoverlay.h>

#include "common/telepathy-errors.h"

#include "tp-stream-engine.h"
#include "stream.h"
#include "types.h"
#include "util.h"

G_DEFINE_TYPE (TpStreamEngineStream, tp_stream_engine_stream, G_TYPE_OBJECT);

#define DEBUG(stream, format, ...) \
  g_debug ("stream %d (%s) %s: " format, \
    stream->stream_id, \
    (stream)->media_type == FARSIGHT_MEDIA_TYPE_AUDIO ? "audio" : "video", \
    G_STRFUNC, \
    ##__VA_ARGS__)

#define STREAM_PRIVATE(o) \
  (G_TYPE_INSTANCE_GET_PRIVATE ((o), TP_STREAM_ENGINE_TYPE_STREAM, \
   TpStreamEngineStreamPrivate))

typedef struct _TpStreamEngineStreamPrivate TpStreamEngineStreamPrivate;

struct _TpStreamEngineStreamPrivate
{
  gchar *channel_path;

  DBusGProxy *stream_handler_proxy;
  TpConn *connection_proxy;

  FarsightStream *fs_stream;
  guint state_changed_handler_id;

  gboolean playing;
  FarsightStreamState state;
  FarsightStreamDirection dir;

  guint output_volume;
  gboolean output_mute;
  gboolean input_mute;
  guint output_window_id;
};

enum
{
  STREAM_CLOSED,
  STREAM_ERROR,
  SIGNAL_COUNT
};

static guint signals[SIGNAL_COUNT] = {0};

static void
add_remote_candidate (DBusGProxy *proxy, gchar *candidate,
                      GPtrArray *transports, gpointer user_data);
static void
remove_remote_candidate (DBusGProxy *proxy, gchar *candidate,
                         gpointer user_data);
static void
set_active_candidate_pair (DBusGProxy *proxy, gchar* native_candidate,
                           gchar* remote_candidate, gpointer user_data);
static void
set_remote_candidate_list (DBusGProxy *proxy, GPtrArray *candidates,
                           gpointer user_data);
static void
set_remote_codecs (DBusGProxy *proxy, GPtrArray *codecs, gpointer user_data);
static void
set_stream_playing (DBusGProxy *proxy, gboolean play, gpointer user_data);
static void
set_stream_sending (DBusGProxy *proxy, gboolean play, gpointer user_data);
static void
start_telephony_event (DBusGProxy *proxy, guchar event, gpointer user_data);
static void
stop_telephony_event (DBusGProxy *proxy, gpointer user_data);

static void
stop_stream (TpStreamEngineStream *self);

static void
_remove_video_sink (TpStreamEngineStream *stream, GstElement *sink)
{
  TpStreamEngine *engine;
  GstElement *pipeline;

  DEBUG (stream, "removing video sink");

  if (sink == NULL)
    return;

  engine = tp_stream_engine_get ();
  pipeline = tp_stream_engine_get_pipeline (engine);
  gst_element_set_state (sink, GST_STATE_NULL);

  DEBUG (stream, "sink refcount: %d", GST_OBJECT_REFCOUNT_VALUE(sink));
  gst_bin_remove (GST_BIN (pipeline), sink);
}

static void
tp_stream_engine_stream_dispose (GObject *object)
{
  TpStreamEngineStream *stream = TP_STREAM_ENGINE_STREAM (object);
  TpStreamEngineStreamPrivate *priv = STREAM_PRIVATE (stream);

  if (priv->connection_proxy)
    {
      g_object_unref (priv->connection_proxy);
      priv->connection_proxy = NULL;
    }

  if (priv->stream_handler_proxy)
    {
      DBusGProxy *tmp;

      dbus_g_proxy_disconnect_signal (priv->stream_handler_proxy,
          "AddRemoteCandidate", G_CALLBACK (add_remote_candidate), stream);

      dbus_g_proxy_disconnect_signal (priv->stream_handler_proxy,
          "RemoveRemoteCandidate", G_CALLBACK (remove_remote_candidate),
          stream);

      dbus_g_proxy_disconnect_signal (priv->stream_handler_proxy,
          "SetActiveCandidatePair",
          G_CALLBACK (set_active_candidate_pair), stream);

      dbus_g_proxy_disconnect_signal (priv->stream_handler_proxy,
          "SetRemoteCandidateList",
          G_CALLBACK (set_remote_candidate_list), stream);

      dbus_g_proxy_disconnect_signal (priv->stream_handler_proxy,
          "SetRemoteCodecs", G_CALLBACK (set_remote_codecs), stream);

      dbus_g_proxy_disconnect_signal (priv->stream_handler_proxy,
          "SetStreamPlaying", G_CALLBACK (set_stream_playing), stream);

      dbus_g_proxy_disconnect_signal (priv->stream_handler_proxy,
          "SetStreamSending", G_CALLBACK (set_stream_sending), stream);

      dbus_g_proxy_disconnect_signal (priv->stream_handler_proxy,
          "StartTelephonyEvent", G_CALLBACK (start_telephony_event), stream);

      dbus_g_proxy_disconnect_signal (priv->stream_handler_proxy,
          "StopTelephonyEvent", G_CALLBACK (stop_telephony_event), stream);

      tmp = priv->stream_handler_proxy;
      priv->stream_handler_proxy = NULL;
      g_object_unref (tmp);
    }

  if (priv->fs_stream)
    {
      stop_stream (stream);

      g_signal_handler_disconnect (priv->fs_stream,
        priv->state_changed_handler_id);
      g_object_unref (priv->fs_stream);
      priv->fs_stream = NULL;
    }

  if (priv->output_window_id)
    {
      gboolean ret;<commit_msg>Disconnect the destroy signal on dispose<commit_after>/*
 * stream.c - Source for TpStreamEngineStream
 * Copyright (C) 2006 Collabora Ltd.
 * Copyright (C) 2006 Nokia Corporation
 *
 * 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; either
 * version 2.1 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
 * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
 */

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

#include <string.h>

#include <libtelepathy/tp-conn.h>
#include <libtelepathy/tp-helpers.h>
#include <libtelepathy/tp-interfaces.h>
#include <libtelepathy/tp-media-stream-handler-gen.h>

#include <farsight/farsight-session.h>
#include <farsight/farsight-stream.h>
#include <farsight/farsight-transport.h>

#include <gst/interfaces/xoverlay.h>

#include "common/telepathy-errors.h"

#include "tp-stream-engine.h"
#include "stream.h"
#include "types.h"
#include "util.h"

G_DEFINE_TYPE (TpStreamEngineStream, tp_stream_engine_stream, G_TYPE_OBJECT);

#define DEBUG(stream, format, ...) \
  g_debug ("stream %d (%s) %s: " format, \
    stream->stream_id, \
    (stream)->media_type == FARSIGHT_MEDIA_TYPE_AUDIO ? "audio" : "video", \
    G_STRFUNC, \
    ##__VA_ARGS__)

#define STREAM_PRIVATE(o) \
  (G_TYPE_INSTANCE_GET_PRIVATE ((o), TP_STREAM_ENGINE_TYPE_STREAM, \
   TpStreamEngineStreamPrivate))

typedef struct _TpStreamEngineStreamPrivate TpStreamEngineStreamPrivate;

struct _TpStreamEngineStreamPrivate
{
  gchar *channel_path;

  DBusGProxy *stream_handler_proxy;
  TpConn *connection_proxy;

  FarsightStream *fs_stream;
  guint state_changed_handler_id;

  gboolean playing;
  FarsightStreamState state;
  FarsightStreamDirection dir;

  guint output_volume;
  gboolean output_mute;
  gboolean input_mute;
  guint output_window_id;
};

enum
{
  STREAM_CLOSED,
  STREAM_ERROR,
  SIGNAL_COUNT
};

static guint signals[SIGNAL_COUNT] = {0};

static void
add_remote_candidate (DBusGProxy *proxy, gchar *candidate,
                      GPtrArray *transports, gpointer user_data);
static void
remove_remote_candidate (DBusGProxy *proxy, gchar *candidate,
                         gpointer user_data);
static void
set_active_candidate_pair (DBusGProxy *proxy, gchar* native_candidate,
                           gchar* remote_candidate, gpointer user_data);
static void
set_remote_candidate_list (DBusGProxy *proxy, GPtrArray *candidates,
                           gpointer user_data);
static void
set_remote_codecs (DBusGProxy *proxy, GPtrArray *codecs, gpointer user_data);
static void
set_stream_playing (DBusGProxy *proxy, gboolean play, gpointer user_data);
static void
set_stream_sending (DBusGProxy *proxy, gboolean play, gpointer user_data);
static void
start_telephony_event (DBusGProxy *proxy, guchar event, gpointer user_data);
static void
stop_telephony_event (DBusGProxy *proxy, gpointer user_data);

static void
stop_stream (TpStreamEngineStream *self);

static void
destroy_cb (DBusGProxy *proxy, gpointer user_data);

static void
_remove_video_sink (TpStreamEngineStream *stream, GstElement *sink)
{
  TpStreamEngine *engine;
  GstElement *pipeline;

  DEBUG (stream, "removing video sink");

  if (sink == NULL)
    return;

  engine = tp_stream_engine_get ();
  pipeline = tp_stream_engine_get_pipeline (engine);
  gst_element_set_state (sink, GST_STATE_NULL);

  DEBUG (stream, "sink refcount: %d", GST_OBJECT_REFCOUNT_VALUE(sink));
  gst_bin_remove (GST_BIN (pipeline), sink);
}

static void
tp_stream_engine_stream_dispose (GObject *object)
{
  TpStreamEngineStream *stream = TP_STREAM_ENGINE_STREAM (object);
  TpStreamEngineStreamPrivate *priv = STREAM_PRIVATE (stream);

  if (priv->connection_proxy)
    {
      g_object_unref (priv->connection_proxy);
      priv->connection_proxy = NULL;
    }

  if (priv->stream_handler_proxy)
    {
      DBusGProxy *tmp;

      dbus_g_proxy_disconnect_signal (priv->stream_handler_proxy,
          "AddRemoteCandidate", G_CALLBACK (add_remote_candidate), stream);

      dbus_g_proxy_disconnect_signal (priv->stream_handler_proxy,
          "RemoveRemoteCandidate", G_CALLBACK (remove_remote_candidate),
          stream);

      dbus_g_proxy_disconnect_signal (priv->stream_handler_proxy,
          "SetActiveCandidatePair",
          G_CALLBACK (set_active_candidate_pair), stream);

      dbus_g_proxy_disconnect_signal (priv->stream_handler_proxy,
          "SetRemoteCandidateList",
          G_CALLBACK (set_remote_candidate_list), stream);

      dbus_g_proxy_disconnect_signal (priv->stream_handler_proxy,
          "SetRemoteCodecs", G_CALLBACK (set_remote_codecs), stream);

      dbus_g_proxy_disconnect_signal (priv->stream_handler_proxy,
          "SetStreamPlaying", G_CALLBACK (set_stream_playing), stream);

      dbus_g_proxy_disconnect_signal (priv->stream_handler_proxy,
          "SetStreamSending", G_CALLBACK (set_stream_sending), stream);

      dbus_g_proxy_disconnect_signal (priv->stream_handler_proxy,
          "StartTelephonyEvent", G_CALLBACK (start_telephony_event), stream);

      dbus_g_proxy_disconnect_signal (priv->stream_handler_proxy,
          "StopTelephonyEvent", G_CALLBACK (stop_telephony_event), stream);

      g_signal_handlers_disconnect_by_func (priv->stream_handler_proxy,
          G_CALLBACK (destroy_cb), stream);


      tmp = priv->stream_handler_proxy;
      priv->stream_handler_proxy = NULL;
      g_object_unref (tmp);
    }

  if (priv->fs_stream)
    {
      stop_stream (stream);

      g_signal_handler_disconnect (priv->fs_stream,
        priv->state_changed_handler_id);
      g_object_unref (priv->fs_stream);
      priv->fs_stream = NULL;
    }

  if (priv->output_window_id)
    {
      gboolean ret;
{'fraction_non_alphanumeric': 0.08863040629095675, 'fraction_numerical': 0.0036041939711664484, 'mean_word_length': 4.378414096916299, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 68, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1399553', 'n_tokens_mistral': 4039, 'n_tokens_neox': 3910, 'n_words': 920}