Exemple #1
0
void CCVideoThread::run_video()
{
	DPTR_D(CCVideoThread);
	
	if (!d.dec || !d.dec->is_available() || !d.writer)
		return;
	reset_state();
	Q_ASSERT(d.clock != 0);
	CCDecodeVideo *dec = static_cast<CCDecodeVideo*>(d.dec);
	CCVideoRenderer* vo = static_cast<CCVideoRenderer*>(d.writer);
	while (!d.stop) {
		if (try_pause()) { 
			if (d.stop)
				break;
		}
		std::unique_lock<std::mutex> lock(d.mutex_);
		if (d.packets.is_empty() && !d.stop) {
			d.stop = d.demux_end;
			if (d.stop) {
				break;
			}
		}
		PacketData pkt;
		d.packets.pop(pkt); 
		
		if (!pkt.is_valid()) {
			qDebug("Invalid pts or empty packet!");
			dec->flush_codec();
			continue;
		}
		d.delay = pkt.pts - d.clock->value();
		
		if (qAbs(d.delay) < 2.718) {
			if (d.delay > kSyncThreshold) { 
				av_usleep(d.delay * 1000000);
			}
			else if (d.delay < -kSyncThreshold) { 
				//continue;
			}
		}
		else { 
			qDebug("delay %f/%f", d.delay, d.clock->value());
			if (d.delay > 0) {
				av_usleep(0.064 * 1000000);
			}
			else {
				continue;
			}
		}

		d.clock->update_video_pts(pkt.pts); 

		bool vo_ok = vo && vo->is_available();
		if (vo_ok) {
			
			if (vo->last_width() > 0 && vo->last_height() > 0 && !vo->scale_in())
				dec->resize_video(vo->last_size());
			else
				vo->set_source_size(dec->width(), dec->height()); //setLastSize()
		}

		ByteArray da(pkt.date);
		if (d.dec->decode(da)) {
			d.pts = pkt.pts;
			d.decoded_datas = d.dec->data_video();
			if (vo_ok) {
				vo->write_data(d.decoded_datas);
			}
			/*d.width = dec->width();
			d.height = dec->height();
			d.decoded_datas = d.dec->data_video();

			if (vo && vo->is_available()) {
				vo->set_source_size(dec->width(), dec->height());
				vo->write_data(d.decoded_datas);
			}*/
		}

		if (vo_ok && !vo->scale_in())
			vo->set_source_size(vo->video_sizes());
	}
	qDebug("Video thread stops running...");
}