bool VideoTheoraPlayer::update() {
    _currentTime = _freezeGame ? _gameRef->getLiveTimer()->getTime() : _gameRef->getTimer()->getTime();

    if (!isPlaying()) {
        return STATUS_OK;
    }

    if (_playbackStarted /*&& m_Sound && !m_Sound->IsPlaying()*/) {
        return STATUS_OK;
    }

    if (_playbackStarted && !_freezeGame && _gameRef->_state == GAME_FROZEN) {
        return STATUS_OK;
    }

    if (_theoraDecoder) {
        if (_theoraDecoder->endOfVideo() && _looping) {
            warning("Should loop movie %s, hacked for now", _filename.c_str());
            _theoraDecoder->rewind();
            //HACK: Just reinitialize the same video again:
            return resetStream();
        } else if (_theoraDecoder->endOfVideo() && !_looping) {
            debugC(kWintermuteDebugLog, "Finished movie %s", _filename.c_str());
            _state = THEORA_STATE_FINISHED;
            _playbackStarted = false;
            if (_freezeGame) {
                _gameRef->unfreeze();
            }
        }
        if (_state == THEORA_STATE_PLAYING) {
            if (!_theoraDecoder->endOfVideo() && _theoraDecoder->getTimeToNextFrame() == 0) {
                const Graphics::Surface *decodedFrame = _theoraDecoder->decodeNextFrame();
                if (decodedFrame) {
                    _surface.free();
                    _surface.copyFrom(*decodedFrame);
                    if (_texture) {
                        writeVideo();
                    }
                }
            }
            return STATUS_OK;
        }
    }
    // Skip the busy-loop?
    if ((!_texture || !_videoFrameReady) && _theoraDecoder && !_theoraDecoder->endOfVideo()) {
        // end playback
        if (!_looping) {
            _state = THEORA_STATE_FINISHED;
            if (_freezeGame) {
                _gameRef->unfreeze();
            }
            return STATUS_OK;
        } else {
            resetStream();
            return STATUS_OK;
        }
    }

    return STATUS_OK;
}
예제 #2
0
LogStream& Logger::operator() (size_t level)
{
	if(willBeLogged(level))
		return resetStreamLevel(level);
	resetStream(NULL);
	return getDeafstream();
}
예제 #3
0
Receiver::Receiver(Rsa *r) : rsa(r)
{
#ifdef REN_DEBUG
	qWarning("Receiver::Receiver(Rsa *r) : rsa(r)");
#endif
	setName("Receiver");

	working = false;
	received = false;

	if ((inputBuffer = (char *)malloc(IN_BUFSIZE))==NULL)
		throw Error(Error::IHU_ERR_MEMORY);
	if ((streamBuffer = (char *)malloc(MAXBUFSIZE))==NULL)
		throw Error(Error::IHU_ERR_MEMORY);

	s = -1;
	notifier = NULL;
	calen = sizeof(ca);

	blowfish = NULL;
	outFile = NULL;

	checkTimer = new QTimer(this);

	reset();
	resetStream();

	// renyang-modify - 初始化primaddr
	primaddr = "";
	// renyang-modify - end

	connect(checkTimer, SIGNAL(timeout()), this, SLOT(checkConnection()));
}
예제 #4
0
Logger::~Logger()
{
	resetStream(NULL);
	if (getLogfile().is_open()) {
		getLogfile().flush();
		getLogfile().close();
	}
	loglevel.reset();
}
예제 #5
0
파일: dtsc.cpp 프로젝트: FihlaTV/mistserver
/// Adds a single DTSC packet to the stream, updating the internal metadata if needed.
void DTSC::Stream::addPacket(JSON::Value & newPack) {
  livePos newPos;
  newPos.trackID = newPack["trackid"].asInt();
  newPos.seekTime = newPack["time"].asInt();
  if (!metadata.tracks.count(newPos.trackID) && (!newPack.isMember("mark") || newPack["mark"].asStringRef() != "pause")) {
    return;
  }
  if (buffercount > 1 && metadata.tracks[newPos.trackID].keys.size() > 1 && newPos.seekTime < (long long unsigned int)metadata.tracks[newPos.trackID].keys.rbegin()->getTime()) {
    resetStream();
  }
  while (buffers.count(newPos) > 0) {
    newPos.seekTime++;
  }
  while (buffercount == 1 && buffers.size() > 0) {
    cutOneBuffer();
  }
  buffers[newPos] = newPack;
  datapointertype = INVALID;
  std::string tmp = "";
  if (newPack.isMember("trackid") && newPack["trackid"].asInt() > 0) {
    tmp = metadata.tracks[newPack["trackid"].asInt()].type;
  }
  if (newPack.isMember("datatype")) {
    tmp = newPack["datatype"].asStringRef();
  }
  if (tmp == "video") {
    datapointertype = VIDEO;
  }
  if (tmp == "audio") {
    datapointertype = AUDIO;
  }
  if (tmp == "meta") {
    datapointertype = META;
  }
  if (tmp == "pause_marker" || (newPack.isMember("mark") && newPack["mark"].asStringRef() == "pause")) {
    datapointertype = PAUSEMARK;
  }
  if (buffercount > 1) {
    metadata.update(newPack);
    if (newPack.isMember("keyframe") || (long long unsigned int)metadata.tracks[newPos.trackID].keys.rbegin()->getTime() == newPos.seekTime) {
      keyframes[newPos.trackID].insert(newPos);
    }
    metadata.live = true;
    //throw away buffers if buffer time is met
    int trid = buffers.begin()->first.trackID;
    int firstTime = buffers.begin()->first.seekTime;
    int lastTime = buffers.rbegin()->first.seekTime - buffertime;
    while ((!metadata.tracks[trid].keys.size() && firstTime < lastTime) || (metadata.tracks[trid].keys.size() && metadata.tracks[trid].keys.rbegin()->getTime() < lastTime) || (metadata.tracks[trid].keys.size() > 2 && metadata.tracks[trid].keys.rbegin()->getTime() - firstTime > buffertime)) {
      cutOneBuffer();
      trid = buffers.begin()->first.trackID;
      firstTime = buffers.begin()->first.seekTime;
    }
    metadata.bufferWindow = buffertime;
  }

}
예제 #6
0
/* AudioEntryPanel::onBtnStop
 * Called when the stop button is pressed
 *******************************************************************/
void AudioEntryPanel::onBtnStop(wxCommandEvent& e)
{
	// Stop playing
	stopStream();
	timer_seek->Stop();

	// Reset
	resetStream();
	slider_seek->SetValue(0);
}
예제 #7
0
/* AudioEntryPanel::~AudioEntryPanel
 * AudioEntryPanel class constructor
 *******************************************************************/
AudioEntryPanel::~AudioEntryPanel()
{
	// Stop the timer to avoid crashes
	timer_seek->Stop();
	resetStream();

	// Clean up
	delete sound;
	delete music;
	delete mod;
}
예제 #8
0
void OggDemuxFilter::DeliverBeginFlush() 
{
	CAutoLock locLock(m_pLock);
    LOG(logDEBUG) << __FUNCTIONW__;
	
	for (unsigned long i = 0; i < m_streamMapper->numPins(); i++) 
    {
		m_streamMapper->getPinByIndex(i)->DeliverBeginFlush();
	}

	//Should this be here or endflush or neither ?
	resetStream();
}
예제 #9
0
// renyang - 開始接收對方的資料
// renyang - socket代表client端的socket file descriptor
// renyang - proto可能是IHU_TCP或IHU_UDP
// renyang-TODO - 要加入IHU_SCTP的部分
void Receiver::start(int socket, int proto)
{
#ifdef REN_DEBUG
	qWarning(QString("Receiver::start(int %1, int %2)").arg(socket).arg(proto));;
#endif
	s = socket;
	protocol = proto;
	// renyang - 連線之後, 可以取得對方的sockaddr_in資料
	// renyang - 由socket取得對方的struct sockaddr
	// renyang - 此s代表client端的socket file descriptor
	::getpeername(s, (struct sockaddr *)&ca, &calen);

	// renyang-modify - 記錄目前的primary
	primaddr = ::inet_ntoa(ca.sin_addr);

	// renyang - 設定sync的型態為STREAM_READ_DATA, 並streamPtr回到起始位址(streamBuffer)
	resetStream();
	// renyang - 設定ihu_refuse, ihu_reply, ihu_abort, connected,...為false
	reset();
	// renayng - working=ture, 表示正在響鈴
	go();

	// renyang - 新增一個QSocketNotifier, 當有資料可以讀時, emit activated()
	// renyang - 用來判斷對方是否有傳資料進來
	notifier = new QSocketNotifier(s, QSocketNotifier::Read, this);
	// renyang - activated(int)其參數是表示哪一個socket file descriptor被觸發
	// renyang - 表示client端有傳送資料過來
	// renyang - 每格一段時間接收一次資料
	connect(notifier,SIGNAL(activated(int)),this, SLOT(receive()));
	// renyang - 因為tcp所接收到的第一個資料是connection,所以,不需要
	// renyang - 但是, udp所接收到的第一個資料就是資料啦, 所以要比tcp多接收一次
	// renyang - 只有waitCalls端才要執行received的程式
	if (received)
	{
		// renyang - 若是udp的話, 則直接開始接收資料, 因udp只要是有資料送過來就直接接收@@@
		switch(protocol)
		{
			case IHU_UDP:
				// renyang - 因為是connection-less的關係, 所以先接收第一筆資料???
				receive();
				break;
		}
		// renyang - 不論是tcp或是udp均會處理目前的函式
		// renyang - 把這一個socket, protocol, ca送到Transmitter, 讓Transmitter可以傳送資料, 給peer端
		// renyang - 只有當是waitCalls才會建立一個Transmitter的一個socket用來傳送資料
		// renyang - ca在IHU_SCTP用不到
		emit newSocket(s, protocol, ca);
	}
	// renyang - 開始倒數計時, false表示timeout一次, 就呼叫timeout()一次
	checkTimer->start(CHECK_TICKTIME, false);
}
예제 #10
0
void OggDemuxFilter::DeliverEOS() 
{
	//m_streamMapper->toStartOfData();
    CAutoLock locStreamLock(&m_streamLock);
    LOG(logDEBUG) << __FUNCTIONW__;
	
    for (unsigned long i = 0; i < m_streamMapper->numPins(); i++) 
    {
		//m_streamMapper->getOggStream(i)->flush();
		m_streamMapper->getPinByIndex(i)->DeliverEndOfStream();
	}

    resetStream();
}
예제 #11
0
/* AudioEntryPanel::loadEntry
 * Loads an entry into the audio entry panel
 *******************************************************************/
bool AudioEntryPanel::loadEntry(ArchiveEntry* entry)
{
	// Are we reopening the same entry? For example having looked at
	// a text file or image or any other non-audio entry, then
	// going back to the original audio entry? Then no need to do
	// abort the current song to restart it.
	if (this->entry == entry)
		return true;

	// Stop anything currently playing
	stopStream();
	resetStream();
	opened = false;

	// Enable all playback controls initially
	slider_seek->Enable();
	btn_play->Enable();
	btn_pause->Enable();

	btn_stop->Enable();
	btn_prev->Enable();
	btn_next->Enable();

	// Reset seek slider
	slider_seek->SetValue(0);

	// Delete previous temp file
	if (wxFileExists(prevfile))
		wxRemoveFile(prevfile);

	// Open new data
	this->entry = entry;
	open();

	// Autoplay if option is on
	if (snd_autoplay)
	{
		startStream();
		timer_seek->Start(10);
	}

	Refresh();
	return true;
}
예제 #12
0
파일: zpp.cpp 프로젝트: jlefley/libzpp
zppZipReader::zppZipReader(zppZipFileInfo *info, int rbSize, char *rdBuf)
{
	// initialize state info...
	readBufSize = rbSize;
	readBuf = rdBuf;
	ourBuffer = false;
	file = info;

	// if the read buffer size == 0, then use the default size.
	if (readBufSize == 0) {
		// but if the read buffer size is 0, then we're going to alloc a buffer...
		// so it better be null.
		if (readBuf != NULL)
			throw zppError("readBufSize == 0 && readBuffer != NULL");

		readBufSize = defaultReadBufSize;
	}

#ifdef ZPP_INCLUDE_CRYPT
	isCrypt = false;
	if (file->isCrypt() && file->getParentZip() != NULL) {
		zppZipArchive *parent = file->getParentZip();
		if (parent->getPasswd() == NULL) throw zppError("attempt to read encrypted file without passwd set");
		isCrypt = true;
	}
#endif /* ZPP_INCLUDE_CRYPT */

	// if the input read buffer is NULL, we allocate one and take
	// ownership of it.
	if (readBuf == NULL) {
		readBuf = new char[readBufSize];
		ourBuffer = true;
	}

	if (file->getMethod() != ZPP_STORED &&
	    file->getMethod() != ZPP_DEFLATED)
		throw zppError("Invalid compression method");
	
	streamInit = false;
	stream = new z_stream;
	resetStream();

}
예제 #13
0
void ofApp::mousePressed(int x, int y, int button){

    if(doesContain(x,y,img_x, img_y + img_h + 75, img_w, 80) && !drawing){
        hideMovement = true;
    }
    
    if(doesContain(x,y,img_x, img_y + img_h + 185, img_w, 80) && !drawing){
        drawing = true;
        hideMovement = false;
    }else if(doesContain(x,y,img_x, img_y + img_h + 185, img_w, 80) && drawing){
        drawing = false;
        hideBackgroundWhileDrawing = false;
    }
    
    //hidebackgroundWhile Drawing:
    if(doesContain(x,y,img_x, img_y + img_h + 295, img_w, 80) && drawing){
        if(!hideBackgroundWhileDrawing){
            hideBackgroundWhileDrawing = true;
        }else{
            hideBackgroundWhileDrawing = false;
        }
    }
    
    
    //next cam:
    if(doesContain(x,y,img_x + img_w + 30, img_y, 80, img_h)){
        loadNextCamera();
    }
    //reset current cam:
    if(doesContain(x,y,img_x - 30 - 80, img_y, 80, img_h)){
        resetStream();
    }
    
    //threshold -
    if(doesContain(x,y,20, 20, 80, 80)){
        threshold -= 2;
    }
    //threshold +
    if(doesContain(x,y,120, 20, 80, 80)){
        threshold += 2;
    }
    
}
예제 #14
0
void Call::stop()
{
#ifdef REN_DEBUG
	qWarning("Call::stop()");
#endif
	if (active)
	{
		active = false;
		recording = false;
		sendRing(false);
		// renyang - 隔一段時間之後, 才正真close掉
		stopTimer->start(STOP_TIME, true);
		transmitter->end();
		receiver->end();
		// renyang-modify - 把所有的iphander內的資料全部清掉
		sctpiphandler->end();
		// renyang-modify - 初始化stream no
		resetStream();
	}
}
예제 #15
0
// -------------------------
// Class Logger
// -------------------------
Logger::Logger(size_t level, std::string filename, bool dual) :
	static_loglevel(level),
	local_stream(),
	loglevel(),
	logfilename(filename)
{
	bool logdual = getLogdual();
	logdual = dual;
	getDeafstream().setstate(std::ios_base::eofbit);
	resetStream(new LogStream);
	loglevel.reset(new size_t(level));

	if (!logfilename.empty())
		getLogfile().open(logfilename.c_str(), std::fstream::out | std::fstream::binary);

	if (logfilename.empty() && dual)
		throw std::runtime_error("dual logging requires file name");

	*local_stream << "*** Started logging @";
	*local_stream << boost::posix_time::second_clock::local_time();
	*local_stream << "with log level: " << getBuffer()[level];
	*local_stream << " ***" << Logger::flush;
}
예제 #16
0
// renyang - 解析封包, 是否在傳送過程中否有出現問題
void Receiver::processData()
{
#ifdef REN_DEBUG
	qWarning("Receiver::processData()");
#endif
	while (working && (sync != STREAM_READ_DATA))
	{
		switch (sync)
		{
			case STREAM_OK:
				// renyang - 至少要有一個資料, 否則就是資料遺失
				if (streamLen < (HEADER_SYNC_LEN + 1))
				{
					sync = STREAM_MISSING_DATA;
					break;
				}
				// renyang - 比較Header是否有問題
				if (strncmp(streamPtr, HEADER_SYNC_STRING, HEADER_SYNC_LEN) != 0)
				{
					sync = STREAM_OUT_OF_SYNC;
#ifdef REN_DEBUG
					fprintf(stderr, "OUT OF SYNC (Dump: 0x");
					for(int i=0;i<4;i++)
						fprintf(stderr, "%02x", (unsigned char) streamPtr[i]);
					fprintf(stderr, "\n");
#endif
					break;
				}
				else
				{
					// renyang - 實際封包的大小(內容值是由peer端送過來的)
					unsigned char packetlen = (unsigned char) streamPtr[HEADER_SYNC_LEN];
					int plen = (int) packetlen;
					// renyang - 封包面裡記錄的資料大小比streamLen還要大, 則表示有資料遺失
					if (plen > streamLen)
					{
						sync = STREAM_MISSING_DATA;
						break;
					}
					else
					{
						try {
							if (plen >= MIN_PACKET_SIZE)
							{
								Packet *p = new Packet(plen);
								// renyang - 把收到的資料以IHU Packet型態呈獻
								PacketHandler::readPacket(p, streamPtr, plen);
								// renyang - 分析這一個封包
								processPacket(p);
								delete p;
							}
							else
							{
								sync = STREAM_OUT_OF_SYNC;
								break;
							}
							if (plen < streamLen)
							{
								// renyang - 要讀取的stream移到下一個位址
								streamPtr = streamPtr + plen;
								// renyang - 可以讀取的stream長度減剛剛建立封包的大小
								streamLen = streamLen - plen;
								// renyang - 表示還可以進行下一次的封包建立
								sync = STREAM_OK;
							}
							else 
							{
								// renyang - 表示stream的封包不夠, 需要讀取stream
								sync = STREAM_READ_DATA;
								resetStream();
							}
						} catch (Error e)
						{
							emitError(e.getText());
						}
					}
				}
				break;
			case STREAM_OUT_OF_SYNC:
				if (streamLen < 3)
					sync = STREAM_MISSING_DATA;
				else
				{
					do
					{
						streamPtr++;
						streamLen--;
						if (streamLen <= 0)
						{
							sync = STREAM_READ_DATA;
							resetStream();
							break;
						}
						if (strncmp(streamPtr, HEADER_SYNC_STRING, HEADER_SYNC_LEN)==0)
						{
							sync = STREAM_OK;
						}
					} while(sync == STREAM_OUT_OF_SYNC);
				}
				break;
			case STREAM_MISSING_DATA:
				sync = STREAM_READ_DATA;
			case STREAM_READ_DATA:
				// renyang - 把streamPtr資料移動streamLen到streamBuffer
				// renyang - 當我們由網路收到資料時, 我們是把它放到streamBuffer
				// renyang - 但是, 我們在讀取的時候是透過streamPtr
				// renyang - 完全就是在這裡設定
				memmove(streamBuffer, streamPtr, streamLen);
				streamPtr = streamBuffer;
				break;
		}
	}
}
예제 #17
0
파일: Manager.c 프로젝트: barroca/Anthill
void resetStreams(Layout *layout) {
    int i =0;
    for (i = 0; i < layout->numStreams; i ++) {
        resetStream((layout->streams[i]));
    }
}
예제 #18
0
bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index, int stream_num)
{
    QString             follow_filter;
    const char          *hostname0 = NULL, *hostname1 = NULL;
    char                *port0 = NULL, *port1 = NULL;
    QString             server_to_client_string;
    QString             client_to_server_string;
    QString             both_directions_string;
    gboolean            is_follower = FALSE;

    resetStream();

    if (file_closed_)
    {
        QMessageBox::warning(this, tr("No capture file."), tr("Please make sure you have a capture file opened."));
        return false;
    }

    if (cap_file_.capFile()->edt == NULL)
    {
        QMessageBox::warning(this, tr("Error following stream."), tr("Capture file invalid."));
        return false;
    }

    is_follower = proto_is_frame_protocol(cap_file_.capFile()->edt->pi.layers, proto_get_protocol_filter_name(get_follow_proto_id(follower_)));
    if (!is_follower) {
        QMessageBox::warning(this, tr("Error following stream."), tr("Please make sure you have a %1 packet selected.").arg
                                (proto_get_protocol_short_name(find_protocol_by_id(get_follow_proto_id(follower_)))));
        return false;
    }

    if (follow_type_ == FOLLOW_SSL)
    {
        /* we got ssl so we can follow */
        removeStreamControls();
    }

    follow_reset_stream(&follow_info_);

    /* Create a new filter that matches all packets in the TCP stream,
        and set the display filter entry accordingly */
    if (use_stream_index) {
        follow_filter = gchar_free_to_qstring(get_follow_index_func(follower_)(stream_num));
    } else {
        follow_filter = gchar_free_to_qstring(get_follow_conv_func(follower_)(&cap_file_.capFile()->edt->pi, &stream_num));
    }
    if (follow_filter.isEmpty()) {
        QMessageBox::warning(this,
                             tr("Error creating filter for this stream."),
                             tr("A transport or network layer header is needed."));
        return false;
    }

    /* append the negation */
    if(!previous_filter.isEmpty()) {
        filter_out_filter_ = QString("%1 and !(%2)")
                .arg(previous_filter).arg(follow_filter);
    }
    else
    {
        filter_out_filter_ = QString("!(%1)").arg(follow_filter);
    }

    /* data will be passed via tap callback*/
    if (!registerTapListener(get_follow_tap_string(follower_), &follow_info_,
                                follow_filter.toUtf8().constData(),
                                0, NULL, get_follow_tap_handler(follower_), NULL)) {
        return false;
    }

    switch (follow_type_)
    {
    case FOLLOW_TCP:
    {
        int stream_count = get_tcp_stream_count();
        ui->streamNumberSpinBox->blockSignals(true);
        ui->streamNumberSpinBox->setMaximum(stream_count-1);
        ui->streamNumberSpinBox->setValue(stream_num);
        ui->streamNumberSpinBox->blockSignals(false);
        ui->streamNumberSpinBox->setToolTip(tr("%Ln total stream(s).", "", stream_count));
        ui->streamNumberLabel->setToolTip(ui->streamNumberSpinBox->toolTip());

        break;
    }
    case FOLLOW_UDP:
    {
        int stream_count = get_udp_stream_count();
        ui->streamNumberSpinBox->blockSignals(true);
        ui->streamNumberSpinBox->setMaximum(stream_count-1);
        ui->streamNumberSpinBox->setValue(stream_num);
        ui->streamNumberSpinBox->blockSignals(false);
        ui->streamNumberSpinBox->setToolTip(tr("%Ln total stream(s).", "", stream_count));
        ui->streamNumberLabel->setToolTip(ui->streamNumberSpinBox->toolTip());

        break;
    }
    case FOLLOW_SSL:
    case FOLLOW_HTTP:
        /* No extra handling */
        break;
    }

    beginRetapPackets();
    updateWidgets(true);

    /* Run the display filter so it goes in effect - even if it's the
       same as the previous display filter. */
    emit updateFilter(follow_filter, TRUE);

    removeTapListeners();

    hostname0 = address_to_name(&follow_info_.client_ip);
    hostname1 = address_to_name(&follow_info_.server_ip);

    port0 = get_follow_port_to_display(follower_)(NULL, follow_info_.client_port);
    port1 = get_follow_port_to_display(follower_)(NULL, follow_info_.server_port);

    server_to_client_string =
            QString("%1:%2 %3 %4:%5 (%6)")
            .arg(hostname0).arg(port0)
            .arg(UTF8_RIGHTWARDS_ARROW)
            .arg(hostname1).arg(port1)
            .arg(gchar_free_to_qstring(format_size(
                                            follow_info_.bytes_written[0],
                                        format_size_unit_bytes|format_size_prefix_si)));

    client_to_server_string =
            QString("%1:%2 %3 %4:%5 (%6)")
            .arg(hostname1).arg(port1)
            .arg(UTF8_RIGHTWARDS_ARROW)
            .arg(hostname0).arg(port0)
            .arg(gchar_free_to_qstring(format_size(
                                            follow_info_.bytes_written[1],
                                        format_size_unit_bytes|format_size_prefix_si)));

    wmem_free(NULL, port0);
    wmem_free(NULL, port1);

    both_directions_string = QString("Entire conversation (%1)")
            .arg(gchar_free_to_qstring(format_size(
                                            follow_info_.bytes_written[0] + follow_info_.bytes_written[1],
                    format_size_unit_bytes|format_size_prefix_si)));
    setWindowSubtitle(tr("Follow %1 Stream (%2)").arg(proto_get_protocol_short_name(find_protocol_by_id(get_follow_proto_id(follower_))))
                                                 .arg(follow_filter));

    ui->cbDirections->clear();
    ui->cbDirections->addItem(both_directions_string);
    ui->cbDirections->addItem(client_to_server_string);
    ui->cbDirections->addItem(server_to_client_string);

    followStream();
    fillHintLabel(-1);

    updateWidgets(false);
    endRetapPackets();
    return true;
}
예제 #19
0
/* AudioEntryPanel::openAudio
 * Opens an audio file for playback (SFML 2.x+)
 *******************************************************************/
bool AudioEntryPanel::openAudio(MemChunk& audio, string filename)
{
	// Stop if sound currently playing
	resetStream();

	// (Re)create sound buffer
	if (sound_buffer)
		delete sound_buffer;
	sound_buffer = new sf::SoundBuffer();
	audio_type = AUTYPE_INVALID;

	// Load into buffer
	if (sound_buffer->loadFromMemory((const char*)audio.getData(), audio.getSize()))
	{
		LOG_MESSAGE(3, "opened as sound");
		// Bind to sound
		sound->setBuffer(*sound_buffer);
		audio_type = AUTYPE_SOUND;

		// Enable play controls
#if (SFML_VERSION_MAJOR == 2 && SFML_VERSION_MINOR < 2)
		// SFML before 2.2 has a bug where it reports an incorrect value for long sounds, so compute it ourselves then
		setAudioDuration((sound_buffer->getSampleCount() / sound_buffer->getSampleRate())*(1000/sound_buffer->getChannelCount()));
#else
		setAudioDuration(sound_buffer->getDuration().asMilliseconds());
#endif
		btn_play->Enable();
		btn_pause->Enable();
		btn_stop->Enable();

		return true;
	}
	else if (music->openFromMemory((const char*)audio.getData(), audio.getSize()))
	{
		LOG_MESSAGE(3, "opened as music");
		// Couldn't open the audio as a sf::SoundBuffer, try sf::Music instead
		audio_type = AUTYPE_MUSIC;

		// Enable play controls
		setAudioDuration(music->getDuration().asMilliseconds());
		btn_play->Enable();
		btn_stop->Enable();

		return true;
	}
	else
	{
		// Couldn't open as sound or music, try the wxMediaCtrl
		LOG_MESSAGE(3, "opened as media");

		// Dump audio to temp file
		audio.exportFile(filename);

		if (openMedia(filename))
			return true;
	}

	// Unable to open audio, disable play controls
	setAudioDuration(0);
	btn_play->Enable(false);
	btn_pause->Enable(false);
	btn_stop->Enable(false);

	return false;
}
예제 #20
0
/* AudioEntryPanel::open
 * Opens the current entry and performs the appropriate conversions
 *******************************************************************/
bool AudioEntryPanel::open()
{
	// Check if already opened
	if (opened)
		return true;

	// Stop if sound currently playing
	resetStream();

	subsong = 0;
	num_tracks = 1;

	// Get entry data
	MemChunk& mcdata = entry->getMCData();

	// Setup temp filename
	wxFileName path(appPath(entry->getName(), DIR_TEMP));
	// Add extension if missing
	if (path.GetExt().IsEmpty())
		path.SetExt(entry->getType()->getExtension());

	// Convert if necessary, then write to file
	MemChunk convdata;
	if (entry->getType()->getFormat() == "snd_doom" ||			// Doom Sound -> WAV
	        entry->getType()->getFormat() == "snd_doom_mac")
		Conversions::doomSndToWav(mcdata, convdata);
	else if (entry->getType()->getFormat() == "snd_speaker")	// Doom PC Speaker Sound -> WAV
		Conversions::spkSndToWav(mcdata, convdata);
	else if (entry->getType()->getFormat() == "snd_audiot")		// AudioT PC Speaker Sound -> WAV
		Conversions::spkSndToWav(mcdata, convdata, true);
	else if (entry->getType()->getFormat() == "snd_wolf")		// Wolfenstein 3D Sound -> WAV
		Conversions::wolfSndToWav(mcdata, convdata);
	else if (entry->getType()->getFormat() == "snd_voc")		// Creative Voice File -> WAV
		Conversions::vocToWav(mcdata, convdata);
	else if (entry->getType()->getFormat() == "snd_jaguar")		// Jaguar Doom Sound -> WAV
		Conversions::jagSndToWav(mcdata, convdata);
	else if (entry->getType()->getFormat() == "snd_bloodsfx")	// Blood Sound -> WAV
		Conversions::bloodToWav(entry, convdata);
	else if (entry->getType()->getFormat() == "midi_mus")  			// MUS -> MIDI
	{
		Conversions::musToMidi(mcdata, convdata);
		path.SetExt("mid");
	}
	else if (entry->getType()->getFormat() == "midi_xmi" ||  		// HMI/HMP/XMI -> MIDI
			 entry->getType()->getFormat() == "midi_hmi" || entry->getType()->getFormat() == "midi_hmp")
	{
		Conversions::zmusToMidi(mcdata, convdata, 0, &num_tracks);
		path.SetExt("mid");
	}
	else if (entry->getType()->getFormat() == "midi_gmid")  		// GMID -> MIDI
	{
		Conversions::gmidToMidi(mcdata, convdata);
		path.SetExt("mid");
	}
	else
		convdata.importMem(mcdata.getData(), mcdata.getSize());

	// MIDI format
	if (entry->getType()->getFormat().StartsWith("midi_"))
	{
		audio_type = AUTYPE_MIDI;
		openMidi(convdata, path.GetFullPath());
	}

	// MOD format
	else if (entry->getType()->getFormat().StartsWith("mod_"))
		openMod(convdata);

	// Other format
	else
		openAudio(convdata, path.GetFullPath());

	// Keep filename so we can delete it later
	prevfile = path.GetFullPath();

	txt_title->SetLabel(entry->getPath(true));
	txt_track->SetLabel(S_FMT("%d/%d", subsong+1, num_tracks));
	updateInfo();

	// Disable prev/next track buttons if only one track is available
	if (num_tracks < 2)
	{
		btn_prev->Disable();
		btn_next->Disable();
	}

	opened = true;
	return true;
}
예제 #21
0
FollowStreamDialog::~FollowStreamDialog()
{
    delete ui;
    resetStream(); // Frees payload
}
예제 #22
0
bool AVIDecoder::AVIAudioTrack::rewind() {
	resetStream();
	return true;
}
예제 #23
0
bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index)
{
    int                 tmp_fd;
    QString             follow_filter;
    const char          *hostname0 = NULL, *hostname1 = NULL;
    char                *port0 = NULL, *port1 = NULL;
    QString             server_to_client_string;
    QString             client_to_server_string;
    QString             both_directions_string;
    follow_stats_t      stats;
    tcp_stream_chunk    sc;
    size_t              nchars;
    gboolean is_tcp = FALSE, is_udp = FALSE;

    beginRetapPackets();
    resetStream();

    if (file_closed_)
    {
        QMessageBox::warning(this, tr("No capture file."), tr("Please make sure you have a capture file opened."));
        return false;
    }

    if (cap_file_.capFile()->edt == NULL)
    {
        QMessageBox::warning(this, tr("Error following stream."), tr("Capture file invalid."));
        return false;
    }

    proto_get_frame_protocols(cap_file_.capFile()->edt->pi.layers, NULL, &is_tcp, &is_udp, NULL, NULL, NULL, NULL);

    switch (follow_type_)
    {
    case FOLLOW_TCP:
        if (!is_tcp) {
            QMessageBox::warning(this, tr("Error following stream."), tr("Please make sure you have a TCP packet selected."));
            return false;
        }
        break;
    case FOLLOW_UDP:
        if (!is_udp) {
            QMessageBox::warning(this, tr("Error following stream."), tr("Please make sure you have a UDP packet selected."));
            return false;
        }
        break;
    case FOLLOW_SSL:
        /* we got ssl so we can follow */
        removeStreamControls();
        if (!epan_dissect_packet_contains_field(cap_file_.capFile()->edt, "ssl")) {
            QMessageBox::critical(this, tr("Error following stream."),
                               tr("Please make sure you have an SSL packet selected."));
            return false;
        }
        break;
    }

    if (follow_type_ == FOLLOW_TCP || follow_type_ == FOLLOW_SSL)
    {
        /* Create a new filter that matches all packets in the TCP stream,
           and set the display filter entry accordingly */
        reset_tcp_reassembly();
    } else {
        reset_udp_follow();
    }

    if (use_stream_index) {
        follow_filter = gchar_free_to_qstring(
            build_follow_index_filter((follow_type_ == FOLLOW_TCP) ? TCP_STREAM : UDP_STREAM));
    } else {
        follow_filter = gchar_free_to_qstring(build_follow_conv_filter(&cap_file_.capFile()->edt->pi));
    }
    if (follow_filter.isEmpty()) {
        QMessageBox::warning(this,
                             tr("Error creating filter for this stream."),
                             tr("A transport or network layer header is needed."));
        return false;
    }

    if (follow_type_ == FOLLOW_TCP || follow_type_ == FOLLOW_SSL)
    {
        /* Create a temporary file into which to dump the reassembled data
           from the TCP stream, and set "data_out_file" to refer to it, so
           that the TCP code will write to it.

           XXX - it might be nicer to just have the TCP code directly
           append stuff to the text widget for the TCP stream window,
           if we can arrange that said window not pop up until we're
           done. */
        gchar *data_out_filename;
        tmp_fd = create_tempfile(&data_out_filename, "follow");
        data_out_filename_ = data_out_filename;

        if (tmp_fd == -1) {
            QMessageBox::warning(this, "Error",
                                 "Could not create temporary file %1: %2",
                                 data_out_filename_, g_strerror(errno));
            data_out_filename_.clear();
            return false;
        }

        data_out_file = fdopen(tmp_fd, "w+b");
        if (data_out_file == NULL) {
            QMessageBox::warning(this, "Error",
                                 "Could not create temporary file %1: %2",
                                 data_out_filename_, g_strerror(errno));
            //ws_close(tmp_fd);
            ws_unlink(data_out_filename_.toUtf8().constData());
            data_out_filename_.clear();
            return false;
        }
    }

    /* append the negation */
    if(!previous_filter.isEmpty()) {
        filter_out_filter_ = QString("%1 and !(%2)")
                .arg(previous_filter).arg(follow_filter);
    }
    else
    {
        filter_out_filter_ = QString("!(%1)").arg(follow_filter);
    }

    switch (follow_type_)
    {
    case FOLLOW_TCP:
    {
        int stream_count = get_tcp_stream_count() - 1;
        ui->streamNumberSpinBox->blockSignals(true);
        ui->streamNumberSpinBox->setMaximum(stream_count);
        ui->streamNumberSpinBox->setValue(get_follow_index(TCP_STREAM));
        ui->streamNumberSpinBox->blockSignals(false);
        ui->streamNumberSpinBox->setToolTip(tr("%Ln total stream(s).", "", stream_count));
        ui->streamNumberLabel->setToolTip(ui->streamNumberSpinBox->toolTip());

        break;
    }
    case FOLLOW_UDP:
    {
        /* data will be passed via tap callback*/
        if (!registerTapListener("udp_follow", &follow_info_,
                                 follow_filter.toUtf8().constData(),
                                 0, NULL, udp_queue_packet_data, NULL)) {
            return false;
        }

        int stream_count = get_udp_stream_count() - 1;
        ui->streamNumberSpinBox->blockSignals(true);
        ui->streamNumberSpinBox->setMaximum(stream_count);
        ui->streamNumberSpinBox->setValue(get_follow_index(UDP_STREAM));
        ui->streamNumberSpinBox->blockSignals(false);
        ui->streamNumberSpinBox->setToolTip(tr("%Ln total stream(s).", "", stream_count));
        ui->streamNumberLabel->setToolTip(ui->streamNumberSpinBox->toolTip());

        break;
    }
    case FOLLOW_SSL:
        /* we got ssl so we can follow */
        if (!registerTapListener("ssl", &follow_info_,
                                 follow_filter.toUtf8().constData(), 0,
                                 NULL, ssl_queue_packet_data, NULL)) {
            return false;
        }
        break;
    }

    /* Run the display filter so it goes in effect - even if it's the
       same as the previous display filter. */
    emit updateFilter(follow_filter, TRUE);

    switch (follow_type_)
    {
    case FOLLOW_TCP:

        break;
    case FOLLOW_UDP:
    case FOLLOW_SSL:
        removeTapListeners();
        break;
    }

    if (follow_type_ == FOLLOW_TCP)
    {
        /* Check whether we got any data written to the file. */
        if (empty_tcp_stream) {
            QMessageBox::warning(this, "Error",
                                 "The packets in the capture file for that stream have no data.");
            //ws_close(tmp_fd);
            ws_unlink(data_out_filename_.toUtf8().constData());
            data_out_filename_.clear();
            return false;
        }

        /* Go back to the top of the file and read the first tcp_stream_chunk
         * to ensure that the IP addresses and port numbers in the drop-down
         * list are tied to the correct lines displayed by follow_read_stream()
         * later on (which also reads from this file).  Close the file when
         * we're done.
         *
         * We read the data now, before we pop up a window, in case the
         * read fails.  We use the data later.
         */

        rewind(data_out_file);
        nchars=fread(&sc, 1, sizeof(sc), data_out_file);
        if (nchars != sizeof(sc)) {
            if (ferror(data_out_file)) {
                QMessageBox::warning(this, "Error",
                                     QString(tr("Could not read from temporary file %1: %2"))
                                     .arg(data_out_filename_)
                                     .arg(g_strerror(errno)));
            } else {
                QMessageBox::warning(this, "Error",
                                     QString(tr("Short read from temporary file %1: expected %2, got %3"))
                                     .arg(data_out_filename_)
                                     .arg((unsigned long)sizeof(sc))
                                     .arg((unsigned long)nchars));

            }
            //ws_close(tmp_fd);
            ws_unlink(data_out_filename_.toUtf8().constData());
            data_out_filename_.clear();
            return false;
        }
        fclose(data_out_file);
        data_out_file = NULL;
    }

    /* Stream to show */
    follow_stats(&stats);

    if (stats.is_ipv6) {
        struct e_in6_addr ipaddr;
        memcpy(&ipaddr, stats.ip_address[0], 16);
        hostname0 = get_hostname6(&ipaddr);
        memcpy(&ipaddr, stats.ip_address[1], 16);
        hostname1 = get_hostname6(&ipaddr);
    } else {
        guint32 ipaddr;
        memcpy(&ipaddr, stats.ip_address[0], 4);
        hostname0 = get_hostname(ipaddr);
        memcpy(&ipaddr, stats.ip_address[1], 4);
        hostname1 = get_hostname(ipaddr);
    }

    switch (follow_type_)
    {
    case FOLLOW_TCP:
        port0 = tcp_port_to_display(NULL, stats.port[0]);
        port1 = tcp_port_to_display(NULL, stats.port[1]);
        break;
    case FOLLOW_UDP:
        port0 = udp_port_to_display(NULL, stats.port[0]);
        port1 = udp_port_to_display(NULL, stats.port[1]);
        break;
    case FOLLOW_SSL:
        port0 = tcp_port_to_display(NULL, stats.port[0]);
        port1 = tcp_port_to_display(NULL, stats.port[1]);
        break;
    }

    follow_info_.is_ipv6 = stats.is_ipv6;

    if (follow_type_ == FOLLOW_TCP)
    {
        /* Host 0 --> Host 1 */
        if ((sc.src_port == stats.port[0]) &&
            ((stats.is_ipv6 && (memcmp(sc.src_addr, stats.ip_address[0], 16) == 0)) ||
             (!stats.is_ipv6 && (memcmp(sc.src_addr, stats.ip_address[0], 4) == 0)))) {
            server_to_client_string =
                    QString("%1:%2 %3 %4:%5 (%6)")
                    .arg(hostname0).arg(port0)
                    .arg(UTF8_RIGHTWARDS_ARROW)
                    .arg(hostname1).arg(port1)
                    .arg(gchar_free_to_qstring(format_size(
                                                   stats.bytes_written[0],
                                               format_size_unit_bytes|format_size_prefix_si)));
        } else {
            server_to_client_string =
                    QString("%1:%2 %3 %4:%5 (%6)")
                    .arg(hostname1).arg(port1)
                    .arg(UTF8_RIGHTWARDS_ARROW)
                    .arg(hostname0).arg(port0)
                    .arg(gchar_free_to_qstring(format_size(
                                                   stats.bytes_written[0],
                                               format_size_unit_bytes|format_size_prefix_si)));
        }

        /* Host 1 --> Host 0 */
        if ((sc.src_port == stats.port[1]) &&
            ((stats.is_ipv6 && (memcmp(sc.src_addr, stats.ip_address[1], 16) == 0)) ||
             (!stats.is_ipv6 && (memcmp(sc.src_addr, stats.ip_address[1], 4) == 0)))) {
            client_to_server_string =
                    QString("%1:%2 %3 %4:%5 (%6)")
                    .arg(hostname0).arg(port0)
                    .arg(UTF8_RIGHTWARDS_ARROW)
                    .arg(hostname1).arg(port1)
                    .arg(gchar_free_to_qstring(format_size(
                                                   stats.bytes_written[1],
                                               format_size_unit_bytes|format_size_prefix_si)));
        } else {
            client_to_server_string =
                    QString("%1:%2 %3 %4:%5 (%6)")
                    .arg(hostname1).arg(port1)
                    .arg(UTF8_RIGHTWARDS_ARROW)
                    .arg(hostname0).arg(port0)
                    .arg(gchar_free_to_qstring(format_size(
                                                   stats.bytes_written[1],
                                               format_size_unit_bytes|format_size_prefix_si)));
        }

    }
    else
    {
        if ((follow_info_.client_port == stats.port[0]) &&
            ((stats.is_ipv6 && (memcmp(follow_info_.client_ip.data, stats.ip_address[0], 16) == 0)) ||
             (!stats.is_ipv6 && (memcmp(follow_info_.client_ip.data, stats.ip_address[0], 4) == 0)))) {
            server_to_client_string =
                    QString("%1:%2 %3 %4:%5 (%6)")
                    .arg(hostname0).arg(port0)
                    .arg(UTF8_RIGHTWARDS_ARROW)
                    .arg(hostname1).arg(port1)
                    .arg(gchar_free_to_qstring(format_size(
                                                   follow_info_.bytes_written[0],
                                               format_size_unit_bytes|format_size_prefix_si)));

            client_to_server_string =
                    QString("%1:%2 %3 %4:%5 (%6)")
                    .arg(hostname1).arg(port1)
                    .arg(UTF8_RIGHTWARDS_ARROW)
                    .arg(hostname0).arg(port0)
                    .arg(gchar_free_to_qstring(format_size(
                                                   follow_info_.bytes_written[1],
                                               format_size_unit_bytes|format_size_prefix_si)));
        } else {
            server_to_client_string =
                    QString("%1:%2 %3 %4:%5 (%6)")
                    .arg(hostname1).arg(port1)
                    .arg(UTF8_RIGHTWARDS_ARROW)
                    .arg(hostname0).arg(port0)
                    .arg(gchar_free_to_qstring(format_size(
                                                   follow_info_.bytes_written[0],
                                               format_size_unit_bytes|format_size_prefix_si)));

            client_to_server_string =
                    QString("%1:%2 %3 %4:%5 (%6)")
                    .arg(hostname0).arg(port0)
                    .arg(UTF8_RIGHTWARDS_ARROW)
                    .arg(hostname1).arg(port1)
                    .arg(gchar_free_to_qstring(format_size(
                                                   follow_info_.bytes_written[1],
                                               format_size_unit_bytes|format_size_prefix_si)));
        }
    }

    wmem_free(NULL, port0);
    wmem_free(NULL, port1);

    /* Both Stream Directions */
    switch (follow_type_)
    {
    case FOLLOW_TCP:
        both_directions_string = QString("Entire conversation (%1)")
                .arg(gchar_free_to_qstring(format_size(
                                               stats.bytes_written[0] + stats.bytes_written[1],
                     format_size_unit_bytes|format_size_prefix_si)));
        setWindowSubtitle(tr("Follow TCP Stream (%1)").arg(follow_filter));
        break;
    case FOLLOW_UDP:
        both_directions_string = QString("Entire conversation (%1)")
                .arg(gchar_free_to_qstring(format_size(
                                               follow_info_.bytes_written[0] + follow_info_.bytes_written[1],
                     format_size_unit_bytes|format_size_prefix_si)));
        setWindowSubtitle(tr("Follow UDP Stream (%1)").arg(follow_filter));
        break;
    case FOLLOW_SSL:
        both_directions_string = QString("Entire conversation (%1)")
                .arg(gchar_free_to_qstring(format_size(
                                               follow_info_.bytes_written[0] + follow_info_.bytes_written[1],
                     format_size_unit_bytes|format_size_prefix_si)));
        setWindowSubtitle(tr("Follow SSL Stream (%1)").arg(follow_filter));
        break;
    }

    ui->cbDirections->clear();
    ui->cbDirections->addItem(both_directions_string);
    ui->cbDirections->addItem(client_to_server_string);
    ui->cbDirections->addItem(server_to_client_string);

    followStream();
    fillHintLabel(-1);

    if (data_out_file) {
        fclose(data_out_file);
        data_out_file = NULL;
    }

    endRetapPackets();
    return true;
}
예제 #24
0
// renyang - 解析封包, 是否在傳送過程中否有出現問題
void Receiver::processData()
{
#ifdef REN_DEBUG
	qWarning("Receiver::processData()");
#endif
	while (working && (sync != STREAM_READ_DATA))
	{
		switch (sync)
		{
			case STREAM_OK:
				// renyang - 至少要有一個資料, 否則就是資料遺失
				if (streamLen < (HEADER_SYNC_LEN + 1))
				{
					sync = STREAM_MISSING_DATA;
					break;
				}
				// renyang - 比較Header是否有問題
				if (strncmp(streamPtr, HEADER_SYNC_STRING, HEADER_SYNC_LEN) != 0)
				{
					sync = STREAM_OUT_OF_SYNC;
#ifdef REN_DEBUG
					fprintf(stderr, "OUT OF SYNC (Dump: 0x");
					for(int i=0;i<4;i++)
						fprintf(stderr, "%02x", (unsigned char) streamPtr[i]);
					fprintf(stderr, "\n");
#endif
					break;
				}
				else
				{
					// renyang - 實際封包(IHU自定的封包)的大小(內容值是由peer端送過來的)
					unsigned short int *packetlen = (unsigned short int *) (streamPtr+HEADER_SYNC_LEN);
					int plen = (int) (*packetlen);
					// renyang - 封包面裡記錄的資料大小比streamLen還要大, 則表示有資料遺失
					if (plen > streamLen)
					{
						sync = STREAM_MISSING_DATA;
						break;
					}
					else
					{
						try {
							if (plen >= MIN_PACKET_SIZE)
							{
								Packet *p = new Packet(plen);
								// renyang - 把收到的資料以IHU Packet型態呈獻
								// renyang - 把streamPtr且長度為plen, 由p的位置開始放
								PacketHandler::readPacket(p, streamPtr, plen);
								// renyang - 分析這一個封包
								processPacket(p);
								delete p;
							}
							else
							{
								// renyang - 比最小的封包還要小, 表示有問題
								sync = STREAM_OUT_OF_SYNC;
								break;
							}
							// renyang - 若目前這一個封包的大小比目前還沒有處理的資料還要小的話
							// renyang - 則表示還有其它封包還在streamPtr中
							if (plen < streamLen)
							{
								// renyang - 要讀取的stream移到下一個位址
								streamPtr = streamPtr + plen;
								// renyang - 可以讀取的stream長度減剛剛建立封包的大小
								streamLen = streamLen - plen;
								// renyang - 表示還可以進行下一次的封包建立
								sync = STREAM_OK;
							}
							else 
							{
								// renyang - 表示stream的封包不夠, 需要讀取stream
								// renyang - 在reliable的情況下, 每接收到一個封包, 應該都會跑到這裡
								// renyang - 表示沒有其它封包在streamBuffer
								sync = STREAM_READ_DATA;
								resetStream();
							}
						} catch (Error e)
						{
							emitError(e.getText());
						}
					}
				}
				break;
			case STREAM_OUT_OF_SYNC:
				if (streamLen < 3)
					sync = STREAM_MISSING_DATA;
				else
				{
					do
					{
						// renyang - 尋找下一個以IHU開頭的封包
						streamPtr++;
						streamLen--;
						if (streamLen <= 0)
						{
							sync = STREAM_READ_DATA;
							resetStream();
							break;
						}
						if (strncmp(streamPtr, HEADER_SYNC_STRING, HEADER_SYNC_LEN)==0)
						{
							sync = STREAM_OK;
						}
					} while(sync == STREAM_OUT_OF_SYNC);
				}
				break;
			case STREAM_MISSING_DATA:
				sync = STREAM_READ_DATA;
			case STREAM_READ_DATA:
				// renyang - 把streamPtr資料移動streamLen個bytes到streamBuffer
				// renyang - 當我們由網路收到資料時, 我們是把它放到streamBuffer
				// renyang - 但是, 我們在讀取的時候是透過streamPtr(代表下一個要讀取的封包位址)
				// renyang - 完全就是在這裡設定
				memmove(streamBuffer, streamPtr, streamLen);
				streamPtr = streamBuffer;
				break;
		}
	}
}