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

📄 media-app.h

📁 柯老师网站上找到的
💻 H
字号:
/* -*-	Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- *///// Copyright (c) 1997 by the University of Southern California// All rights reserved.//// Permission to use, copy, modify, and distribute this software and its// documentation in source and binary forms for non-commercial purposes// and without fee is hereby granted, provided that the above copyright// notice appear in all copies and that both the copyright notice and// this permission notice appear in supporting documentation. and that// any documentation, advertising materials, and other materials related// to such distribution and use acknowledge that the software was// developed by the University of Southern California, Information// Sciences Institute.  The name of the University may not be used to// endorse or promote products derived from this software without// specific prior written permission.//// THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no representations about// the suitability of this software for any purpose.  THIS SOFTWARE IS// PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,// INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.//// Other copyrights might apply to parts of this software and are so// noted when applicable.//// Media applications: wrappers of transport agents for multimedia objects// // Their tasks are to receive 'data' from underlying transport agents, // and to notify "above" applications that such data has arrived. //// When required (by RapAgent), it also provides callbacks to the // transport agent, and contact the above application on behalf of the // transport agent.//// $Header: /nfs/jade/vint/CVSROOT/ns-2/rap/media-app.h,v 1.11 1999/11/18 23:14:32 haoboy Exp $#ifndef ns_media_app_h#define ns_media_app_h#include <stdlib.h>#include <tcl.h>#include "config.h"#include "agent.h"#include "app.h"#include "webcache/http-aux.h"#include "rap/rap.h"#include "rap/utilities.h"class HttpMediaData;// Fixed length segment in a multimedia streamclass MediaSegment : public DoubleListElem {public: 	MediaSegment() : start_(0), end_(0), flags_(0) {}	MediaSegment(int start, int end) : start_(start),end_(end),flags_(0) {}	MediaSegment(const HttpMediaData& d);	MediaSegment(const MediaSegment& s) {		// XXX Don't copy pointers (prev_,next_)?		start_ = s.start_;		end_ = s.end_;		flags_ = s.flags_;	}	int start() const { return start_; }	int end() const { return end_; }	int datasize() const { return end_ - start_; }	MediaSegment* next() const { 		return (MediaSegment *)DoubleListElem::next(); 	}	MediaSegment* prev() const { 		return (MediaSegment *)DoubleListElem::prev(); 	}	void set_start(int d) { start_ = d; }	void set_end(int d) { end_ = d; }	void set_datasize(int d) { end_ = start_ + d; }	// Advance the segment by size	void advance(int size) { start_ += size, end_ = start_ + size; }	int in(const MediaSegment& s) const {		return ((start_ >= s.start_) && (end_ <= s.end_));	}	int before(const MediaSegment& s) const {		return (end_ <= s.start_);	}	int overlap(const MediaSegment& s) const {		assert(s.start_ <= s.end_);		return ((s.end_ >= start_) && (s.start_ <= end_));	}	// Return the overlapping size between the two	int merge(const MediaSegment& s) {		if ((s.end_ < start_) || (s.start_ > end_))			// No overlap			return 0;		int size = datasize() + s.datasize();		if (s.start_ < start_) start_ = s.start_;		if (s.end_ > end_) end_ = s.end_;		assert(size >= datasize());		return (size - datasize());	}	// Return the amount of data evicted	int evict_tail(int sz) {		// Adjust both the size and playout time#ifdef MCACHE_DEBUG		fprintf(stderr, "evicted (%d, %d) ", end_-sz, end_);#endif		if (datasize() >= sz) 			end_ -= sz;		else {			sz = datasize();			end_ = start_;		}		return sz;	}	// Return the amount of data evicted	int evict_head(int sz) {		// Adjust both the size and playout time		if (datasize() >= sz) 			start_ += sz;		else {			sz = datasize();			end_ = start_;		}		return sz;	}	int is_empty() const { return end_ == start_; }	// Whether this is the last segment of the available data	enum { MS_LAST = 1, MS_PREF = 2 };	int is_last() const { return (flags_ & MS_LAST); }	void set_last() { flags_ |= MS_LAST; }	int is_pref() const { return (flags_ & MS_PREF); }	void set_pref() { flags_ |= MS_PREF; }private: 	int start_;	int end_;	int flags_;};// Maintains received segments of every layerclass MediaSegmentList : public DoubleList {public:	MediaSegmentList() : DoubleList(), length_(0) {}	int length() const { return length_; }	void add(const MediaSegment& s);	int in(const MediaSegment& s);	MediaSegment get_nextseg(const MediaSegment& s);	int evict_tail(int size);	int evict_head(int size);	int evict_head_offset(int offset);	int overlap_size(const MediaSegment& s) const;	MediaSegmentList check_holes(const MediaSegment& s);	char* dump2buf();	virtual void destroy() {		DoubleList::destroy();		length_ = 0;	}	// Debug only	void print(void);	int getsize();	void check_integrity();protected:	void merge_seg(MediaSegment* seg);private:	int length_;};// Represents a multimedia segment transmitted through the networkclass HttpMediaData : public HttpData {private:	char page_[HTTP_MAXURLLEN];	// Page ID	char sender_[HTTP_MAXURLLEN];	// Sender name	int layer_;			// Layer id. 0 if no layered encoding	int st_;			// Segment start time	int et_; 			// Segment end time	int flags_; 			// flags: end of all data, etc.	Application* conid_;		// Connection ID. Used for statisticspublic:	struct hdr {		char sender_[HTTP_MAXURLLEN];		char page_[HTTP_MAXURLLEN];		int layer_;		int st_, et_;		int flags_;	};public:	HttpMediaData(const char* sender, const char* name, int layer, 		      int st, int et);	HttpMediaData(HttpMediaData& d) : HttpData(d) {		layer_ = d.layer_;		st_ = d.st_;		et_ = d.et_;		flags_ = d.flags_;		strcpy(page_, d.page_);		strcpy(sender_, d.sender_);	}	virtual int size() const { return HttpData::size() + sizeof(hdr); }	virtual AppData* copy() { return (new HttpMediaData(*this)); }	int st() const { return st_; }	int et() const { return et_; }	int datasize() const { return et_ - st_; }	int layer() const { return layer_; }	const char* page() const { return page_; }	const char* sender() const { return sender_; }	Application* conid() { return conid_; }	void set_conid(Application* c) { conid_ = c; }	// flags	// MD_LAST: last segment of this layre	// MD_FINISH: completed the entire stream	enum {		MD_LAST = 1, 		MD_FINISH = 2,		MD_PREFETCH = 4	}; 	// Whether this is the last data segment of the layer	int is_last() const { return (flags_ & MD_LAST); }	void set_last() { flags_ |= MD_LAST; }	int is_finished() const { return (flags_ & MD_FINISH); }	void set_finish() { flags_ |= MD_FINISH; }	int is_pref() const { return (flags_ & MD_PREFETCH); }	void set_pref() { flags_ |= MD_PREFETCH; }};const int MEDIAREQ_GETSEG   	= 1;const int MEDIAREQ_CHECKSEG 	= 2;const int MEDIAREQ_SEGAVAIL 	= 3;const int MEDIAREQ_SEGUNAVAIL 	= 4;// It provides a MediaApp two types of requests: check data availability and // request data. It won't be sent in a packet so we don't need copy(). class MediaRequest : public AppData {private:	int request_; 			// Request code	char name_[HTTP_MAXURLLEN];	// Page URL	int layer_;			// Layer ID	u_int st_;			// Start playout time	u_int et_;			// End playout time	Application* app_;		// Calling applicationpublic:	MediaRequest(int rc) : AppData(MEDIA_REQUEST), request_(rc) {}	MediaRequest(const MediaRequest& r) : AppData(MEDIA_REQUEST) {		request_ = r.request();		st_ = r.st();		et_ = r.et();		layer_ = r.layer();		strcpy(name_, r.name());	}	// We don't need it, but have to declare.	virtual AppData* copy() { abort(); return NULL; }	int request() const { return request_; }	int st() const { return st_; }	int et() const { return et_; }	int datasize() const { return et_ - st_; }	int layer() const { return layer_; }	const char* name() const { return name_; }	Application* app() const { return app_; }	// These functions allow the caller to fill in only the 	// necessary fields	void set_st(int d) { st_ = d; }	void set_et(int d) { et_ = d; }	void set_datasize(int d) { et_ = st_ + d; }	void set_name(const char *s) { strcpy(name_, s); }	void set_layer(int d) { layer_ = d; }	void set_app(Application* a) { app_ = a; }};// Maximum number of layers for all streams in the simulationconst int MAX_LAYER = 10;// XXX A media app is only responsible for transmission of a single // media stream!! Once the transmission is done, the media app will be // deleted.class MediaApp : public Application {public:	MediaApp(const char* page);	virtual AppData* get_data(int& size, AppData* req_data = 0);	virtual void process_data(int size, AppData* data) {		send_data(size, data);	}	void set_page(const char* pg) { strcpy(page_, pg); }	void log(const char* fmt, ...);	int command(int argc, const char*const* argv);protected:	virtual void start();	virtual void stop();	// Helper function	RapAgent* rap() { return (RapAgent*)agent_; }	int seg_size_; 			// data segment size	char page_[HTTP_MAXURLLEN];	MediaSegment data_[MAX_LAYER];	// Pointer to next data to be sent	Tcl_Channel log_; 		// log file	// XXX assuming all streams in the simulation have the same	// number of layers.	int num_layer_;private:	int last_layer_;};class QA; class QATimer : public TimerHandler {public:	QATimer(QA *a) : TimerHandler() { a_ = a; }protected:	virtual void expire(Event *e);	QA *a_;};const double QA_EPSILON = 1e-6;class QA : public MediaApp { public:	QA(const char *page);	virtual ~QA();	virtual AppData* get_data(int& size, AppData* req_data = 0);	void UpdateState();	double UpdateInterval() { return rap()->srtt(); } protected:	virtual int command(int argc, const char*const* argv);	virtual void stop();	// Helper functions	void check_availability(int layer, const MediaSegment& s);	RapAgent* rap() { return (RapAgent*)agent_; }	// Misc helpers	inline double MWM(double srtt) {		return 2 * LAYERBW_ * srtt;	}	inline double rate() { 		return (double)seg_size_ / rap()->ipg();	}	// Calculate area of a triangle for a given side and slope	inline double BufNeed(double side, double slope) {		return (side <= 0) ? 0.0 : ((side*side) / (2.0*slope));	}	int AllZero(double *arr, int len);	double TotalBuf(int n, double *buffer);	AppData* output(int& size, int layer);	void DumpInfo(double t, double last_t, double rate, 		      double avgrate, double srtt);	double bufOptScen1(int layer, int layers, double currrate, 			   double slope, int backoffs);	double bufOptScen2(int layer, int layers, double currrate, 			   double slope, int backoffs);	void drain_buf(double* DrainArr, double bufToDrain, 		       double* FinalDrainArray, double* bufAvail, 		       int layers, double rate, double srtt);	void DrainPacket(double bufToDrain, double* FinalDrainArray, 			 int layers, double rate, double srtt, 			 double* FinalBuffer);	// Ack feedback information	void DrainBuffers();	// Debugging output	void debug(const char* fmt, ...);	void panic(const char* fmt, ...);	void check_layers(int layer, MediaSegment& tmp);	// Data members	int layer_;	double    playTime_; // playout time of the receiver	double    startTime_; // Absoloute time when playout started	// Internal state info for QA	double   buffer_[MAX_LAYER];	double   drained_[MAX_LAYER]; 	double   bw_[MAX_LAYER];	int	 playing_[MAX_LAYER]; 	int	 sending_[MAX_LAYER];	QATimer* updTimer_;	// Average transmission rate and its moving average weight	// Measured whenever a segment is sent out (XXX why??)	double   avgrate_; 	double   rate_weight_;	// Variables related to playout buffer management	int      poffset_;  /* The playout offset: estimation of client 			       playout time */	// Linked list keeping track of holes between poffset_ and current	// transmission pointer	MediaSegmentList outlist_[MAX_LAYER];	// The end offset of the prefetch requests. Used to avoid redundant	// prefetching requests	int pref_[MAX_LAYER];	// OTcl-bound variables	int debug_;  		// Turn on/off debug output	double pref_srtt_;	// Prefetching SRTT	int LAYERBW_;	int MAXACTIVELAYERS_;	double SRTTWEIGHT_;	int SMOOTHFACTOR_;	int MAXBKOFF_;}; #endif // ns_media_app_h

⌨️ 快捷键说明

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