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

📄 ffmpeg_audio.cpp

📁 彩信浏览器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		AM_DBG lib::logger::get_logger()->debug("ffmpeg_decoder_datasource::start(): calling m_src->start(0x%x, 0x%x)", m_event_processor, e);		m_src->start(evp,  e);	} else {		AM_DBG lib::logger::get_logger()->debug("ffmpeg_decoder_datasource::start(): not restarting, eof=%d, buffer_full=%d", (int)_end_of_file(), (int)m_buffer.buffer_full());	}	m_lock.leave();} void ffmpeg_decoder_datasource::readdone(int len){	m_lock.enter();	m_buffer.readdone(len);	AM_DBG lib::logger::get_logger()->debug("ffmpeg_decoder_datasource.readdone : done with %d bytes", len);/* 	if(( !(buffer_full()) && !m_src->end_of_file() )) { * 		lib::event *e = new readdone_callback(this, &ffmpeg_decoder_datasource::data_avail); * 		m_src->start(m_event_processor, e); * 	} */	m_lock.leave();}void ffmpeg_decoder_datasource::data_avail(){	m_lock.enter();		    	AM_DBG lib::logger::get_logger()->debug("ffmpeg_decoder_datasource.data_avail: called : m_src->get_read_ptr() m_src=0x%x, this=0x%x", (void*) m_src, (void*) this);			int sz;	if (m_con) {		if (m_src == NULL) {			lib::logger::get_logger()->debug("ffmpeg_decoder_datasource::data_avail(): No datasource !");			lib::logger::get_logger()->warn(gettext("Programmer error encountered during audio playback"));			return;		}			if (!m_buffer.buffer_full()) {			AM_DBG lib::logger::get_logger()->debug("ffmpeg_decoder_datasource.data_avail: m_src->get_read_ptr() m_src=0x%x, this=0x%x", (void*) m_src, (void*) this);						ts_packet_t audio_packet = m_src->get_ts_packet_t();			uint8_t *inbuf = (uint8_t*) audio_packet.data;			sz = audio_packet.size;			AM_DBG lib::logger::get_logger()->debug("ffmpeg_decoder_datasource.data_avail: %d bytes available", sz);			// Note: outsize is only written by avcodec_decode_audio, not read!			// You must always supply a buffer that is AVCODEC_MAX_AUDIO_FRAME_SIZE			// bytes big!			int outsize = AVCODEC_MAX_AUDIO_FRAME_SIZE;			uint8_t *outbuf = (uint8_t*) m_buffer.get_write_ptr(outsize);			if (outbuf) {				if(inbuf) {					// Don't feed to much data to the decoder, it doesn't like to do lists ;-)					int cursz = sz;					if (cursz > AVCODEC_MAX_AUDIO_FRAME_SIZE/2) cursz = AVCODEC_MAX_AUDIO_FRAME_SIZE/2;															AM_DBG lib::logger::get_logger()->debug("avcodec_decode_audio(0x%x, 0x%x, 0x%x(%d), 0x%x, %d)", (void*)m_con, (void*)outbuf, (void*)&outsize, outsize, (void*)inbuf, sz);					int decoded = avcodec_decode_audio(m_con, (short*) outbuf, &outsize, inbuf, cursz);					free(inbuf);					_need_fmt_uptodate();					AM_DBG lib::logger::get_logger()->debug("ffmpeg_decoder_datasource.data_avail : %d bps, %d channels",m_fmt.samplerate, m_fmt.channels);					AM_DBG lib::logger::get_logger()->debug("ffmpeg_decoder_datasource.data_avail : %d bytes decoded  to %d bytes", decoded,outsize );					assert(m_fmt.samplerate);					double duration = ((double) outsize)* sizeof(uint8_t)*8 / (m_fmt.samplerate* m_fmt.channels * m_fmt.bits);					timestamp_t old_elapsed = m_elapsed;					m_elapsed += (timestamp_t) (duration*1000000);					AM_DBG lib::logger::get_logger()->debug("ffmpeg_decoder_datasource.data_avail elapsed = %d ", m_elapsed);					// We need to do some tricks to handle clip_begin falling within this buffer.					// First we push all the data we have into the buffer, then we check whether the beginning					// should have been skipped and, if so, read out the bytes.					if (m_elapsed > m_src->get_clip_begin()) {							AM_DBG lib::logger::get_logger()->debug("ffmpeg_decoder_datasource.data_avail We passed clip_begin : (outsize = %d) ", outsize);						if (outsize > 0) {							m_buffer.pushdata(outsize);						} else {							m_buffer.pushdata(0);						}						if (old_elapsed < m_src->get_clip_begin()) {							timestamp_t delta_t_unwanted = m_src->get_clip_begin() - old_elapsed;							assert(delta_t_unwanted > 0);							int bytes_unwanted = (delta_t_unwanted * ((m_fmt.samplerate* m_fmt.channels * m_fmt.bits)/(sizeof(uint8_t)*8)))/1000000;							bytes_unwanted &= ~3;							AM_DBG lib::logger::get_logger()->debug("ffmpeg_decoder_datasource: clip_begin within buffer, dropping %lld us, %d bytes", delta_t_unwanted, bytes_unwanted);							(void)m_buffer.get_read_ptr();							assert(m_buffer.size() > bytes_unwanted);							m_buffer.readdone(bytes_unwanted);						}					} else {						AM_DBG lib::logger::get_logger()->debug("ffmpeg_decoder_datasource.data_avail: m_elapsed = %lld < clip_begin = %lld, skipped %d bytes", m_elapsed, m_src->get_clip_begin(), outsize);						m_buffer.pushdata(0);					}					AM_DBG lib::logger::get_logger()->debug("ffmpeg_decoder_datasource.data_avail : m_src->readdone(%d) called m_src=0x%x, this=0x%x", decoded,(void*) m_src, (void*) this );				} else {					m_buffer.pushdata(0);				}			} else {				lib::logger::get_logger()->debug("ffmpeg_decoder_datasource::data_avail: no room in output buffer");				lib::logger::get_logger()->warn(gettext("Programmer error encountered during audio playback"));				m_buffer.pushdata(0);				AM_DBG lib::logger::get_logger()->debug("ffmpeg_decoder_datasource::data_avail m_src->readdone(0) called this=0x%x");			}		//	sz = m_src->size();		}		// Restart reading if we still have room to accomodate more data		// XXX The note regarding m_elapsed holds here as well.		if (!m_src->end_of_file() && m_event_processor && !m_buffer.buffer_full() && !_clip_end() ) {			AM_DBG lib::logger::get_logger()->debug("ffmpeg_decoder_datasource::data_avail(): calling m_src->start() again");			lib::event *e = new readdone_callback(this, &ffmpeg_decoder_datasource::data_avail);			m_src->start(m_event_processor, e);		} else {			AM_DBG lib::logger::get_logger()->debug("ffmpeg_decoder_datasource::data_avail: not calling start: eof=%d m_ep=0x%x buffull=%d", 				(int)m_src->end_of_file(), (void*)m_event_processor, (int)m_buffer.buffer_full());		}				if ( m_client_callback && (m_buffer.buffer_not_empty() ||  _end_of_file() || _clip_end()  ) ) {			AM_DBG lib::logger::get_logger()->debug("ffmpeg_decoder_datasource::data_avail(): calling client callback (%d, %d)", m_buffer.size(), _end_of_file());			assert(m_event_processor);			if (m_elapsed >= m_src->get_clip_begin()) {				m_event_processor->add_event(m_client_callback, 0, ambulant::lib::ep_med);				m_client_callback = NULL;			}			//m_event_processor = NULL;		} else {			AM_DBG lib::logger::get_logger()->debug("ffmpeg_decoder_datasource::data_avail(): No client callback!");		}	} else {		AM_DBG lib::logger::get_logger()->debug("ffmpeg_decoder_datasource::data_avail(): No decoder, flushing available data");	}	m_lock.leave();}bool ffmpeg_decoder_datasource::end_of_file(){	m_lock.enter();	if (_clip_end()) {		m_lock.leave();		AM_DBG lib::logger::get_logger()->debug("ffmpeg_decoder_datasource::end_of_file(): clip_end reached");		return true;	}	bool rv = _end_of_file();	m_lock.leave();	return rv;}bool ffmpeg_decoder_datasource::_end_of_file(){	// private method - no need to lock		if (m_buffer.buffer_not_empty()) return false;	return m_src->end_of_file();}bool ffmpeg_decoder_datasource::_clip_end() const{	// private method - no need to lock	timestamp_t clip_end = m_src->get_clip_end();	if (clip_end == -1) return false;		AM_DBG lib::logger::get_logger()->debug("ffmpeg_decoder_datasource::_clip_end(): m_elapsed=%lld , clip_end=%lld", m_elapsed, clip_end);	if (m_elapsed > clip_end) {		return true;	}		return false;}void ffmpeg_decoder_datasource::read_ahead(timestamp_t clip_begin){		m_src->read_ahead(clip_begin);} bool ffmpeg_decoder_datasource::buffer_full(){	m_lock.enter();	bool rv = m_buffer.buffer_full();	m_lock.leave();	return rv;}	char* ffmpeg_decoder_datasource::get_read_ptr(){	m_lock.enter();	char *rv = m_buffer.get_read_ptr();	m_lock.leave();	return rv;}int ffmpeg_decoder_datasource::size() const{	const_cast <ffmpeg_decoder_datasource*>(this)->m_lock.enter();	int rv = m_buffer.size();	if (_clip_end()) {		// clip end falls within the current buffer (or maybe even before it)		timestamp_t clip_end = m_src->get_clip_end();		timestamp_t delta_t_unwanted = m_elapsed - clip_end;		assert(delta_t_unwanted >= 0);		// ((double) outsize)* sizeof(uint8_t)*8 / (m_fmt.samplerate* m_fmt.channels * m_fmt.bits);		int bytes_unwanted = (delta_t_unwanted * ((m_fmt.samplerate* m_fmt.channels * m_fmt.bits)/(sizeof(uint8_t)*8)))/1000000;		assert(bytes_unwanted >= 0);		rv -= bytes_unwanted;		rv &= ~3;		if (rv < 0) rv = 0;	}	const_cast <ffmpeg_decoder_datasource*>(this)->m_lock.leave();	return rv;}	timestamp_tffmpeg_decoder_datasource::get_clip_end(){	m_lock.enter();	timestamp_t clip_end;	clip_end =  m_src->get_clip_end();	m_lock.leave();	return clip_end;}timestamp_tffmpeg_decoder_datasource::get_clip_begin(){	m_lock.enter();	timestamp_t clip_begin;	clip_begin =  m_src->get_clip_begin();	m_lock.leave();	return clip_begin;}bool ffmpeg_decoder_datasource::_select_decoder(const char* file_ext){	// private method - no need to lock	AVCodec *codec = avcodec_find_decoder_by_name(file_ext);	if (codec == NULL) {			lib::logger::get_logger()->trace("ffmpeg_decoder_datasource._select_decoder: Failed to find codec for \"%s\"", file_ext);			lib::logger::get_logger()->error(gettext("No support for \"%s\" audio"), file_ext);			return false;	}	m_con = avcodec_alloc_context();		if(avcodec_open(m_con,codec) < 0) {			lib::logger::get_logger()->trace("ffmpeg_decoder_datasource._select_decoder: Failed to open avcodec for \"%s\"", file_ext);			lib::logger::get_logger()->error(gettext("No support for \"%s\" audio"), file_ext);			return false;	}	return true;}bool ffmpeg_decoder_datasource::_select_decoder(audio_format &fmt){	// private method - no need to lock	if (fmt.name == "ffmpeg") {		AVCodecContext *enc = (AVCodecContext *)fmt.parameters;		if (enc == NULL) {				lib::logger::get_logger()->debug("Internal error: ffmpeg_decoder_datasource._select_decoder: Parameters missing for %s(0x%x)", fmt.name.c_str(), fmt.parameters);				return false;		}		if (enc->codec_type != CODEC_TYPE_AUDIO) {				lib::logger::get_logger()->debug("Internal error: ffmpeg_decoder_datasource._select_decoder: Non-audio stream for %s(0x%x)", fmt.name.c_str(), enc->codec_type);				return false;		}		AVCodec *codec = avcodec_find_decoder(enc->codec_id);		if (codec == NULL) {				lib::logger::get_logger()->debug("Internal error: ffmpeg_decoder_datasource._select_decoder: Failed to find codec for %s(0x%x)", fmt.name.c_str(), enc->codec_id);				return false;		}		m_con = avcodec_alloc_context();				m_con->channels = 0;		if(avcodec_open(m_con,codec) < 0) {				lib::logger::get_logger()->debug("Internal error: ffmpeg_decoder_datasource._select_decoder: Failed to open avcodec for %s(0x%x)", fmt.name.c_str(), enc->codec_id);				av_free(m_con);				m_con = NULL;				return false;		}		AM_DBG lib::logger::get_logger()->debug("ffmpeg_decoder_datasource::_select_decoder: codec_name=%s, codec_id=%d", m_con->codec_name, m_con->codec_id);		m_fmt = audio_format(enc->sample_rate, enc->channels, 16);		return true;	} else if (fmt.name == "live") {		const char* codec_name = (char*) fmt.parameters;			AM_DBG lib::logger::get_logger()->debug("ffmpeg_decoder_datasource::selectdecoder(): audio codec : %s", codec_name);		ffmpeg_codec_id* codecid = ffmpeg_codec_id::instance();		AVCodec *codec = avcodec_find_decoder(codecid->get_codec_id(codec_name));				if( !codec) {			//lib::logger::get_logger()->error(gettext("%s: Audio codec %d(%s) not supported"), repr(url).c_str(), m_con->codec_id, m_con->codec_name);			return false;		} else {			AM_DBG lib::logger::get_logger()->debug("ffmpeg_decoder_datasource::selectdecoder(): codec found!");		}			m_con = avcodec_alloc_context();			m_con->channels = 0;		if((avcodec_open(m_con,codec) < 0) ) {			//lib::logger::get_logger()->error(gettext("%s: Cannot open audio codec %d(%s)"), repr(url).c_str(), m_con->codec_id, m_con->codec_name);			av_free(m_con);			m_con = NULL;			return false;		} else {			AM_DBG lib::logger::get_logger()->debug("ffmpeg_decoder_datasource::ffmpeg_decoder_datasource(): succesfully opened codec");		}				m_con->codec_type = CODEC_TYPE_AUDIO;		return true;	}	// Could add support here for raw mp3, etc.	return false;}audio_format&ffmpeg_decoder_datasource::get_audio_format(){	m_lock.enter();	_need_fmt_uptodate();	AM_DBG lib::logger::get_logger()->debug("ffmpeg_decoder_datasource::get_audio_format: rate=%d, bits=%d,channels=%d",m_fmt.samplerate, m_fmt.bits, m_fmt.channels);	m_lock.leave();	return m_fmt;}voidffmpeg_decoder_datasource::_need_fmt_uptodate(){	// Private method - no locking	if (m_fmt.samplerate == 0) {

⌨️ 快捷键说明

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