コード例 #1
0
ファイル: swfdec_test.c プロジェクト: fengye/swfdec
static SwfdecScript *
load_script (const char *filename)
{
    SwfdecBuffer *file, *buffer;
    SwfdecScript *script;
    GError *error = NULL;

    if (filename == NULL)
        filename = "default.sts";

    file = swfdec_buffer_new_from_file (filename, &error);
    if (file == NULL) {
        g_print ("ERROR: %s\n", error->message);
        g_error_free (error);
        return NULL;
    }
    if (file->length < sizeof (SWFDEC_TEST_FILE_ID) + 1 ||
            memcmp (file->data, SWFDEC_TEST_FILE_ID, sizeof (SWFDEC_TEST_FILE_ID) != 0)) {
        g_print ("ERROR: %s is not a Swfdec test script\n", filename);
        swfdec_buffer_unref (file);
        return NULL;
    }
    buffer = swfdec_buffer_new_subbuffer (file, sizeof (SWFDEC_TEST_FILE_ID),
                                          file->length - sizeof (SWFDEC_TEST_FILE_ID));
    swfdec_buffer_unref (file);
    script = swfdec_script_new (buffer, "main", SWFDEC_TEST_VERSION);
    return script;
}
コード例 #2
0
ファイル: swfdec_audio_stream.c プロジェクト: fengye/swfdec
/* returns: number of samples available */
static void
swfdec_audio_stream_require (SwfdecAudioStream *stream, guint n_samples)
{
  SwfdecAudioStreamClass *klass = SWFDEC_AUDIO_STREAM_GET_CLASS (stream);
  SwfdecBuffer *buffer;

  /* subclasses are responsible for having set a proper decoder */
  g_assert (SWFDEC_IS_AUDIO_DECODER (stream->decoder));

  while (stream->queue_size < n_samples && !stream->done) {
    /* if the decoder still has data */
    buffer = swfdec_audio_decoder_pull (stream->decoder);
    if (buffer) {
      g_queue_push_tail (stream->queue, buffer);
      stream->queue_size += buffer->length / 4;
      continue;
    }
    /* otherwise get a new buffer from the decoder */
    buffer = klass->pull (stream);
    if (buffer == NULL) {
      stream->buffering = TRUE;
      break;
    }
    swfdec_audio_decoder_push (stream->decoder, buffer);
    swfdec_buffer_unref (buffer);
  }
}
コード例 #3
0
ファイル: swfdec_audio_flv.c プロジェクト: fengye/swfdec
static gsize
swfdec_audio_flv_iterate (SwfdecAudio *audio, gsize remove)
{
  SwfdecAudioFlv *flv = SWFDEC_AUDIO_FLV (audio);
  SwfdecBuffer *buffer;
  guint next;

  flv->playback_skip += remove;
  buffer = g_queue_peek_head (flv->playback_queue);
  while (buffer && flv->playback_skip >= 
	 swfdec_sound_buffer_get_n_samples (buffer, swfdec_audio_format_new (44100, 2, TRUE))
	 + swfdec_audio_format_get_granularity (swfdec_audio_format_new (44100, 2, TRUE))) {
    buffer = g_queue_pop_head (flv->playback_queue);
    SWFDEC_LOG ("removing buffer with %u samples", 
	swfdec_sound_buffer_get_n_samples (buffer, swfdec_audio_format_new (44100, 2, TRUE))); 
    flv->playback_skip -= swfdec_sound_buffer_get_n_samples (buffer, 
	swfdec_audio_format_new (44100, 2, TRUE));
    swfdec_buffer_unref (buffer);
    buffer = g_queue_peek_head (flv->playback_queue);
  }
  flv->timestamp += SWFDEC_SAMPLES_TO_TICKS (remove);
  
  if (!g_queue_is_empty (flv->playback_queue))
    return G_MAXUINT;
  swfdec_flv_decoder_get_audio (flv->flvdecoder,
      SWFDEC_TICKS_TO_MSECS (flv->timestamp),
      NULL, NULL, NULL, &next);
  return next ? G_MAXUINT : 0;
}
コード例 #4
0
ファイル: swfdec_sprite.c プロジェクト: fengye/swfdec
static void
swfdec_sprite_dispose (GObject *object)
{
  SwfdecSprite * sprite = SWFDEC_SPRITE (object);
  guint i;

  if (sprite->frames) {
    for (i = 0; i < sprite->n_frames; i++) {
      g_slist_foreach (sprite->frames[i].labels, (GFunc) g_free, NULL);
      g_slist_free (sprite->frames[i].labels);
    }
    g_free(sprite->frames);
  }
  for (i = 0; i < sprite->actions->len; i++) {
    SwfdecSpriteAction *cur = &g_array_index (sprite->actions, SwfdecSpriteAction, i);
    if (cur->buffer)
      swfdec_buffer_unref (cur->buffer);
  }
  g_array_free (sprite->actions, TRUE);
  sprite->actions = NULL;
  if (sprite->init_action) {
    swfdec_script_unref (sprite->init_action);
    sprite->init_action = NULL;
  }

  G_OBJECT_CLASS (swfdec_sprite_parent_class)->dispose (object);
}
コード例 #5
0
ファイル: vivi_code_emitter.c プロジェクト: fengye/swfdec
SwfdecBuffer *
vivi_code_emitter_finish (ViviCodeEmitter *emitter, GError **error)
{
  SwfdecBuffer *buffer;
  GSList *walk;

  g_return_val_if_fail (VIVI_IS_CODE_EMITTER (emitter), NULL);

  buffer = swfdec_bots_close (emitter->bots);
  emitter->bots = NULL;
  for (walk = emitter->later; walk; walk = walk->next) {
    Later *later = walk->data;
    if (!later->func (emitter, buffer, later->offset, later->data, error)) {
      swfdec_buffer_unref (buffer);
      buffer = NULL;
      break;
    }
  }
  g_slist_foreach (emitter->later, (GFunc) g_free, NULL);
  g_slist_free (emitter->later);
  emitter->later = NULL;
  g_hash_table_remove_all (emitter->labels);
  emitter->bots = swfdec_bots_open ();

  return buffer;
}
コード例 #6
0
ファイル: swfdec_buffer.c プロジェクト: fengye/swfdec
/**
 * swfdec_buffer_queue_flush:
 * @queue: a #SwfdecBufferQueue
 * @n_bytes: amount of bytes to flush from the queue
 *
 * Removes the first @n_bytes bytes from the queue.
 */
