Windows2003-3790/enduser/netmeeting/av/codecs/dec/dech261/marker.c
2020-09-30 16:53:55 +02:00

354 lines
9.7 KiB
C

/* File: sv_h261_marker.c */
/*****************************************************************************
** Copyright (c) Digital Equipment Corporation, 1995, 1997 **
** **
** All Rights Reserved. Unpublished rights reserved under the copyright **
** laws of the United States. **
** **
** The software contained on this media is proprietary to and embodies **
** the confidential technology of Digital Equipment Corporation. **
** Possession, use, duplication or dissemination of the software and **
** media is authorized only pursuant to a valid written license from **
** Digital Equipment Corporation. **
** **
** RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure by the U.S. **
** Government is subject to restrictions as set forth in Subparagraph **
** (c)(1)(ii) of DFARS 252.227-7013, or in FAR 52.227-19, as applicable. **
******************************************************************************/
/*************************************************************
This file contains most of the marker information.
*************************************************************/
/*
#define _VERBOSE_
*/
/*LABEL marker.c */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "sv_intrn.h"
#include "SC.h"
#include "SC_err.h"
#include "sv_h261.h"
#include "proto.h"
#include "sv_proto.h"
#include "h261.h"
/*PRIVATE*/
/*extern int TemporalReference;
extern int PType;
*/
extern int Type2;
/*
extern int MType;
extern int GQuant;
extern int MQuant;
*/
/*
extern int MVDH;
extern int MVDV;
extern int CBP;
*/
/*
extern int ParityEnable;
extern int PSpareEnable;
extern int GSpareEnable;
extern int Parity;
extern int PSpare;
extern int GSpare;
extern int GRead;
extern int MBA;
extern int LastMBA;
extern int LastMVDV;
extern int LastMVDH;
extern int LastMType;
*/
extern int QuantMType[];
extern int CBPMType[];
extern int MFMType[];
extern int extend_mask[];
const int bit_set_mask[] =
{0x00000001,0x00000002,0x00000004,0x00000008,
0x00000010,0x00000020,0x00000040,0x00000080,
0x00000100,0x00000200,0x00000400,0x00000800,
0x00001000,0x00002000,0x00004000,0x00008000,
0x00010000,0x00020000,0x00040000,0x00080000,
0x00100000,0x00200000,0x00400000,0x00800000,
0x01000000,0x02000000,0x04000000,0x08000000,
0x10000000,0x20000000,0x40000000,0x80000000};
/*
** Function: WritePictureHeader()
** Purpose: Writes the header of picture out to the stream.
** One of these is necessary before every frame is transmitted.
*/
void WritePictureHeader(SvH261Info_t *H261, ScBitstream_t *bs)
{
sc_vprintf("WritePictureHeader()\n");
ScBSPutBits(bs, H261_PICTURE_START_CODE, H261_PICTURE_START_CODE_LEN);
ScBSPutBits(bs, H261->TemporalReference, 5);
ScBSPutBits(bs, H261->PType, 6);
if (H261->PSpareEnable)
{
ScBSPutBit(bs, 1);
ScBSPutBits(bs, H261->PSpare, 8);
}
ScBSPutBit(bs, 0);
}
/*
** Function: ReadPictureHeader()
** Purpose: Reads the header off of the stream. It assumes that the
** first PSC has already been read in. (Necessary to tell the
** difference between a new picture and another GOB.)
*/
void ReadPictureHeader(SvH261Info_t *H261, ScBitstream_t *bs)
{
sc_vprintf ("ReadPictureHeader \n");
H261->TemporalReference = (int) ScBSGetBits(bs,5);
H261->PType = (int)ScBSGetBits(bs,6);
for(H261->PSpareEnable = 0;ScBSGetBit(bs);)
{
H261->PSpareEnable=1;
H261->PSpare = (int)ScBSGetBits(bs,8);
}
}
/*
** Function: WriteGOBHeader()
** Purpose: Writes a GOB out to the stream.
*/
void WriteGOBHeader(SvH261Info_t *H261, ScBitstream_t *bs)
{
sc_vprintf("WriteGOBHeader()\n");
ScBSPutBits(bs, H261_GOB_START_CODE, H261_GOB_START_CODE_LEN);
ScBSPutBits(bs, H261->GRead+1, 4);
ScBSPutBits(bs, H261->GQuant, 5);
if (H261->GSpareEnable)
{
ScBSPutBit(bs, 1);
ScBSPutBits(bs, H261->GSpare, 8);
}
ScBSPutBit(bs, 0);
}
/*
** Function: ReadHeaderTrailer()
** Purpose: Reads the trailer of the PSC or H261_GOB_START_CODE code. It is
** used to determine whether it is just a GOB or a new picture.
*/
void ReadHeaderTrailer(SvH261Info_t *H261, ScBitstream_t *bs)
{
sc_vprintf("ReadHeaderTrailer \n");
H261->GRead = (int)ScBSGetBits(bs, 4)-1;
}
/*
** Function: ReadHeaderHeader()
** Purpose: Reads the header header off of the stream. This is
** a precursor to the GOB read or the PSC read.
** Return: -1 on error
*/
SvStatus_t ReadHeaderHeader(SvH261Info_t *H261, ScBitstream_t *bs)
{
int input;
sc_vprintf("ReadHeaderHeader\n");
input = (int)ScBSPeekBits(bs, H261_GOB_START_CODE_LEN);
if (input != H261_GOB_START_CODE)
{
if (!ScBSSeekStopBefore(bs, H261_GOB_START_CODE, H261_GOB_START_CODE_LEN))
{
sc_dprintf("Illegal GOB Start Code. Read: %d\n",input);
return(SvErrorIllegalGBSC);
}
}
input = (int)ScBSGetBits(bs, H261_GOB_START_CODE_LEN);
return(NoErrors);
}
/*
** Function: ReadGOBHeader()
** Purpose: Reads the GOB information off of the stream. We assume
** that the first bits have been read in by ReadHeaderHeader...
** or some such routine.
*/
void ReadGOBHeader(SvH261Info_t *H261, ScBitstream_t *bs)
{
sc_vprintf("ReadGOBHeader()\n");
H261->GQuant =(int)ScBSGetBits(bs,5);
for(H261->GSpareEnable=0; ScBSGetBit(bs);)
{
H261->GSpareEnable = 1;
H261->GSpare = (int)ScBSGetBits(bs,8);
}
}
/*
** Function: WriteMBHeader()
** Purpose: Writes a macro-block out to the stream.
*/
SvStatus_t WriteMBHeader(SvH261Info_t *H261, ScBitstream_t *bs)
{
int TempH,TempV;
ScBSPosition_t Start;
sc_vprintf("WriteMBHeader()\n");
sc_dprintf("\n Macro Block Type is %d and MQuant is %d",
H261->MType, H261->MQuant);
Start=ScBSBitPosition(bs); /* Start=swtellb(H261); */
if (!sv_H261HuffEncode(H261,bs,H261->MBA,H261->MBAEHuff))
{
sc_dprintf("Attempting to write an empty Huffman code.\n");
return (SvErrorEmptyHuff);
}
if (!sv_H261HuffEncode(H261,bs,H261->MType,H261->T3EHuff))
{
sc_dprintf("Attempting to write an empty Huffman code.\n");
return (SvErrorEmptyHuff);
}
if (QuantMType[H261->MType])
ScBSPutBits(bs, H261->MQuant, 5); /* mputvb(H261, 5, H261->MQuant); */
H261->NumberBitsCoded=0;
if (MFMType[H261->MType])
{
if ((!MFMType[H261->LastMType])||(H261->MBA!=1)||
(H261->LastMBA==-1)||(H261->LastMBA==10)||(H261->LastMBA==21))
{
if (!sv_H261HuffEncode(H261,bs,(H261->MVDH&0x1f),H261->MVDEHuff)||
!sv_H261HuffEncode(H261,bs,(H261->MVDV&0x1f),H261->MVDEHuff))
{
sc_dprintf("Cannot encode motion vectors.\n");
return (SvErrorEncodingMV);
}
}
else
{
TempH = H261->MVDH - H261->LastMVDH;
if (TempH < -16) TempH += 32;
if (TempH > 15) TempH -= 32;
TempV = H261->MVDV - H261->LastMVDV;
if (TempV < -16) TempV += 32;
if (TempV > 15) TempV -= 32;
if (!sv_H261HuffEncode(H261,bs,TempH&0x1f,H261->MVDEHuff)||
!sv_H261HuffEncode(H261,bs,TempV&0x1f,H261->MVDEHuff))
{
sc_dprintf("Cannot encode motion vectors.\n");
return (SvErrorEncodingMV);
}
}
H261->LastMVDV = H261->MVDV;
H261->LastMVDH = H261->MVDH;
}
else
{
H261->LastMVDV=H261->LastMVDH=H261->MVDV=H261->MVDH=0; /* Redundant in most cases */
}
H261->MotionVectorBits+=H261->NumberBitsCoded;
if (CBPMType[H261->MType])
{
if (!sv_H261HuffEncode(H261,bs,H261->CBP,H261->CBPEHuff))
{
sc_dprintf("CBP write error\n");
return (SvErrorCBPWrite);
}
}
H261->Current_MBBits = ScBSBitPosition(bs)-Start; /* (swtellb(H261)-Start); */
H261->MacroAttributeBits+=H261->Current_MBBits ;
return (NoErrors);
}
/*
** Function: ReadMBHeader()
** Purpose: Reads the macroblock header from the stream.
*/
int ReadMBHeader(SvH261Info_t *H261, ScBitstream_t *bs)
{
DHUFF *huff = H261->MBADHuff;
register unsigned short cb;
register int State, temp;
do {
DecodeHuff(bs, huff, State, cb, temp);
} while (State == 34 && ! bs->EOI); /* Get rid of stuff bits */
H261->MBA = State;
if (H261->MBA == 35 || bs->EOI)
return(-1); /* Start of Picture Headers */
H261->LastMType = H261->MType;
huff = H261->T3DHuff;
DecodeHuff(bs, huff, State, cb, temp);
H261->MType = State;
if (QuantMType[H261->MType])
H261->MQuant = (int)ScBSGetBits(bs,5);
huff = H261->MVDDHuff;
if (MFMType[H261->MType])
{
if ((!MFMType[H261->LastMType])||(H261->MBA!=1)||
(H261->LastMBA==-1)||(H261->LastMBA==10)||(H261->LastMBA==21))
{
DecodeHuff(bs, huff, State, cb, temp);
if (State & bit_set_mask[4])
H261->MVDH = State | extend_mask[4];
else
H261->MVDH = State;
DecodeHuff(bs, huff, State, cb, temp);
if (State & bit_set_mask[4])
H261->MVDV = State | extend_mask[4];
else
H261->MVDV = State;
}
else
{
DecodeHuff(bs, huff, State, cb, temp);
if (State & bit_set_mask[4])
State |= extend_mask[4];
H261->MVDH += State;
DecodeHuff(bs, huff, State, cb, temp);
if (State & bit_set_mask[4])
State |= extend_mask[4];
H261->MVDV += State;
if (H261->MVDH < -16) H261->MVDH += 32;
if (H261->MVDH > 15) H261->MVDH -= 32;
if (H261->MVDV < -16) H261->MVDV += 32;
if (H261->MVDV > 15) H261->MVDV -= 32;
}
}
else
H261->MVDV=H261->MVDH=0; /* Theoretically redundant */
if (CBPMType[H261->MType])
{
huff = H261->CBPDHuff;
DecodeHuff(bs, huff, State, cb, temp);
H261->CBP = State;
}
return(0);
}