⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 demux_datasource.cpp

📁 彩信浏览器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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 <math.h>//#include <map>#include "ambulant/config/config.h"#include "ambulant/net/demux_datasource.h"#include "ambulant/net/ffmpeg_audio.h"// Minimum delay#define MIN_EVENT_DELAY 1// How many video frames we would like to buffer at most#define MAX_VIDEO_FRAMES 300// How many audio packets we would like to buffer at most// This limit is indicative: if demux_audio_datasource::buffer_full()// returns true, you are advised not to throw in more data; but if// you nevertheless do, no data is lost and a DEBUG message is printed#define MAX_AUDIO_PACKETS 300// WARNING: turning on AM_DBG globally in this file seems to trigger// a condition that makes the whole player hang or collapse. So you probably// shouldn't do it:-)//#define AM_DBG#ifndef AM_DBG#define AM_DBG if(0)#endif using namespace ambulant;using namespace net;// **************************** demux_audio_datasource ******************************demux_audio_datasource *demux_audio_datasource::new_demux_audio_datasource(  		const net::url& url, 		abstract_demux *thread){		int stream_index;		AM_DBG lib::logger::get_logger()->debug("demux_audio_datasource::new_demux_audio_datasource()");	// Find the index of the audio stream	stream_index = thread->audio_stream_nr();	assert(stream_index >= 0);		if (stream_index >= thread->nstreams()) {		lib::logger::get_logger()->error(gettext("%s: no more audio streams"), url.get_url().c_str());		return NULL;	} 	AM_DBG lib::logger::get_logger()->debug("demux_audio_datasource::new_demux_audio_datasource() looking for the right codec");		return new demux_audio_datasource(url, thread, stream_index);}demux_audio_datasource::demux_audio_datasource(const net::url& url, abstract_demux *thread, int stream_index):	m_url(url),	m_stream_index(stream_index),//	m_fmt(audio_format("ffmpeg")),	m_src_end_of_file(false),	m_event_processor(NULL),	m_thread(thread),	m_client_callback(NULL){		//AM_DBG lib::logger::get_logger()->debug("demux_audio_datasource::demux_audio_datasource: rate=%d, channels=%d", context->streams[m_stream_index]->codec.sample_rate, context->streams[m_stream_index]->codec.channels);	// XXX ignoring the codec for now but i'll have to look into this real soon	//m_fmt.parameters = (void *)&context->streams[m_stream_index]->codec;	m_thread->add_datasink(this, stream_index);}demux_audio_datasource::~demux_audio_datasource(){	AM_DBG lib::logger::get_logger()->debug("demux_audio_datasource::~demux_audio_datasource(0x%x)", (void*)this);	stop();}voiddemux_audio_datasource::stop(){	m_lock.enter();	AM_DBG lib::logger::get_logger()->debug("demux_audio_datasource::stop(0x%x)", (void*)this);	if (m_thread) {		abstract_demux *tmpthread = m_thread;		m_thread = NULL;		m_lock.leave();		tmpthread->remove_datasink(m_stream_index);		m_lock.enter();	}	m_thread = NULL;	AM_DBG lib::logger::get_logger()->debug("demux_audio_datasource::stop: thread stopped");	//if (m_con) delete m_con;	//m_con = NULL; // owned by the thread	if (m_client_callback) delete m_client_callback;	m_client_callback = NULL;	m_lock.leave();}	void demux_audio_datasource::start(ambulant::lib::event_processor *evp, ambulant::lib::event *callbackk){	m_lock.enter();	assert(m_thread);	m_thread->start();		if (m_client_callback != NULL) {		delete m_client_callback;		m_client_callback = NULL;		AM_DBG lib::logger::get_logger()->debug("demux_audio_datasource::start(): m_client_callback already set!");	}	if (m_queue.size() > 0) {		// We have data (or EOF) available. Don't bother starting up our source again, in stead		// immedeately signal our client again		if (callbackk) {			assert(evp);			AM_DBG lib::logger::get_logger()->debug("demux_audio_datasource::start: trigger client callback");			evp->add_event(callbackk, MIN_EVENT_DELAY, ambulant::lib::ep_med);		} else {			lib::logger::get_logger()->debug("Internal error: demux_audio_datasource::start(): no client callback!");			lib::logger::get_logger()->warn(gettext("Programmer error encountered during audio playback"));		}	} else {		// We have no data available. Start our source, and in our data available callback we		// will signal the client.		m_client_callback = callbackk;		m_event_processor = evp;	}	m_lock.leave();} void demux_audio_datasource::seek(timestamp_t time){	m_lock.enter();	assert(m_thread);	m_thread->seek(time);	m_lock.leave();}void demux_audio_datasource::read_ahead(timestamp_t time){	m_lock.enter();	assert(m_thread);	assert(!m_thread->is_running());		m_thread->seek(time);	m_thread->start();	m_lock.leave();}void demux_audio_datasource::data_avail(timestamp_t pts, const uint8_t *inbuf, int sz){	// XXX timestamp is ignored, for now	m_lock.enter();	m_src_end_of_file = (sz == 0);	AM_DBG lib::logger::get_logger()->debug("demux_audio_datasource.data_avail: %d bytes available (ts = %lld)", sz, pts);	void* data = malloc(sz);	assert(data);	memcpy(data, inbuf, sz);	ts_packet_t tsp(pts,data,sz);	m_queue.push(tsp);	int new_queue_size = m_queue.size();	if (m_queue.size() > MAX_AUDIO_PACKETS) {		AM_DBG lib::logger::get_logger()->debug("demux_audio_datasource.data_avail: m_queue.size()(=%d) exceeds desired maximum(=%d)", m_queue.size(), MAX_AUDIO_PACKETS);	}	m_lock.leave();}bool demux_audio_datasource::end_of_file(){	m_lock.enter();	bool rv = _end_of_file();	m_lock.leave();	return rv;}bool demux_audio_datasource::_end_of_file(){	// private method - no need to lock	return m_src_end_of_file && m_queue.empty();}bool demux_audio_datasource::buffer_full(){	m_lock.enter();	bool rv = m_queue.size() >= MAX_AUDIO_PACKETS;	m_lock.leave();	return rv;}	ts_packet_tdemux_audio_datasource::get_ts_packet_t(){	ts_packet_t tsp(0,NULL,0);	m_lock.enter();	if (m_queue.size() > 0) {		tsp = m_queue.front();		m_queue.pop();	}	m_lock.leave();	return tsp;}timestamp_tdemux_audio_datasource::get_clip_end(){		m_lock.enter();	assert(m_thread);	timestamp_t clip_end = m_thread->get_clip_end();	AM_DBG lib::logger::get_logger()->debug("demux_audio_datasource::get_clip_end: clip_end=%d", clip_end);	m_lock.leave();	return  clip_end;}timestamp_tdemux_audio_datasource::get_clip_begin(){	m_lock.enter();	assert(m_thread);	timestamp_t clip_begin = m_thread->get_clip_begin();	AM_DBG lib::logger::get_logger()->debug("demux_audio_datasource::get_clip_begin: clip_begin=%d", clip_begin);	m_lock.leave();	return  clip_begin;}audio_format&demux_audio_datasource::get_audio_format(){    assert(m_thread);	return m_thread->get_audio_format();}common::durationdemux_audio_datasource::get_dur(){	common::duration rv(false, 0.0);	m_lock.enter();	assert(m_thread);	if (m_thread->duration() >= 0) {		rv = common::duration(true, m_thread->duration());		AM_DBG lib::logger::get_logger()->debug("demux_audio_datasource::get_dur: duration=%f", rv.second);	}	m_lock.leave();	return rv;}// **************************** demux_video_datasource *****************************demux_video_datasource *demux_video_datasource::new_demux_video_datasource(  		const net::url& url, 		abstract_demux *thread){		int stream_index;		AM_DBG lib::logger::get_logger()->debug("demux_video_datasource::new_demux_video_datasource()");	// Find the index of the audio stream	stream_index = thread->video_stream_nr();	assert(stream_index >= 0);		if (stream_index >= thread->nstreams()) {		lib::logger::get_logger()->error(gettext("%s: no more audio streams"), url.get_url().c_str());		return NULL;	} 	AM_DBG lib::logger::get_logger()->debug("demux_video_datasource::new_demux_video_datasource() looking for the right codec");			return new demux_video_datasource(url, thread, stream_index);}demux_video_datasource::demux_video_datasource(const net::url& url, abstract_demux *thread, int stream_index):	m_url(url),	m_stream_index(stream_index),//	m_fmt(audio_format(0,0,0)),	m_src_end_of_file(false),	m_event_processor(NULL),	m_thread(thread),	m_client_callback(NULL),	m_audio_src(NULL),	m_frame_nr(0){	assert(m_thread);	m_thread->add_datasink(this, stream_index);	int audio_stream_idx = m_thread->audio_stream_nr();	if (audio_stream_idx >= 0) 		m_audio_src = new demux_audio_datasource(m_url, m_thread, audio_stream_idx);	AM_DBG lib::logger::get_logger()->debug("demux_video_datasource::demux_video_datasource(0x%x) m_audio_src=0x%x url=%s", (void*)this, m_audio_src, url.get_url().c_str());	}demux_video_datasource::~demux_video_datasource(){	stop();	AM_DBG lib::logger::get_logger()->debug("demux_video_datasource::~demux_video_datasource(0x%x)", (void*)this);}voiddemux_video_datasource::stop(){	m_lock.enter();	AM_DBG lib::logger::get_logger()->debug("demux_video_datasource::stop(0x%x): m_thread=0x%x, m_client_callback=0x%x, m_frames.size()=%d", (void*)this, m_thread, m_client_callback,m_frames.size());	if (m_thread) {		abstract_demux *tmpthread = m_thread;		m_thread = NULL;		m_lock.leave();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -