diff options
Diffstat (limited to 'client/encoder.cc')
| -rw-r--r-- | client/encoder.cc | 273 | 
1 files changed, 273 insertions, 0 deletions
| diff --git a/client/encoder.cc b/client/encoder.cc new file mode 100644 index 0000000..e7b79bf --- /dev/null +++ b/client/encoder.cc @@ -0,0 +1,273 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            encoder.cc + * + *  Tue Apr 19 12:10:34 CEST 2005 + *  Copyright  2005 Bent Bisballe + *  deva@aasimon.org + ****************************************************************************/ + +/* + * Originally from: + * RTVideoRec Realtime video recoder and encoder for Linux + * + * Copyright (C) 2004  B. Stultiens + * Copyright (C) 2004  Koen Otter and Glenn van der Meyden + */ + +/* + *    This file is part of MIaV. + * + *    MIaV is free software; you can redistribute it and/or modify + *    it under the terms of the GNU General Public License as published by + *    the Free Software Foundation; either version 2 of the License, or + *    (at your option) any later version. + * + *    MIaV is distributed in the hope that it will be useful, + *    but WITHOUT ANY WARRANTY; without even the implied warranty of + *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *    GNU General Public License for more details. + * + *    You should have received a copy of the GNU General Public License + *    along with MIaV; if not, write to the Free Software + *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include <config.h> +#ifdef USE_GUI + +#include "util.h" +#include "encoder.h" + +Encoder::Encoder(Info *ginfo, +                 const char *gip, +                 const int gport, +                 sem_t	*gsem, +                 Queue<Frame> *gqueue, +                 pthread_mutex_t *gmutex, +                 volatile int *grunning) +{ +  info = ginfo; + +  strcpy(ip, gip); +  port = gport; +  memset(cpr, 0, sizeof(cpr)); + +  sem = gsem; +  queue = gqueue; +  mutex = gmutex; +  running = grunning; + +  //  record = 0; + + 	sem_init(&record_sem, 0, 0); + +  s = NULL; +  n = NULL; + +  frozen = false; + +  savestate_sent = false; +  savestate = NO_CHANGE; + +  //  shoot_request = 0; +  //  shoot_value = 0; +  //  freeze_request = 0; +  //  freeze_value = 0; +} + + +Encoder::~Encoder() +{ +  // If a hanging connection exists, we better close it. +  /* // Already deleted in thread_main +  if(s) { +    if(n) delete n; +    delete s; +    s = NULL; +    n = NULL; +  } +  */ +} + + +void Encoder::encode() +{  +  Frame *frame; + +  while(*running) { +    sem_wait(sem); + +    frame = queue->pop(); +     +    if(frame) { +      if(frame->freeze == 1) frozen = true; +      if(frame->freeze == -1) frozen = false; +      if(frame->shoot) frozen = false; + +      if(frame->record ||  +         (frame->freeze == 1) ||  +         frame->shoot) { + +        // If no connection is present, make a new one +        if(!s) { +          s = new Socket(port, info); +          s->sconnect(ip); +          n = new Network(s, info); +        } + +        n_header h; +       +        if(savestate != NO_CHANGE) savestate_sent = true; + +        h.header_type = DATA_HEADER; +        sprintf(h.header.h_data.cpr, cpr); +        h.header.h_data.freeze = frame->freeze; +        h.header.h_data.snapshot = frame->shoot; +        h.header.h_data.record = frame->record; +        h.header.h_data.savestate = savestate;//NO_CHANGE; +        h.header.h_data.mute = frame->mute; + +        savestate = NO_CHANGE; // only transmit once! +         +        //        if(freeze_request != freeze_value) freeze_value = freeze_request; +        //        if(shoot_request != shoot_value) shoot_value = shoot_request; +         +        n->sendPackage(&h, frame->data, frame->size); +      } else { +        // When frozen we need to preserve the connection in order to +        // remember the frozen frame on the server side. +        if(!frozen) { +          // No data is to be sent, if we have a connection, destroy it. +          if(s) { +            if(n) delete n; +            delete s; +            s = NULL; +            n = NULL; +          } +        } +      } + +      if(frame->shoot && !frozen && !frame->record) { +        // FIXME: This is ugly! +        // Bugfix... connection not cleared, when an 'unfrozen' snapshot is taken,  +        // and no recording is done. +        if(s) { +          if(n) delete n; +          delete s; +          s = NULL; +          n = NULL; +        } +      } + +      if(frame) delete frame; +    } +  } +} + + +void Encoder::setCpr(char *newcpr) +{ +  strcpy(cpr, newcpr); +} + + +void Encoder::freeze() +{  +  /*  +  if(!s) { +    s = new Socket(port, errobj); +    s->sconnect(ip); +    n = new Network(s, errobj); +  } +  */ +  //  if(!errobj->hasError()) freeze_request = 1 - freeze_request; +} + + +/* + * shoot + * Set the shoot bit in the network header on the current frame. + * return the decodet (rgba) version af that frame, for thumbnail show. + */ +void Encoder::shoot() +{ +  /* +  if(!s) { +    s = new Socket(port, errobj); +    s->sconnect(ip); +    n = new Network(s, errobj); +  } +  */ +  //  if(!errobj->hasError()) shoot_request = 1 - shoot_request; +  //  getScreenshot(rgb); +} + + +void Encoder::thread_main() +{ +  encode(); +  if(s) { +    if(n) delete n; +    delete s; +    s = NULL; +    n = NULL; +  } +  fprintf(stderr, "Encoder thread stopped.\n"); fflush(stderr); +} + + +void Encoder::start() +{ +  savestate = NO_CHANGE; +  savestate_sent = false; +  /* +  if(!s) { +    s = new Socket(port, errobj); +    s->sconnect(ip); +    n = new Network(s, errobj); +  } +  */ +  //  if(!errobj->hasError()) record = 1; +} + + +void Encoder::stop(n_savestate save) +{ +  savestate = save; +  // Don't return until we are sure the savestate has been sent. +  while(savestate_sent == false) { +    // Just wait a while (in a while!) +    sleep_0_2_frame(); +  } +/* +  struct timespec ts; +  // TODO: set save state in package header. + +  // Lock the queue and wait until all elements are sent on the network. +  queue->lock(); +  fprintf(stderr, "Emptying queue"); fflush(stderr); +  while(queue->peek()) { +    // Remove any late buffer +    // We don't care, the encoder finishes them all +    ts.tv_sec = 0; +    ts.tv_nsec = 500000000L;	// 100ms +    fprintf(stderr, "."); fflush(stderr); +    nanosleep(&ts, NULL); +  } +  fprintf(stderr, "done!\n"); fflush(stderr); + +  record = 0; + +  queue->unlock(); +*/ +/* +  if(s) { +    if(n) delete n; +    delete s; +    s = NULL; +    n = NULL; +  } +*/ +} + +#endif /*USE_GUI*/ | 
