📄 datasource.cpp
字号:
// This file is part of Ambulant Player, www.ambulantplayer.org.//// Copyright (C) 2003-2007 Stichting CWI, // Kruislaan 413, 1098 SJ Amsterdam, The Netherlands.//// Ambulant Player is free software; you can redistribute it and/or modify// it under the terms of the GNU Lesser General Public License as published by// the Free Software Foundation; either version 2.1 of the License, or// (at your option) any later version.//// Ambulant Player 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 Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser General Public License// along with Ambulant Player; if not, write to the Free Software// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA#include "ambulant/common/factory.h"#include "ambulant/net/datasource.h"#include "ambulant/lib/asb.h"#include "ambulant/lib/event_processor.h"//#define AM_DBG#ifndef AM_DBG#define AM_DBG if(0)#endifusing namespace ambulant;using namespace net;// Helper class for data: urls.class mem_datasource : virtual public datasource, virtual public ambulant::lib::ref_counted_obj { public: mem_datasource(const net::url &url) { std::string str_url = url.get_path(); const char *data = str_url.c_str(); size_t datalen = strlen(data); if (datalen) { char *ptr = m_databuf.get_write_ptr((int)datalen); memcpy(ptr, data, datalen); m_databuf.pushdata((int)datalen); } } ~mem_datasource() {}; void start(ambulant::lib::event_processor *evp, ambulant::lib::event *callback) { evp->add_event(callback, 0, ambulant::lib::ep_med); }; void readdone(int len) { m_databuf.readdone(len); }; void stop() {}; bool end_of_file() { return m_databuf.size() == 0; }; char* get_read_ptr() { return m_databuf.get_read_ptr(); }; int size() const { return m_databuf.size(); } ; private: databuffer m_databuf;};// *********************** filter_datasource base classtypedef lib::no_arg_callback<filter_datasource_impl> data_avail_callback;filter_datasource_impl::filter_datasource_impl(datasource *src): m_src(src), m_callback(NULL){ m_src->add_ref();}filter_datasource_impl::~filter_datasource_impl(){ stop();};size_tfilter_datasource_impl::_process(char *data, size_t size){ char *optr = m_databuf.get_write_ptr(size); memcpy(optr, data, size); m_databuf.pushdata(size); return size;}voidfilter_datasource_impl::data_avail(){ m_lock.enter(); if (!m_src) { m_lock.leave(); return; } // Convert data, if we have space if (!m_databuf.buffer_full()) { size_t sz = m_src->size(); char *ptr = m_src->get_read_ptr(); size_t bytes_done = _process(ptr, sz); m_src->readdone(bytes_done); } // Restart input, if we have space if (!m_src->end_of_file() && m_event_processor && !m_databuf.buffer_full()) { // Restart input lib::event *ev = new data_avail_callback(this, &filter_datasource_impl::data_avail); m_src->start(m_event_processor, ev); } // If we have data, notify client if (m_event_processor && m_callback && (m_databuf.buffer_not_empty() || !m_src->end_of_file())) { m_event_processor->add_event(m_callback, 0, ambulant::lib::ep_med); m_callback = NULL; } m_lock.leave();} voidfilter_datasource_impl::start(ambulant::lib::event_processor *evp, ambulant::lib::event *callback){ m_lock.enter(); assert(m_callback == NULL); // If we have data for the client we immedeately tell it so. if (m_databuf.buffer_not_empty() || !m_src || m_src->end_of_file()) evp->add_event(callback, 0, ambulant::lib::ep_med); else { m_callback = callback; m_event_processor = evp; } // Restart input, if possible if (m_src && !m_src->end_of_file() && !m_databuf.buffer_full()) { lib::event *ev = new data_avail_callback(this, &filter_datasource_impl::data_avail); m_src->start(evp, ev); } m_lock.leave();}voidfilter_datasource_impl::stop(){ m_lock.enter(); if (m_src) { m_src->stop(); m_src->release(); } m_src = NULL; delete m_callback; m_lock.leave();}boolfilter_datasource_impl::end_of_file(){ m_lock.enter(); bool rv = !m_databuf.buffer_not_empty() && m_src->end_of_file(); m_lock.leave(); return rv;}char*filter_datasource_impl::get_read_ptr(){ m_lock.enter(); char *rv = m_databuf.get_read_ptr(); m_lock.leave(); return rv;}intfilter_datasource_impl::size() const{ const_cast <filter_datasource_impl*>(this)->m_lock.enter(); int rv = m_databuf.size(); const_cast <filter_datasource_impl*>(this)->m_lock.leave(); return rv;} voidfilter_datasource_impl::readdone(int len){ m_lock.enter(); m_databuf.readdone(len); if (!m_src->end_of_file() && m_event_processor && !m_databuf.buffer_full()) { // Restart input lib::event *ev = new data_avail_callback(this, &filter_datasource_impl::data_avail); m_src->start(m_event_processor, ev); } m_lock.leave();}// *********************** audio_format_choices ***********************************************audio_format_choices::audio_format_choices(): m_best(audio_format("unknown")){ add_named_format("unknown");}audio_format_choices::audio_format_choices(const audio_format &fmt): m_best(fmt){ add_samplerate(fmt.samplerate); add_channels(fmt.channels); add_bits(fmt.bits);}audio_format_choices::audio_format_choices(int samplerate, int channels, int bits): m_best(audio_format(samplerate, channels, bits)){ add_samplerate(samplerate); add_channels(channels); add_bits(bits);};audio_format_choices::audio_format_choices(const std::string &name): m_best(audio_format(name)){ add_named_format(name);}const audio_format& audio_format_choices::best() const{ return m_best;}voidaudio_format_choices::add_samplerate(int samplerate){ m_samplerate.insert(samplerate);}voidaudio_format_choices::add_channels(int channels){ m_channels.insert(channels);}voidaudio_format_choices::add_bits(int bits){ m_bits.insert(bits);}voidaudio_format_choices::add_named_format(const std::string &name){ m_named_formats.insert(name);}bool audio_format_choices::contains(const audio_format& fmt) const{ if (fmt.name != "") return m_named_formats.count(fmt.name) != 0; else return ( m_samplerate.count(fmt.samplerate) && m_channels.count(fmt.channels) && m_bits.count(fmt.bits));}// *********************** datasource_factory *********************************************** datasource_factory::~datasource_factory(){ std::vector<raw_datasource_factory*>::iterator i; for (i=m_raw_factories.begin(); i!=m_raw_factories.end(); i++) delete (*i); std::vector<audio_datasource_factory*>::iterator i2; for (i2=m_audio_factories.begin(); i2!=m_audio_factories.end(); i2++) delete (*i2); std::vector<audio_parser_finder*>::iterator i3; for (i3=m_audio_parser_finders.begin(); i3!=m_audio_parser_finders.end(); i3++) delete (*i3); std::vector<audio_filter_finder*>::iterator i4; for (i4=m_audio_filter_finders.begin(); i4!=m_audio_filter_finders.end(); i4++) delete (*i4); std::vector<video_datasource_factory*>::iterator i5; for (i5=m_video_factories.begin(); i5!=m_video_factories.end(); i5++) delete (*i5);}voiddatasource_factory::add_raw_factory(raw_datasource_factory *df){ AM_DBG lib::logger::get_logger()->debug("datasource_factory: add_raw_factory(0x%x)", (void*)df); m_raw_factories.push_back(df);}voiddatasource_factory::add_audio_factory(audio_datasource_factory *df)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -