static void gst_tarkindec_chain (GstPad * pad, GstData * _data) { GstBuffer *buf = GST_BUFFER (_data); TarkinDec *tarkindec; g_return_if_fail (pad != NULL); g_return_if_fail (GST_IS_PAD (pad)); g_return_if_fail (buf != NULL); tarkindec = GST_TARKINDEC (gst_pad_get_parent (pad)); if (!tarkindec->setup) { GST_ELEMENT_ERROR (tarkindec, CORE, NEGOTATION, (NULL), ("decoder not initialized (input is not tarkin?)")); if (GST_IS_BUFFER (buf)) gst_buffer_unref (buf); else gst_pad_event_default (pad, GST_EVENT (buf)); return; } if (GST_IS_EVENT (buf)) { switch (GST_EVENT_TYPE (buf)) { case GST_EVENT_EOS: default: gst_pad_event_default (pad, GST_EVENT (buf)); break; } } else { gchar *data; gulong size; gchar *buffer; guchar *rgb; TarkinTime date; TarkinVideoLayerDesc *layer; /* data to decode */ data = GST_BUFFER_DATA (buf); size = GST_BUFFER_SIZE (buf); buffer = ogg_sync_buffer (&tarkindec->oy, size); memcpy (buffer, data, size); ogg_sync_wrote (&tarkindec->oy, size); if (ogg_sync_pageout (&tarkindec->oy, &tarkindec->og)) { ogg_stream_pagein (&tarkindec->os, &tarkindec->og); while (ogg_stream_packetout (&tarkindec->os, &tarkindec->op)) { if (tarkindec->op.e_o_s) break; if (tarkindec->nheader < 3) { /* 3 first packets to headerin */ tarkin_synthesis_headerin (&tarkindec->ti, &tarkindec->tc, &tarkindec->op); if (tarkindec->nheader == 2) { tarkin_synthesis_init (tarkindec->tarkin_stream, &tarkindec->ti); } tarkindec->nheader++; } else { tarkin_synthesis_packetin (tarkindec->tarkin_stream, &tarkindec->op); while (tarkin_synthesis_frameout (tarkindec->tarkin_stream, &rgb, 0, &date) == 0) { GstBuffer *outbuf; layer = &tarkindec->tarkin_stream->layer->desc; if (!GST_PAD_CAPS (tarkindec->srcpad)) { if (gst_pad_try_set_caps (tarkindec->srcpad, GST_CAPS_NEW ("tarkin_raw", "video/x-raw-rgb", "bpp", GST_PROPS_INT (24), "depth", GST_PROPS_INT (24), "endianness", GST_PROPS_INT (G_BYTE_ORDER), "red_mask", GST_PROPS_INT (0xff0000), "green_mask", GST_PROPS_INT (0xff00), "blue_mask", GST_PROPS_INT (0xff), "width", GST_PROPS_INT (layer->width), "height", GST_PROPS_INT (layer->height), "framerate", GST_PROPS_FLOAT (0.) /* FIXME!!! */ )) <= 0) { GST_ELEMENT_ERROR (tarkindec, CORE, NEGOTATION, (NULL), ("could not output format")); gst_buffer_unref (buf); return; } } outbuf = gst_buffer_new (); GST_BUFFER_DATA (outbuf) = rgb; GST_BUFFER_SIZE (outbuf) = layer->width * layer->height * 3; GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_DONTFREE); gst_pad_push (tarkindec->srcpad, GST_DATA (outbuf)); tarkin_synthesis_freeframe (tarkindec->tarkin_stream, rgb); } } } } gst_buffer_unref (buf); } }
/***************************************************************************** * DecodePacket: decodes a Tarkin packet. *****************************************************************************/ static picture_t *DecodePacket( decoder_t *p_dec, block_t **pp_block, ogg_packet *p_oggpacket ) { decoder_sys_t *p_sys = p_dec->p_sys; uint8_t *rgb; if( p_oggpacket->bytes ) { tarkin_synthesis_packetin( p_sys->tarkin_stream, p_oggpacket ); //block_Release( *pp_block ); /* FIXME duplicate packet */ *pp_block = NULL; } if( tarkin_synthesis_frameout( p_sys->tarkin_stream, &rgb, 0, &p_sys->tarkdate ) == 0 ) { int i_width, i_height, i_chroma, i_stride; picture_t *p_pic; msg_Err( p_dec, "Tarkin frame decoded" ); i_width = p_sys->tarkin_stream->layer->desc.width; i_height = p_sys->tarkin_stream->layer->desc.height; switch( p_sys->tarkin_stream->layer->desc.format ) { case TARKIN_RGB24: i_chroma = VLC_CODEC_RGB24; i_stride = i_width * 3; break; case TARKIN_RGB32: i_chroma = VLC_CODEC_RGB32; i_stride = i_width * 4; break; case TARKIN_RGBA: i_chroma = VLC_CODEC_RGBA; i_stride = i_width * 4; break; default: i_chroma = VLC_CODEC_I420; i_stride = i_width; break; } /* Set output properties */ p_dec->fmt_out.video.i_width = i_width; p_dec->fmt_out.video.i_height = i_height; p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR * i_width / i_height; p_dec->fmt_out.i_codec = i_chroma; /* Get a new picture */ if( (p_pic = decoder_NewPicture( p_dec )) ) { tarkin_CopyPicture( p_dec, p_pic, rgb, i_stride ); tarkin_synthesis_freeframe( p_sys->tarkin_stream, rgb ); p_pic->date = mdate() + DEFAULT_PTS_DELAY/*i_pts*/; return p_pic; } } return NULL; }