📄 datasource.cpp
字号:
{ AM_DBG lib::logger::get_logger()->debug("datasource_factory: add_audio_factory(0x%x)", (void*)df); m_audio_factories.push_back(df);}voiddatasource_factory::add_audio_parser_finder(audio_parser_finder *df){ AM_DBG lib::logger::get_logger()->debug("datasource_factory: add_audio_parser_finder(0x%x)", (void*)df); m_audio_parser_finders.push_back(df);}voiddatasource_factory::add_audio_decoder_finder(audio_decoder_finder *df){ AM_DBG lib::logger::get_logger()->debug("datasource_factory: add_audio_decoder_finder(0x%x)", (void*)df); m_audio_decoder_finders.push_back(df);}voiddatasource_factory::add_audio_filter_finder(audio_filter_finder *df){ AM_DBG lib::logger::get_logger()->debug("datasource_factory: add_audio_filter_finder(0x%x)", (void*)df); m_audio_filter_finders.push_back(df);}voiddatasource_factory::add_video_factory(video_datasource_factory *df){ AM_DBG lib::logger::get_logger()->debug("datasource_factory: add_video_factory(0x%x)", (void*)df); m_video_factories.push_back(df);}voiddatasource_factory::add_raw_filter(raw_filter_finder *df){ AM_DBG lib::logger::get_logger()->debug("datasource_factory: add_raw_filter(0x%x)", (void*)df); m_raw_filters.push_back(df);} datasource*datasource_factory::new_raw_datasource(const net::url &url){ std::vector<raw_datasource_factory *>::iterator i; datasource *src = NULL; for(i=m_raw_factories.begin(); i != m_raw_factories.end(); i++) { src = (*i)->new_raw_datasource(url); AM_DBG lib::logger::get_logger()->debug("0x%x->new_raw_datasource returned 0x%x", (void*)(*i), (void*)src); if (src) break; } // Check for a data: url if (src == NULL && lib::starts_with(url.get_url(), "data:")) { AM_DBG lib::logger::get_logger()->debug("new_raw_datasource: returning mem_datasource"); src = new mem_datasource(url); } if (src == NULL) { lib::logger::get_logger()->trace(gettext("%s: Cannot open, not supported by any datasource"), repr(url).c_str()); return NULL; } // Apply filters datasource *newsrc = src; do { src = newsrc; std::vector<raw_filter_finder*>::iterator fi; for(fi=m_raw_filters.begin(); fi != m_raw_filters.end(); fi++) { newsrc = (*fi)->new_raw_filter(url, src); // If we found one: exit this loop, so we try from the start for the next filter. if (newsrc != src) break; } } while (newsrc != src); return newsrc;}audio_datasource*datasource_factory::new_audio_datasource(const net::url &url, const audio_format_choices& fmts, timestamp_t clip_begin, timestamp_t clip_end){ audio_datasource *src = NULL; // First try to see if anything supports the whole chain std::vector<audio_datasource_factory *>::iterator i; for(i=m_audio_factories.begin(); i != m_audio_factories.end(); i++) { src = (*i)->new_audio_datasource(url, fmts, clip_begin, clip_end); if (src) return src; } // If that didn't work we try to first create a raw datasource, and // then stack a parser and possibly a filter datasource *rawsrc = new_raw_datasource(url); if (rawsrc == NULL) return NULL; //next create a raw_audio_datasource; audio_datasource *raw_audio_src = new raw_audio_datasource(rawsrc); std::vector<audio_parser_finder*>::iterator ip; for(ip=m_audio_parser_finders.begin(); ip != m_audio_parser_finders.end(); ip++) { src = (*ip)->new_audio_parser(url, fmts, raw_audio_src); if (src) break; } if (src == NULL) { int rem = rawsrc->release(); assert(rem == 0); lib::logger::get_logger()->warn(gettext("%s: Cannot open, no compatible parser"), repr(url).c_str()); return NULL; } // Check whether the format happens to match already. if (fmts.contains(src->get_audio_format())) return src; // Now stack a filter. Note that the first filter finder is the identity // filter. std::vector<audio_filter_finder*>::iterator ic; audio_datasource *convsrc = NULL; for(ic=m_audio_filter_finders.begin(); ic != m_audio_filter_finders.end(); ic++) { convsrc = (*ic)->new_audio_filter(src, fmts); if (convsrc) return convsrc; } // Failed to find a filter. Clean up. int rem = src->release(); // This will also release rawsrc assert(rem == 0); lib::logger::get_logger()->warn(gettext("%s: Cannot open, cannot find conversion filter"), repr(url).c_str()); return NULL;}audio_datasource*datasource_factory::new_audio_filter(const net::url& url, const audio_format_choices& fmts, audio_datasource* ds){ if (!ds) return NULL; // Check whether the format happens to match already. if (fmts.contains(ds->get_audio_format())) return ds; // Now stack a filter. Note that the first filter finder is the identity // filter. std::vector<audio_filter_finder*>::iterator ic; audio_datasource *convsrc = NULL; for(ic=m_audio_filter_finders.begin(); ic != m_audio_filter_finders.end(); ic++) { convsrc = (*ic)->new_audio_filter(ds, fmts); if (convsrc) return convsrc; } // Failed to find a filter. Clean up. lib::logger::get_logger()->warn(gettext("%s: Cannot open, cannot find conversion filter"), repr(url).c_str()); return NULL;}video_datasource*datasource_factory::new_video_datasource(const net::url &url, timestamp_t clip_begin, timestamp_t clip_end){ std::vector<video_datasource_factory *>::iterator i; video_datasource *src; for(i=m_video_factories.begin(); i != m_video_factories.end(); i++) { src = (*i)->new_video_datasource(url, clip_begin, clip_end ); AM_DBG lib::logger::get_logger()->debug("0x%x->new_video_datasource returned 0x%x", (void*)(*i), (void*)src); if (src) return src; } lib::logger::get_logger()->warn(gettext("%s: Cannot open, not supported by any video datasource"), repr(url).c_str()); return NULL;}// Helper class - Read all data from a datasourceclass datasource_reader : public lib::ref_counted_obj { public: datasource_reader(datasource *src); ~datasource_reader(); void run(); int getresult(char **result) ; private: void readdone(); lib::timer *m_timer; lib::event_processor *m_event_processor; datasource *m_src; char *m_data; int m_size; lib::critical_section m_lock;};typedef lib::no_arg_callback<datasource_reader> readdone_callback;datasource_reader::datasource_reader(datasource *src): m_timer(lib::realtime_timer_factory()), m_src(src), m_data(NULL), m_size(0){ m_event_processor = lib::event_processor_factory(m_timer);}datasource_reader::~datasource_reader(){ m_lock.enter(); m_src->release(); delete m_event_processor; delete m_timer; if (m_data) free(m_data); m_lock.leave();}voiddatasource_reader::run(){ lib::event *e = new readdone_callback(this, &datasource_reader::readdone); m_src->start(m_event_processor, e); while (!m_src->end_of_file()) {#ifdef AMBULANT_PLATFORM_WIN32 ambulant::lib::sleep_msec(10); // XXXX should be woken by readdone()#else usleep(10000);#endif//AMBULANT_PLATFORM_WIN32 }}intdatasource_reader::getresult(char **result){ m_lock.enter(); *result = m_data; m_data = NULL; int rv = m_size; m_lock.leave(); return rv;}voiddatasource_reader::readdone(){ m_lock.enter(); if (m_src->end_of_file()) { // XXX Should wake up run() m_lock.leave(); return; } int newsize = m_src->size(); if (newsize) { assert(newsize < 100000000); // TMP sanity check m_data = (char *)realloc(m_data, m_size + newsize); if (m_data == NULL) { m_size = 0; lib::logger::get_logger()->fatal(gettext("datasource_reader: out of memory")); abort(); } char* dataptr = m_src->get_read_ptr(); assert(dataptr); memcpy(m_data+m_size, dataptr, newsize); m_size += newsize; m_src->readdone(newsize); } else { lib::logger::get_logger()->debug("datasource_readed::readdone: callback, but no data available"); } lib::event *e = new readdone_callback(this, &datasource_reader::readdone); m_src->start(m_event_processor, e); m_lock.leave();}boolambulant::net::read_data_from_url(const net::url &url, datasource_factory *df, char **result, size_t *sizep){ *result = NULL; *sizep = 0; datasource *src = df->new_raw_datasource(url); if (src == NULL) { return 0; } datasource_reader *dr = new datasource_reader(src); dr->run(); int nbytes = dr->getresult(result); dr->release(); if( nbytes < 0 ) return false; *sizep = nbytes; return true;}boolambulant::net::read_data_from_datasource(datasource *src, char **result, size_t *sizep){ *result = NULL; *sizep = 0; src->add_ref(); datasource_reader *dr = new datasource_reader(src); dr->run(); int nbytes = dr->getresult(result); dr->release(); if( nbytes < 0 ) return false; *sizep = nbytes; return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -