void cTransfer::Action(void) { int PollTimeouts = 0; uchar *p = NULL; int Result = 0; while (Running()) { int Count; uchar *b = ringBuffer->Get(Count); if (b) { if (ringBuffer->Available() > TRANSFERBUFSIZE * 9 / 10) { // If the buffer runs full, we have no chance of ever catching up // since the data comes in at the same rate as it goes out (it's "live"). // So let's clear the buffer instead of suffering from permanent // overflows. dsyslog("clearing transfer buffer to avoid overflows"); DeviceClear(); ringBuffer->Clear(); remux->Clear(); PlayPes(NULL, 0); p = NULL; continue; } Count = remux->Put(b, Count); if (Count) ringBuffer->Del(Count); } if (!p) p = remux->Get(Result); if (p) { cPoller Poller; if (DevicePoll(Poller, 100)) { PollTimeouts = 0; int w = PlayPes(p, Result); if (w > 0) { p += w; Result -= w; remux->Del(w); if (Result <= 0) p = NULL; } else if (w < 0 && FATALERRNO) LOG_ERROR; } else { PollTimeouts++; if (PollTimeouts == POLLTIMEOUTS_BEFORE_DEVICECLEAR) { dsyslog("clearing device because of consecutive poll timeouts"); DeviceClear(); ringBuffer->Clear(); remux->Clear(); PlayPes(NULL, 0); p = NULL; } } } } }
void cTransfer::Receive(uchar *Data, int Length) { if (cPlayer::IsAttached()) { // Transfer Mode means "live tv", so there's no point in doing any additional // buffering here. The TS packets *must* get through here! However, every // now and then there may be conditions where the packet just can't be // handled when offered the first time, so that's why we try several times: for (int i = 0; i < MAXRETRIES; i++) { if (PlayTs(Data, Length) > 0) return; cCondWait::SleepMs(RETRYWAIT); } DeviceClear(); esyslog("ERROR: TS packet not accepted in Transfer Mode"); } }
void cDvbPlayer::Empty(void) { LOCK_THREAD; if (nonBlockingFileReader) nonBlockingFileReader->Clear(); if (!firstPacket) // don't set the readIndex twice if Empty() is called more than once readIndex = ptsIndex.FindIndex(DeviceGetSTC()) - 1; // Action() will first increment it! delete readFrame; // might not have been stored in the buffer in Action() readFrame = NULL; playFrame = NULL; dropFrame = NULL; ringBuffer->Clear(); ptsIndex.Clear(); DeviceClear(); firstPacket = true; }
int main(int argc,char **argv) { int MySocket,MyControlPort; char SocketsBuffer[SOCKETS_BUFFER_SIZE]; struct sockaddr_in MyAddress,MyControlAddress; unsigned int ControlPort; int status; int retval; // Create socket (allocate resources) if((MySocket=socket( PF_INET, // IPv4 SOCK_STREAM, // TCP 0))==-1) { printf("Error: Unable to create socket (%i)...\n",errno); perror("sockets"); // Print error message based on errno exit(1); } // Establish TCP connection memset(&MyAddress,0,sizeof(struct sockaddr_in)); // Set structure to zero MyAddress.sin_family=PF_INET; // IPv4 MyAddress.sin_port=htons(SOCKETS_PORT); // Port number (in network order) MyAddress.sin_addr.s_addr= inet_addr(SOCKETS_IP_ADDRESS); // IP address (in network order) if(connect(MySocket,(struct sockaddr *)&MyAddress, sizeof(struct sockaddr_in))==-1) { printf("Error: Unable to establish connection to socket (%i)...\n", errno); perror("sockets"); // Print error message based on errno exit(1); } // Minimize latency by setting TCP_NODELAY option SetNODELAY(MySocket); // Clear status and reset instrument WriteString(MySocket,"*CLS;*RST\n"); // Get instrument's ID string WriteString(MySocket,"*IDN?\n"); ReadString(MySocket,SocketsBuffer); printf("Instrument ID: %s\n",SocketsBuffer); // Ask for control port WriteString(MySocket,"SYST:COMM:TCPIP:CONTROL?\n"); if(ReadString(MySocket,SocketsBuffer)==0) { printf("Warning: No response from instrument (control port).\n"); retval=0; goto SocketMainClose; } sscanf(SocketsBuffer,"%u",&ControlPort); printf("Control Port: %u\n",ControlPort); // Create socket for control port if((MyControlPort=socket(PF_INET,SOCK_STREAM,0))==-1) { printf("Error: Unable to create control port socket (%i)...\n",errno); perror("sockets"); // Print error message based on errno retval=1; goto SocketMainClose; } // Establish TCP connection to control port memset(&MyControlAddress,0, sizeof(struct sockaddr_in)); // Set structure to zero MyControlAddress.sin_family=PF_INET; // IPv4 MyControlAddress.sin_port= htons(ControlPort); // Port number (in network order) MyControlAddress.sin_addr.s_addr= inet_addr(SOCKETS_IP_ADDRESS); // IP address (in network order) if(connect(MyControlPort,(struct sockaddr *)&MyControlAddress, sizeof(struct sockaddr_in))==-1) { printf( "Error: Unable to establish connection to control port (%i)...\n", errno); perror("sockets"); // Print error message based on errno retval=1; goto SocketMainClose; } // Do a device clear DeviceClear(MyControlPort,SocketsBuffer); // Demonstrate SRQ... First, tell the instrument when to generate an SRQ // NOTE: The following commands are dependant of the instrument // This example is for the Agilent L4410A, L4411A,34410A or 34411A WriteString(MySocket, "*ESE 1\n"); // Operation Complete causes Standard Event WriteString(MySocket, "*SRE 32\n"); // Standard Event causes SRQ // Now perform some operation(s) and raise SRQ when done WriteString(MySocket,"CONF:FREQ\n"); // Go to frequency measurement mode WriteString(MySocket,"*OPC\n"); // Tell us when you're ready! // Now wait until data becomes available on the control link if(WaitForData(MyControlPort)==0) { printf("Warning: Instrument did not generate SRQ.\n"); retval=0; goto SocketClose; } // Data available... Read and interpret! ReadString(MyControlPort,SocketsBuffer); printf("Data read on control port: %s\n",SocketsBuffer); if(strncmp(SocketsBuffer,"SRQ",3)!=0) { printf("Warning: Didn't receive an SRQ!\n"); retval=0; goto SocketClose; } sscanf(SocketsBuffer,"SRQ%i",&status); printf("Status is: %d",status); SocketClose: // Close control port if(close(MyControlPort)==-1) { printf("Error: Unable to close control port socket (%i)...\n",errno); perror("sockets"); // Print error message based on errno retval=1; } SocketMainClose: // Close main port if(close(MySocket)==-1) { printf("Error: Unable to close socket (%i)...\n",errno); perror("sockets"); // Print error message based on errno retval=1;; } exit(retval); }
void cSoftPlayer::Action() { PLDBG("Thread started: SoftPlayer\n"); running=true; SoftDevice=cDevice::PrimaryDevice(); #if VDRVERSNUM >= 10330 cPlugin *softdevicePlugin=cPluginManager::GetPlugin("softdevice"); printf("softdevicePlugin %p\n",softdevicePlugin); if ( !softdevicePlugin || !softdevicePlugin->Service(GET_PACKET_HANDEL_IDV100, (void *) &SoftHandles) ) { printf("Didn't find the softdevice for output!!\n"); exit(-1); }; //SoftDevice->SetPlayMode( (ePlayMode) pmAudioVideo ); if (SoftplaySetup.UseReceiver()) { const cChannel *channel=Channels.GetByNumber(cDevice::CurrentChannel()); Receiver=new cSoftplayReceiver(channel, cDevice::PrimaryDevice(),SoftHandles); #if VDRVERSNUM >= 10500 cDevice *receiveDev=cDevice::GetDevice(channel,1,false); #else cDevice *receiveDev=cDevice::GetDevice(channel,1); #endif if (receiveDev) receiveDev->AttachReceiver(Receiver); }; #else if (!SoftDevice) { printf("the Softdevice has to be primary device!!\n"); exit(-1); }; // limitation in cPlayer: we have to know the play mode at // start time. Workaraound set play mode again and // put the softdevice in packet mode SoftDevice->SetPlayMode( (ePlayMode) -pmAudioVideo ); // Length = -1: set format context SoftDevice->PlayVideo((uchar *) ic,-1); #endif while ( running ) { if (newFile) FileReplay(); usleep(20000); }; if (Receiver) delete Receiver; Receiver=NULL; DeviceClear(); // force a softdevice reset //SoftDevice->SetPlayMode( pmNone ); //FIXME find a different solution running=false; PLDBG("Thread beendet : SoftPlayer \n"); };
void cSoftPlayer::FileReplay() { AVPacket pkt; int ret; int PacketCount=0; int64_t PTS=0; int64_t lastPTS=0; pollTimeouts=0; pause=false; forward=true; new_forward=true; speed=-1; new_speed=-1; AudioIdx=-1; VideoIdx=-1; reading=true; OpenFile(filename); newFile=false; if (!ic) { printf("ic is null!!\n"); reading= false; return; }; if (Receiver && (Streams & SOFTDEVICE_VIDEO_STREAM) ) { Receiver->StopTransfer(); DeviceClear(); }; if (Receiver && !(Streams & SOFTDEVICE_VIDEO_STREAM) ) Receiver->StartTransfer(); ResetDevice(Streams); while ( running && reading && !newFile) { if ( PollDevice(Streams) ) { //PLDBG("poll timeout!!!\n"); pollTimeouts++; if (pollTimeouts > 100) { PLDBG("Too many poll timeouts! Reseting device.\n"); ResetDevice(Streams); pollTimeouts=0; }; continue; } else pollTimeouts=0; // seek forward / backward if (skip) { PLDBG("player skip %d curr pts: %lld, lastPTS %lld\n",skip, SoftDevice->GetSTC()/9*1000,lastPTS); //av_seek_frame(ic,-1, // (SoftDevice->GetSTC()/9+skip*100)*100); #if LIBAVFORMAT_BUILD > 4618 av_seek_frame(ic,-1, (SoftDevice->GetSTC()/9+skip*10000)*100, AVSEEK_FLAG_BACKWARD); #else av_seek_frame(ic,-1, (SoftDevice->GetSTC()/9+skip*10000)*100); #endif PLDBG("clear\n"); skip=0; ResetDevice(Streams); //SoftDevice->ClearPacketQueue(); PLDBG("clear finished\n"); }; if ( speed != new_speed ) { PLDBG("speed change\n"); ResetDevice(Streams); // if (new_speed!=-1) // av_seek_frame(ic,-1,SoftDevice->GetSTC()/9*100); // if (new_speed != -1) // cPlayer::DeviceTrickSpeed(2); // else cPlayer::DeviceTrickSpeed(1); fast_STC=SoftDevice->GetSTC()/9*100; forward = new_forward; speed = new_speed; }; if ( speed!=-1 ) { int step=5*100000; // 5 zehntel sek. if (!forward) step=-step; fast_STC+=step; #if LIBAVFORMAT_BUILD > 4618 av_seek_frame(ic,-1,fast_STC, AVSEEK_FLAG_BACKWARD); #else av_seek_frame(ic,-1,fast_STC); #endif PKTDBG("fast_STC %lld diff %lld forward %d step %d\n", fast_STC,PTS-lastPTS,forward,step); }; ret = av_read_frame(ic, &pkt); //ret = av_read_packet(ic, &pkt); PacketCount++; if (ret < 0) { printf("Error (%d) reading packet!\n",ret); reading=false; continue; } if (pause) { FreezeDevice(Streams,1); while (pause && running && reading) usleep(10000); FreezeDevice(Streams,0); }; lastPTS=PTS; PTS=pkt.pts; RemuxAndQueue(pkt); if (PacketCount == 200) dump_format(ic, 0, "test", 0); // update duration (FIXME does that help?) duration=ic->duration; int currPos= SoftDevice->GetSTC()*AV_TIME_BASE/(9*10000); if (duration<currPos) duration=currPos; } //if (running) // DeviceFlush(20000); PLDBG("Before FlushDevice %d %d \n",running,newFile); if (running && !newFile) { FlushDevice(Streams); }; ResetDevice(Streams); };