⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 swfdec_codec_gst.c

📁 Swfdec is a decoder/renderer for Macromedia Flash animations. The decoding and rendering engine is
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Swfdec * Copyright (C) 2007 Benjamin Otte <otte@gnome.org> * * 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 Street, Fifth Floor,  * Boston, MA  02110-1301  USA */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <string.h>#include <gst/gst.h>#include "swfdec_codec_audio.h"#include "swfdec_codec_video.h"#include "swfdec_debug.h"#include "swfdec_internal.h"#if 0#define swfdec_cond_wait(cond, mutex) G_STMT_START { \  g_print ("waiting at %s\n", G_STRLOC); \  g_cond_wait (cond, mutex); \  g_print ("   done at %s\n", G_STRLOC); \}G_STMT_END#else#define swfdec_cond_wait g_cond_wait#endif/*** AUDIO ***/typedef struct _SwfdecGstAudio SwfdecGstAudio;struct _SwfdecGstAudio {  SwfdecAudioDecoder	decoder;  GMutex *	  	mutex;		/* mutex that blocks everything below */  GCond *		cond;		/* cond used to signal when stuff below changes */  volatile int		refcount;	/* refcount (d'oh) */  GstElement *		pipeline;	/* pipeline that is playing or NULL when done */  SwfdecBuffer *	in;		/* next input buffer or NULL */  SwfdecBufferQueue *	out;		/* all the stored output buffers */  GstCaps *		srccaps;	/* caps to set on buffers */  gboolean		eof;      	/* we've pushed EOF */  gboolean		done;		/* TRUE after decoding stopped (error or EOF) */};static voidswfdec_gst_audio_unref (gpointer data, GObject *unused){  SwfdecGstAudio *player = data;  if (!g_atomic_int_dec_and_test (&player->refcount))    return;  g_cond_free (player->cond);  g_mutex_free (player->mutex);  gst_caps_unref (player->srccaps);  if (player->in)    swfdec_buffer_unref (player->in);  swfdec_buffer_queue_unref (player->out);  g_slice_free (SwfdecGstAudio, player);}static voidswfdec_audio_decoder_gst_free (SwfdecAudioDecoder *dec){  SwfdecGstAudio *player = (SwfdecGstAudio *) dec;  GstElement *pipeline;  g_mutex_lock (player->mutex);  pipeline = player->pipeline;  player->pipeline = NULL;  g_cond_signal (player->cond);  g_mutex_unlock (player->mutex);  gst_element_set_state (pipeline, GST_STATE_NULL);  g_object_unref (pipeline);  swfdec_gst_audio_unref (player, NULL);}static voidswfdec_audio_decoder_gst_push (SwfdecAudioDecoder *dec, SwfdecBuffer *buffer){  SwfdecGstAudio *player = (SwfdecGstAudio *) dec;  g_mutex_lock (player->mutex);  g_return_if_fail (!player->eof);  while (player->in != NULL && !player->done) {    swfdec_cond_wait (player->cond, player->mutex);  }  if (buffer) {    player->in = buffer;  } else {    player->eof = TRUE;  }  g_cond_signal (player->cond);  g_mutex_unlock (player->mutex);}static SwfdecBuffer *swfdec_audio_decoder_gst_pull (SwfdecAudioDecoder *dec){  SwfdecGstAudio *player = (SwfdecGstAudio *) dec;  SwfdecBuffer *buffer;  g_mutex_lock (player->mutex);  if (player->eof) {    while (!player->done)      swfdec_cond_wait (player->cond, player->mutex);  }  buffer = swfdec_buffer_queue_pull_buffer (player->out);  g_mutex_unlock (player->mutex);  return buffer;}static voidswfdec_audio_decoder_gst_fakesrc_handoff (GstElement *fakesrc, GstBuffer *buf,     GstPad *pad, SwfdecGstAudio *player){  g_mutex_lock (player->mutex);  while (player->pipeline != NULL && player->in == NULL && player->eof == FALSE)    swfdec_cond_wait (player->cond, player->mutex);  if (player->pipeline == NULL) {    g_mutex_unlock (player->mutex);    return;  }  if (player->eof) {    //doesn't work: g_object_set (fakesrc, "num-buffers", 1, NULL);    /* HACK: just tell everyone we're done, that'll probably lose data in the     * gst stream, since we can't properly push EOF, but that's life... */    player->done = TRUE;  }  if (player->in) {    buf->data = g_memdup (player->in->data, player->in->length);    buf->malloc_data = buf->data;    buf->size = player->in->length;  }  gst_buffer_set_caps (buf, player->srccaps);  player->in = NULL;  g_cond_signal (player->cond);  g_mutex_unlock (player->mutex);}static voidswfdec_audio_decoder_gst_fakesink_handoff (GstElement *fakesrc, GstBuffer *buf,     GstPad *pad, SwfdecGstAudio *player){  SwfdecBuffer *buffer;  g_mutex_lock (player->mutex);  while (player->pipeline == NULL && player->out != NULL)    swfdec_cond_wait (player->cond, player->mutex);  buffer = swfdec_buffer_new_for_data (      g_memdup (buf->data, buf->size), buf->size);  swfdec_buffer_queue_push (player->out, buffer);  g_cond_signal (player->cond);  g_mutex_unlock (player->mutex);}static voidswfdec_audio_decoder_gst_link (GstElement *src, GstPad *pad, GstElement *sink){  if (!gst_element_link (src, sink)) {    SWFDEC_ERROR ("no delayed link");  }}static GstBusSyncReplyswfdec_audio_decoder_gst_handle_bus (GstBus *bus, GstMessage *message, gpointer data){  SwfdecGstAudio *player = data;  switch (message->type) {    case GST_MESSAGE_EOS:    case GST_MESSAGE_ERROR:      g_mutex_lock (player->mutex);      g_cond_signal (player->cond);      player->done = TRUE;      g_mutex_unlock (player->mutex);      break;    default:      break;  }  return GST_BUS_PASS;}SwfdecAudioDecoder *swfdec_audio_decoder_gst_new (SwfdecAudioFormat type, gboolean width, SwfdecAudioOut format){  SwfdecGstAudio *player;  GstElement *fakesrc, *fakesink, *decoder, *convert;  GstBus *bus;  GstCaps *caps;  if (!gst_init_check (NULL, NULL, NULL))    return NULL;  switch (type) {    case SWFDEC_AUDIO_FORMAT_MP3:      caps = gst_caps_from_string ("audio/mpeg, mpegversion=(int)1, layer=(int)3");      break;    default:      return NULL;  }  g_assert (caps);  player = g_slice_new0 (SwfdecGstAudio);  player->decoder.out_format = SWFDEC_AUDIO_OUT_STEREO_44100;  player->decoder.pull = swfdec_audio_decoder_gst_pull;  player->decoder.push = swfdec_audio_decoder_gst_push;  player->decoder.free = swfdec_audio_decoder_gst_free;  player->pipeline = gst_pipeline_new ("pipeline");  player->refcount = 1;  g_assert (player->pipeline);  bus = gst_element_get_bus (player->pipeline);  g_atomic_int_inc (&player->refcount);  g_object_weak_ref (G_OBJECT (bus), swfdec_gst_audio_unref, player);  gst_bus_set_sync_handler (bus, swfdec_audio_decoder_gst_handle_bus, player);  player->mutex = g_mutex_new ();  player->cond = g_cond_new ();  player->out = swfdec_buffer_queue_new ();  player->srccaps = caps;  fakesrc = gst_element_factory_make ("fakesrc", NULL);  if (fakesrc == NULL) {    SWFDEC_ERROR ("failed to create fakesrc");    swfdec_audio_decoder_gst_free (&player->decoder);    return NULL;  }  g_object_set (fakesrc, "signal-handoffs", TRUE,       "can-activate-pull", FALSE, NULL);  g_signal_connect (fakesrc, "handoff",       G_CALLBACK (swfdec_audio_decoder_gst_fakesrc_handoff), player);  g_atomic_int_inc (&player->refcount);  g_object_weak_ref (G_OBJECT (fakesrc), swfdec_gst_audio_unref, player);  gst_bin_add (GST_BIN (player->pipeline), fakesrc);  fakesink = gst_element_factory_make ("fakesink", NULL);  if (fakesink == NULL) {    SWFDEC_ERROR ("failed to create fakesink");    swfdec_audio_decoder_gst_free (&player->decoder);    return NULL;  }  g_object_set (fakesink, "signal-handoffs", TRUE, NULL);  g_signal_connect (fakesink, "handoff",       G_CALLBACK (swfdec_audio_decoder_gst_fakesink_handoff), player);  g_atomic_int_inc (&player->refcount);  g_object_weak_ref (G_OBJECT (fakesink), swfdec_gst_audio_unref, player);  gst_bin_add (GST_BIN (player->pipeline), fakesink);  decoder = gst_element_factory_make ("decodebin", NULL);  if (decoder == NULL) {    SWFDEC_ERROR ("failed to create decoder");    swfdec_audio_decoder_gst_free (&player->decoder);    return NULL;  }  gst_bin_add (GST_BIN (player->pipeline), decoder);  convert = gst_element_factory_make ("audioconvert", NULL);  if (convert == NULL) {    SWFDEC_ERROR ("failed to create audioconvert");    swfdec_audio_decoder_gst_free (&player->decoder);    return NULL;  }  gst_bin_add (GST_BIN (player->pipeline), convert);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -