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

📄 swfdec_flv_decoder.c

📁 Swfdec is a decoder/renderer for Macromedia Flash animations. The decoding and rendering engine is
💻 C
📖 第 1 页 / 共 2 页
字号:
  tag.timestamp = timestamp;  tag.buffer = swfdec_bits_get_buffer (bits, -1);  if (tag.buffer == NULL) {    SWFDEC_WARNING ("no buffer, ignoring");    return;  }  if (flv->data->len == 0) {    g_array_append_val (flv->data, tag);  } else if (g_array_index (flv->data, SwfdecFlvDataTag, 	flv->data->len - 1).timestamp < tag.timestamp) {    g_array_append_val (flv->data, tag);  } else {    guint idx;    SWFDEC_WARNING ("timestamps of data buffers not increasing (last was %u, now %u)",	g_array_index (flv->data, SwfdecFlvDataTag, flv->data->len - 1).timestamp, 	tag.timestamp);    idx = swfdec_flv_decoder_find_data (flv, tag.timestamp);    g_array_insert_val (flv->data, idx, tag);  }}static SwfdecStatusswfdec_flv_decoder_parse_tag (SwfdecFlvDecoder *flv){  SwfdecDecoder *dec = SWFDEC_DECODER (flv);  SwfdecBuffer *buffer;  SwfdecBits bits;  guint size, type, timestamp;  SwfdecStatus ret = SWFDEC_STATUS_OK;  buffer = swfdec_buffer_queue_peek (dec->queue, 4);  if (buffer == NULL)    return SWFDEC_STATUS_NEEDBITS;  swfdec_bits_init (&bits, buffer);  swfdec_bits_get_u8 (&bits);  size = swfdec_bits_get_bu24 (&bits);  swfdec_buffer_unref (buffer);  buffer = swfdec_buffer_queue_pull (dec->queue, 11 + size);  if (buffer == NULL)    return SWFDEC_STATUS_NEEDBITS;  swfdec_bits_init (&bits, buffer);  type = swfdec_bits_get_u8 (&bits);  /* I think I'm paranoid and complicated. I think I'm paranoid, manipulated */  if (size != swfdec_bits_get_bu24 (&bits)) {    g_assert_not_reached ();  }  timestamp = swfdec_bits_get_bu24 (&bits);  swfdec_bits_get_bu32 (&bits);  SWFDEC_LOG ("new tag");  SWFDEC_LOG ("  type %u", type);  SWFDEC_LOG ("  size %u", size);  SWFDEC_LOG ("  timestamp %u", timestamp);  switch (type) {    case 8:      swfdec_flv_decoder_parse_audio_tag (flv, &bits, timestamp);      break;    case 9:      ret = swfdec_flv_decoder_parse_video_tag (flv, &bits, timestamp);      break;    case 18:      swfdec_flv_decoder_parse_data_tag (flv, &bits, timestamp);      break;    default:      SWFDEC_WARNING ("unknown tag (type %u)", type);      break;  }  swfdec_buffer_unref (buffer);  flv->state = SWFDEC_STATE_LAST_TAG;  return ret;}static SwfdecStatusswfdec_flv_decoder_parse (SwfdecDecoder *dec){  SwfdecFlvDecoder *flv = SWFDEC_FLV_DECODER (dec);  SwfdecStatus ret;  switch (flv->state) {    case SWFDEC_STATE_HEADER:      ret = swfdec_flv_decoder_parse_header (flv);      break;    case SWFDEC_STATE_LAST_TAG:      ret = swfdec_flv_decoder_parse_last_tag (flv);      break;    case SWFDEC_STATE_TAG:      ret = swfdec_flv_decoder_parse_tag (flv);      break;    case SWFDEC_STATE_EOF:      ret = SWFDEC_STATUS_EOF;      break;    default:      g_assert_not_reached ();      ret = SWFDEC_STATUS_ERROR;      break;  }  return ret;}static voidswfdec_flv_decoder_class_init (SwfdecFlvDecoderClass *class){  GObjectClass *object_class = G_OBJECT_CLASS (class);  SwfdecDecoderClass *decoder_class = SWFDEC_DECODER_CLASS (class);  object_class->dispose = swfdec_flv_decoder_dispose;  decoder_class->parse = swfdec_flv_decoder_parse;}static voidswfdec_flv_decoder_init (SwfdecFlvDecoder *flv){  flv->state = SWFDEC_STATE_HEADER;}SwfdecBuffer *swfdec_flv_decoder_get_video (SwfdecFlvDecoder *flv, guint timestamp,    gboolean keyframe, SwfdecVideoFormat *format, guint *real_timestamp, guint *next_timestamp){  guint id, offset;  SwfdecFlvVideoTag *tag;  g_return_val_if_fail (SWFDEC_IS_FLV_DECODER (flv), NULL);  g_return_val_if_fail (flv->video != NULL, NULL);  if (flv->video->len == 0) {    if (next_timestamp)      *next_timestamp = 0;    if (real_timestamp)      *real_timestamp = 0;    if (format)      *format = SWFDEC_VIDEO_FORMAT_UNDEFINED;    return NULL;  }  offset = g_array_index (flv->video, SwfdecFlvVideoTag, 0).timestamp;  timestamp += offset;  id = swfdec_flv_decoder_find_video (flv, timestamp);  tag = &g_array_index (flv->video, SwfdecFlvVideoTag, id);  if (keyframe) {    while (id > 0 && tag->frame_type != 1) {      id--;      tag--;    }  }  if (next_timestamp) {    if (id + 1 >= flv->video->len)      *next_timestamp = 0;    else      *next_timestamp = g_array_index (flv->video, SwfdecFlvVideoTag, id + 1).timestamp - offset;  }  if (real_timestamp)    *real_timestamp = tag->timestamp - offset;  if (format)    *format = tag->format;  return tag->buffer;}gbooleanswfdec_flv_decoder_get_video_info (SwfdecFlvDecoder *flv,    guint *first_timestamp, guint *last_timestamp){  g_return_val_if_fail (SWFDEC_IS_FLV_DECODER (flv), FALSE);  if (flv->video == NULL)    return FALSE;  if (flv->video->len == 0) {    if (first_timestamp)      *first_timestamp = 0;    if (last_timestamp)      *last_timestamp = 0;    return TRUE;  }  if (first_timestamp)    *first_timestamp = g_array_index (flv->video, SwfdecFlvVideoTag, 0).timestamp;  if (last_timestamp)    *last_timestamp = g_array_index (flv->video, SwfdecFlvVideoTag, flv->video->len - 1).timestamp;  return TRUE;}SwfdecBuffer *swfdec_flv_decoder_get_audio (SwfdecFlvDecoder *flv, guint timestamp,    SwfdecAudioFormat *codec_format, gboolean *width, SwfdecAudioOut *format,    guint *real_timestamp, guint *next_timestamp){  guint id, offset;  SwfdecFlvAudioTag *tag;  g_return_val_if_fail (SWFDEC_IS_FLV_DECODER (flv), NULL);  g_return_val_if_fail (flv->audio != NULL, NULL);  if (flv->audio->len == 0) {    if (next_timestamp)      *next_timestamp = 0;    if (real_timestamp)      *real_timestamp = 0;    if (codec_format)      *codec_format = SWFDEC_AUDIO_FORMAT_UNDEFINED;    if (width)      *width = TRUE;    if (format)      *format = SWFDEC_AUDIO_OUT_STEREO_44100;    return NULL;  }  offset = g_array_index (flv->audio, SwfdecFlvAudioTag, 0).timestamp;  timestamp += offset;  id = swfdec_flv_decoder_find_audio (flv, timestamp);  if (next_timestamp) {    if (id + 1 >= flv->audio->len)      *next_timestamp = 0;    else      *next_timestamp = g_array_index (flv->audio, SwfdecFlvAudioTag, id + 1).timestamp - offset;  }  tag = &g_array_index (flv->audio, SwfdecFlvAudioTag, id);  if (real_timestamp)    *real_timestamp = tag->timestamp - offset;  if (codec_format)    *codec_format = tag->format;  if (width)    *width = tag->width;  if (format)    *format = tag->original_format;  return tag->buffer;}/** * swfdec_flv_decoder_get_data: * @flv: a #SwfdecFlvDecoder * @timestamp: timestamp to look for * @real_timestamp: the timestamp of the returned buffer, if any * * Finds the next data event with a timestamp of at least @timestamp. If one  * exists, it is returned, and its real timestamp put into @real_timestamp.  * Otherwise, %NULL is returned. * * Returns: a #SwfdecBuffer containing the next data or NULL if none **/SwfdecBuffer *swfdec_flv_decoder_get_data (SwfdecFlvDecoder *flv, guint timestamp, guint *real_timestamp){  guint id;  SwfdecFlvDataTag *tag;  g_return_val_if_fail (SWFDEC_IS_FLV_DECODER (flv), NULL);    if (flv->data == NULL ||      flv->data->len == 0)    return NULL;  id = swfdec_flv_decoder_find_data (flv, timestamp);  tag = &g_array_index (flv->data, SwfdecFlvDataTag, id);  while (tag->timestamp < timestamp) {    id++;    if (id >= flv->data->len)      return NULL;    tag++;  }  if (real_timestamp)    *real_timestamp = tag->timestamp;  return tag->buffer;}/*** HACK ***//* This is a hack to allow native FLV playback IN SwfdecPlayer */#include "swfdec_loadertarget.h"#include "swfdec_net_stream.h"#include "swfdec_sprite.h"#include "swfdec_video_movie.h"#if 0static voidnotify_initialized (SwfdecPlayer *player, GParamSpec *pspec, SwfdecVideoMovie *movie){  movie->video->width = player->width;  movie->video->height = player->height;  swfdec_movie_queue_update (SWFDEC_MOVIE (movie), SWFDEC_MOVIE_INVALID_MATRIX);  swfdec_movie_invalidate (SWFDEC_MOVIE (movie));}#endifgbooleanswfdec_flv_decoder_is_eof (SwfdecFlvDecoder *flv){  g_return_val_if_fail (SWFDEC_IS_FLV_DECODER (flv), TRUE);  return flv->state == SWFDEC_STATE_EOF;}voidswfdec_flv_decoder_eof (SwfdecFlvDecoder *flv){  g_return_if_fail (SWFDEC_IS_FLV_DECODER (flv));  flv->state = SWFDEC_STATE_EOF;}SwfdecMovie *swfdec_flv_decoder_add_movie (SwfdecFlvDecoder *flv, SwfdecMovie *parent){  //g_assert_not_reached ();  return NULL;#if 0  SwfdecContent *content = swfdec_content_new (0);  SwfdecMovie *movie;  SwfdecVideo *video;  SwfdecConnection *conn;  SwfdecNetStream *stream;  /* set up the video movie */  video = g_object_new (SWFDEC_TYPE_VIDEO, NULL);  video->width = G_MAXUINT;  video->height = G_MAXUINT;  content->graphic = SWFDEC_GRAPHIC (video);  content->free = TRUE;  movie = swfdec_movie_new (parent, content);  g_object_weak_ref (G_OBJECT (movie), (GWeakNotify) g_object_unref, video);  g_signal_connect (SWFDEC_ROOT_MOVIE (parent)->player, "notify::initialized",      G_CALLBACK (notify_initialized), movie);  /* set up the playback stream */  conn = swfdec_connection_new (SWFDEC_ROOT_MOVIE (parent)->player->jscx);  stream = swfdec_net_stream_new (SWFDEC_ROOT_MOVIE (parent)->player, conn);  swfdec_net_stream_set_loader (stream, SWFDEC_ROOT_MOVIE (parent)->loader);  stream->flvdecoder = flv;  swfdec_video_movie_set_input (SWFDEC_VIDEO_MOVIE (movie), &stream->input);  swfdec_net_stream_set_playing (stream, TRUE);  g_object_unref (conn);  g_object_unref (stream);  return movie;#endif}

⌨️ 快捷键说明

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