void
swfdec_buffer_queue_flush (SwfdecBufferQueue *queue, gsize n_bytes)
{
  g_return_if_fail (queue != NULL);
  g_return_if_fail (n_bytes <= queue->depth);

  queue->depth -= n_bytes;
  queue->offset += n_bytes;

  SWFDEC_LOG ("flushing %zu bytes (%zu left)", n_bytes, queue->depth);

  while (n_bytes > 0) {
    SwfdecBuffer *buffer = queue->first_buffer->data;

    if (buffer->length <= n_bytes) {
      n_bytes -= buffer->length;
      queue->first_buffer = g_slist_remove (queue->first_buffer, buffer);
    } else {
      queue->first_buffer->data = swfdec_buffer_new_subbuffer (buffer, 
	  n_bytes, buffer->length - n_bytes);
      n_bytes = 0;
    }
    swfdec_buffer_unref (buffer);
  }
  if (queue->first_buffer == NULL)
    queue->last_buffer = NULL;
}
コード例 #7
0
static void
swfdec_test_swfdec_socket_send (SwfdecSocket *sock, SwfdecBuffer *buffer)
{
  SwfdecTestSwfdecSocket *test = SWFDEC_TEST_SWFDEC_SOCKET (sock);

  test->plugin.send (&test->plugin, buffer->data, buffer->length);
  swfdec_buffer_unref (buffer);
}
コード例 #8
0
ファイル: swfdec_buffer.c プロジェクト: fengye/swfdec
char *
swfdec_buffer_queue_pull_text (SwfdecBufferQueue *queue, guint version)
{
  SwfdecBuffer *buffer;
  char *text;
  guint size, i, j;

  size = swfdec_buffer_queue_get_depth (queue);
  if (size == 0) {
    SWFDEC_LOG ("empty loader, returning empty string");
    return g_strdup ("");
  }

  buffer = swfdec_buffer_queue_pull (queue, size);
  g_assert (buffer);

  if (version > 5) {
    for (i = 0; boms[i].length > 0; i++) {
      // FIXME: test what happens if we have BOM and nothing else
      if (size < boms[i].length)
	continue;

      for (j = 0; j < boms[i].length; j++) {
	if (buffer->data[j] != boms[i].data[j])
	  break;
      }
      if (j == boms[i].length)
	break;
    }

    if (!strcmp (boms[i].name, "UTF-8")) {
      if (!g_utf8_validate ((char *)buffer->data + boms[i].length,
	    size - boms[i].length, NULL)) {
	SWFDEC_ERROR ("downloaded data is not valid UTF-8");
	text = NULL;
      } else {
	text =
	  g_strndup ((char *)buffer->data + boms[i].length,
	      size - boms[i].length);
      }
    } else {
      text = g_convert ((char *)buffer->data + boms[i].length,
	  size - boms[i].length, "UTF-8", boms[i].name, NULL, NULL, NULL);
      if (text == NULL)
	SWFDEC_ERROR ("downloaded data is not valid %s", boms[i].name);
    }
  } else {
    text = g_convert ((char *)buffer->data, size, "UTF-8", "LATIN1", NULL,
	NULL, NULL);
    if (text == NULL)
      SWFDEC_ERROR ("downloaded data is not valid LATIN1");
  }

  swfdec_buffer_unref (buffer);

  return text;
}
コード例 #9
0
ファイル: gstswfdec.c プロジェクト: collects/gst-plugins-bad
static void
gst_swfdecbuffer_finalize (GstSwfdecBuffer * swfdecbuffer)
{
  g_return_if_fail (swfdecbuffer != NULL);

  GST_LOG ("finalize %p", swfdecbuffer);

  swfdec_buffer_unref (swfdecbuffer->swfdec_buffer);

  ((GstMiniObjectClass *) buffer_parent_class)->finalize ((GstMiniObject *)
      swfdecbuffer);
}
コード例 #10
0
GstBuffer *
swfdec_gst_buffer_new (SwfdecBuffer *buffer)
{
  /* FIXME: make this a zero-copy operation */
  GstBuffer *ret;

  g_return_val_if_fail (buffer != NULL , NULL);
  
  ret = gst_buffer_new_and_alloc (buffer->length);
  memcpy (GST_BUFFER_DATA (ret), buffer->data, buffer->length);
  swfdec_buffer_unref (buffer);

  return ret;
}
コード例 #11
0
static void
swfdec_xml_socket_do_write (SwfdecXmlSocket *xml)
{
  SwfdecBuffer *buffer;
  gsize written, length;

  do {
    buffer = swfdec_buffer_queue_peek_buffer (xml->send_queue);
    if (buffer == NULL)
      break;
    length = buffer->length;
    written = swfdec_socket_send (xml->socket, buffer);
    swfdec_buffer_unref (buffer);
    swfdec_buffer_queue_flush (xml->send_queue, written);
  } while (written == length);
}
コード例 #12
0
ファイル: vivi_code_emitter.c プロジェクト: fengye/swfdec
static void
vivi_code_emitter_dispose (GObject *object)
{
  ViviCodeEmitter *emit = VIVI_CODE_EMITTER (object);

  if (emit->bots) {
    SwfdecBuffer *buffer = swfdec_bots_close (emit->bots);
    swfdec_buffer_unref (buffer);
    emit->bots = NULL;
  }
  g_slist_foreach (emit->later, (GFunc) g_free, NULL);
  g_slist_free (emit->later);
  emit->later = NULL;
  g_hash_table_destroy (emit->labels);
  emit->labels = NULL;

  G_OBJECT_CLASS (vivi_code_emitter_parent_class)->dispose (object);
}
コード例 #13
0
ファイル: swfdec_buffer.c プロジェクト: fengye/swfdec
/**
 * swfdec_buffer_queue_push:
 * @queue: a #SwfdecBufferQueue
 * @buffer: #SwfdecBuffer to append to @queue
 *
 * Appends the given @buffer to the buffers already in @queue. This function
 * will take ownership of the given @buffer. Use swfdec_buffer_ref () before
 * calling this function to keep a reference.
 **/
void
swfdec_buffer_queue_push (SwfdecBufferQueue * queue, SwfdecBuffer * buffer)
{
  g_return_if_fail (queue != NULL);
  g_return_if_fail (buffer != NULL);

  if (buffer->length == 0) {
    swfdec_buffer_unref (buffer);
    return;
  }
  queue->last_buffer = g_slist_append (queue->last_buffer, buffer);
  if (queue->first_buffer == NULL) {
    queue->first_buffer = queue->last_buffer;
  } else {
    queue->last_buffer = queue->last_buffer->next;
  }
  queue->depth += buffer->length;
}
コード例 #14
0
ファイル: swfdec_load_object.c プロジェクト: fengye/swfdec
static void
swfdec_load_object_dispose (GObject *object)
{
  SwfdecLoadObject *load = SWFDEC_LOAD_OBJECT (object);

  if (load->loader) {
    swfdec_stream_set_target (SWFDEC_STREAM (load->loader), NULL);
    g_object_unref (load->loader);
    load->loader = NULL;
  }
  if (load->buffer) {
    swfdec_buffer_unref (load->buffer);
    load->buffer = NULL;
  }
  g_strfreev (load->header_names);
  g_strfreev (load->header_values);

  G_OBJECT_CLASS (swfdec_load_object_parent_class)->dispose (object);
}
コード例 #15
0
ファイル: swfdec_audio_stream.c プロジェクト: fengye/swfdec
static gboolean
swfdec_audio_stream_check_buffering (SwfdecAudioStream *stream)
{
  SwfdecAudioStreamClass *klass;
  SwfdecBuffer *buffer;

  if (!stream->buffering || stream->done)
    return FALSE;

  klass = SWFDEC_AUDIO_STREAM_GET_CLASS (stream);
  buffer = klass->pull (stream);
  if (buffer == NULL)
    return FALSE;

  swfdec_audio_decoder_push (stream->decoder, buffer);
  swfdec_buffer_unref (buffer);
  stream->buffering = FALSE;
  g_signal_emit_by_name (stream, "new-data");
  return stream->queue_size == 0;
}
コード例 #16
0
static gboolean
swfdec_xml_socket_stream_target_parse (SwfdecStreamTarget *target,
    SwfdecStream *stream)
{
  SwfdecXmlSocket *xml = SWFDEC_XML_SOCKET (target);
  SwfdecBufferQueue *queue;
  SwfdecBuffer *buffer;
  gsize len;

  /* parse until next 0 byte or take everything */
  queue = swfdec_stream_get_queue (stream);
  while ((buffer = swfdec_buffer_queue_peek_buffer (queue))) {
    guchar *nul = memchr (buffer->data, 0, buffer->length);
    
    len = nul ? (gsize) (nul - buffer->data + 1) : buffer->length;
    g_assert (len > 0);
    swfdec_buffer_unref (buffer);
    buffer = swfdec_buffer_queue_pull (queue, len);
    swfdec_buffer_queue_push (xml->queue, buffer);
    if (nul) {
      len = swfdec_buffer_queue_get_depth (xml->queue);
      g_assert (len > 0);
      buffer = swfdec_buffer_queue_pull (xml->queue, len);
      if (!g_utf8_validate ((char *) buffer->data, len, NULL)) {
	SWFDEC_FIXME ("invalid utf8 sent through socket, what now?");
      } else {
	SwfdecAsValue val;

	SWFDEC_AS_VALUE_SET_STRING (&val, swfdec_as_context_get_string (
	      swfdec_gc_object_get_context (xml), (char *) buffer->data));
	swfdec_sandbox_use (xml->sandbox);
	swfdec_as_object_call (xml->target, SWFDEC_AS_STR_onData, 1, &val, NULL);
	swfdec_sandbox_unuse (xml->sandbox);
      }
    }
  }
  return FALSE;
}
コード例 #17
0
ファイル: swfdec_audio_flv.c プロジェクト: fengye/swfdec
static SwfdecBuffer *
swfdec_audio_flv_decode_one (SwfdecAudioFlv *flv)
{
  SwfdecBuffer *buffer;
  guint format;
  SwfdecAudioFormat in;
  guint now, soon;

  if  (g_queue_is_empty (flv->playback_queue)) {
    /* sync */
    guint last;
    swfdec_flv_decoder_get_audio (flv->flvdecoder, 
	SWFDEC_TICKS_TO_MSECS (flv->timestamp),
	NULL, NULL, &last, NULL);
    flv->playback_skip = SWFDEC_TICKS_TO_SAMPLES (
	flv->timestamp - SWFDEC_MSECS_TO_TICKS (last));
    flv->next_timestamp = last;
    SWFDEC_DEBUG ("syncing to %ums: next timestamp to decode is %ums, skipping %u samples", 
	(guint) SWFDEC_TICKS_TO_MSECS (flv->timestamp), 
	flv->next_timestamp, flv->playback_skip);
  }
  if (flv->decoder)
    buffer = swfdec_audio_decoder_pull (flv->decoder);
  else
    buffer = NULL;
  while (buffer == NULL) {
    if (flv->decoder && flv->next_timestamp == 0)
      return NULL;
    buffer = swfdec_flv_decoder_get_audio (flv->flvdecoder, flv->next_timestamp,
      &format, &in, &now, &soon);

    if (flv->next_timestamp != now) {
      /* FIXME: do sync on first frame here */
      SWFDEC_WARNING ("FIXME: didn't get requested timestamp - still loading?");
    }
    /* FIXME FIXME FIXME: This avoids decoding the last frame forever, however it ensures sync */
    if (soon == 0)
      return NULL;
    flv->next_timestamp = soon;
    if (flv->in == 0) {
      /* init */
      if (flv->decoder) {
	g_object_unref (flv->decoder);
	flv->decoder = NULL;
      }
      flv->format = format;
      flv->in = in;
      flv->decoder = swfdec_audio_decoder_new (flv->format, flv->in);
      if (flv->decoder == NULL)
	return NULL;
      /* This is a hack that ensures AAC codec data is always present, even if
       * the decoder gets initialized in the middle of the stream */
      if (format == SWFDEC_AUDIO_CODEC_AAC) {
	SwfdecBuffer *tmp = swfdec_flv_decoder_get_audio (flv->flvdecoder,
	    0, &format, NULL, NULL, NULL);
	if (format == SWFDEC_AUDIO_CODEC_AAC && tmp->data[0] == 0 &&
	    tmp->length > 1) {
	  tmp = swfdec_buffer_new_subbuffer (tmp, 1, tmp->length - 1);
	  swfdec_audio_decoder_set_codec_data (flv->decoder, tmp);
	  swfdec_buffer_unref (tmp);
	}
      }
    } else if (format != flv->format ||
	in != flv->in) {
      SWFDEC_ERROR ("FIXME: format change not implemented");
      return NULL;
    } else if (flv->decoder == NULL) {
      return NULL;
    }
    if (format == SWFDEC_AUDIO_CODEC_AAC) {
      SwfdecBuffer *data;
      SwfdecBits bits;
      guint type;
      swfdec_bits_init (&bits, buffer);
      type = swfdec_bits_get_u8 (&bits);
      switch (type) {
	case 0:
	  data = swfdec_bits_get_buffer (&bits, -1);
	  if (data) {
	    swfdec_audio_decoder_set_codec_data (flv->decoder, data);
	    swfdec_buffer_unref (data);
	  }
	  break;
	case 1:
	  data = swfdec_bits_get_buffer (&bits, -1);
	  if (data) {
	    swfdec_audio_decoder_push (flv->decoder, data);
	    swfdec_buffer_unref (data);
	  } else {
	    SWFDEC_ERROR ("no data in AAC data buffer?");
	  }
	  break;
	default:
	  SWFDEC_FIXME ("handle AAC type %u", type);
	  break;
      }
    } else {
      swfdec_audio_decoder_push (flv->decoder, buffer);
    }
    if (flv->next_timestamp == 0)
      swfdec_audio_decoder_push (flv->decoder, NULL);
    buffer = swfdec_audio_decoder_pull (flv->decoder);
  }

  g_queue_push_tail (flv->playback_queue, buffer);
  return buffer;
}