Quality and Usage enhancement in TÉLÉSIA

H261 video packetization, h261ip.h:

/**************************************************************************\
*          Copyright (c) 1991,1992,1993,1994,1995 INRIA siege, FRANCE.     *
*          Copyright (c) 1993, 1994, 1995, Pierre leonard                  *
*                                                                          *
* Permission to use, copy, modify, and distribute this software and        *
* its documentation for any purpose and without fee is hereby granted,     *
* provided that this copyright notice and this permission notice appear    *
* in all copies, and that both that copyright notice and this permission   *
* notice appear in supporting documentation.                               *
* WE MAKE NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY OF THIS     *
* MATERIAL FOR ANY PURPOSE.  IT IS PROVIDED "AS IS", WITHOUT ANY EXPRESS   *
* OR IMPLIED WARRANTIES.                                                   *
*                                                                          *
* This software and its documentation has been produced by the TELESIA     *
* project. The TELESIA project focuse these research on the Teleworking    *
* on Wide Area Network, the usage through a wide experimentation plan.     *
*                                                                          *
* The TELESIA Team is currently composed by:                               *
*                                                                          *
*       - Alain Caristan        Project manager   *
*       - Pierre De La Motte                      *
*       - Andrzej Wozniak                       *
*       - Pierre Leonard                    *
*                                                                          *
*   Many thank's to :                                                      *
*                                                                          *
*       - Christian Donot      MBONE Manager     *
*       - Olivier Marset                                                   *
*       - Georges Gyory                                                    *
*       - Philippe Riguet                                                  *
*                                                                          *
* The TELESIA project is sponsored by:                                     *
*                                                                          *
*       - INRIA siege (Rocquencourt)                                       *
*       - ARISTOTE, an association of important users, studying, testing   *
*         and promoting advanced technologie in the network field,         *
*         interoperability, multimedia.                                    *
*       - Pierre Leonard, from October 1993 until January 1995             *
*                                                                          *
* The TELESIA patners are:                                                 *
*                                                                          *
*       - PAGEIN, a European project dedicated to the sharing of high      *
*         computing ressources,                                            *
*       - Rodeo, INRIA Sophia Antipolis network project.                   *
*                                                                          *
*                                                                          *
* This file was created by:   Pierre Leonard                               *
*            creation date:   19 Octobre 1994                              *
*                                                                          *
* This file receive contributions from:                                    *
*          Andrzej Wozniak: bit_state definitions and structures           *
\**************************************************************************/
//
//
// Mise en paquet d'un flux H261 dans une connexion IP.
// en unicast ou Multicast.
// Cette version de MEP, integre les dernieres proposition de Andrzej
// Wozniak et Pierre Leonard, destinees a ameliorer le robustesse
// du decodeur.

// New packetization of a H261 stream in IP packets.
// That code is the implementation of the propositions of
// andrzej Wozniak and Pierre Leonard, in November 1994,
// in order to improve the robustness of the H261 decoder.

/*
 * fonctionnalites :
 *		creation,
 *		decoupage et envoi d'un flux h261, GOB par GOB
 *		reception, decodage des paquets, envoi au decodeur
 *              class creation,
 *              cut the stream at the Block border,
 *              complet the new H261 header with absolute frame references
 */

#ifndef HH261IP
#define HH261IP

extern "C" {
#include "h261.h"
}
#include "protocol_rtp.h"

#ifdef __alpha
#include 
#endif
/*-----------------------------*/
typedef enum TypeState {
  AT_UNKNOWN,
  AT_LOST,   
  AT_RESYNC, 
  AT_RESYNC_N,
  AT_TR,     
  AT_GBSC,
  AT_GN,
  AT_GN_N,
  AT_MBA,  
  AT_MTYPE, 
  AT_ERROR} ; 
/*-----------------------------*/

#define DEC_STAT_NONE          0x00000000 /* initial non valid status                  */
#define DEC_STAT_VALID         0x80000000 /* validation mask                           */
#define DEC_STAT_IDLE          0x40000000 /* decoder reads the stream without decoding */
#define DEC_STAT_FMT_CHG       0x20000000 /* format/color change indicator             */
#define DEC_STAT_ALLOC_CHG     0x10000000 /* buffer size need to change                */
#define DEC_STAT_DISPLAY       0x08000000 /* display image                   */
#define DEC_STAT_RESYNCHRO     0x04000000 /* try to resynchronize after error          */
#define DEC_STAT_STUFF_LOST    0x02000000 /* inserting MBA_STUFFING after packet lost  */
#define DEC_STAT_LOST_FLUSH    0x01000000 /* ignore errors                             */
#define DEC_STAT_FMT_CIF       0x00800000 /* format status mask (CIF4|CIF)/QCIF)       */
#define DEC_STAT_FMT_CIF4      0x00400000 /* format status mask  CIF4                  */
#define DEC_STAT_COLOR         0x00200000 /* color encoded                             */
#define DEC_STAT_MVD           0x00100000 /* mov estimation coded                      */
#define DEC_STAT_CIF_NBR_MASK  0x000000f0 /* mask to read cif number,  0,1,2,3         */
#define DEC_STAT_SIZE_MASK     0x0000000f /* mask to read format code, 4 bits for 3    */
                                          /* possible values:                          */
                                          /* QCIF_SIZE, CIF_SIZE, CIF4_SIZE            */
#define DEC_STAT_CIF_NBR_POS   4

#define DEC_STAT_FMT_MASK     (DEC_STAT_FMT_CIF    \
			       | DEC_STAT_COLOR    \
			       | DEC_STAT_FMT_CIF4 \
			       | DEC_STAT_SIZE_MASK)

#define DEC_STAT_ALLOC_MASK   (DEC_STAT_FMT_MASK   \
			       | DEC_STAT_MVD)


#define DEC_STAT_FLOW_MASK    ( DEC_STAT_ALLOC_MASK           \
			       | DEC_STAT_CIF_NBR_MASK)

#define DEC_STAT_LOST_MASK    (DEC_STAT_STUFF_LOST | DEC_STAT_LOST_FLUSH)

#define DEC_STAT_PACK_INFO     0x00080000 /* packcetization info valid                 */
#define DEC_STAT_PACK_USED     0x00040000 /* packcetization info used                 */
#define DEC_STAT_PACK_LOST     0x00020000 /* some packet are lost status               */
#define DEC_STAT_PACK_PSC      0x00008000 /* PSC in begin of the packet                */
#define DEC_STAT_PACK_GBSC     0x00004000 /* GBSC in begin of the packet               */
#define DEC_STAT_PACK_MBA      0x00002000 /* MBA  in begin of the packet               */
#define DEC_STAT_PACK_PEC      0x00000800 /* last MB of the picture is in the packet   */
#define DEC_STAT_PACK_GBEB     0x00000400 /* last MB of the GOB is in the packet       */

#define MASK_PACK_HEAD    (DEC_STAT_PACK_PSC     \
			  | DEC_STAT_PACK_GBSC  \
			  | DEC_STAT_PACK_MBA)

#define MASK_PACK_TAIL    (DEC_STAT_PACK_PEC     \
			  | DEC_STAT_PACK_GBED )

/*----------------------------------------------------------------------------*/
typedef struct{
u_int dec_stat;      /* decoder status word                    */
u_int pack_stat;     /* packetisation status word              */
u_int unexpected;    /* unexpected event status word           */

int max_GN;     
int inc_h261_GN;
int size;
int image;
int full_cbp;


u_char* buf;     /* ptr to first non read h261 stream byte */ 
int blen;        /* byte length of the buffer contents     */
int sbit;        /* start bit int the first byte           */
int ebit;        /* end bit int the last byte              */

u_char* pb;      /* ptr to the last byte + 1   */
int cb;          /* byte count/negative offset */
int cbit;        /* bit counter (negative)     */
u_int cache;     /* 32-bit bit-stream cache    */

u_char h_tr;
u_char h_gob;
u_char h_mb;
u_char h_mb_last;
int cif_number;

char* input_file_name;
int h261_error;
int err_val0;
int err_val1;
TypeState glob_state;
int l_zero;
int dvm_horiz;
int dvm_verti;

int h261_PTYPE;
int decoded_CBP;
int decoded_MTYPE;
int decoded_MBA;
int h261_TR;

int current_GN;
int expected_GN;

int mba;
} TYPE_dec_bit_state;
/*
   ReadBuffer must set buf, blen, sbit ebit values
*/



typedef struct {
  unsigned char       h_gob;         // GOB nb
  unsigned char       h_mb;          // MB nb
  unsigned char       h_mb_last;     // dernier MB encode/ last MB encoded
  unsigned char       Sbit;          // adr debut du GOB en bits
                                     // beginning addr of the GOB in bit
  unsigned char       Ebit;          // adr fin du GOB en bits
                                     // end of the GOB in bit
#if defined (ARCH_LITTLE_ENDIAN)
  unsigned int        mbz:1;         // doit etre a 0 pas teste
                                     // must be 0
  unsigned int        Couleur:1;     // codage de la couleur
                                     // color coding
  unsigned int        vecteur:1;     // codage du chgt vectorise
                                     // vector coding
  unsigned int        intra:1;       // Image codee en intra
                                     // frame coded in INTRA or INTER
  unsigned int        typf:2;        // type de paquet fin I G M
                                     // packet begin with a I G M
  unsigned int        typd:2;        // type de paquet debut I G M
                                     // packet ended with a I G M
#else
  unsigned int        typd:2;        // type de paquet debut I G M
                                     // packet ended with a I G M
  unsigned int        typf:2;        // type de paquet fin I G M
                                     // packet begin with a I G M
  unsigned int        intra:1;       // Image cote en intra
                                     // frame coded in INTRA or INTER
  unsigned int        vecteur:1;     // codage du chgt vectorise
                                     // vector coding
  unsigned int        Couleur:1;     // codage de la couleur
                                     // color coding
  unsigned int        mbz:1;         // doit etre a 0 pas teste
                                     // must be 0
#endif
  unsigned char       format;        // format de l'image qcif, cif, scif
                                     // frame format Qcif, cif or Super cif *4
  unsigned char       MBz;
} h261_et;

extern "C" int errno;

const  int          H261_DEP_BUF = 8 /*sizeof(rtphdr_t)*/ + sizeof(h261_et);
const  int          RTP_H261_CONTENT = 31;
const  int          MAX_PACKET = 1446;      // taille d'un paquet ip

// Copyright (c) 1993, 1994, 1995, Pierre leonard, INRIA Rocquencourt
class h261ip {
  short               nbpaquet;      // nb paquets emis pour cet envoi
                                     // nb packets sent
  short               nbgob;         // nb GOB dans ce paquet
                                     // nb GOB in that packet
  short               nbmb;          // nb MB dans ce paquet
                                     // nb MB in that packet
  short               bindok;        // bind deja fait ?
                                     // network bind already done
  short               initheader;    // flag d'en-tete d'image faite
                                     // H261 header already filled
  u_int               rechost;       // ipaddr de reception pour connection
                                     // IP addr for the connect
  proto_rtp*          res;           // acces au reseau par rtp
                                     // RTP access methode
  rtpbuf*             prec;          // paquet precedent en lecture
                                     // previous packet read
  h261_et             h261hd;        // en tete h261
                                     // h261 header


  void buildh261hnext ();            // construit l'en tete h261 d'un gob mb
                                     // filled the H261 header

  char* copyh261hd (char* from);     // copy de l'en tete h261
                                     // retour : adresse du debut
                                     // h261 header copy

  void constrpaquet (TypeHuffDescrTab* marques, int preums, int der);
                                     // construit et envoi un paquet h261
                                     // build and send a H261 packet


  int recpaquet (h261_et** h261_hd, char** flux, rtpbuf** buf);
                                     // lecture decodage d'un paquet h261
                                     // h261paq pointeur sur l'en-tete h261
                                     // flux donnees H261
                                     // retour :
                                     //          longueur du flux a decoder
               // read a network packet, decode it. return a pointer on the
               // h261 header, the h261 stream and the size of the stream.

public:
  const  u_int        PSC_DEB  = 1;    // debut d'une image
                                       // beginning of the frame
  const  u_int        GBSC_DEB = 2;    // debut d'un GOB / beginning of a GOB
  const  u_int        MBA_DEB  = 3;    // debut d'un Macro Bloc
                                       // beginning of a MB
  const  u_int        PSC_FIN  = 1;    // fin d'une image / frame end
  const  u_int        GBSC_FIN = 2;    // fin de GOB / GOB end
  const  u_int        MBA_FIN  = 3;    // fin de Macro Bloc / MB end
  
  h261ip();                          // creation par defaut / create the class

  ~h261ip();                         // destruction par defaut

  void change_encoding (Boolean full_INTRA) // change le format de codage
  {                                         // change the coding format
    if (initheader == 0)
      h261hd.intra = full_INTRA;
  };

  int nbimage()
  {
    return(initheader);
  };


                                     // construit l'en tete h261 d'une image
                                     // build a frame H261 header 
  void inith261image (int color, int size,
		     Boolean full_intra, int cif_number, 
		     struct timeval* heure);


  void create ( proto_rtp* reseau, u_int host);
                                     // creation avec acces au reseau
                                     // create the object and the RTP header

  void send (char* flux, TypeHuffDescrTab*  marques);
                                     // decoupage d'un flux, d'un GOB
                                     // cut the h261 stream at the Block
                                     // borders


  void ReadBuffer (TYPE_dec_bit_state* dscflux);
                                     // lecture du flux h261 paquetise
                                     // prepare les structures pour
                                     // le decodeur
                                     // read the H261 stream, prepare
                                     // the decoding structures
};
#endif

H261 video packetization, h261ip.cc:

/**************************************************************************\
*          Copyright (c) 1991,1992,1993,1994,1995 INRIA siege, FRANCE.     *
*          Copyright (c) 1993, 1994, 1995, Pierre leonard                  *
*                                                                          *
* Permission to use, copy, modify, and distribute this software and        *
* its documentation for any purpose and without fee is hereby granted,     *
* provided that this copyright notice and this permission notice appear    *
* in all copies, and that both that copyright notice and this permission   *
* notice appear in supporting documentation.                               *
* WE MAKE NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY OF THIS     *
* MATERIAL FOR ANY PURPOSE.  IT IS PROVIDED "AS IS", WITHOUT ANY EXPRESS   *
* OR IMPLIED WARRANTIES.                                                   *
*                                                                          *
* This software and its documentation has been produced by the TELESIA     *
* project. The TELESIA project focuse these research on the Teleworking    *
* on Wide Area Network, the usage through a wide experimentation plan.     *
*                                                                          *
* The TELESIA Team is currently composed by:                               *
*                                                                          *
*       - Alain Caristan        Project manager   *
*       - Pierre De La Motte                      *
*       - Andrzej Wozniak                       *
*       - Pierre Leonard                          *
*                                                                          *
*   Many thank's to :                                                      *
*                                                                          *
*       - Christian Donot      MBONE Manager     *
*       - Olivier Marset                                                   *
*       - Georges Gyory                                                    *
*       - Philippe Riguet                                                  *
*                                                                          *
* The TELESIA project is sponsored by:                                     *
*                                                                          *
*       - INRIA siege (Rocquencourt)                                       *
*       - ARISTOTE, an association of important users, studying, testing   *
*         and promoting advanced technologie in the network field,         *
*         interoperability, multimedia.                                    *
*       - Pierre Leonard, from October 1993 until January 1995             *
*                                                                          *
* The TELESIA patners are:                                                 *
*                                                                          *
*       - PAGEIN, a European project dedicated to the sharing of high      *
*         computing ressources,                                            *
*       - Rodeo, INRIA Sophia Antipolis network project.                   *
*                                                                          *
*                                                                          *
* This file was created by:   Pierre Leonard                               *
*            creation date:   19 Octobre 1994                              *
*                                                                          *
\**************************************************************************/
//
//
// Mise en paquet d'un flux H261 dans une connexion IP.
// en unicast ou Multicast.
// Cette version de MEP, integre les dernieres proposition de Andrzej
// Wozniak et Pierre Leonard, destinee a ameliorer le robustesse
// du decodeur.

// New packetization of a H261 stream in IP packets.
// That code is the implementation of the propositions of
// andrzej Wozniak and Pierre Leonard, in November 1994,
// in order to improve the robustness of the H261 decoder.

/*
 * fonctionnalites :
 *		creation,
 *		decoupage et envoi d'un flux h261, GOB par GOB,
 *		reception, decodage des paquets, envoi au decodeur.
 *              class creation,
 *              cut the stream at the Block border,
 *              complet the new H261 header with absolute frame references
 */
#define NO_H261IPECR_MESURES 1
#define NO_H261IPECR_DEBUG 1
#define NO_H261IPLEC_DEBUG 1

#include "h261ip.h"

// Copyright (c) 1993, 1994, 1995, Pierre leonard, INRIA Rocquencourt
h261ip::h261ip()                           // creation par defaut
{
  res = 0;
};


h261ip::~h261ip()                          // destruction par defaut
{
  res = 0;
};

// construit l'en tete h261 d'une image
// build a frame H261 header
// Copyright (C)  1994, 1995, Pierre Leonard, INRIA Rocquencourt.
void h261ip::inith261image (int Color, int Size,
			    Boolean full_intra, int cif_number, 
			    struct timeval* heure)
{
  if (initheader == 0) {
    res->putts(heure);
    h261hd.Couleur = !!Color;
    h261hd.vecteur = 0;
    h261hd.intra = full_intra;
    switch(Size){
    case QCIF_SIZE:
      h261hd.format = 0;
      break;
    case CIF_SIZE:
      h261hd.format = 0x1;
      break;
    case CIF4_SIZE:
      h261hd.format = 0x4 | cif_number;
      break;
    };
  };
  initheader = initheader + 1;                // interdire les init successives
                                              // only one initialization
#ifdef H261IPECR_MESURES
fprintf(stderr,"BuildH261Header fait %d  type %d\n",initheader,full_intra);
#endif
};



// creation de la mise en paquet, preparation de l'en-tete
// create the object and the RTP header
// Copyright (C)  1994, 1995, Pierre Leonard, INRIA Rocquencourt.
void h261ip::create ( proto_rtp* reseau, u_int host_name)
{
  res = reseau;
  bindok = 0;
  initheader = 0;
  nbpaquet = 0;
  nbgob = 0;
  nbmb = 0;
  rechost = host_name;
  res->putformat (RTP_H261_CONTENT);
  if (res->getsens() == LECTURE)
    prec = creerrtpbuf();
};


// copy de l'en tete H261 devant les donnees a envoyer
// copy the H261 header in front of the data
// Copyright (C)  1994, 1995, Pierre Leonard, INRIA Rocquencourt.
inline char* h261ip::copyh261hd (char* ptr)
{
  char*   to = (ptr - sizeof(h261_et));
  ((int*) to)[0] =   ((int*) (&h261hd))[0];
  ((int*) to)[1] =   ((int*) (&h261hd))[1];
  return(to);
};



// Construction de l'en tete H261 et envoi d'un paquet deja designe.
// build the H261 header, send the network packet to the RTP layer
// Copyright (C)  1994, 1995, Pierre Leonard, INRIA Rocquencourt.
void h261ip::constrpaquet (TypeHuffDescrTab* marques, int preums, int der)
{
  char*          buf;
  int            lg;

  unsigned long  ptr_val;
  int            bit_offset;
  int            end_bits;

#ifdef H261IPECR_DEBUG
  fprintf(stderr,"constrpaquet preums %d  der %d\n",preums,der);
#endif
  switch (marques->dsc[preums].mark_type) {  // quoi au debut ?
  case PSC_MARK:                             // first object type
    h261hd.typd = PSC_DEB;
    break;
  case GBSC_MARK: 
    h261hd.typd = GBSC_DEB;
    break;
  case MB_MARK: 
    h261hd.typd = MBA_DEB;
    break;
  };
  if (marques->dsc[der].mark_type == LAST_PEC)        // quoi a la fin ?
                                                      // last object type
    h261hd.typf = PSC_FIN;                    // une image / a frame
  else
    if ((der+1) == marques->num)
      h261hd.typf = GBSC_FIN;                 // un GOB / a GOB
    else
      h261hd.typf = MBA_FIN;                  // un MB / a Macro Block
  switch (marques->dsc[preums].mark_type) {
  case PSC_MARK:
    h261hd.h_gob = 0; //(int)marques->dsc[preums+1].mb;
    h261hd.h_mb = 0;
    h261hd.h_mb_last = 0;
    break;
  case GBSC_MARK:
    h261hd.h_gob = (int)marques->dsc[preums].h_gob;
    h261hd.h_mb = 0;
    h261hd.h_mb_last = 0;
    break;
  case MB_MARK:
    h261hd.h_gob = marques->dsc[preums].h_gob;
    h261hd.h_mb = marques->dsc[preums].val;
    h261hd.h_mb_last = marques->dsc[preums].aux;
    break;
  case LAST_MARK:
  case LAST_PEC:
    fprintf(stderr,"constrpaquet ne rien envoyer\n");
    return;
  };

  ptr_val = ((unsigned long)(marques->dsc[preums].byte_ptr));
  bit_offset = (ptr_val & 0x3)*8;
  ptr_val &= ~0x3; /* word aligned pointer value */
  end_bits = marques->dsc[der+1].bit_ptr;

  h261hd.Sbit = ((8-marques->dsc[preums].bit_ptr)&0x7) + bit_offset;
  h261hd.Ebit = end_bits;
#ifdef H261IPECR_DEBUG
  fprintf(stderr,"preums gob %d  preums mb %d Sbit %d Ebit %d\n",
	  h261hd.h_gob, h261hd.h_mb, h261hd.Sbit, h261hd.Ebit);
#endif

  buf = copyh261hd ((char *)ptr_val);
  lg = (char *)marques->dsc[der+1].byte_ptr - buf + (!!end_bits);
#ifdef H261IPECR_DEBUG
  fprintf(stderr,"addr flux %lx addr h261hd %lx  lg calculee %d\n",
	  (long)marques->dsc[preums].byte_ptr,(long)buf,lg);
#endif
  if ((lg = res->send (buf, lg)) < 0) {
    fprintf(stderr,"h261ip::constrpaquet erreur envoi reseau %d ",lg);
    perror("");
  };
#ifdef H261IPECR_MESURES
  fprintf(stderr,"sendto %d  mba de %d a %d\n",lg,preums, der);
#endif
};



// decoupage d'un flux, d'un GOB
// cut the h261 stream at the Block borders
// Copyright (C)  1994, 1995, Pierre Leonard, INRIA Rocquencourt.
void h261ip::send (char* flux, TypeHuffDescrTab*  marques)
{
  int       i;
  int       preums;         // premier element dans la paquet
                            // first item to copy in the network packet
  char*     addr_deb;       // adresse du premier element du paquet
                            // it's address
  int       lg;             // longueur de l'envoi
                            // size of the data to send
  int       nbpaq;          // nombre de paquets calculé pour cet envoi
                            // nb packets to send
  int       taillepaq;      // taille moyenne du paquet pour cet envoi
                            // average size of the packets

  initheader = 0;           // autoriser la construction de l'en-tete
                            // allow the H261 header building
  marques->num = marques->num - 1;
  lg = marques->dsc[marques->num].byte_ptr - marques->dsc[0].byte_ptr;
  nbpaq = (lg + MAX_PACKET) / MAX_PACKET;
  nbpaq = (lg + MAX_PACKET + nbpaq * H261_DEP_BUF) / MAX_PACKET;
  taillepaq = MAX_PACKET;

#ifdef H261IPECR_MESURES
fprintf(stderr,"Taille %d  nb elements %d calcule : nb %d  taille %d\n",
	lg,marques->num,nbpaq, taillepaq);
#endif
  preums = 0;
  addr_deb = (char *)marques->dsc[0].byte_ptr;
  for (i = 0; i < marques->num; i=i+1) {
#ifdef H261IPECR_DEBUG
    fprintf(stderr,"%d MARK %d cumul %d / ",i,marques->dsc[i].mark_type,
	    ((char*)marques->dsc[i+1].byte_ptr - addr_deb));
#endif
    if (((char *)marques->dsc[i+1].byte_ptr - addr_deb) > taillepaq) {
      constrpaquet (marques, preums, i-1);
      nbpaq = nbpaq - 1 ;
      if (nbpaq == 2) {
	lg = lg - ((char *)marques->dsc[i].byte_ptr -
		   (char*)marques->dsc[0].byte_ptr);
	taillepaq = lg / 2;
	if (taillepaq > MAX_PACKET)
	  taillepaq = MAX_PACKET;
      };
      addr_deb = marques->dsc[i].byte_ptr;
      preums = i;
    };
  };
  constrpaquet (marques, preums, i-1);
};



// lecture decodage d'un paquet h261, h261paq pointeur sur le paquet h261
// bit_ptr deplacement en bit au debut
// retour : longueur du flux a decoder
// read a network packet, return pointeurs on the packet, h261 header
// h261 stream. return value : size of the stream.
// try to connect to the emitting IP addr to reduce the input throughput.
// Copyright (C)  1994, 1995, Pierre Leonard, INRIA Rocquencourt.
int h261ip::recpaquet (h261_et** h261_hd, char** flux, rtpbuf** buf)
{
  int           lg;            // longueur des donnees / data size
  int           result;        // retour du connect / connect result
  sockaddr_in*  recname;

  while (((lg = res->recb(buf)) < 0) && ((*buf)->getfromaddr() != rechost)) {
    if (lg == RTP_LUVIDE)
      continue;
    fprintf (stderr,"h261ip::recb erreur lecture reseau %d\n", lg);
    perror("");
  };
  if (!(bindok)) {
    if ((*buf)->getfromaddr() == rechost) {
      recname = (*buf)->getfaddrp();
      if ((result = res->connection(recname)) < 0) {
	fprintf(stderr,"h261ip::recb erreur connect %d %s / %d ",result,
		inet_ntoa(*(in_addr*)&rechost),
		htons(recname->sin_port));
	perror("");
      };
      bindok = 1;
    };
  };
    
#ifdef H261IPLEC_DEBUG
  fprintf(stderr,"recb lg %d\n",lg);
#endif
  lg = (* buf)->getdata((char**)h261_hd);
  lg = lg - sizeof(h261_et);
  *flux = (char*) (((char*)*h261_hd) + sizeof(h261_et));
  return(lg);
};


// lecture et decodage des premiers octes du flux H261
// read the H261 stream, prepare the decoding structures
// Copyright (C)  1994, 1995, Pierre Leonard, INRIA Rocquencourt.
void h261ip::ReadBuffer (TYPE_dec_bit_state* dscflux)
{
  int          lg;
  int          calcul;
  h261_et*     eth261;
  char*        flux;
  rtpbuf*      buf;


#ifdef H261IPLEC_DEBUG
  fprintf(stderr,"ReadBuffer ");
#endif
  lg = recpaquet(ð261, &flux, &buf);             // je lis le paquet
                                                    // packet read
  calcul = buf->getseq();
  dscflux->h_gob     = eth261->h_gob;
  dscflux->h_mb      = eth261->h_mb;
  dscflux->h_mb_last = eth261->h_mb_last;
  dscflux->h_tr      = 0;
  dscflux->pack_stat = DEC_STAT_PACK_INFO;
#ifdef H261IPLEC_DEBUG
  fprintf(stderr,"gob %d mb %d typd %d typf %d ",dscflux->h_gob,dscflux->h_mb,
	  eth261->typd, eth261->typf);
#endif

  switch (eth261->typf) {                  // decodage fin de paquet
  case PSC_FIN:                            // decoding of the packet end
    dscflux->pack_stat |= DEC_STAT_PACK_PEC;
    break;
  case GBSC_FIN:
    dscflux->pack_stat |= DEC_STAT_PACK_GBEB;
    break;
  };
  switch (eth261->typd) {                  // decodage debut de paquet
  case PSC_DEB:                            // decoding of the packet beginning
    dscflux->pack_stat |= DEC_STAT_PACK_PSC;
    break;
  case GBSC_DEB:
    dscflux->pack_stat |= DEC_STAT_PACK_GBSC;
    break;
  case MBA_DEB:
    dscflux->pack_stat |= DEC_STAT_PACK_MBA;
    break;
  };
  if (eth261->Couleur)                     // decodage type d'image
    dscflux->pack_stat |= DEC_STAT_COLOR;  // decoding the frame type
  if (eth261->vecteur)
    dscflux->pack_stat |= DEC_STAT_MVD;
  calcul = calcul - prec->getseq();
  if (calcul > 1) {                            // il y a des pertes ??
    dscflux->pack_stat |= DEC_STAT_PACK_LOST;  // lost packets ??
#ifdef H261IPLEC_DEBUG
    fprintf(stderr,"H261IP: pertes %d\n",calcul);
#endif
  };

  dscflux->buf  = (u_char*) flux + (eth261->Sbit)/8;
  dscflux->blen = lg - (eth261->Sbit)/8;
  dscflux->sbit = eth261->Sbit & 0x07;
  dscflux->ebit = eth261->Ebit;

  switch(eth261->format){
  case 0x0:
    dscflux->pack_stat |= QCIF_SIZE;
    break;
  case 0x1:
    dscflux->pack_stat |= CIF_SIZE | DEC_STAT_FMT_CIF;
    break;
  case 0x4:
  case 0x5:
  case 0x6:
  case 0x7:
    dscflux->pack_stat |= CIF4_SIZE | DEC_STAT_FMT_CIF4 | DEC_STAT_FMT_CIF;
    dscflux->pack_stat |= (eth261->format & 0x3)<< DEC_STAT_CIF_NBR_POS;
    break;
  default:
    fprintf(stderr, "ReadBuffer:bad image size %d\n", eth261->format);
    dscflux->pack_stat |= CIF_SIZE;
    break;
  }/* switch */
#ifdef H261IPLEC_DEBUG
  fprintf(stderr,"Sbit %d  Ebit %d lg %d buf %lx\n",eth261->Sbit,eth261->Ebit,
	  lg, (long)flux);
#endif
  res->libere(prec);
  prec = buf;
};


Copyright (C) 1994, 1995, Pierre Léonard, TÉLÉSIA, INRIA Rocquencourt