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/mpegVideoStream.cpp

225 lines
4.3 KiB

/*
a mpegVideoStream buffer
Copyright (C) 1999 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 "mpegVideoStream.h"
#include <iostream>
using namespace std;
MpegVideoStream::MpegVideoStream(InputStream* input) {
this->input=input;
lHasStream=false;
mpegSystemStream=new MpegSystemStream(input);
mpegSystemHeader=new MpegSystemHeader();
mpegVideoBitWindow= new MpegVideoBitWindow();
}
MpegVideoStream::~MpegVideoStream() {
delete mpegSystemStream;
delete mpegSystemHeader;
delete mpegVideoBitWindow;
}
int MpegVideoStream::firstInitialize(MpegVideoHeader* mpegHeader) {
if (lHasStream == false) {
if (mpegSystemStream->firstInitialize(mpegSystemHeader)==false) {
return false;
}
fill_videoBuffer(mpegSystemHeader);
lHasStream=true;
}
// now find SEQ_START_CODE
hasBytes(4);
mpegVideoBitWindow->flushByteOffset();
if (mpegSystemHeader->getLayer() == _PACKET_SYSLAYER) {
unsigned int startCode=showBits(32);
if (startCode != _SEQ_START_CODE) {
flushBits(8);
return false;
}
flushBits(32);
}
if (mpegHeader->parseSeq(this)==false) {
return false;
}
return true;
}
int MpegVideoStream::isStartCode(unsigned int data) {
switch(data) {
case SEQ_END_CODE:
case SEQ_START_CODE:
case GOP_START_CODE:
case PICTURE_START_CODE:
case SLICE_MIN_START_CODE:
case SLICE_MAX_START_CODE:
case EXT_START_CODE:
case USER_START_CODE:
case SEQUENCE_ERROR_CODE:
case SYSTEM_HEADER_START_CODE:
case ISO_11172_END_CODE:
case (unsigned)EOF:
return true;
}
if ((SLICE_MIN_START_CODE < data) && (data < SLICE_MAX_START_CODE)) {
return true;
}
return false;
}
int MpegVideoStream::next_start_code() {
flushByteOffset();
unsigned int data;
data=showBits(32);
while(eof()==false) {
data=showBits(32);
if (isStartCode(data)) {
return true;
}
flushBits(8);
}
return true;
}
int MpegVideoStream::nextGOP() {
mpegVideoBitWindow->flushByteOffset();
unsigned int data=showBits(32);
if (data != GOP_START_CODE) {
flushBits(8);
return false;
}
return true;
}
int MpegVideoStream::nextPIC() {
mpegVideoBitWindow->flushByteOffset();
unsigned int data=showBits(32);
if ( (data != PICTURE_START_CODE) &&
(data != GOP_START_CODE) &&
(data != SEQ_START_CODE) ) {
flushBits(8);
return false;
}
return true;
}
int MpegVideoStream::hasBytes(int byteCnt) {
if (mpegVideoBitWindow->getLength() < byteCnt) {
get_more_video_data();
if (mpegVideoBitWindow->getLength() < byteCnt) {
return hasBytes(byteCnt);
}
}
return true;
}
int MpegVideoStream::eof() {
if (input->eof()) {
return true;
}
return false;
}
int MpegVideoStream::getByteDirect() {
unsigned char byte;
if (input->read((char*)&byte,1) != 1) {
return -1;
}
return (int)byte;
}
int MpegVideoStream::get_more_video_data() {
while(1) {
if (mpegSystemStream->nextPacket(mpegSystemHeader)==false) {
continue;
}
if (mpegSystemStream->eof() == true) {
printf ("\n");
mpegVideoBitWindow->fillWithIsoEndCode(1024);
cout <<"Unexpected read error."<<endl;
return false;
}
if (mpegSystemHeader->getPacketID() == _PAKET_ID_VIDEO) {
break;
}
}
fill_videoBuffer(mpegSystemHeader);
return true;
}
void MpegVideoStream::fill_videoBuffer(MpegSystemHeader* mpegSystemHeader) {
int bytes;
bytes=mpegSystemHeader->getPacketLen();
unsigned char* packetBuffer= new unsigned char[bytes];
int didRead;
didRead=input->read((char*)packetBuffer,bytes);
if (bytes==0) {
mpegVideoBitWindow->fillWithIsoEndCode(1024);
return ;
}
mpegVideoBitWindow->appendToBuffer(packetBuffer,didRead);
if (input->eof()) {
mpegVideoBitWindow->fillWithIsoEndCode(bytes-didRead);
}
delete packetBuffer;
}
TimeStamp* MpegVideoStream::getCurrentTimeStamp() {
long pos=input->getBytePosition();
int transfered=4*mpegVideoBitWindow->getLength();
pos=pos-transfered;
TimeStamp* timeStamp=input->getTimeStamp(pos);
return timeStamp;
}