diff options
Diffstat (limited to 'TAO/orbsvcs/tests/AVStreams/mpeg/source/mpeg_server/Globals.cpp')
-rw-r--r-- | TAO/orbsvcs/tests/AVStreams/mpeg/source/mpeg_server/Globals.cpp | 2018 |
1 files changed, 0 insertions, 2018 deletions
diff --git a/TAO/orbsvcs/tests/AVStreams/mpeg/source/mpeg_server/Globals.cpp b/TAO/orbsvcs/tests/AVStreams/mpeg/source/mpeg_server/Globals.cpp deleted file mode 100644 index 1cc160e3451..00000000000 --- a/TAO/orbsvcs/tests/AVStreams/mpeg/source/mpeg_server/Globals.cpp +++ /dev/null @@ -1,2018 +0,0 @@ -// $Id$ -/* Copyright (c) 1995 Oregon Graduate Institute of Science and Technology - * P.O.Box 91000-1000, Portland, OR 97291, USA; - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of O.G.I. not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. O.G.I. makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * O.G.I. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING - * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL - * O.G.I. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY - * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Author: Shanwei Cen - * Department of Computer Science and Engineering - * email: scen@cse.ogi.edu - */ - -#include "Globals.h" - -int Mpeg_Global::parentpid = -1; -int Mpeg_Global::listenSocketIn = -1; -int Mpeg_Global::listenSocketUn = -1; -struct linger Mpeg_Global::linger = {1,1}; -int Mpeg_Global::live_audio = 0; -int Mpeg_Global::live_video = 0; /* 0 - no, 1 - to open, 2 - opened */ -int Mpeg_Global::drift_ppm = 0; /* clock drift in ppm */ -int Mpeg_Global::session_limit = SESSION_NUM; -int Mpeg_Global::session_num = 0; -int Mpeg_Global::rttag = 0; - -int Video_Timer_Global::timerHeader = 0; -int Video_Timer_Global::timerGroup = 0; -int Video_Timer_Global::timerFrame = 0; -int Video_Timer_Global::timerOn = 0; -int Video_Timer_Global::timerAdjust = 0; -int Video_Timer_Global::preTimerVal = 0; - -// Initialize the nasty int's, doubles and their friends -Video_Global::Video_Global () -{ - live_source = 0; - video_format = 0; - - pkts_sent = 0; - start_time = 0; - - conn_tag = 0; - - normalExit = 1; - - serviceSocket = 0; - videoSocket = -1; - - ACE_OS::memset (videoFile, - 0, - PATH_SIZE); - - fp = 0; - - needHeader = 0; - - lastRef [0] = lastRef [1] = 0; - - lastRefPtr = 0; - currentUPF = 0; - addedUPF = 0; - addedSignals = 0; - VStimeAdvance = 0; - fps = 0; /* current frames-per-second: playback speed */ - frameRateLimit = 0; - - packet = 0; - packetBufSize = 0; - msgsn = 0; - packetsn = 0; - msgsize = 0; - - precmd = 0; - cmd = 0; - cmdsn = 0; - nextFrame = 0; - nextGroup = 0; - firstPatternSize = 0; - firstSendPattern = 0; - sendPatternGops = 0; - ACE_OS::memset (sendPattern, - 0, - PATTERN_SIZE); - -#ifdef STAT - framesSent = 0; -#endif - - fileSize = 0; - maxS = 0; - maxG = 0; - maxI = 0; - maxP = 0; - maxB = 0; - minS = 0x7fffffff; - minG = 0x7fffffff; - minI = 0x7fffffff; - minP = 0x7fffffff; - minB = 0x7fffffff; - - numS = 0; - numG = 0; - numF = 0; - numI = 0; - numP = 0; - numB = 0; - - averageFrameSize = 0; - horizontalSize = 0; - verticalSize = 0; - pelAspectRatio = 0; - pictureRate = 0; - vbvBufferSize = 0; - firstGopFrames = 0; - patternSize = 0; - - ACE_OS::memset (pattern, - 0, - PATTERN_SIZE); - - // struct pointers - systemHeader = 0; - - gopTable = 0; - - frameTable = 0; - - // playvideo local vars - - preGroup = -1; - preHeader = -1; - preFrame = -1; - - fast_preGroup = -1; - fast_preHeader= -1; -} - -int -Video_Global::FBread (char * buf, int size) -{ - int res; - while ( (res = (this->conn_tag >= 0 ? wait_read_bytes (this->videoSocket, buf, size) : - read (this->videoSocket, buf, size))) == -1) - { - if (errno == EINTR) {errno = 0; continue; } - if (errno == EPIPE || errno == ECONNRESET) exit (0); - perror ("VS reads Feedback this->packet"); - return -1; - } - if (res < size) { - if (res) fprintf (stderr, "VS warn: FBread () res %dB < size %dB\n", res, size); - return -1; - } - return 0; -} - -/* send a given this->packet pointed by 'this->packet' to the network */ - -int -Video_Global::send_to_network (int timeToUse) -{ - int count = 0; - VideoMessage * msghd = (VideoMessage *) ( ( (char *)this->packet) - sizeof (VideoMessage)); - int sent = 0; - int packetSize = ntohl (this->packet->dataBytes); - - msghd->packetsn = htonl (this->packetsn ++); - msghd->packetSize = htonl (packetSize + sizeof (* this->packet)); - /* - fprintf (stderr, "VS to send pkt %d of size %d.\n", - ntohl (msghd->this->packetsn), ntohl (msghd->this->packetSize)); - */ - { - VideoMessage * msg = NULL; - int size = packetSize + sizeof (* this->packet); /* msghd->this->packetSize */ - int offset = 0; - int targetTime; - - if (size > this->msgsize) - { - - if (!timeToUse) - { - timeToUse = (this->msgsize + sizeof (*msg) + 28) * 2; - /* - set the max network as 500KB. - 28 - UDP header size - */ - /* - fprintf (stderr, "computed timeToUse %d. ", timeToUse); - */ - } - else - { - timeToUse = (timeToUse * 7) >> 3; - /* - fprintf (stderr, "preset timeToUse %d.", timeToUse); - */ - timeToUse /= (size + this->msgsize - 1) / this->msgsize; - timeToUse = min (timeToUse, (this->msgsize + sizeof (*msg) + 28) * 100); - /* limit min network bandwidth = 10K */ - } - - } - while (size > 0) - { - int segsize, sentsize; - int resent = 0; - - if (msg == NULL) { /* first message for current this->packet */ - count = 0; - msg = msghd; - targetTime = get_usec (); - } - else { -#if 0 - /* the select () is not precise enough for being used here*/ - int sleepTime; - targetTime += timeToUse; - sleepTime = get_duration (get_usec (), targetTime); - if (sleepTime >= 5000) { /* resolution of timer is 10,000 usec */ - usleep (sleepTime); /* not first message, wait for a while */ - } -#endif - /* - count ++; - if (! (count % 10)) usleep (10000); - */ - msg = (VideoMessage *) ( (char *)msg + this->msgsize); - memcpy ( (char *)msg, (char *)msghd, sizeof (* msg)); - } - msg->msgsn = htonl (this->msgsn++); - msg->msgOffset = htonl (offset); - msg->msgSize = htonl (min (size, this->msgsize)); - - segsize = min (size, this->msgsize)+sizeof (*msg); - if (this->conn_tag != 0) { /* this->packet stream */ - while ( (sentsize = write (this->videoSocket, (char *)msg, segsize)) == -1) { - if (errno == EINTR) - continue; - if (errno == ENOBUFS) { - if (resent) { - perror ("Warning, pkt discarded because"); - sent = -1; - break; - } - else { - resent = 1; - perror ("VS to sleep 5ms"); - usleep (5000); - continue; - } - } - if (errno != EPIPE) { - fprintf (stderr, "VS error on send this->packet %d of size %d ", - this->msgsn-1, min (size, this->msgsize)+sizeof (*msg)); - perror (""); - } - exit (errno != EPIPE); - } - } - else { - sentsize = wait_write_bytes (this->videoSocket, (char *)msg, segsize); - if (sentsize == -1) { - if (errno != EPIPE) { - fprintf (stderr, "VS error on send this->packet %d of size %d ", - this->msgsn-1, min (size, this->msgsize)+sizeof (*msg)); - perror (""); - } - exit (errno != EPIPE); - } - } - if (sentsize < segsize) { - SFprintf (stderr, "VS warning: message size %dB, sent only %dB\n", - segsize, sentsize); - } - if (sent == -1) - break; - /* - fprintf (stderr, "VS: message %d of size %d sent.\n", - this->msgsn-1, min (size, this->msgsize)+sizeof (*msg)); - */ - size -= this->msgsize; - offset += this->msgsize; - } - } - /* - fprintf (stderr, "sent = %d\n", sent); - */ - if (!sent) this->pkts_sent ++; - return sent; -} - -/* - * send a this->packet with given this->systemHeader (optional), gop (optional) and frame. - * - * sh - system header id, if -1, then no system header will be sent. - * otherwise, only when frame == 0, the given system header will be sent. - * gop - group of pictures, gop header will be sent when frame == 0 - * (first I frame ); - * frame - frame to be sent, offset internal to given gop. - */ - -/* returns: 0 - this->packet sent, -1 - this->packet not sent (failed) */ -int -Video_Global::SendPacket (int shtag, int gop, int frame, int timeToUse) -/* frame maybe out of range (PLAY, STEP), in this case, END_SEQ is sent - to force display of last frame in VD */ -{ - char * buf = ( (char *) this->packet) + sizeof (VideoPacket); - int f = this->gopTable[gop].previousFrames + frame; - int sh = this->gopTable[gop].systemHeader; - /* - SFprintf (stderr, "VS to send this->packet gop-%d, frame-%d.\n", gop, frame); - */ - - this->packet->currentUPF = ntohl (this->currentUPF); - - if (frame >= this->gopTable[gop].totalFrames) - { - this->packet->cmd = htonl (this->cmd); - this->packet->cmdsn = htonl (this->cmdsn); - this->packet->sh = htonl (sh); - this->packet->gop = htonl (gop); - this->packet->frame = htonl (this->numF); - this->packet->display = htonl (this->numF-1); - this->packet->future = htonl ( (unsigned)-1); - this->packet->past = htonl ( (unsigned)-1); - this->packet->dataBytes = htonl (4); - * (int*) ( (char*)this->packet + sizeof (*this->packet)) = htonl (SEQ_END_CODE); - - return send_to_network (timeToUse); - } - - if (frame) - shtag = 0; - else if (this->needHeader) - { - shtag = 1; - this->needHeader = 0; - } - - this->packet->cmd = htonl (this->cmd); - this->packet->cmdsn = htonl (this->cmdsn); - this->packet->sh = htonl (sh); - this->packet->gop = htonl (gop); - this->packet->frame = htonl (f); - if (this->frameTable[f].type == 'B') - { - int pre1 = -1, pre2 = -1, i = f; - while (i>0) - if (this->frameTable[--i].type != 'B') - { - pre1 = i; - break; - } - while (i>0) - if (this->frameTable[--i].type != 'B') - { - pre2 = i; - break; - } - if (pre2 == -1) - { - /* - fprintf (stderr, - "frame %d-%d (%d) is a B without past ref, no to be sent.\n", - gop, frame, f); - */ - return -1; - } - if (pre1 != this->lastRef[this->lastRefPtr] || - pre2 != this->lastRef[1 - this->lastRefPtr]) - { - /* - fprintf (stderr, - "send of B frame %d gaveup for past %d/future %d ref not sent.\n", - f, pre2, pre1); - */ - return -1; - } - this->packet->display = htonl (f); - this->packet->future = htonl (pre1); - this->packet->past = htonl (pre2); - } - else - { - int next = f; - int pre = f; - - while (next < this->numF && this->frameTable[++next].type == 'B'); - while (pre > 0 && this->frameTable[--pre].type == 'B'); - if (this->frameTable[f].type == 'P' && pre != this->lastRef[this->lastRefPtr]) - { - /* - fprintf (stderr, - "send of P frame %d gaveup for past ref %d not sent.\n", - f, pre); - fprintf (stderr, "ref0=%d, ref1=%d, ptr=%d.\n", - this->lastRef[0], this->lastRef[1], this->lastRefPtr); - */ - return -1; - } - this->packet->display = htonl (next); - this->packet->future = htonl ( (unsigned)-1); - this->packet->past = htonl (this->frameTable[f].type == 'P' ? pre : (unsigned)-1); - } - { - char * ptr = buf; - int size = 0, offset = 0, i; - if (shtag) /* send system header */ - { - size = this->systemHeader[sh].size; - FileRead (this->systemHeader[sh].offset, ptr, size); - ptr += size; - } - if (!frame) /* send gop header */ - { - size = this->gopTable[gop].headerSize; - FileRead (this->gopTable[gop].offset, ptr, size); - ptr += size; - } - size = this->frameTable[f].size; - for (i=this->gopTable[gop].previousFrames; i<f; i++) - offset += this->frameTable[i].size; - FileRead ( (this->gopTable[gop].firstIoffset + offset), ptr, size); - ptr += size; - this->packet->dataBytes = htonl (ptr - buf); - } - - { - int sent = send_to_network (timeToUse); - if (!sent) - { - /* - fprintf (stderr, "%c%d\n", this->frameTable[f].type, f); - fprintf (stderr, "%c frame %d sent.\n", this->frameTable[f].type, f); - */ - if (this->frameTable[f].type != 'B') - { - this->lastRefPtr = 1 - this->lastRefPtr; - this->lastRef[this->lastRefPtr] = f; - } - } - return sent; - } -} - - -int -Video_Global::CmdRead (char *buf, int psize) -{ - int res = wait_read_bytes (this->serviceSocket, - buf, - psize); - if (res == 0) return (1); - if (res == -1) { - fprintf (stderr, "VS error on read this->cmdSocket, size %d", psize); - perror (""); - return (-1); - } - return 0; -} - -int -Video_Global::CmdWrite (char *buf, int size) -{ - int res = wait_write_bytes (this->serviceSocket, buf, size); - if (res == -1) { - if (errno != EPIPE) perror ("VS writes to this->serviceSocket"); - return (-1); - } - return 0; -} - - -int -Video_Global::PLAYliveVideo (PLAYpara * para) -{ - int doscale; - int count; - int first_frame; - int frame = para->nextFrame; - int nfds = (this->serviceSocket > this->videoSocket ? this->serviceSocket : this->videoSocket) + 1; - struct fd_set read_mask; - struct timeval tval = {0, 0}; - double ratio; - int result; - - this->currentUPF = (int) (1000000.0 / this->fps); /* ignore para.usecPerFrame */ - if (this->frameRateLimit < this->fps) { - doscale = 1; - ratio = min (this->frameRateLimit, this->fps) / this->fps; - first_frame = frame; - count = 0; - /* - fprintf (stderr, "doscale %d, this->frameRateLimit %5.2f, this->fps %5.2f, ratio %5.2f\n", - doscale, this->frameRateLimit, this->fps, ratio); - */ - } - else doscale = 0; - StartPlayLiveVideo (); - - for (;;) { - - if (doscale) { - for (;;) { - if ( (int) ( (frame - first_frame) * ratio + 0.5) < count) frame ++; - else break; - } - count ++; - } - SendPicture (&frame); - frame ++; - - FD_ZERO (&read_mask); - FD_SET (this->serviceSocket, &read_mask); - FD_SET (this->videoSocket, &read_mask); -#ifdef _HPUX_SOURCE - if (select (nfds, (int *)&read_mask, NULL, NULL, &tval) == -1) -#else - if (select (nfds, &read_mask, NULL, NULL, &tval) == -1) -#endif - { - if (errno == EINTR) - continue; - perror ("Error - VS select between service and video sockets"); - StopPlayLiveVideo (); - exit (1); - - } - if (FD_ISSET (this->serviceSocket, &read_mask)) /* stop */ - { - unsigned char tmp; - result = CmdRead ( (char *)&tmp, 1); - if (result != 0) - return result; - if (tmp == CmdCLOSE) { - StopPlayLiveVideo (); - exit (0); - } - else if (tmp == CmdSTOP) { - this->cmd = tmp; - /* - fprintf (stderr, "VS: this->CmdSTOP. . .\n"); - */ - result = CmdRead ( (char *)&this->cmdsn, sizeof (int)); - if (result != 0) - return result; -#ifdef NeedByteOrderConversion - this->cmdsn = ntohl (this->cmdsn); -#endif - StopPlayLiveVideo (); - break; - } - else if (tmp == CmdSPEED) - { - SPEEDpara speed_para; - /* - fprintf (stderr, "VS: this->CmdSPEED. . .\n"); - */ - result = CmdRead ( (char *)&speed_para, sizeof (speed_para)); - if (result != 0) - return result; - /* ignore this thing for live video */ - } - else - { - fprintf (stderr, "VS error (live): this->cmd=%d while expect STOP/SPEED.\n", tmp); - this->normalExit = 0; - StopPlayLiveVideo (); - exit (1); - } - } - if (FD_ISSET (this->videoSocket, &read_mask)) /* feedback, only for frame rate - adjustment */ - { - VideoFeedBackPara fb_para; - if (FBread ( (char *)&fb_para, sizeof (fb_para)) == -1 || - ntohl (fb_para.cmdsn) != this->cmdsn) { - /* - SFprintf (stderr, "VS warning: a FB this->packet discarded.\n"); - */ - return 0; - } -#ifdef NeedByteOrderConversion - fb_para.this->frameRateLimit1000 = ntohl (fb_para.this->frameRateLimit1000); -#endif - this->frameRateLimit = fb_para.frameRateLimit1000 / 1000.0; - if (this->frameRateLimit < this->fps) { - doscale = 1; - ratio = min (this->frameRateLimit, this->fps) / this->fps; - first_frame = frame; - count = 0; - /* - fprintf (stderr, "doscale %d, this->frameRateLimit %5.2f, this->fps %5.2f, ratio %5.2f\n", - doscale, this->frameRateLimit, this->fps, ratio); - */ - } - else doscale = 0; - } - } - return 0; -} - -void -Video_Global::ComputeFirstSendPattern (float limit) -{ - char * buf = this->firstSendPattern; - int len = this->firstPatternSize; - char * pat = (char *)malloc (len); - int f; - - if (pat == NULL) { - fprintf (stderr, "VS error on allocating %d bytes for computing first SP", len); - perror (""); - exit (1); - } - for (f = 0; f < len; f ++) { - pat[f] = this->frameTable[f].type; - } - memset (buf, 0, len); - - if (limit <= 0) - limit = 1.0; - - f = (int) ( (double)len * - ( (double)limit / (1000000.0 / (double)this->currentUPF)) + 0.5); - /* rounded to integer, instead of truncated */ - if (f >= len) - f = len; - else if (f <= 1) - f = 1; - - ComputeSendPattern (pat, buf, len, f); - - /* - f = len - f; - fprintf (stderr, "this->Firstthis->Sendthis->Pattern (%d frames dropped): ", f); - { - int i; - for (i = 0; i < len; i ++) - fputc (buf[i] ? pat[i] : '-', stderr); - } - fputc ('\n', stderr); - */ - free (pat); -} - -int -Video_Global::FrameToGroup (int * frame) -{ - int f = * frame; - int i = 0; - while (i < this->numG && this->gopTable[i].previousFrames <= f) i++; - i --; - * frame = f - this->gopTable[i].previousFrames; - return i; -} - -int -Video_Global::SendReferences (int group, int frame) -{ - unsigned char orgcmd; - int i, base; - int pregroup; - int result; - - if (group < 0 || group >= this->numG) return 0; - if (frame <= 0 || frame >= this->gopTable[group].totalFrames) return 0; - - orgcmd = this->cmd; - this->cmd = CmdREF; - - if (group > 0) { - pregroup = 1; - base = this->gopTable[group].previousFrames; - for (i = 0; i <= frame; i ++) { - if (this->frameTable[i + base].type == 'P') { - pregroup = 0; - break; - } - } - } - else pregroup = 0; - - if (pregroup) { /* reference frame can be in previous group */ - pregroup = group -1; - base = this->gopTable[pregroup].previousFrames; - for (i = 0; i < this->gopTable[pregroup].totalFrames; i ++) { - if (this->frameTable[i + base].type != 'B') { - /* - SFprintf (stderr, "REF group%d, frame%d\n", pregroup, i); - */ - result = SendPacket (i == 0, pregroup, i, 0); - if (result != 0) - return result; - } - } - } - - base = this->gopTable[group].previousFrames; - for (i = 0; i < frame; i ++) { - if (this->frameTable[i + base].type != 'B') { - /* - SFprintf (stderr, "REF group%d, frame%d\n", group, i); - */ - SendPacket (i == 0, group, i, 0); - } - } - this->cmd = orgcmd; -} - - -void -Video_Global::GetFeedBack () -{ - VideoFeedBackPara para; - struct itimerval val; - int timerUsec; - - if (FBread ( (char *)¶, sizeof (para)) == -1 || - ntohl (para.cmdsn) != this->cmdsn) { - /* - SFprintf (stderr, "VS warning: a FB this->packet discarded.\n"); - */ - return; - } -#ifdef NeedByteOrderConversion - para.this->needHeader = ntohl (para.this->needHeader); - para.addUsecPerFrame = ntohl (para.addUsecPerFrame); - para.addFrames = ntohl (para.addFrames); - para.this->sendthis->PatternGops = ntohl (para.this->sendthis->PatternGops); - para.this->frameRateLimit1000 = ntohl (para.this->frameRateLimit1000); -#endif - this->frameRateLimit = para.frameRateLimit1000 / 1000.0; - this->sendPatternGops = para.sendPatternGops; - - if (!Video_Timer_Global::timerOn) return; - - this->needHeader = para.needHeader; - memcpy (this->sendPattern, para.sendPattern, PATTERN_SIZE); - if (para.addFrames <= 0 || Video_Timer_Global::timerAdjust < MAX_TIMER_ADJUST) - { - Video_Timer_Global::timerAdjust += para.addFrames * SPEEDUP_INV_SCALE; - Video_Timer_Global::TimerSpeed (); - } - else /* drastic compensation for big gap */ - this->addedSignals += para.addFrames; - if (para.addUsecPerFrame) { - this->addedUPF += para.addUsecPerFrame; - Video_Timer_Global::TimerSpeed (); - } - /* - SFprintf (stderr, "VS fb: addf %d, addupf %d\n", - para.addFrames, para.addUsecPerFrame); - */ -} - -int -Video_Global::SendPicture (int * frame) -{ - int size; - char * buf = ( (char *) this->packet) + sizeof (VideoPacket); - /* - SFprintf (stderr, "VS to send picture %d.\n", *frame); - */ - - size = ReadLiveVideoPicture (frame, buf, this->packetBufSize); - - this->packet->currentUPF = ntohl (this->currentUPF); - this->packet->cmd = htonl (this->cmd); - this->packet->cmdsn = htonl (this->cmdsn); - this->packet->sh = this->packet->gop = this->packet->frame = this->packet->display = htonl (*frame); - this->packet->future = htonl ( (unsigned)-1); - this->packet->past = htonl ( (unsigned)-1); - - this->packet->dataBytes = htonl (size); - - return send_to_network (this->currentUPF); -} - -int -Video_Global::ReadInfoFromFile (void) -{ - int fd = -1, i; - int fnlen = strlen (this->videoFile); - - strcpy (&this->videoFile[fnlen], ".Info"); - fd = open (this->videoFile, O_RDONLY); - if (fd == -1) - { - fprintf (stderr, "Reminder: VS fails to open %s for read, ", this->videoFile); - perror ("try create one"); - goto fail_ReadInfoFromFile; - } - read_int (fd, &i); - if (i != this->fileSize) - { - fprintf (stderr, "Warning: this->fileSize in Info: %d not the same as actual %d.\n", - i, this->fileSize); - goto fail_ReadInfoFromFile; - } - - read_int (fd, &this->maxS); - read_int (fd, &this->maxG); - read_int (fd, &this->maxI); - read_int (fd, &this->maxP); - read_int (fd, &this->maxB); - read_int (fd, &this->minS); - read_int (fd, &this->minG); - read_int (fd, &this->minI); - read_int (fd, &this->minP); - read_int (fd, &this->minB); - read_int (fd, &this->numS); - read_int (fd, &this->numG); - read_int (fd, &this->numF); - read_int (fd, &this->numI); - read_int (fd, &this->numP); - read_int (fd, &this->numB); - read_int (fd, &this->averageFrameSize); - read_int (fd, &this->horizontalSize); - read_int (fd, &this->verticalSize); - read_int (fd, &this->pelAspectRatio); - read_int (fd, &this->pictureRate); - read_int (fd, &this->vbvBufferSize); - read_int (fd, &this->patternSize); - - memset (this->pattern, 0, PATTERN_SIZE); - read_bytes (fd, this->pattern, this->patternSize); -#ifdef STAT - this->framesSent = (char *)malloc ( (this->numF + 7)>>3); - if (this->framesSent == NULL) - { - fprintf (stderr, "Error: VS fails to alloc mem for this->framesSent for %d frames", this->numF); - perror (""); - exit (1); - } -#endif - this->systemHeader = (struct Video_Global::SystemHeader *)malloc (sizeof (struct Video_Global::SystemHeader) * this->numS); - if (this->systemHeader == NULL) - { - perror ("Error: VS error on malloc this->SystemHeader"); - exit (1); - } - this->gopTable = (struct Video_Global::GopTable *)malloc (sizeof (struct Video_Global::GopTable) * this->numG); - if (this->gopTable == NULL) - { - perror ("Error: VS error on malloc GopHeader"); - exit (1); - } - this->frameTable = (struct Video_Global::FrameTable *)malloc (sizeof (Video_Global::FrameTable) * this->numF); - if (this->frameTable == NULL) - { - perror ("Error: VS error on malloc this->frameTable"); - exit (1); - } - this->packetBufSize = this->maxS + this->maxG + max (this->maxI, max (this->maxP, this->maxB)); - this->packet = (VideoPacket *)malloc (sizeof (VideoMessage) + sizeof (VideoPacket) + - this->packetBufSize); - if (this->packet == NULL) - { - perror ("Error: VS error on malloc this->packet buffer"); - exit (1); - } - this->packet = (VideoPacket *) ( (char *)this->packet + sizeof (VideoMessage)); - - for (i = 0; i < this->numS; i ++) - { - read_int (fd, (int *)&this->systemHeader[i].offset); - read_int (fd, &this->systemHeader[i].size); - } - for (i = 0; i < this->numG; i ++) - { - read_int (fd, &this->gopTable[i].systemHeader); - read_int (fd, (int *)&this->gopTable[i].offset); - read_int (fd, &this->gopTable[i].headerSize); - read_int (fd, &this->gopTable[i].size); - read_int (fd, &this->gopTable[i].totalFrames); - read_int (fd, &this->gopTable[i].previousFrames); - read_int (fd, (int *)&this->gopTable[i].firstIoffset); - } - for (i = 0; i < this->numF; i ++) - { - read_byte (fd, &this->frameTable[i].type); - read_short (fd, (short *)&this->frameTable[i].size); - } - - close (fd); - /* - fprintf (stderr, "Read Info from %s\n", this->videoFile); - */ - this->videoFile[fnlen] = 0; - return 0; - fail_ReadInfoFromFile: - if (fd >= 0) - close (fd); - this->videoFile[fnlen] = 0; - /* - fprintf (stderr, "To scan Info from %s\n", this->videoFile); - */ - return -1; -} - -void -Video_Global::WriteInfoToFile (void) -{ - int fd = -1, i; - int fnlen = strlen (this->videoFile); - - strcpy (&this->videoFile[fnlen], ".Info"); - fd = open (this->videoFile, O_WRONLY | O_CREAT, 0444); - if (fd == -1) - { - fprintf (stderr, "VS fails to open %s for write", this->videoFile); - perror (""); - goto fail_WriteInfoToFile; - } - write_int (fd, this->fileSize); - write_int (fd, this->maxS); - write_int (fd, this->maxG); - write_int (fd, this->maxI); - write_int (fd, this->maxP); - write_int (fd, this->maxB); - write_int (fd, this->minS); - write_int (fd, this->minG); - write_int (fd, this->minI); - write_int (fd, this->minP); - write_int (fd, this->minB); - write_int (fd, this->numS); - write_int (fd, this->numG); - write_int (fd, this->numF); - write_int (fd, this->numI); - write_int (fd, this->numP); - write_int (fd, this->numB); - write_int (fd, this->averageFrameSize); - write_int (fd, this->horizontalSize); - write_int (fd, this->verticalSize); - write_int (fd, this->pelAspectRatio); - write_int (fd, this->pictureRate); - write_int (fd, this->vbvBufferSize); - write_int (fd, this->patternSize); - - write_bytes (fd, this->pattern, this->patternSize); - - for (i = 0; i < this->numS; i ++) - { - write_int (fd, this->systemHeader[i].offset); - write_int (fd, this->systemHeader[i].size); - } - for (i = 0; i < this->numG; i ++) - { - write_int (fd, this->gopTable[i].systemHeader); - write_int (fd, this->gopTable[i].offset); - write_int (fd, this->gopTable[i].headerSize); - write_int (fd, this->gopTable[i].size); - write_int (fd, this->gopTable[i].totalFrames); - write_int (fd, this->gopTable[i].previousFrames); - write_int (fd, this->gopTable[i].firstIoffset); - } - for (i = 0; i < this->numF; i ++) - { - write_byte (fd, this->frameTable[i].type); - write_short (fd, this->frameTable[i].size); - } - - close (fd); - this->videoFile[fnlen] = 0; - return; - fail_WriteInfoToFile: - if (fd >= 0) - close (fd); - this->videoFile[fnlen] = 0; - return; -} - -int -Video_Global::init_MPEG1_video_file (void) -{ - unsigned char nb; - int state = 0; - unsigned long fileptr = 0; - unsigned long i, j, k; - int shptr, gopptr, ftptr; - int inpic = 0; - unsigned long picptr = 0; - int pictype = 0; - int first = 0; - int failureType = 0; - - this->fp = fopen (this->videoFile, "r"); - if (this->fp == NULL) - { - fprintf (stderr, "error on opening video file %s", this->videoFile); - perror (""); - return 2; - } - if (fseek (this->fp, 0, 2) == -1) - { - fprintf (stderr, "File %s not seekable", this->videoFile); - perror (""); - return 3; - } - this->fileSize = ftell (this->fp); - - fseek (this->fp, 0, 0); - - if (ReadInfoFromFile ()) - { - for (;;) - { - nextByte; - if (state >= 0 && nb == 0x00) - state ++; - else if (state >= 2 && nb == 0x01) - state = -1; - else if (state == -1) - { - if (!first) first ++; - else if (first == 1) first ++; - - switch (nb) - { - case 0xb7: /* seq_end_code */ - goto exit_phase1; - break; - case 0xb3: /* seq_start_code */ - if (first == 1) first = 3; - if (first != 3) - { - fprintf (stderr, "VS error: given file is not in MPEG format.\n"); - return 4; - } - this->numS ++; - break; - case 0xb8: /* gop_start_code */ - this->numG ++; - break; - case 0x00: /* picture_start_code */ - nextByte; - nextByte; - nb &= 0x38; - if (nb == 0x08) - { - this->numI ++; - if (this->numG == 2) - this->pattern[this->patternSize++] = 'I'; - } - else if (nb == 0x10) - { - this->numP ++; - if (this->numG == 2) - this->pattern[this->patternSize++] = 'P'; - } - else if (nb == 0x18) - { - this->numB ++; - if (this->numG == 2) - this->pattern[this->patternSize++] = 'B'; - } - /* - else - fprintf (stderr, "VS error: unkonw picture type %d\n", nb); - */ - break; - default: - break; - } - state = 0; - } - else - state = 0; - } - exit_phase1: - - if (first != 3) - { - fprintf (stderr, "VS error: given file \"%s\" is not of MPEG format.\n", this->videoFile); - return 4; - } - - this->pattern[this->patternSize] = 0; - memset (this->sendPattern, 1, PATTERN_SIZE); - - this->numF = this->numI + this->numP + this->numB; - this->averageFrameSize = fileptr / (unsigned)this->numF; - /* - fprintf (stderr, "Pass one finished, total bytes read: %u, average frame size %d\n", - fileptr, this->averageFrameSize); - fprintf (stderr, "this->numS-%d, this->numG-%d, this->numF-%d, this->numI-%d, this->numP-%d, this->numB-%d\n", - this->numS, this->numG, this->numI, this->numI, this->numP, this->numB); - fprintf (stderr, "this->Pattern detected: %s\n", this->pattern); - */ - if (this->numF > MAX_FRAMES) - { - fprintf (stderr, "VS error: this->Number of frames (%d) is bigger than MAX_FRAMES (%d).\n\ - you need to update the constant definition in common.h and recompile.\n", - this->numF, MAX_FRAMES); - return 5; - } - -#ifdef STAT - this->framesSent = (char *)malloc ( (this->numF + 7)>>3); - if (this->framesSent == NULL) - { - fprintf (stderr, "VS fails to alloc mem for this->framesSent for %d frames", this->numF); - perror (""); - return 6; - } -#endif - - this->systemHeader = (struct Video_Global::SystemHeader *)malloc (sizeof (struct Video_Global::SystemHeader) * this->numS); - if (this->systemHeader == NULL) - { - perror ("VS error on malloc this->SystemHeader"); - return 7; - } - this->gopTable = (struct Video_Global::GopTable *)malloc (sizeof (struct Video_Global::GopTable) * this->numG); - if (this->gopTable == NULL) - { - perror ("VS error on malloc GopHeader"); - return 8; - } - this->frameTable = (struct Video_Global::FrameTable *)malloc (sizeof (Video_Global::FrameTable) * this->numF); - if (this->frameTable == NULL) - { - perror ("VS error on malloc this->frameTable"); - return 9; - } - - rewind (this->fp); - fileptr = 0; - state = 0; - inpic = 0; - shptr = -1; - gopptr = -1; - ftptr = 0; - - for (;;) - { - nextByte; - if (state >= 0 && nb == 0x00) - state ++; - else if (state >= 2 && nb == 0x01) - state = -1; - else if (state == -1) - { - switch (nb) - { - case 0xb7: /* seq_end_code */ - if (gopptr >= 0 && this->gopTable[gopptr].size == 0) - this->gopTable[gopptr].size = fileptr - this->gopTable[gopptr].offset - 4; - computePicSize; - goto exit_phase2; - break; - case 0xb3: /* seq_start_code */ - if (gopptr >= 0 && this->gopTable[gopptr].size == 0) - this->gopTable[gopptr].size = fileptr - this->gopTable[gopptr].offset - 4; - computePicSize; - shptr ++; - this->systemHeader[shptr].offset = fileptr - 4; - this->systemHeader[shptr].size = 0; - break; - case 0xb8: /* gop_start_code */ - if (this->systemHeader[shptr].size == 0) - this->systemHeader[shptr].size =fileptr - this->systemHeader[shptr].offset - 4; - if (gopptr >= 0 && this->gopTable[gopptr].size == 0) - this->gopTable[gopptr].size = fileptr - this->gopTable[gopptr].offset - 4; - computePicSize; - gopptr ++; - this->gopTable[gopptr].systemHeader = shptr; - this->gopTable[gopptr].offset = fileptr - 4; - this->gopTable[gopptr].headerSize = 0; - this->gopTable[gopptr].size = 0; - this->gopTable[gopptr].totalFrames = 0; - this->gopTable[gopptr].previousFrames = gopptr ? - (this->gopTable[gopptr - 1].totalFrames + this->gopTable[gopptr - 1].previousFrames) : 0; - - break; - case 0x00: /* picture_start_code */ - if (this->gopTable[gopptr].headerSize == 0) - { - this->gopTable[gopptr].headerSize = fileptr - this->gopTable[gopptr].offset - 4; - this->gopTable[gopptr].firstIoffset = fileptr - 4; - } - this->gopTable[gopptr].totalFrames ++; - computePicSize; - picptr = fileptr - 4; - nextByte; - nextByte; - nb &= 0x38; - if (nb == 0x08) - { - pictype = 'I'; - inpic = 1; - } - else if (nb == 0x10) - { - pictype = 'P'; - inpic = 1; - } - else if (nb == 0x18) - { - pictype = 'B'; - inpic = 1; - } - break; - default: - - break; - } - state = 0; - } - else - state = 0; - } - - exit_phase2: - for (shptr = 0; shptr<this->numS; shptr++) - { - this->maxS = max (this->maxS, this->systemHeader[shptr].size); - this->minS = min (this->minS, this->systemHeader[shptr].size); - } - for (gopptr = 0; gopptr<this->numG; gopptr++) - { - this->maxG = max (this->maxG, this->gopTable[gopptr].headerSize); - this->minG = min (this->minG, this->gopTable[gopptr].headerSize); - } - this->packetBufSize = this->maxS + this->maxG + max (this->maxI, max (this->maxP, this->maxB)); - this->packet = (VideoPacket *)malloc (sizeof (VideoMessage) + sizeof (VideoPacket) + - this->packetBufSize); - if (this->packet == NULL) - { - perror ("VS error on malloc this->packet buffer"); - return 10; - } - this->packet = (VideoPacket *) ( (char *)this->packet + sizeof (VideoMessage)); - /* - fprintf (stderr, "Pass 2 finished.\n"); - fprintf (stderr, "this->maxS-%d, this->maxG-%d, this->maxI-%d, this->maxP-%d, this->maxB-%d.\n", this->maxS, this->maxG, this->maxI, this->maxP, this->maxB); - fprintf (stderr, "this->minS-%d, this->minG-%d, this->minI-%d, this->minP-%d, this->minB-%d.\n", this->minS, this->minG, this->minI, this->minP, this->minB); - */ - /* - { - int i; - - fprintf (stderr, "id: offset size -- system header table:\n"); - for (i=0; i<this->numS; i++) - fprintf (stderr, "%-3d %-9u %d\n", i, this->systemHeader[i].offset, this->systemHeader[i].size); - fprintf (stderr, - "id: header offset hdsize totSize frames preframs Ioffset Isize -- GOP\n"); - for (i=0; i<this->numG; i++) - { - fprintf (stderr, "%-4d %-8d %-8u %-8d %-8d %-8d %-8d %-8u %d\n", - i, - this->gopTable[i].this->systemHeader, - this->gopTable[i].offset, - this->gopTable[i].headerSize, - this->gopTable[i].size, - this->gopTable[i].totalFrames, - this->gopTable[i].previousFrames, - this->gopTable[i].firstIoffset, - this->frameTable[this->gopTable[i].previousFrames].size - ); - } - - fprintf (stderr, "\nframe information:"); - for (i=0; i<this->numF; i++) - fprintf (stderr, "%c%c%-8d", (i%10 ? '\0' : '\n'), this->frameTable[i].type, this->frameTable[i].size); - fprintf (stderr, "\n"); - - } - */ - fseek (this->fp, this->systemHeader[0].offset+4, 0); - nextByte; - this->horizontalSize = ( (int)nb <<4) & 0xff0; - nextByte; - this->horizontalSize |= (nb >>4) & 0x0f; - this->verticalSize = ( (int)nb <<8) & 0xf00; - nextByte; - this->verticalSize |= (int)nb & 0xff; - nextByte; - this->pelAspectRatio = ( (int)nb >> 4) & 0x0f; - this->pictureRate = (int)nb & 0x0f; - nextByte; - nextByte; - nextByte; - this->vbvBufferSize = ( (int)nb << 5) & 0x3e0; - nextByte; - this->vbvBufferSize |= ( (int)nb >>3) & 0x1f; - /* - fprintf (stderr, "SysHeader info: hsize-%d, vsize-%d, pelAspect-%d, rate-%d, vbv-%d.\n", - this->horizontalSize, this->verticalSize, this->pelAspectRatio, this->pictureRate, this->vbvBufferSize); - */ - WriteInfoToFile (); - } -#if 0 - { - int i, j = 20; - - for (i = this->numG - 1;; i --) { - if (this->gopTable[i].offset < 4235260) { - fprintf (stderr, "group %d: offset %ld\n", i, this->gopTable[i].offset); - if (j -- == 0) break; - } - } - /* - for (i = 0; i < this->numG; i ++) { - if (this->gopTable[i].previousFrames > 1800) { - fprintf (stderr, "group %d: offset %ld pre-frames %d\n", - i, this->gopTable[i].offset, this->gopTable[i].previousFrames); - break; - } - } - */ - } -#endif - { - this->firstPatternSize = this->gopTable[0].totalFrames; - this->firstSendPattern = (char *)malloc (this->firstPatternSize); - if (this->firstSendPattern == NULL) - { - fprintf (stderr, "VS failed to allocate this->firstthis->Sendthis->Pattern for %d frames", - this->firstPatternSize); - perror (""); - return 11; - } - } - this->firstGopFrames = this->gopTable[0].totalFrames; - return 0; -} -int -Video_Global::play_send (int debug) -{ - - // ACE_DEBUG ( (LM_DEBUG,"play_send: sending the frame \n")); - int curGroup = Video_Timer_Global::timerGroup; - int curFrame = Video_Timer_Global::timerFrame; - int curHeader = Video_Timer_Global::timerHeader; - char * sp; - - if (this->preGroup != curGroup || - curFrame != this->preFrame) - { - int sendStatus = -1; - int frameStep = 1; - if (debug) - cerr << " curgroup = " << curGroup << endl ; - if (curGroup == 0) - { - - int i = curFrame + 1; - while (i < this->firstPatternSize && - !this->firstSendPattern[i]) - { - frameStep ++; - i++; - } - } - else /* (curGroup > 0) */ - { - int i = curFrame + 1; - sp = this->sendPattern + ( (curGroup - 1) % this->sendPatternGops) * this->patternSize; - while (i < this->patternSize && !sp[i]) - { - frameStep ++; - i++; - } - } - if (curGroup == 0) - { - if (debug) - cerr << "first : " << - this->firstSendPattern[curFrame] << endl; - if (this->firstSendPattern[curFrame]) - sendStatus = 0; - else /* (!this->firstthis->Sendthis->Pattern[curFrame]) */ - { - int i = curFrame - 1; - while (i > 0 && !this->firstSendPattern[i]) - i--; - if (i > this->preFrame) - /* the frame (curGroup, i) hasn't been sent yet */ - { - sendStatus = 0; - curFrame = i; - } - else - sendStatus = -1; - if (debug) - cerr << "SendStatus = " << sendStatus << endl; - } - } - else if (sp[curFrame]) /* curGroup > 0 */ - sendStatus = 0; - else /* (!sp[curFrame]) */ - { - int i = curFrame - 1; - while (i > 0 && !sp[i]) - i--; - if (curGroup == this->preGroup && i > this->preFrame) - /* the frame (curGroup, i) hasn't been sent yet */ - { - sendStatus = 0; - curFrame = i; - } - else - sendStatus = -1; - } - if (!sendStatus) - { - // Send the current video frame, calls send_to_network which - // fragments and sends via blocking write . - sendStatus = this->SendPacket (this->preHeader != curHeader, - curGroup, curFrame, - (this->currentUPF + this->addedUPF) * frameStep); - if (!sendStatus) - { - this->preHeader = curHeader; - this->preGroup = curGroup; - this->preFrame = curFrame; -#ifdef STAT - if (this->play_para.collectStat) - { - int f = this->gopTable[curGroup].previousFrames + curFrame; - this->framesSent[f>>3] |= (1 << (f % 8)); - } -#endif - } - } - } - return 0; -} - -int -Video_Global::fast_play_send (void) -{ - if (this->fast_preGroup != Video_Timer_Global::timerGroup) - { - this->SendPacket (this->fast_preHeader != Video_Timer_Global::timerHeader, Video_Timer_Global::timerGroup, 0, - this->fast_para.usecPerFrame * this->patternSize >> 2); - this->fast_preHeader = Video_Timer_Global::timerHeader; - this->fast_preGroup = Video_Timer_Global::timerGroup; - } - return 0; -} - -int -Video_Global::position (void) -{ - int result; - POSITIONpara pos_para; - /* - fprintf (stderr, "POSITION . . .\n"); - */ - result = CmdRead ( (char *)&pos_para, sizeof (pos_para)); - if (result != 0) - return result; - - if (this->live_source) return 0; - -#ifdef NeedByteOrderConversion - pos_para.nextGroup = ntohl (pos_para.nextGroup); - pos_para.sn = ntohl (pos_para.sn); -#endif - - CheckGroupRange (pos_para.nextGroup); - this->cmdsn = pos_para.sn; - result = SendPacket (this->numS>1 || pos_para.nextGroup == 0, pos_para.nextGroup, 0, 0); - return result; -} - -int -Video_Global::step_video () -{ - int group; - STEPpara step_para; - int tag = 0; - int result; - - result = CmdRead ( (char *)&step_para, sizeof (step_para)); - if (result != 0) - return result; -#ifdef NeedByteOrderConversion - step_para.sn = ntohl (step_para.sn); - step_para.this->nextFrame = ntohl (step_para.this->nextFrame); -#endif - - this->cmdsn = step_para.sn; - - if (!this->live_source) { - if (step_para.nextFrame >= this->numF) /* send SEQ_END */ - { - tag = 1; - step_para.nextFrame --; - } - /* - fprintf (stderr, "STEP . . .frame-%d\n", step_para.this->nextFrame); - */ - CheckFrameRange (step_para.nextFrame); - group = FrameToGroup (&step_para.nextFrame); - if (this->precmd != CmdSTEP && !tag ) { - result = SendReferences (group, step_para.nextFrame); - if (result < 0 ) - return result; - } - } - if (this->live_source) StartPlayLiveVideo (); - - if (this->live_source) { - SendPicture (&step_para.nextFrame); - } - else if (this->video_format == VIDEO_MPEG1) { - SendPacket (this->numS>1, group, tag ? this->numF : step_para.nextFrame, 0); - } - else { - fprintf (stderr, "VS: wierd1\n"); - } - - if (this->live_source) StopPlayLiveVideo (); - return 0; -} - -int -Video_Global::fast_forward (void) -{ - return this->init_fast_play (); -} - -int -Video_Global::fast_backward (void) -{ - return this->init_fast_play (); -} - -int -Video_Global::stat_stream (void) -{ - int i, j = 0; - for (i = 0; i < this->numF; i++) - { - short size = htons (this->frameTable[i].size); - char type = this->frameTable[i].type; - if (i == this->gopTable[j].previousFrames) - { - type = tolower (type); - j ++; - } - CmdWrite ( (char *)&type, 1); - CmdWrite ( (char *)&size, 2); - } - return 0; -} - -int -Video_Global::stat_sent (void) -{ -#ifdef STAT - CmdWrite ( (char *)this->framesSent, (this->numF + 7) / 8); -#else - int i; - char zeroByte = 0; - for (i = 0; i < (this->numF + 7) / 8; i++) - CmdWrite ( (char *)&zeroByte, 1); -#endif - return 0; -} - -int -Video_Global::init_play (void) -{ - int result; - - ACE_DEBUG ( (LM_DEBUG, - " (%P|%t) this->play ()")); - - // this gets the parameters for the play command - result = this->CmdRead ( (char *)&this->play_para, sizeof (this->play_para)); - if (result != 0) - return result; -#ifdef NeedByteOrderConversion - this->play_para.sn = ntohl (this->play_para.sn); - this->play_para.this->nextFrame = ntohl (this->play_para.this->nextFrame); - this->play_para.usecPerFrame = ntohl (this->play_para.usecPerFrame); - this->play_para.framesPerSecond = ntohl (this->play_para.framesPerSecond); - this->play_para.this->frameRateLimit1000 = ntohl (this->play_para.this->frameRateLimit1000); - this->play_para.collectStat = ntohl (this->play_para.collectStat); - this->play_para.this->sendPatternGops = ntohl (this->play_para.this->sendPatternGops); - this->play_para.this->VStimeAdvance = ntohl (this->play_para.this->VStimeAdvance); -#endif - - this->frameRateLimit = this->play_para.frameRateLimit1000 / 1000.0; - this->cmdsn = this->play_para.sn; - this->currentUPF = this->play_para.usecPerFrame; - this->VStimeAdvance = this->play_para.VStimeAdvance; - - { - int ts = htonl (get_usec ()); - this->CmdWrite ( (char *)&ts, sizeof (int)); - } - - if (this->live_source || this->video_format != VIDEO_MPEG1) { - if (this->live_source) - this->PLAYliveVideo (&this->play_para); - return 0; - } - - fprintf (stderr, "this->VStimeAdvance from client: %d\n", this->VStimeAdvance); - - this->sendPatternGops = this->play_para.sendPatternGops; - ComputeFirstSendPattern (this->frameRateLimit); -#ifdef STAT - if (this->play_para.collectStat) - memset (this->framesSent, 0, (this->numF + 7)>>3); -#endif - CheckFrameRange (this->play_para.nextFrame); - Video_Timer_Global::timerFrame = this->play_para.nextFrame; - Video_Timer_Global::timerGroup = FrameToGroup (&Video_Timer_Global::timerFrame); - Video_Timer_Global::timerHeader = this->gopTable[Video_Timer_Global::timerGroup].systemHeader; - memcpy (this->sendPattern, this->play_para.sendPattern, PATTERN_SIZE); - result = SendReferences (Video_Timer_Global::timerGroup, Video_Timer_Global::timerFrame); - if (result < 0) - return result; - Video_Timer_Global::StartTimer (); - - // Sends the first frame of the video... - result = play_send (0); - return 0; -} - -int -Video_Global::init_fast_play (void) -{ - int result; - - result = CmdRead ( (char *)&this->fast_para, sizeof (this->fast_para)); - if (result != 0) - return result; -#ifdef NeedByteOrderConversion - this->fast_para.sn = ntohl (this->fast_para.sn); - this->fast_para.this->nextGroup = ntohl (this->fast_para.this->nextGroup); - this->fast_para.usecPerFrame = ntohl (this->fast_para.usecPerFrame); - this->fast_para.framesPerSecond = ntohl (this->fast_para.framesPerSecond); - this->fast_para.this->VStimeAdvance = ntohl (this->fast_para.this->VStimeAdvance); -#endif - - if (this->live_source) return 0; - - this->VStimeAdvance = this->fast_para.VStimeAdvance; - /* - fprintf (stderr, "this->VStimeAdvance from client: %d\n", this->VStimeAdvance); - */ - CheckGroupRange (this->fast_para.nextGroup); - this->cmdsn = this->fast_para.sn; - Video_Timer_Global::timerGroup = this->fast_para.nextGroup; - Video_Timer_Global::timerFrame = 0; - Video_Timer_Global::timerHeader = this->gopTable[Video_Timer_Global::timerGroup].systemHeader; - this->currentUPF = this->fast_para.usecPerFrame; - Video_Timer_Global::StartTimer (); - - fast_play_send (); - return 0; -} - -int -Video_Global::init_video (void) -{ - INITvideoPara para; - int failureType = 0; - int result; - /* - fprintf (stderr, "VS about to read Para.\n"); - */ - result = CmdRead ( (char *)¶, sizeof (para)); - if (result != 0) - return result; -#ifdef NeedByteOrderConversion - para.sn = ntohl (para.sn); - para.version = ntohl (para.version); - para.nameLength = ntohl (para.nameLength); -#endif - if (para.nameLength>0) - { - result = CmdRead (this->videoFile, para.nameLength); - if (result != 0) - return result; - } - if (Mpeg_Global::session_num > Mpeg_Global::session_limit || para.version != VERSION) { - char errmsg[128]; - this->cmd = CmdFAIL; - CmdWrite ( (char *)&this->cmd, 1); - if (Mpeg_Global::session_num > Mpeg_Global::session_limit) { - sprintf (errmsg, - "Too many sessions being serviced, please try again later.\n"); - } - else { - sprintf (errmsg, "Version # not match, VS %d.%02d, Client %d.%02d", - VERSION / 100, VERSION % 100, - para.version / 100, para.version % 100); - } - write_string (this->serviceSocket, errmsg); - exit (0); - } - this->cmdsn = para.sn; - /* - fprintf (stderr, "MPEG file %s got.\n", this->videoFile); - */ - this->videoFile[para.nameLength] = 0; - - if (!strncasecmp ("LiveVideo", this->videoFile, 9)) { - if (OpenLiveVideo (&this->video_format, &this->horizontalSize, - &this->verticalSize, &this->averageFrameSize, - &this->fps, &this->pelAspectRatio) == -1) { - failureType = 100; - goto failure; - } - if (this->video_format == VIDEO_MPEG2) { - failureType = 101; - goto failure; - } - this->live_source = 1; - - this->fileSize =0x7fffffff; - this->maxS = this->maxG = this->maxI = this->maxP = this->maxB = this->minS = this->minG = this->minI = this->minP = this->minB = 1; - this->numS = this->numG = this->numF = this->numI = 0x7fffffff; - this->numP = this->numB = 0; - this->vbvBufferSize = 1; - this->firstGopFrames = 1; - this->patternSize = 1; - this->pattern[0] = 'I'; - this->pattern[1] = 0; - this->packetBufSize = this->verticalSize * this->horizontalSize * 3; - this->packet = (VideoPacket *)malloc (sizeof (VideoMessage) + sizeof (VideoPacket) + - this->packetBufSize); - if (this->packet == NULL) - { - perror ("Error: VS error on malloc this->packet buffer"); - exit (1); - } - this->packet = (VideoPacket *) ( (char *)this->packet + sizeof (VideoMessage)); - - } - else { - static double pictureRateTable[] = {23.976, 24, 25, 29.97, 30, 50, 59.94, 60}; - - this->video_format = VIDEO_MPEG1; - failureType = init_MPEG1_video_file (); - if (failureType) goto failure; - this->fps = pictureRateTable[this->pictureRate - 1]; - } - - { - INITvideoReply reply; - - reply.totalHeaders = htonl (this->numS); - reply.totalGroups = htonl (this->numG); - reply.totalFrames = htonl (this->numF); - reply.sizeIFrame = htonl (this->maxI); - reply.sizePFrame = htonl (this->maxP); - reply.sizeBFrame = htonl (this->maxB); - reply.sizeSystemHeader = htonl (this->maxS); - reply.sizeGop = htonl (this->maxG); - reply.averageFrameSize = htonl (this->averageFrameSize); - reply.verticalSize = htonl (this->verticalSize); - reply.horizontalSize = htonl (this->horizontalSize); - reply.pelAspectRatio = htonl (this->pelAspectRatio); - reply.pictureRate1000 = htonl ( (int) (this->fps * 1000)); - reply.vbvBufferSize = htonl (this->vbvBufferSize); - reply.firstGopFrames = htonl (this->firstGopFrames); - reply.patternSize = htonl (this->patternSize); - strncpy (reply.pattern, this->pattern, PATTERN_SIZE); - - reply.live = htonl (this->live_source); - reply.format = htonl (this->video_format); - - CmdWrite ( (char *)&this->cmd, 1); - - CmdWrite ( (char *)&reply, sizeof (reply)); - - /* write the first SH, GOP and IFrame to this->serviceSocket (TCP), - using code for SendPacket () */ - { - int tmpSocket = this->videoSocket; - - if (this->live_source) StartPlayLiveVideo (); - - this->videoSocket = this->serviceSocket; - - if (this->live_source) { - int frame = 0; - SendPicture (&frame); - } - else if (this->video_format == VIDEO_MPEG1) { - SendPacket (1, 0, 0, 0); - } - else { - fprintf (stderr, "VS: this->video_format %d not supported.\n", - this->video_format); - } - this->videoSocket = tmpSocket; - - if (this->live_source) StopPlayLiveVideo (); - } - - return 0; - - } - failure: - { - char * msg; - char errmsg[64]; - this->cmd = CmdFAIL; - sprintf (errmsg, "VS failed to alloc internal buf (type %d)", failureType); - CmdWrite ( (char *)&this->cmd, 1); - msg = failureType == 1 ? "not a complete MPEG stream" : - failureType == 2 ? "can't open MPEG file" : - failureType == 3 ? "MPEG file is not seekable" : - failureType == 4 ? "not an MPEG stream" : - failureType == 5 ? - "too many frames in MPEG file, need change MAX_FRAMES and recompile VS" : - failureType == 100 ? "failed to connect to live video source" : - failureType == 101 ? "live MPEG2 not supported" : - errmsg; - write_string (this->serviceSocket, msg); - exit (0); - } -} - -//-------------------------------------------------------- -// Video_Timer_Global methods -void -Video_Timer_Global::StartTimer (void) -{ - VIDEO_SINGLETON::instance ()->addedUPF = 0; - VIDEO_SINGLETON::instance ()->addedSignals = 0; - timerAdjust = (VIDEO_SINGLETON::instance ()->VStimeAdvance * SPEEDUP_INV_SCALE) / VIDEO_SINGLETON::instance ()->currentUPF; - /* - SFprintf (stderr, "VS StartTimer (): fast-start frames %d\n", - timerAdjust / SPEEDUP_INV_SCALE); - */ - TimerSpeed (); - // setsignal (SIGALRM, timerHandler); - timerOn = 1; - preTimerVal = get_usec (); - /* - fprintf (stderr, "VS: timer started at %d upf.\n", VIDEO_SINGLETON::instance ()->currentUPF + VIDEO_SINGLETON::instance ()->addedUPF); - */ -} - -void -Video_Timer_Global::StopTimer (void) -{ - struct itimerval val; - // ## I have to incorporate this logic into the changed code - // setsignal (SIGALRM, SIG_IGN); - val.it_interval.tv_sec = val.it_value.tv_sec = 0; - val.it_interval.tv_usec = val.it_value.tv_usec = 0; - setitimer (ITIMER_REAL, &val, NULL); - timerOn = 0; - /* - fprintf (stderr, "VS: timer stopped.\n"); - */ -} - -void -Video_Timer_Global::TimerSpeed (void) -{ - struct itimerval val; - int usec = VIDEO_SINGLETON::instance ()->currentUPF + VIDEO_SINGLETON::instance ()->addedUPF; - if (Mpeg_Global::drift_ppm) { - /* - int drift = (double)usec * (double)Mpeg_Global::drift_ppm / 1000000.0; - SFprintf (stderr, "Mpeg_Global::drift_ppm %d, usec %d, drift %d, new usec %d\n", - Mpeg_Global::drift_ppm, usec, drift, usec - drift); - */ - usec -= (int) ( (double)usec * (double)Mpeg_Global::drift_ppm / 1000000.0); - } - if (timerAdjust > 1) - usec = (int) ( ( (double)usec * (double) (SPEEDUP_INV_SCALE - 1)) / - (double)SPEEDUP_INV_SCALE); - val.it_interval.tv_sec = val.it_value.tv_sec = usec / 1000000; - val.it_interval.tv_usec = val.it_value.tv_usec = usec % 1000000; - setitimer (ITIMER_REAL, &val, NULL); - /* - SFprintf (stderr, - "VS TimerSpeed () at %s speed, timerAdjust %d VIDEO_SINGLETON::instance ()->addedSignals %d.\n", - (timerAdjust > 1) ? "higher" : "normal", timerAdjust, VIDEO_SINGLETON::instance ()->addedSignals); - */ - -} - -void -Video_Timer_Global::TimerProcessing (void) -{ -/* - fprintf (stderr, "VS: timerHandler...\n"); -*/ - if (!timerOn) { - return; - } - if (timerAdjust < 0) - { - timerAdjust += SPEEDUP_INV_SCALE; - return; - } - if (timerAdjust >0) - { - if ( (--timerAdjust) == 0) - TimerSpeed (); - } - if (VIDEO_SINGLETON::instance ()->cmd == CmdPLAY) - { - if (timerGroup == VIDEO_SINGLETON::instance ()->numG - 1 && timerFrame >= VIDEO_SINGLETON::instance ()->gopTable[timerGroup].totalFrames - 1) - { - timerFrame ++; /* force sending of END_SEQ when PLAY VIDEO_SINGLETON::instance ()->cmd */ - StopTimer (); - return; - } - else - { - timerFrame ++; - if (timerFrame >= VIDEO_SINGLETON::instance ()->gopTable[timerGroup].totalFrames) - { - timerGroup ++; - timerFrame = 0; - timerHeader = VIDEO_SINGLETON::instance ()->gopTable[timerGroup].systemHeader; - } - } - } - else { - if (VIDEO_SINGLETON::instance ()->cmd == CmdFF) { - if (timerGroup == VIDEO_SINGLETON::instance ()->numG - 1) { - StopTimer (); - return; - } - timerGroup ++; - timerHeader = VIDEO_SINGLETON::instance ()->gopTable[timerGroup].systemHeader; - } - else { - if (timerGroup == 0) { - StopTimer (); - return; - } - timerGroup --; - timerHeader = VIDEO_SINGLETON::instance ()->gopTable[timerGroup].systemHeader; - } - } - -} - -void -Video_Timer_Global::timerHandler (int sig) -{ - // ACE_DEBUG ( (LM_DEBUG, - // "Video_Timer_Global::timerHandler\n")); - - int val2, val3; - int usec = VIDEO_SINGLETON::instance ()->currentUPF + VIDEO_SINGLETON::instance ()->addedUPF; - - if (Mpeg_Global::drift_ppm) { - usec -= (int) ( (double)usec * (double)Mpeg_Global::drift_ppm / 1000000.0); - } - - if (timerAdjust > 1) - usec = (int) ( ( (double)usec * (double) (SPEEDUP_INV_SCALE - 1)) / - (double)SPEEDUP_INV_SCALE); - val3 = get_duration (preTimerVal, (val2 = get_usec ())); - /* - if (val3 >= usec<< 1)) - fprintf (stderr, "Slower: %d out of VIDEO_SINGLETON::instance ()->currentUPF %d.\n", - val3, usec); - else - fprintf (stderr, "+\n"); - */ - preTimerVal = val2; - if (val3 < 0 || val3 > 100000000) - val3 = usec; - val2 = (val3 + (usec>>1)) / usec; - if (val2 < 0) val2 = 0; - if (val2) { - TimerProcessing (); - val2 --; - } - VIDEO_SINGLETON::instance ()->addedSignals += val2; - - if (VIDEO_SINGLETON::instance ()->addedSignals) { - val2 = timerAdjust; - if (timerAdjust < MAX_TIMER_ADJUST) { - timerAdjust += VIDEO_SINGLETON::instance ()->addedSignals * SPEEDUP_INV_SCALE; - if (val2 < SPEEDUP_INV_SCALE) { - TimerSpeed (); - } - } - else { - /* - fprintf (stderr, "VS timerAdjust %d, VIDEO_SINGLETON::instance ()->addedSignals %d, timerFrame %d\n", - timerAdjust, VIDEO_SINGLETON::instance ()->addedSignals, timerFrame); - */ - for (val3 = 0; val3 < VIDEO_SINGLETON::instance ()->addedSignals; val3 ++) - TimerProcessing (); - } - VIDEO_SINGLETON::instance ()->addedSignals = 0; - } -} |