AVDecoder.cpp 2.8 KB
#include "AVDecoder.h"


CAVDecoder::CAVDecoder() :
_a_start_time_ms(INT64_MAX),
_v_start_time_ms(INT64_MAX),
_cur_a_ts_ms(INT64_MAX),
_cur_v_ts_ms(INT64_MAX),
_end_time_ms(0),
_cur_a_frame(NULL),
_cur_v_frame(NULL),
_media_role(mr_student)
{
}


CAVDecoder::~CAVDecoder()
{
}

int CAVDecoder::add(media_info &info)
{
	_media_role = info.m_role;
	_uid = info.uid;
	if (info.m_type == mt_audio) {
		_a_start_time_ms = info.start_time_ms;
		_a_end_time_ms = info.end_time_ms;
		_audio_info.push_back(info);
		_audio_decoder.add(info);
	}
	else {
		_v_start_time_ms = info.start_time_ms;
		_v_end_time_ms = info.end_time_ms;
		_video_info.push_back(info);
		_video_decoder.add(info);
	}

	if (_cur_a_ts_ms == INT64_MAX) {
		_cur_a_ts_ms = info.start_time_ms;
		_cur_v_ts_ms = info.start_time_ms;
	}

	if (_end_time_ms < info.end_time_ms) {
		_end_time_ms = info.end_time_ms;
	}
	
	av_log(NULL, AV_LOG_INFO, "CAVDecoder add info:%lf, %"PRIu64", %"PRIu64"\n", _cur_a_ts_ms, _cur_v_ts_ms, _end_time_ms);

	return 0;
}

unsigned int CAVDecoder::getuid()
{
	return _uid;
}

bool CAVDecoder::get_one_v_frame()
{
	int64_t ts;
	int ret = -1;
	if (_video_info.size()) {
		ret = _video_decoder.get_one_frame(&_cur_v_frame, ts);
		if (ret == 0) {
			//_cur_v_ts_ms = _v_start_time_ms + ts;
			_cur_v_ts_ms  += VFRAME_DURATION_MS;
		}
		else {
			_video_info.pop_front();
			if (_cur_v_ts_ms < _end_time_ms) {
				_cur_v_ts_ms += VFRAME_DURATION_MS;//return last v frame
				ret = 0;
			}
		}
	}

	if (ret) {//no video decoded
		if (_cur_v_ts_ms < _end_time_ms) {//should have as video frame
			_cur_v_ts_ms += VFRAME_DURATION_MS;//return last v frame
			ret = 0;
			if (!_cur_v_frame) {
				_cur_v_frame = get_blank_frame();
			}
    	}
	}

	return ret == 0;
}

AVFrame * CAVDecoder::get_blank_frame()
{
	return NULL;
}

AVFrame * CAVDecoder::get_silence_frame()
{
	return NULL;
}



void CAVDecoder::free_cur_a_frame()
{
	if (_cur_a_frame) {
		av_frame_free(&_cur_a_frame);
	}
}


void CAVDecoder::free_cur_v_frame()
{
	if (_cur_v_frame) {
		av_frame_free(&_cur_v_frame);
	}
}

bool CAVDecoder::get_one_a_frame()
{
	int64_t ts;
	int ret = -1;
	if (_audio_info.size()) {
		ret = _audio_decoder.get_one_frame(&_cur_a_frame, ts);
		if (ret == 0) {
			_cur_a_ts_ms += AFRAME_DURATION_MS;
		}
		else {
			_audio_info.pop_front();
			if (_cur_a_ts_ms < _end_time_ms) {
				_cur_a_ts_ms += AFRAME_DURATION_MS;//return silence frame
				ret = 0;
			}
		}
	}

	if (ret) {//no video decoded
		if (_cur_a_ts_ms < _end_time_ms) {//should have a audio frame
			_cur_a_ts_ms += AFRAME_DURATION_MS;//return last a frame
			ret = 0;
			if (!_cur_a_frame) {
				_cur_a_frame = get_silence_frame();
			}
		}
	}

	return ret == 0;
}