static void swfdec_video_decoder_gst_decode (SwfdecVideoDecoder *dec, SwfdecBuffer *buffer) { SwfdecVideoDecoderGst *player = SWFDEC_VIDEO_DECODER_GST (dec); #define SWFDEC_ALIGN(x, n) (((x) + (n) - 1) & (~((n) - 1))) GstBuffer *buf; GstCaps *caps; GstStructure *structure; buf = swfdec_gst_buffer_new (swfdec_buffer_ref (buffer)); if (!swfdec_gst_decoder_push (&player->dec, buf)) { swfdec_video_decoder_error (dec, "failed to push buffer"); return; } buf = swfdec_gst_decoder_pull (&player->dec); if (buf == NULL) { SWFDEC_ERROR ("failed to pull decoded buffer. Broken stream?"); return; } else { if (player->last) gst_buffer_unref (player->last); player->last = buf; } while ((buf = swfdec_gst_decoder_pull (&player->dec))) { SWFDEC_ERROR ("too many output buffers!"); gst_buffer_unref (buf); } caps = gst_buffer_get_caps (player->last); if (caps == NULL) { swfdec_video_decoder_error (dec, "no caps on decoded buffer"); return; } structure = gst_caps_get_structure (caps, 0); if (!gst_structure_get_int (structure, "width", (int *) &dec->width) || !gst_structure_get_int (structure, "height", (int *) &dec->height)) { swfdec_video_decoder_error (dec, "invalid caps on decoded buffer"); return; } buf = player->last; switch (swfdec_video_codec_get_format (dec->codec)) { case SWFDEC_VIDEO_FORMAT_RGBA: dec->plane[0] = buf->data; dec->rowstride[0] = dec->width * 4; break; case SWFDEC_VIDEO_FORMAT_I420: dec->plane[0] = buf->data; dec->rowstride[0] = SWFDEC_ALIGN (dec->width, 4); dec->plane[1] = dec->plane[0] + dec->rowstride[0] * SWFDEC_ALIGN (dec->height, 2); dec->rowstride[1] = SWFDEC_ALIGN (dec->width, 8) / 2; dec->plane[2] = dec->plane[1] + dec->rowstride[1] * SWFDEC_ALIGN (dec->height, 2) / 2; dec->rowstride[2] = dec->rowstride[1]; g_assert (dec->plane[2] + dec->rowstride[2] * SWFDEC_ALIGN (dec->height, 2) / 2 == dec->plane[0] + buf->size); break; default: g_return_if_reached (); } #undef SWFDEC_ALIGN }
/* private */ boost::uint8_t* AudioDecoderGst::pullBuffers(boost::uint32_t& outputSize) { outputSize = 0; g_queue_foreach(_decoder.queue, buf_add, &outputSize); if (!outputSize) { log_debug(_("Pushed data, but there's nothing to pull (yet)")); return 0; } boost::uint8_t* rbuf = new boost::uint8_t[outputSize]; boost::uint8_t* ptr = rbuf; while (true) { GstBuffer* buffer = swfdec_gst_decoder_pull (&_decoder); if (!buffer) { break; } memcpy(ptr, GST_BUFFER_DATA(buffer), GST_BUFFER_SIZE(buffer)); ptr += GST_BUFFER_SIZE(buffer); gst_buffer_unref (buffer); } return rbuf; }
static SwfdecBuffer * swfdec_audio_decoder_gst_pull (SwfdecAudioDecoder *dec) { SwfdecAudioDecoderGst *player = SWFDEC_AUDIO_DECODER_GST (dec); GstBuffer *buf; buf = swfdec_gst_decoder_pull (&player->dec); if (buf == NULL) return NULL; return swfdec_buffer_new_from_gst (buf); }
std::auto_ptr<GnashImage> VideoDecoderGst::pop() { GstBuffer * buffer = swfdec_gst_decoder_pull (&_decoder); if (!buffer) { return std::auto_ptr<GnashImage>(); } GstCaps* caps = gst_buffer_get_caps(buffer); assert(gst_caps_get_size(caps) == 1); GstStructure* structure = gst_caps_get_structure (caps, 0); gst_structure_get_int (structure, "width", &_width); gst_structure_get_int (structure, "height", &_height); gst_caps_unref(caps); std::auto_ptr<GnashImage> ret(new gnashGstBuffer(buffer, _width, _height)); return ret; }