16
16
// along with this program; if not, write to the Free Software
17
17
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
// $Id: VideoDecoderGst.cpp,v 1.15.2.2 2008/02/27 20:55:02 bjacques Exp $
21
20
#ifdef HAVE_CONFIG_H
22
21
#include "gnashconfig.h"
25
24
#include "VideoDecoderGst.h"
26
#include "gstappsink.h"
27
#include "gstappsrc.h"
25
#include "MediaParserGst.h"
33
// gstappsrc -> decodebin -> (decoder) -> ffmpegcolorspace -> gstappsink (with rgb caps)
35
31
// TODO: implement proper seeking.
33
VideoDecoderGst::VideoDecoderGst(GstCaps* caps)
35
// init GStreamer. TODO: what about doing this in MediaHandlerGst ctor?
36
gst_init (NULL, NULL);
37
42
VideoDecoderGst::VideoDecoderGst(videoCodecType codec_type, int width, int height)
41
gst_init (NULL, NULL);
43
_pipeline = gst_pipeline_new (NULL);
44
// init GStreamer. TODO: what about doing this in MediaHandlerGst ctor?
45
gst_init (NULL, NULL);
45
_appsrc = gst_element_factory_make ("appsrc", NULL);
47
GstElement* decoder = NULL;
50
48
switch (codec_type) {
51
49
case VIDEO_CODEC_H263:
52
decoder = gst_element_factory_make ("ffdec_flv", NULL);
53
50
caps = gst_caps_new_simple ("video/x-flash-video",
54
"width", G_TYPE_INT, width,
55
"height", G_TYPE_INT, height,
58
53
case VIDEO_CODEC_VP6:
54
caps = gst_caps_new_simple ("video/x-vp6-flash",
59
57
case VIDEO_CODEC_VP6A:
60
decoder = gst_element_factory_make ("ffdec_vp6f", NULL);
61
caps = gst_caps_new_simple ("video/x-vp6-flash",
62
"width", G_TYPE_INT, width,
63
"height", G_TYPE_INT, height,
58
caps = gst_caps_new_simple ("video/x-vp6-alpha",
66
61
case VIDEO_CODEC_SCREENVIDEO:
67
62
case VIDEO_CODEC_SCREENVIDEO2:
68
decoder = gst_element_factory_make ("ffdec_flashsv", NULL);
69
63
caps = gst_caps_new_simple ("video/x-flash-screen",
70
"width", G_TYPE_INT, width,
71
"height", G_TYPE_INT, height,
75
log_debug("Video codec is zero. Streaming video expected later.");
76
gst_object_unref (GST_OBJECT (_pipeline));
67
throw MediaException(_("Video codec is zero. Streaming video expected later."));
80
log_error("No support for this video codec. %d", codec_type);
81
gst_object_unref (GST_OBJECT (_pipeline));
70
boost::format msg = boost::format(_("No support for video codec %d.")) % (int)codec_type;
71
throw MediaException(msg.str());
87
log_error(_("failed to initialize the video decoder. Embedded video "
88
"playback will not be available; consider installing "
89
"gstreamer-ffmpeg."));
90
gst_object_unref (GST_OBJECT (_pipeline));
95
gst_app_src_set_caps (GST_APP_SRC(_appsrc), caps);
98
_colorspace = gst_element_factory_make ("ffmpegcolorspace", NULL);
100
_appsink = gst_element_factory_make ("appsink", NULL);
103
caps = gst_caps_new_simple ("video/x-raw-rgb", NULL);
105
gst_app_sink_set_caps(GST_APP_SINK(_appsink), caps);
107
gst_caps_unref (caps);
110
gst_bin_add_many (GST_BIN (_pipeline), _appsrc, decoder, _colorspace, _appsink, NULL);
112
gst_element_link_many(_appsrc, decoder, _colorspace, _appsink, NULL);
114
gst_base_src_set_live(GST_BASE_SRC(_appsrc), TRUE);
116
gst_element_set_state (GST_ELEMENT (_pipeline), GST_STATE_PLAYING);
119
81
VideoDecoderGst::~VideoDecoderGst()
122
gst_element_set_state (GST_ELEMENT (_pipeline), GST_STATE_NULL);
123
gst_object_unref (GST_OBJECT (_pipeline));
83
swfdec_gst_decoder_push_eos(&_decoder);
84
swfdec_gst_decoder_finish(&_decoder);
88
VideoDecoderGst::setup(GstCaps* srccaps)
91
throw MediaException(_("VideoDecoderGst: internal error (caps creation failed)"));
94
bool success = GstUtil::check_missing_plugins(srccaps);
96
throw MediaException(_("Couldn't find a plugin for video type ..."));
99
GstCaps* sinkcaps = gst_caps_new_simple ("video/x-raw-rgb", "bpp", G_TYPE_INT, 24,
100
"depth", G_TYPE_INT, 24,
103
throw MediaException(_("VideoDecoderGst: internal error (caps creation failed)"));
106
bool rv = swfdec_gst_decoder_init (&_decoder, srccaps, sinkcaps, "ffmpegcolorspace", NULL);
108
throw MediaException(_("VideoDecoderGst: initialisation failed."));
111
gst_caps_unref (srccaps);
112
gst_caps_unref (sinkcaps);
128
116
VideoDecoderGst::push(const EncodedVideoFrame& frame)
134
GstBuffer* buffer = gst_buffer_new();
136
GST_BUFFER_DATA(buffer) = frame.data();
137
GST_BUFFER_SIZE(buffer) = frame.dataSize();
138
GST_BUFFER_OFFSET(buffer) = frame.frameNum();
139
GST_BUFFER_TIMESTAMP(buffer) = GST_CLOCK_TIME_NONE;
140
GST_BUFFER_DURATION(buffer) = GST_CLOCK_TIME_NONE;
142
gst_app_src_push_buffer (GST_APP_SRC(_appsrc), buffer);
120
EncodedExtraGstData* extradata = dynamic_cast<EncodedExtraGstData*>(frame.extradata.get());
123
buffer = extradata->buffer;
125
buffer = gst_buffer_new();
127
GST_BUFFER_DATA(buffer) = const_cast<uint8_t*>(frame.data());
128
GST_BUFFER_SIZE(buffer) = frame.dataSize();
129
GST_BUFFER_OFFSET(buffer) = frame.frameNum();
130
GST_BUFFER_TIMESTAMP(buffer) = GST_CLOCK_TIME_NONE;
131
GST_BUFFER_DURATION(buffer) = GST_CLOCK_TIME_NONE;
134
bool success = swfdec_gst_decoder_push(&_decoder, buffer);
136
log_error(_("VideoDecoderGst: buffer push failed."));
148
std::auto_ptr<image::rgb>
141
std::auto_ptr<image::ImageBase>
149
142
VideoDecoderGst::pop()
152
return std::auto_ptr<image::rgb>();
157
GstBuffer* buffer = gst_app_sink_pull_buffer_timed (GST_APP_SINK(_appsink));
160
return std::auto_ptr<image::rgb>();
163
GstCaps* caps = gst_buffer_get_caps(buffer);
165
assert(gst_caps_get_size(caps) == 1);
167
GstStructure* structure = gst_caps_get_structure (caps, 0);
171
gst_structure_get_int (structure, "width", &width);
172
gst_structure_get_int (structure, "height", &height);
174
gst_caps_unref(caps);
176
std::auto_ptr<image::rgb> ret(new gnashGstBuffer(buffer, width, height));
144
GstBuffer * buffer = swfdec_gst_decoder_pull (&_decoder);
147
return std::auto_ptr<image::ImageBase>();
150
GstCaps* caps = gst_buffer_get_caps(buffer);
152
assert(gst_caps_get_size(caps) == 1);
154
GstStructure* structure = gst_caps_get_structure (caps, 0);
158
gst_structure_get_int (structure, "width", &width);
159
gst_structure_get_int (structure, "height", &height);
161
gst_caps_unref(caps);
163
std::auto_ptr<image::ImageBase> ret(new gnashGstBuffer(buffer, width, height));
183
170
VideoDecoderGst::peek()
189
return gst_app_sink_peek_buffer (GST_APP_SINK(_appsink));
193
VideoDecoderGst::checkMessages() // any messages for me?
199
GstBus* bus = gst_element_get_bus(_pipeline);
201
while (gst_bus_have_pending(bus)) {
202
GstMessage* msg = gst_bus_pop(bus);
205
gst_message_unref(msg);
208
gst_object_unref(GST_OBJECT(bus));
212
VideoDecoderGst::handleMessage (GstMessage *message)
215
g_print ("Got %s message\n", GST_MESSAGE_TYPE_NAME (message));
218
switch (GST_MESSAGE_TYPE (message)) {
219
case GST_MESSAGE_ERROR:
223
gst_message_parse_error (message, &err, &debug);
225
log_error(_("Embedded video playback halted; module %s reported: %s\n"),
226
gst_element_get_name(GST_MESSAGE_SRC (message)), err->message);
231
// Clear any buffers.
232
gst_element_set_state (_pipeline, GST_STATE_NULL);
236
case GST_MESSAGE_EOS:
237
log_debug(_("NetStream has reached the end of the stream."));
244
g_print("unhandled message\n");
172
return !g_queue_is_empty (_decoder.queue);