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/decoder/mpgPlugin.cpp

261 lines
5.7 KiB

/*
mpg I video/audio player plugin
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 "mpgPlugin.h"
#include "../mpegplay/mpegSystemStream.h"
#include "../mpgplayer/mpegStreamPlayer.h"
#include "../mpegplay/mpegVideoLength.h"
#include "splayPlugin.h"
#include "mpegPlugin.h"
#include <iostream>
using namespace std;
MpgPlugin::MpgPlugin() {
mpegSystemHeader=NULL;
mpegSystemStream=NULL;
mpegStreamPlayer=NULL;
mpegVideoLength=NULL;
// make runtime config easier, no NULL check necessary
mpegSystemHeader=new MpegSystemHeader();
timeStamp=new TimeStamp();
lMono=false;
lDown=false;
lWriteStreams=false;
lDoLength=true;
}
MpgPlugin::~MpgPlugin() {
delete mpegSystemHeader;
delete timeStamp;
}
void MpgPlugin::decoder_loop() {
if (input == NULL) {
cout << "MPGPlugin::decoder_loop input is NULL"<<endl;
exit(0);
}
if (output == NULL) {
cout << "MPGPlugin::decoder_loop output is NULL"<<endl;
exit(0);
}
// decoder
SplayPlugin* splayPlugin=new SplayPlugin();
splayPlugin->config("-c","true",NULL);
if (lMono) {
splayPlugin->config("-m","true",NULL);
}
if (lDown) {
splayPlugin->config("-2","true",NULL);
}
MpegPlugin* mpegplayPlugin=new MpegPlugin();
mpegSystemStream=new MpegSystemStream(input);
mpegStreamPlayer=new MpegStreamPlayer(input,output,
splayPlugin,mpegplayPlugin);
mpegStreamPlayer->setWriteToDisk(lWriteStreams);
mpegVideoLength=new MpegVideoLength(input);
int lSysLayer=false;
int lHasLength=false;
while(runCheck()) {
switch(streamState) {
case _STREAM_STATE_FIRST_INIT :
if ((lHasLength==false) && (lDoLength)) {
if (mpegVideoLength->firstInitialize()==false) {
continue;
}
lHasLength=true;
}
if (mpegSystemStream->firstInitialize(mpegSystemHeader)==false) {
//cout << "still initializing system stream"<<endl;
} else {
// if we have found a raw stream,
// make sure we pass as first argument a SEQ_START_CODE
if (mpegSystemHeader->getLayer() == _PACKET_SYSLAYER) {
lSysLayer=true;
mpegStreamPlayer->processSystemHeader(mpegSystemHeader);
} else {
//output->config("-s","false");
unsigned int startCodeRaw=htonl(_SEQ_START_CODE);
mpegStreamPlayer->
insertVideoDataRaw((unsigned char*)&startCodeRaw,4,timeStamp);
}
pluginInfo->setLength(mpegVideoLength->getLength());
output->writeInfo(pluginInfo);
setStreamState(_STREAM_STATE_INIT);
if (mpegSystemHeader->getMPEG2()==true) {
cout << "this plugin does not support MPEG2/VOB/DVD"<<endl;
lDecoderLoop=false;
if (lWriteStreams == true) {
cout << "demux is supported"<<endl;
lDecoderLoop=true;
}
break;
}
}
break;
case _STREAM_STATE_INIT :
setStreamState(_STREAM_STATE_PLAY);
break;
case _STREAM_STATE_PLAY :
// syslayer
if (mpegSystemStream->nextPacket(mpegSystemHeader) == false) {
break;
}
if (mpegStreamPlayer->processSystemHeader(mpegSystemHeader) == false) {
mpegSystemStream->reset();
setStreamState(_STREAM_STATE_INIT);
}
break;
case _STREAM_STATE_WAIT_FOR_END:
if (mpegStreamPlayer->hasEnd()==true) {
// exit while loop
lDecoderLoop=false;
}
TimeWrapper::usleep(100000);
break;
default:
cout << "unknown stream state:"<<streamState<<endl;
}
}
delete mpegStreamPlayer;
delete mpegSystemStream;
delete mpegVideoLength;
delete mpegplayPlugin;
delete splayPlugin;
mpegSystemStream=NULL;
mpegStreamPlayer=NULL;
mpegVideoLength=NULL;
output->audioFlush();
output->flushWindow();
}
// here we can config our decoder with special flags
void MpgPlugin::config(const char* key,const char* value,void* user_data) {
if(strcmp("VideoLayer", key) == 0) {
int videoLayerSelect=atoi(value);
mpegSystemHeader->setVideoLayerSelect(videoLayerSelect);
}
if(strcmp("AudioLayer", key) == 0) {
int audioLayerSelect=atoi(value);
mpegSystemHeader->setAudioLayerSelect(audioLayerSelect);
}
if (strcmp(key,"-2")==0) {
lDown=true;
}
if (strcmp(key,"-m")==0) {
lMono=true;
}
if (strcmp(key,"-c")==0) {
lDoLength=false;
}
if (strcmp(key,"-w")==0) {
if (strcmp(value,"true")==0) {
lWriteStreams=true;
} else {
lWriteStreams=true;
}
}
// now try to set it if stream is running:
shutdownLock();
if (mpegStreamPlayer != NULL) {
mpegStreamPlayer->setWriteToDisk(lWriteStreams);
}
shutdownUnlock();
DecoderPlugin::config(key,value,user_data);
}
int MpgPlugin::getTotalLength() {
shutdownLock();
int back=0;
if (mpegVideoLength != NULL) {
back=mpegVideoLength->getLength();
} else {
cout << "cannot report total length, plugin not initialized"<<endl;
}
shutdownUnlock();
return back;
}
int MpgPlugin::processThreadCommand(Command* command) {
int id=command->getID();
int arg;
switch(id) {
case _COMMAND_SEEK: {
//
// mapping from second to bytePosition
//
if (mpegStreamPlayer->isInit()==false) {
command->print("MPGPLUGIN:ignore command in _STREAM_STATE_FIRST_INIT");
} else {
arg=command->getIntArg();
int pos=mpegVideoLength->getSeekPos(arg);
Command seek(_COMMAND_SEEK,pos);
// insert correct values
mpegStreamPlayer->processThreadCommand(&seek);
}
return _RUN_CHECK_CONTINUE;
}
default:
// we forward the command to the mpegStreamPlayer
mpegStreamPlayer->processThreadCommand(command);
}
// use default
return (DecoderPlugin::processThreadCommand(command));
}