/* [<][>][^][v][top][bottom][index][help] */
// MediaParserGst.h: gstreamer media parsers, for Gnash
//
// Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#ifndef GNASH_MEDIAPARSER_GST_H
#define GNASH_MEDIAPARSER_GST_H
#include "MediaParser.h" // for inheritance
#include <deque>
#include <boost/scoped_array.hpp>
#include <memory>
#include <queue>
#include <gst/gst.h>
#include "ClockTime.h"
// Forward declaration
namespace gnash {
class IOChannel;
}
namespace gnash {
namespace media {
namespace gst {
/// Class to hold extra info found in any stream by the parser.
struct ExtraInfoGst : public AudioInfo::ExtraInfo, VideoInfo::ExtraInfo,
boost::noncopyable
{
ExtraInfoGst(GstCaps* gstcaps)
:
caps(gstcaps)
{
gst_caps_ref(caps);
}
~ExtraInfoGst()
{
gst_caps_unref(caps);
}
GstCaps* caps;
};
/// Class to hold GstBuffer. Takes ownership.
struct EncodedExtraGstData : public EncodedExtraData, boost::noncopyable
{
EncodedExtraGstData(GstBuffer* buf)
: buffer(buf)
{
gst_buffer_ref(buffer);
}
~EncodedExtraGstData()
{
gst_buffer_unref(buffer);
}
GstBuffer* buffer;
};
/// Simple timer used for probe timeout (deprecated)
//
/// @deprecated probe-on-construction requirement for MediaParser was drop,
/// so no use for this class anymore
///
class SimpleTimer : public boost::noncopyable
{
public:
SimpleTimer()
: _start_time(clocktime::getTicks())
{
}
bool expired() const
{
return (clocktime::getTicks() - _start_time) > 1000;
}
private:
boost::uint64_t _start_time;
};
/// Gstreamer based MediaParser
class MediaParserGst: public MediaParser
{
public:
/// Construct a Gstreamer-based media parser for given stream
//
/// Can throw a MediaException if input format couldn't be detected
///
MediaParserGst(std::auto_ptr<IOChannel> stream);
~MediaParserGst();
// See dox in MediaParser.h
bool seek(boost::uint32_t&);
// See dox in MediaParser.h
bool parseNextChunk();
// See dox in MediaParser.h
boost::uint64_t getBytesLoaded() const;
void rememberAudioFrame(EncodedAudioFrame* frame);
void rememberVideoFrame(EncodedVideoFrame* frame);
private:
bool foundAllStreams();
bool probingConditionsMet(const SimpleTimer& timer);
void link_to_fakesink(GstPad* pad);
static void cb_typefound (GstElement *typefind, guint probability,
GstCaps *caps, gpointer data);
static void cb_pad_added(GstElement* element,
GstPad* new_pad, gpointer user_data);
static void cb_no_more_pads (GstElement* element, gpointer data);
static GstFlowReturn cb_chain_func_audio (GstPad *pad, GstBuffer *buffer);
static GstFlowReturn cb_chain_func_video (GstPad *pad, GstBuffer *buffer);
bool pushGstBuffer();
bool emitEncodedFrames();
GstElement* _bin;
GstPad* _srcpad;
GstPad* _audiosink;
GstPad* _videosink;
bool _demux_probe_ended;
std::deque<EncodedAudioFrame*> _enc_audio_frames;
std::deque<EncodedVideoFrame*> _enc_video_frames;
};
} // gnash.media.gst namespace
} // gnash.media namespace
} // namespace gnash
#endif // __MEDIAPARSER_GST_H__