⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpeg.cpp

📁 This code is based on mpeg_play, available from: http://bmrc.berkeley.edu/frame/research/mpeg/
💻 CPP
字号:
#include "SDL.h"#include "MPEG.h"#ifdef WIN32#include <io.h>#else#include <unistd.h>#endif#include <fcntl.h>#include <string.h>#include <errno.h>#ifndef O_BINARY#define O_BINARY 0#endifMPEG::MPEG(const char * name, bool SDLaudio) :  MPEGerror(){  SDL_RWops *source;  mpeg_mem = 0;  source = SDL_RWFromFile(name, "rb");  if (!source) {    InitErrorState();    SetError(SDL_GetError());    return;  }  Init(source, SDLaudio);}MPEG::MPEG(int Mpeg_FD, bool SDLaudio) :  MPEGerror(){  SDL_RWops *source;  mpeg_mem = 0;  // *** FIXME we're leaking a bit of memory for the FILE *  // best solution would be to have SDL_RWFromFD  FILE *file = fdopen(Mpeg_FD, "rb");  if (!file) {    InitErrorState();    SetError(strerror(errno));    return;  }  source = SDL_RWFromFP(file,false);  if (!source) {    InitErrorState();    SetError(SDL_GetError());    return;  }  Init(source, SDLaudio);}MPEG::MPEG(void *data, int size, bool SDLaudio) :  MPEGerror(){  SDL_RWops *source;  // The semantics are that the data passed in should be copied  // (?)  mpeg_mem = new char[size];  memcpy(mpeg_mem, data, size);  source = SDL_RWFromMem(mpeg_mem, size);  if (!source) {    InitErrorState();    SetError(SDL_GetError());    return;  }  Init(source, SDLaudio);}MPEG::MPEG(SDL_RWops *mpeg_source, bool SDLaudio) :  MPEGerror(){  mpeg_mem = 0;  Init(mpeg_source, SDLaudio);}void MPEG::Init(SDL_RWops *mpeg_source, bool SDLaudio){    source = mpeg_source;    sdlaudio = SDLaudio;    /* Create the system that will parse the MPEG stream */    system = new MPEGsystem(source);    /* Initialize everything to invalid values for cleanup */    error = NULL;    audiostream = videostream = NULL;    audioaction = NULL;    videoaction = NULL;    audio = NULL;    video = NULL;    audioaction_enabled = videoaction_enabled = false;    loop = false;    pause = false;    parse_stream_list();    EnableAudio(audioaction_enabled);    EnableVideo(videoaction_enabled);    if ( ! audiostream && ! videostream ) {      SetError("No audio/video stream found in MPEG");    }    if ( system && system->WasError() ) {      SetError(system->TheError());    }    if ( audio && audio->WasError() ) {      SetError(audio->TheError());    }    if ( video && video->WasError() ) {      SetError(video->TheError());    }    if ( WasError() ) {      SetError(TheError());    }}void MPEG::InitErrorState() {    audio = NULL;    video = NULL;    system = NULL;    error = NULL;    audiostream = videostream = NULL;    audioaction = NULL;    videoaction = NULL;    audio = NULL;    video = NULL;    audioaction_enabled = videoaction_enabled = false;    loop = false;    pause = false;}MPEG::~MPEG(){  Stop();  if(video) delete video;  if(audio) delete audio;  if(system) delete system;    SDL_RWclose(source);  if ( mpeg_mem )    delete[] mpeg_mem;}bool MPEG::AudioEnabled(void) {  return(audioaction_enabled);}void MPEG::EnableAudio(bool enabled) {  if ( enabled && ! audioaction ) {    enabled = false;  }  audioaction_enabled = enabled;  /* Stop currently playing stream, if necessary */  if ( audioaction && ! audioaction_enabled ) {    audioaction->Stop();  }   /* Set the video time source */  if ( videoaction ) {    if ( audioaction_enabled ) {      videoaction->SetTimeSource(audioaction);    } else {      videoaction->SetTimeSource(NULL);    }  }/*  if(audiostream)    audiostream->enable(enabled);*/}bool MPEG::VideoEnabled(void) {  return(videoaction_enabled);}void MPEG::EnableVideo(bool enabled) {  if ( enabled && ! videoaction ) {    enabled = false;  }  videoaction_enabled = enabled;  /* Stop currently playing stream, if necessary */  if ( videoaction && ! videoaction_enabled ) {    videoaction->Stop();  } }/* MPEG actions */void MPEG::Loop(bool toggle) {  loop = toggle;  system->Loop(toggle);}void MPEG::Play(void) {  if ( AudioEnabled() ) {    audioaction->Play();  }  if ( VideoEnabled() ) {    videoaction->Play();  }}void MPEG::Stop(void) {  if ( VideoEnabled() ) {    videoaction->Stop();  }  if ( AudioEnabled() ) {    audioaction->Stop();  }}void MPEG::Rewind(void) {  seekIntoStream(0);}void MPEG::Pause(void) {  pause = !pause;  if ( VideoEnabled() ) {    videoaction->Pause();  }  if ( AudioEnabled() ) {    audioaction->Pause();  }}/* Michel Darricau from eProcess <mdarricau@eprocess.fr> conflict name with popcorn */MPEGstatus MPEG::GetStatus(void) {  MPEGstatus status;  status = MPEG_STOPPED;  if ( VideoEnabled() ) {		/* Michel Darricau from eProcess <mdarricau@eprocess.fr> conflict name with popcorn */    switch (videoaction->GetStatus()) {      case MPEG_PLAYING:        status = MPEG_PLAYING;      break;      default:      break;    }  }  if ( AudioEnabled() ) {		/* Michel Darricau from eProcess <mdarricau@eprocess.fr> conflict name with popcorn */    switch (audioaction->GetStatus()) {      case MPEG_PLAYING:        status = MPEG_PLAYING;      break;      default:      break;    }  }  if(status == MPEG_STOPPED && loop && !pause)  {    /* Here we go again */    Rewind();    Play();    if ( VideoEnabled() ) {		/* Michel Darricau from eProcess <mdarricau@eprocess.fr> conflict name with popcorn */      switch (videoaction->GetStatus()) {      case MPEG_PLAYING:        status = MPEG_PLAYING;	break;        default:        break;      }    }    if ( AudioEnabled() ) {		/* Michel Darricau from eProcess <mdarricau@eprocess.fr> conflict name with popcorn */      switch (audioaction->GetStatus()) {      case MPEG_PLAYING:        status = MPEG_PLAYING;	break;        default:        break;      }    }  }  return(status);}/* MPEG audio actions */bool MPEG::GetAudioInfo(MPEG_AudioInfo *info) {  if ( AudioEnabled() ) {    return(audioaction->GetAudioInfo(info));  }  return(false);}void MPEG::Volume(int vol) {  if ( AudioEnabled() ) {    audioaction->Volume(vol);  }}bool MPEG::WantedSpec(SDL_AudioSpec *wanted) {  if( audiostream ) {    return(GetAudio()->WantedSpec(wanted));  }  return(false);}void MPEG::ActualSpec(const SDL_AudioSpec *actual) {  if( audiostream ) {    GetAudio()->ActualSpec(actual);  }}MPEGaudio *MPEG::GetAudio(void) { // Simple accessor used in the C interface  return audio;}/* MPEG video actions */bool MPEG::GetVideoInfo(MPEG_VideoInfo *info) {  if ( VideoEnabled() ) {    return(videoaction->GetVideoInfo(info));  }  return(false);}bool MPEG::SetDisplay(SDL_Surface *dst, SDL_mutex *lock,		MPEG_DisplayCallback callback) {  if ( VideoEnabled() ) {    return(videoaction->SetDisplay(dst, lock, callback));  }  return(false);}void MPEG::MoveDisplay(int x, int y) {  if ( VideoEnabled() ) {    videoaction->MoveDisplay(x, y);  }}void MPEG::ScaleDisplayXY(int w, int h) {  if ( VideoEnabled() ) {    videoaction->ScaleDisplayXY(w, h);  }}void MPEG::SetDisplayRegion(int x, int y, int w, int h) {  if ( VideoEnabled() ) {    videoaction->SetDisplayRegion(x, y, w, h);  }}void MPEG::RenderFrame(int frame){    if ( VideoEnabled() ) {        videoaction->RenderFrame(frame);    }}void MPEG::RenderFinal(SDL_Surface *dst, int x, int y){    Stop();    if ( VideoEnabled() ) {        videoaction->RenderFinal(dst, x, y);    }    Rewind();}SMPEG_Filter * MPEG::Filter(SMPEG_Filter * filter){  if ( VideoEnabled() ) {    return(videoaction->Filter(filter));  }  return 0;}void MPEG::Seek(int position){  int was_playing = 0;  /* Cannot seek past end of file */  if((Uint32)position > system->TotalSize()) return;  	/* Michel Darricau from eProcess <mdarricau@eprocess.fr> conflict name with popcorn */  /* get info whrether we need to restart playing at the end */  if( GetStatus() == MPEG_PLAYING )    was_playing = 1;  if(!seekIntoStream(position)) return;  /* If we were playing and not rewind then play again */  if (was_playing)    Play();  if (VideoEnabled() && !was_playing)     videoaction->RenderFrame(0);  if ( pause && VideoEnabled() ) {    videoaction->Pause();  }  if ( pause && AudioEnabled() ) {    audioaction->Pause();  }}bool MPEG::seekIntoStream(int position){  /* First we stop everything */  Stop();  /* Go to the desired position into file */  if(!system->Seek(position)) return(false);  /* Seek first aligned data */  if(audiostream)    while(audiostream->time() == -1)      audiostream->next_packet();  if(videostream)    while(videostream->time() == -1)      videostream->next_packet();  /* Calculating current play time on audio only makes sense when there     is no video */    if ( audioaction && !videoaction) {    audioaction->Rewind();    audioaction->ResetSynchro(system->TimeElapsedAudio(position));  }  /* And forget what we previouly buffered */  else if ( audioaction ) {    audioaction->Rewind();    audioaction->ResetSynchro(audiostream->time());  }  if ( videoaction ) {    videoaction->Rewind();    videoaction->ResetSynchro(videostream->time());  }  return(true);}void MPEG::Skip(float seconds){  if(system->get_stream(SYSTEM_STREAMID))  {    system->Skip(seconds);  }  else  {    /* No system information in MPEG */    if( VideoEnabled() ) videoaction->Skip(seconds);    if( AudioEnabled() ) audioaction->Skip(seconds);  }}void MPEG::GetSystemInfo(MPEG_SystemInfo * sinfo){  sinfo->total_size = system->TotalSize();  sinfo->current_offset = system->Tell();  sinfo->total_time = system->TotalTime();  /* Get current time from audio or video decoder */  /* TODO: move timing reference in MPEGsystem    */  sinfo->current_time = 0;  if( videoaction )     sinfo->current_time = videoaction->Time();  if( audioaction )    sinfo->current_time = audioaction->Time();}void MPEG::parse_stream_list(){  MPEGstream ** stream_list;  register int i;  /* A new thread is created for each video and audio */  /* stream                                           */   /* TODO: support MPEG systems containing more than  */  /*       one audio or video stream                  */  i = 0;  do  {    /* Retreive the list of streams */    stream_list = system->GetStreamList();    switch(stream_list[i]->streamid)    {      case SYSTEM_STREAMID:      break;      case AUDIO_STREAMID:	audiostream = stream_list[i];	audioaction_enabled = true;	audiostream->next_packet();	audio = new MPEGaudio(audiostream, sdlaudio);	audioaction = audio;      break;      case VIDEO_STREAMID:	videostream = stream_list[i];	videoaction_enabled = true;	videostream->next_packet();	video = new MPEGvideo(videostream);	videoaction = video;      break;    }    i++;  }  while(stream_list[i]);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -