You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdemultimedia/mpeglib/lib/mpegplay/mpegVideoBitWindow.cpp

259 lines
5.2 KiB

/*
bitwindow mpeg video
Copyright (C) 2000 Martin Vogt
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
the Free Software Foundation.
For more information look at the file COPYRIGHT in this package
*/
#include "mpegVideoBitWindow.h"
#include <iostream>
using namespace std;
MpegVideoBitWindow::MpegVideoBitWindow() {
// Make buffer length multiple of 4.
this->size=80000;
if ((size % 4) != 0) {
cout << "MpegVideoStream not multiple of 4"<<endl;
exit(-1);
}
/* Create MpegVideoStream. */
buf_start = (unsigned int*) malloc (sizeof(unsigned int)*(size*4));
/*
* Set max_buf_length to one less than actual length to deal with messy
* data without proper seq. end codes.
*/
max_buf_length=size-1;
/* Initialize bitstream i/o fields. */
bit_offset = 0;
buffer = buf_start;
buf_length = 0;
num_left=0;
leftover_bytes=0;
curBits = 0;
nBitMask[0] = 0x00000000;
nBitMask[1] = 0x80000000;
nBitMask[2] = 0xc0000000;
nBitMask[3] = 0xe0000000;
nBitMask[4] = 0xf0000000;
nBitMask[5] = 0xf8000000;
nBitMask[6] = 0xfc000000;
nBitMask[7] = 0xfe000000;
nBitMask[8] = 0xff000000;
nBitMask[9] = 0xff800000;
nBitMask[10] = 0xffc00000;
nBitMask[11] = 0xffe00000;
nBitMask[12] = 0xfff00000;
nBitMask[13] = 0xfff80000;
nBitMask[14] = 0xfffc0000;
nBitMask[15] = 0xfffe0000;
nBitMask[16] = 0xffff0000;
nBitMask[17] = 0xffff8000;
nBitMask[18] = 0xffffc000;
nBitMask[19] = 0xffffe000;
nBitMask[20] = 0xfffff000;
nBitMask[21] = 0xfffff800;
nBitMask[22] = 0xfffffc00;
nBitMask[23] = 0xfffffe00;
nBitMask[24] = 0xffffff00;
nBitMask[25] = 0xffffff80;
nBitMask[26] = 0xffffffc0;
nBitMask[27] = 0xffffffe0;
nBitMask[28] = 0xfffffff0;
nBitMask[29] = 0xfffffff8;
nBitMask[30] = 0xfffffffc;
nBitMask[31] = 0xfffffffe;
nBitMask[32] = 0xffffffff;
}
MpegVideoBitWindow::~MpegVideoBitWindow() {
delete buf_start;
}
int MpegVideoBitWindow::appendToBuffer(unsigned char* ptr,int len) {
int byte_length = getLength()*4;
resizeBuffer(len);
if (num_left != 0) {
byte_length += num_left;
*(buffer+buf_length)=leftover_bytes;
}
memcpy(((unsigned char *)buffer)+byte_length,ptr,len);
if ((unsigned long int)1 != ntohl(1)) {
unsigned int *mark = buffer+buf_length;
int i;
int n=(len+num_left)&0xfffffffc;
for (i=0; i < n; i+=4) {
*mark=ntohl(*mark);
mark++;
}
}
byte_length = byte_length + len;
num_left = byte_length % 4;
buf_length = byte_length / 4;
updateCurBits();
leftover_bytes = *(buffer +buf_length);
return true;
}
int MpegVideoBitWindow::getLinearFree() {
unsigned int* endPos=buf_start+size;
unsigned int* currPos=buffer+buf_length;
int back=endPos-currPos;
return back;
}
void MpegVideoBitWindow::flushByteOffset() {
int byteoff;
byteoff = bit_offset % 8;
if (byteoff != 0) {
flushBitsDirect((8-byteoff));
}
}
void MpegVideoBitWindow::appendToBuffer(unsigned int startCode) {
unsigned int startCodeRaw=htonl(startCode);
resizeBuffer(4);
appendToBuffer((unsigned char*)&startCodeRaw,4);
}
void MpegVideoBitWindow::clear() {
buffer = buf_start;
buf_length = 0;
bit_offset = 0;
curBits = 0;
}
int MpegVideoBitWindow::getLength() {
return buf_length;
}
void MpegVideoBitWindow::printChar(int bytes) {
int i;
unsigned char* mark;
mark=(unsigned char *)buffer;
for(i=0;i<bytes;i++) {
printf("i:%d read=%x\n",i,mark[i]);
}
printf("*********\n");
}
void MpegVideoBitWindow::printInt(int bytes) {
int i;
int n;
unsigned int* mark;
mark=(unsigned int*)buf_start;
n=bytes/sizeof(int);
for(i=0;i<n;i++) {
printf("i:%d read=%x\n",i,mark[i]);
}
printf("*********\n");
}
void MpegVideoBitWindow::print() {
int byte_length = getLength()*4;
printf("bit_offset:%x\n",bit_offset);
printf("num_left:%x\n",num_left);
printf("leftover_bytes:%x\n",leftover_bytes);
printf("buf_length:%x\n",buf_length);
printf("curBits:%x\n",curBits);
printf("pos:%8x\n",byte_length);
printChar(8);
}
void MpegVideoBitWindow::resizeBuffer(int insertBytes) {
/* Read all the headers, now make room for packet */
if (buf_start+max_buf_length < buffer+insertBytes/4+buf_length) {
if (max_buf_length - buf_length < (int) insertBytes/4) {
/* Buffer too small for a packet (plus whats there),
* time to enlarge it!
*/
unsigned int *old = buf_start;
max_buf_length=buf_length+insertBytes/4+1;
buf_start=(unsigned int*) malloc(sizeof(unsigned int)*max_buf_length);
if (buf_start == NULL) {
cout << "allocation of:"<<max_buf_length<<" bytes failed"<<endl;
exit(0);
}
memcpy((unsigned char *)buf_start,buffer,(unsigned int)buf_length*4);
delete old;
buffer = buf_start;
cout << "enlarge buffer-1 end***********"<<endl;
} else {
memcpy((unsigned char *)buf_start,
buffer, (unsigned int) buf_length*4);
buffer = buf_start;
}
}
}
void MpegVideoBitWindow::fillWithIsoEndCode(int bytes) {
int i;
int n=bytes/4;
for (i=0;i<n;i++) {
appendToBuffer(ISO_11172_END_CODE);
}
}