AudioDecoderSpeex::AudioDecoderSpeex() : _speex_dec_state(speex_decoder_init(&speex_wb_mode)) { if (!_speex_dec_state) { throw MediaException(_("AudioDecoderSpeex: state initialization failed.")); } speex_bits_init(&_speex_bits); speex_decoder_ctl(_speex_dec_state, SPEEX_GET_FRAME_SIZE, &_speex_framesize); #ifdef RESAMPLING_SPEEX int err = 0; _resampler = speex_resampler_init(1, 16000, 44100, SPEEX_RESAMPLER_QUALITY_DEFAULT, &err); if (err != RESAMPLER_ERR_SUCCESS) { throw MediaException(_("AudioDecoderSpeex: initialization failed.")); } spx_uint32_t num = 0, den = 0; speex_resampler_get_ratio (_resampler, &num, &den); assert(num && den); boost::rational<boost::uint32_t> numsamples(den, num); numsamples *= _speex_framesize * 2 /* convert to stereo */; _target_frame_size = boost::rational_cast<boost::uint32_t>(numsamples); #endif }
void MediaParserGst::link_to_fakesink(GstPad* pad) { GstElement* fakesink = gst_element_factory_make("fakesink", NULL); if (!fakesink) { throw MediaException(_("MediaParserGst Failed to create fakesink.")); } gboolean success = gst_bin_add(GST_BIN(_bin), fakesink); if (!success) { gst_object_unref(fakesink); throw MediaException(_("MediaParserGst Failed to create fakesink.")); } GstPad* sinkpad = gst_element_get_static_pad (fakesink, "sink"); if (!sinkpad) { gst_object_unref(fakesink); throw MediaException(_("MediaParserGst: couldn't get the fakesink " "src element.")); } GstPadLinkReturn ret = gst_pad_link(pad, sinkpad); if (!GST_PAD_LINK_SUCCESSFUL(ret)) { gst_object_unref(fakesink); gst_object_unref(sinkpad); throw MediaException(_("MediaParserGst: couln't link fakesink")); } if (!gst_element_set_state (_bin, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS) { throw GnashException(_("MediaParserGst could not change element state")); } }
// static void MediaParserGst::cb_typefound(GstElement* typefind, guint /*probability*/, GstCaps* caps, gpointer data) { print_caps(caps); MediaParserGst* parser = static_cast<MediaParserGst*>(data); GstElementFactory* demuxfactory = swfdec_gst_get_demuxer_factory(caps); if (!demuxfactory) { GstPad* srcpad = gst_element_get_static_pad(typefind, "src"); if (!srcpad) { throw MediaException(_("MediaParserGst: couldn't get the typefind " "src element.")); } cb_pad_added(typefind, srcpad, parser); gst_object_unref(GST_OBJECT(srcpad)); parser->_demux_probe_ended = true; return; } // We have a factory, so create the demuxer. GstElement* demuxer = gst_element_factory_create(demuxfactory, "demuxer"); gst_object_unref(GST_OBJECT(demuxfactory)); if (!demuxer) { throw MediaException(_("MediaParserGst: couldn't create the " "demuxer")); } gboolean success = gst_bin_add(GST_BIN(parser->_bin), demuxer); if (!success) { log_error(_("MediaParserGst: failed adding demuxer to bin.")); } success = gst_element_link(typefind, demuxer); if (!success) { throw MediaException(_("MediaParserGst: failed adding demuxer " "to bin.")); } g_signal_connect(demuxer, "pad-added", G_CALLBACK(MediaParserGst::cb_pad_added), parser); g_signal_connect(demuxer, "no-more-pads", G_CALLBACK(MediaParserGst::cb_no_more_pads), parser); if (!gst_element_set_state(parser->_bin, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS) { throw GnashException(_("MediaParserGst could not change " "element state")); } }
VideoDecoderGst::VideoDecoderGst(videoCodecType codec_type, int /*width*/, int /*height*/, const boost::uint8_t* extradata, size_t extradatasize) { // init GStreamer. TODO: what about doing this in MediaHandlerGst ctor? gst_init (NULL, NULL); GstCaps* caps; switch (codec_type) { case VIDEO_CODEC_H264: { caps = gst_caps_new_simple ("video/x-h264", NULL); if (extradata && extradatasize) { GstBuffer* buf = gst_buffer_new_and_alloc(extradatasize); memcpy(GST_BUFFER_DATA(buf), extradata, extradatasize); gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL); } break; } case VIDEO_CODEC_H263: caps = gst_caps_new_simple ("video/x-flash-video", NULL); break; case VIDEO_CODEC_VP6: caps = gst_caps_new_simple ("video/x-vp6-flash", NULL); break; case VIDEO_CODEC_VP6A: caps = gst_caps_new_simple ("video/x-vp6-alpha", NULL); break; case VIDEO_CODEC_SCREENVIDEO: case VIDEO_CODEC_SCREENVIDEO2: caps = gst_caps_new_simple ("video/x-flash-screen", NULL); break; case 0: throw MediaException(_("Video codec is zero. Streaming video expected later.")); break; default: boost::format msg = boost::format(_("No support for video codec %s.")) % codec_type; throw MediaException(msg.str()); return; } setup(caps); }
std::auto_ptr<AudioDecoder> MediaHandlerGst::createAudioDecoder(const AudioInfo& info) { std::auto_ptr<AudioDecoder> ret; #ifdef DECODING_SPEEX if (info.codec == AUDIO_CODEC_SPEEX) { assert(info.type == CODEC_TYPE_FLASH); ret.reset(new AudioDecoderSpeex); } else #endif { try { ret.reset(new AudioDecoderGst(info)); } catch (const MediaException& ex) { if (info.type != CODEC_TYPE_FLASH) throw; try { ret = createFlashAudioDecoder(info); } catch (const MediaException& ex2) { boost::format err = boost::format( _("MediaHandlerGst::createAudioDecoder: %s " "-- %s")) % ex.what() % ex2.what(); throw MediaException(err.str()); } } } return ret; }
std::auto_ptr<AudioDecoder> MediaHandlerFfmpeg::createAudioDecoder(const AudioInfo& info) { std::auto_ptr<AudioDecoder> ret; try { ret.reset(new AudioDecoderFfmpeg(info)); } catch (const MediaException& ex) { if (info.type != CODEC_TYPE_FLASH) throw; try { ret = createFlashAudioDecoder(info); } catch (const MediaException& ex2) { boost::format err = boost::format( _("MediaHandlerFfmpeg::createAudioDecoder: %s " "-- %s")) % ex.what() % ex2.what(); throw MediaException(err.str()); } } return ret; }
std::auto_ptr<AudioDecoder> MediaHandler::createFlashAudioDecoder(const AudioInfo& info) { assert ( info.type == FLASH ); audioCodecType codec = static_cast<audioCodecType>(info.codec); switch (codec) { case media::AUDIO_CODEC_ADPCM: case media::AUDIO_CODEC_RAW: { std::auto_ptr<AudioDecoder> ret(new AudioDecoderSimple(info)); return ret; } #ifdef DECODING_SPEEX case AUDIO_CODEC_SPEEX: { std::auto_ptr<AudioDecoder> ret(new AudioDecoderSpeex); return ret; } #endif default: { boost::format err = boost::format( _("MediaHandler::createFlashAudioDecoder:" " no available FLASH decoders for codec %d (%s)")) % (int)codec % codec; throw MediaException(err.str()); } } }
VideoConverterFfmpeg::VideoConverterFfmpeg(ImgBuf::Type4CC srcFormat, ImgBuf::Type4CC dstFormat) : VideoConverter(srcFormat, dstFormat) { if(fourcc_to_ffmpeg(_dst_fmt) == PIX_FMT_NONE) { throw MediaException(_("VideoConverterFfmpeg cannot convert to the " "requested format")); } }
void VideoDecoderGst::setup(GstCaps* srccaps) { if (!srccaps) { throw MediaException(_("VideoDecoderGst: internal error " "(caps creation failed)")); } bool success = GstUtil::check_missing_plugins(srccaps); if (!success) { GstStructure* sct = gst_caps_get_structure(srccaps, 0); std::string type(gst_structure_get_name(sct)); std::string msg = (boost::format(_("Couldn't find a plugin for " "video type %s!")) % type).str(); if (type == "video/x-flash-video" || type == "video/x-h264") { msg += _(" Please make sure you have gstreamer-ffmpeg installed."); } gst_caps_unref(srccaps); throw MediaException(msg); } GstCaps* sinkcaps = gst_caps_new_simple("video/x-raw-rgb", "bpp", G_TYPE_INT, 24, "depth", G_TYPE_INT, 24, NULL); if (!sinkcaps) { throw MediaException(_("VideoDecoderGst: internal error " "(caps creation failed)")); } bool rv = swfdec_gst_decoder_init (&_decoder, srccaps, sinkcaps, "ffmpegcolorspace", NULL); if (!rv) { throw MediaException(_("VideoDecoderGst: initialisation failed.")); } gst_caps_unref (srccaps); gst_caps_unref (sinkcaps); }
void AudioDecoderGst::setup(GstCaps* srccaps) { if (!srccaps) { throw MediaException(_("AudioDecoderGst: internal error (caps creation failed)")); } bool success = GstUtil::check_missing_plugins(srccaps); if (!success) { GstStructure* sct = gst_caps_get_structure(srccaps, 0); std::string type(gst_structure_get_name(sct)); std::string msg = (boost::format(_("Couldn't find a plugin for " "audio type %s!")) % type).str(); gst_caps_unref(srccaps); throw MediaException(msg); } GstCaps* sinkcaps = gst_caps_from_string ("audio/x-raw-int, " "endianness=byte_order, signed=(boolean)true, width=16, " "depth=16, rate=44100, channels=2"); if (!sinkcaps) { throw MediaException(_("AudioDecoderGst: internal error " "(caps creation failed)")); } std::string resampler = findResampler(); success = swfdec_gst_decoder_init (&_decoder, srccaps, sinkcaps, "audioconvert", resampler.c_str(), NULL); if (!success) { GstStructure* sct = gst_caps_get_structure(srccaps, 0); std::string type(gst_structure_get_name(sct)); std::string msg = (boost::format( _("AudioDecoderGst: initialisation failed for audio type %s!")) % type).str(); throw MediaException(msg); } gst_caps_unref (srccaps); gst_caps_unref (sinkcaps); }
FLVParser::FLVParser(std::auto_ptr<IOChannel> lt) : MediaParser(lt), _lastParsedPosition(0), _nextPosToIndex(0), _nextAudioFrame(0), _nextVideoFrame(0), _audio(false), _video(false), _cuePoints(), _indexingCompleted(false) { if (!parseHeader()) { throw MediaException("FLVParser couldn't parse header from input"); } startParserThread(); }
AudioDecoderGst::AudioDecoderGst(const AudioInfo& info) { // init GStreamer. TODO: what about doing this in MediaHandlerGst ctor? gst_init (NULL, NULL); GstCaps* srccaps=0; if (info.type == CODEC_TYPE_FLASH && info.codec == AUDIO_CODEC_MP3) { srccaps = gst_caps_new_simple ("audio/mpeg", "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 3, "rate", G_TYPE_INT, info.sampleRate, "channels", G_TYPE_INT, info.stereo ? 2 : 1, NULL); setup(srccaps); return; } if (info.type == CODEC_TYPE_FLASH && info.codec == AUDIO_CODEC_NELLYMOSER) { srccaps = gst_caps_new_simple ("audio/x-nellymoser", "rate", G_TYPE_INT, info.sampleRate, "channels", G_TYPE_INT, info.stereo ? 2 : 1, NULL); setup(srccaps); return; } if (info.type == CODEC_TYPE_FLASH && info.codec == AUDIO_CODEC_ADPCM) { srccaps = gst_caps_new_simple ("audio/x-adpcm", "rate", G_TYPE_INT, info.sampleRate, "channels", G_TYPE_INT, info.stereo ? 2 : 1, "layout", G_TYPE_STRING, "swf", NULL); setup(srccaps); return; } if (info.type == CODEC_TYPE_FLASH && info.codec == AUDIO_CODEC_AAC) { srccaps = gst_caps_new_simple ("audio/mpeg", "mpegversion", G_TYPE_INT, 4, "rate", G_TYPE_INT, 44100, "channels", G_TYPE_INT, 2, NULL); ExtraAudioInfoFlv* extra = dynamic_cast<ExtraAudioInfoFlv*>(info.extra.get()); if (extra) { GstBuffer* buf = gst_buffer_new_and_alloc(extra->size); memcpy(GST_BUFFER_DATA(buf), extra->data.get(), extra->size); gst_caps_set_simple (srccaps, "codec_data", GST_TYPE_BUFFER, buf, NULL); } else { log_error(_("Creating AAC decoder without extra data. This will probably fail!")); } setup(srccaps); return; } if (info.type == CODEC_TYPE_FLASH) { boost::format err = boost::format( _("AudioDecoderGst: cannot handle codec %d (%s)")) % info.codec % (audioCodecType)info.codec; throw MediaException(err.str()); } ExtraInfoGst* extraaudioinfo = dynamic_cast<ExtraInfoGst*>(info.extra.get()); if (!extraaudioinfo) { boost::format err = boost::format( _("AudioDecoderGst: cannot handle codec %d " "(no ExtraInfoGst attached)")) % info.codec; throw MediaException(err.str()); } gst_caps_ref(extraaudioinfo->caps); setup(extraaudioinfo->caps); }