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

📄 mpeg2buff.cc

📁 ac3的解码程序
💻 CC
字号:
/*   File: mpeg2buff.cc   By: Alex Theo de Jong   Created: February 1996   Description:   "Multi-Threading Save" read/write buffer*/#ifdef GNU#pragma implementation#endif#include "athread.hh"#include <stdio.h>#include <string.h>#include <String.h>#include <sys/time.h>#include <fcntl.h>#ifdef HAVE_MMX#include <mmx.h>#endif#include "error.hh"#include "debug.hh"#include "util.hh"#include "mpeg2const.hh"#include "mpeg2buff.hh"/* * * Memory * */Memory::Memory(int size) : end_ahead(1), mem_size(size) {               mem_min=mem_begin=mem_end=new unsigned char[mem_size];               mem_max=mem_min+mem_size;}Memory::~Memory(){ delete[] mem_min; }int Memory::reset(){ mem_begin=mem_end=mem_min; end_ahead=1; return 0; }unsigned char Memory::getchr(){    if (mem_begin>=mem_max){      mem_begin=mem_min;      end_ahead=1;    }    return *mem_begin++;}unsigned int Memory::getbits32(){#ifdef HAVE_MMX      if (mem_begin+4>=mem_max)#endif        return ((getchr() << 24) | (getchr() << 16) | (getchr() << 8) | getchr());#ifdef HAVE_MMX      else {        mmx_m2r(movl,mem_begin,eax);        __asm__ ("movl (%eax),%eax");        __asm__ ("bswap %eax");        mem_begin += 4;      }#endif}int Memory::mem_skip(int size){  if (end_ahead){    mem_begin+=size;  }  else {    if (size<(mem_max-mem_begin)){      mem_begin+=size;    }    else {      end_ahead=1;      mem_begin=mem_min+size-(mem_max-mem_begin);    }  }  return size;}int Memory::put(unsigned char* data, int size){  if (!end_ahead){    memcpy(mem_end, data, size);    mem_end+=size;   }  else {    if (size<(mem_max-mem_end)){      memcpy(mem_end, data, size);      mem_end+=size;    }    else {      unsigned char* dataptr=data;      int bytes=mem_max-mem_end;      memcpy(mem_end, dataptr, bytes);         dataptr+=bytes;      mem_end=mem_min;      end_ahead=0;      int lastbytes=size-bytes;      memcpy(mem_end, dataptr, lastbytes);      mem_end+=lastbytes;      return bytes+lastbytes;    }  }  return size;}  int Memory::used(){ return (end_ahead) ? (mem_end-mem_begin) : (mem_size - (mem_begin - mem_end)); }  int Memory::unused(){ return (end_ahead) ? (mem_size - (mem_end - mem_begin)) : (mem_begin - mem_end); }  unsigned int Memory::getbyte(){ return getchr(); }int Memory::get(unsigned char* data, int size){  if (end_ahead){    memcpy(data, mem_begin, size);    mem_begin+=size;  }  else {    if (size<(mem_max-mem_begin)){      memcpy(data, mem_begin, size);      mem_begin+=size;    }    else {      unsigned char* dataptr=data;      int bytes=mem_max-mem_begin;      memcpy(dataptr, mem_begin, bytes);      dataptr+=bytes;      mem_begin=mem_min;      end_ahead=1;      int lastbytes=size-bytes;      memcpy(dataptr, mem_begin, lastbytes);      mem_begin+=lastbytes;      return bytes+lastbytes;    }  }  return size;}/* * *   Mpeg2Buffer * */Mpeg2Buffer::Mpeg2Buffer(int size) : Memory(size), completed(0) {  TRACER("Mpeg2Buffer::Mpeg2Buffer(int size)");}Mpeg2Buffer::~Mpeg2Buffer(){  TRACER("Mpeg2Buffer::~Mpeg2Buffer()");}int Mpeg2Buffer::close(){  TRACER("int Mpeg2Buffer::close()");  lock();  completed=1;  reset();  signal_read();  unlock();  return 0;}int Mpeg2Buffer::waitforbytes(int size){   lock();  signal_write();  // waitforbytes does not move the pointer, therefore                   // this should be done afterwards which means at the                    // beginning of the next call (the first is redundant)#ifdef TRACEDEEP  while ((rsize=used())<size && !completed){    if (rsize < (0.05*mem_size)) msg("Memory usage < 5%");    wait_read();  }#else  while ((rsize=used())<size && !completed) {//  while ((rsize=used())<=0 && !completed) {    wait_read();  }#endif  unlock();  return (!completed) ? ((rsize < size) ? rsize : size) : rsize; }int Mpeg2Buffer::skipbytes(int size){  DDEBUGGER("int Mpeg2Buffer::skipbytes(int size)");  lock();  while (used()<size && !completed) wait_read();  size = (completed && used()<size)    ? size=mem_skip(used())     // get what's available!    : size=mem_skip(size);   signal_write();  unlock();  return size;}int Mpeg2Buffer::write(unsigned char* data, int size){  DDEBUGGER("int Mpeg2Buffer::write(unsigned char* data, int size)");  lock();#ifdef TRACEDEEP  if (unused() < 0.05*mem_size) msg("Memory usage > 95%");#endif  while (unused()<size && !completed){    wait_write();  }  size = (completed && unused()<size)    ? put(data, unused())          // put what's available    : put(data, size);  signal_read();  unlock();  return size;}int Mpeg2Buffer::read(unsigned char* data, int size){  DDEBUGGER("int Mpeg2Buffer::read(unsigned char* data, int size)");  lock();  while (used()<size && !completed) wait_read();  size = (completed && used()<size)    ? get(data, used())          // get what's available!    : get(data, size);   signal_write();  unlock();  return size;}  void Mpeg2Buffer::lock(){ mem_lock.lock(); }  void Mpeg2Buffer::unlock(){ mem_lock.unlock(); }  void Mpeg2Buffer::wait_write(){ memory_in_cond.wait(&mem_lock); }  void Mpeg2Buffer::wait_read(){ memory_out_cond.wait(&mem_lock); }  void Mpeg2Buffer::signal_write(){ memory_in_cond.signal(); }  void Mpeg2Buffer::signal_read(){ memory_out_cond.signal(); }  int Mpeg2Buffer::available(){ lock(); int b=used(); unlock(); return b; }  int Mpeg2Buffer::maximum() { return mem_size; }  void Mpeg2Buffer::signal_buffer(){ lock(); signal_write(); unlock(); }/* * * Mpeg2Input * */Mpeg2Input::Mpeg2Input(const char* filename, int size, int b) :   Mpeg2Buffer(size), buffer_size(size), bitrate(b){  TRACER("Mpeg2Input::Mpeg2Input(const char* filename, int size, int b)");  if (filename[0] == '-' && filename[1] == '\0')    fd = 0;  else if ((fd=open(filename, O_RDONLY, 0))<=0){    String err="could not open file `";    err+=filename;    err+="' for reading";    cerr << err.chars();    return;  }  if (athr_create((void*(*)(void*)) Mpeg2Input::filereader, this, &id)<0){    error("could not create reader thread");    athr_exit(0);  }}void* Mpeg2Input::filereader(Mpeg2Input* base){  TRACER("void* Mpeg2Input::filereader(Mpeg2Input* base)");  int rsize=0, wsize=base->buffer_size/4;  unsigned char* data=new unsigned char[wsize];  int interval_usec=base->bitrate*wsize, time_real_usec;  Mpeg2Timer timer;  timeval tstart, tstop;  if (base->bitrate)    gettimeofday(&tstart, 0);TRACER("Bitrate " << itoa(base->bitrate));  int eof=0;  while (base->fd >= 0 && !eof){    {      int thisread, got = 0;      unsigned char *dp = data;      while (!eof && got < wsize) {            thisread = ::read(base->fd, dp, wsize - got);        if (thisread > 0) {           got += thisread;           dp += thisread;        } else {           eof = 1;        }       }      rsize = got;    }#ifdef DEBUG    cout << "FileData: " << data << "\n";    uint32 value;    value=((data[0] << 24) | (data[1] << 16) |  (data[2] << 8) |  data[3]);    cout << "FileValue: " << value << "\n";#endif    if (base->write(data, rsize)!=rsize)      error("could not write file data in buffer");    if (base->bitrate>0){      gettimeofday(&tstop, 0);      time_real_usec=(tstop.tv_sec-tstart.tv_sec)*1000000+(tstop.tv_usec-tstart.tv_usec);         if (time_real_usec<interval_usec)	timer.wait(interval_usec - time_real_usec);      gettimeofday(&tstart, 0);    }  }  delete data;  base->close();  athr_exit(0);  return 0;}/* * * Mpeg2Timer * */Mpeg2Timer::Mpeg2Timer(){}Mpeg2Timer::~Mpeg2Timer(){}void Mpeg2Timer::lock(){ timer_lock.lock(); }void Mpeg2Timer::unlock(){ timer_lock.unlock(); }int Mpeg2Timer::wait(int interval_usec){   if (interval_usec<0) error("invalid interval for timer to wait");//  msg("!"); // This is very primitive!!  gettimeofday(&time_new, 0);  time_out=time_new;  time_out.tv_usec+=interval_usec;  if (time_out.tv_usec>1000000){    time_out.tv_sec++;    time_out.tv_usec-=1000000;  }  while (time_new.tv_sec<time_out.tv_sec ||          (time_new.tv_sec==time_out.tv_sec && time_new.tv_usec<time_out.tv_usec)){    athr_yield();    gettimeofday(&time_new, 0);  }  return 1;} int Mpeg2Timer::waitcond(int interval_usec){  lock();  gettimeofday(&time_new, 0);  time.tv_sec=time_new.tv_sec;  time.tv_nsec=(time_new.tv_usec+interval_usec)*1000;  if (time.tv_nsec>1000000000){    time.tv_sec+=(int)(time.tv_nsec/1000000000);    time.tv_nsec-=(time.tv_nsec - (time.tv_nsec % 1000000000));  }  int val=timer_cond.timedwait(&timer_lock, &time);  unlock();  return val;}/*  static sigset_t set;  static siginfo_t info;  info.si_signo=SIGALRM;  sigemptyset(&set);  sigaddset(&set, SIGALRM);  thr_sigsetmask(SIG_UNBLOCK, &set, 0);  int val=sigtimedwait(&set, &info, &time); *//*  Static sigset_t set;  static itimerval val;  sigemptyset(&set);  sigaddset(&set, SIGVTALRM);  thr_sigsetmask(SIG_BLOCK, &set, NULL);  getitimer(ITIMER_VIRTUAL, &val);  gettimeofday(&time_new, 0);  val.it_interval.tv_usec=interval_usec;  val.it_value.tv_sec=time_new.tv_sec;  val.it_value.tv_usec=time_new.tv_usec + interval_usec;  if (val.it_value.tv_usec>1000000){    val.it_value.tv_sec++;    val.it_value.tv_usec-=1000000;  }  setitimer(ITIMER_VIRTUAL, &val, 0);  sigwait(&set);*/#ifdef MAINmain(int argc, char** argv){  TRACER("main(int argc, char** argv)");  Mpeg2Input* myfile=new Mpeg2Input(argv[1], 10*418);  unsigned char* data=new unsigned char[418];  fflush(stdout);  cout.flush();  cerr.flush();  bool eof=False;  while (!eof){    myfile->waitforbytes(418);    //    TRACER("Data=" << data);    TRACER("Value=" << myfile->getbits32());    break;  }  fflush(stdout);  cout.flush();  cerr.flush();  delete myfile;  delete data;}#endif

⌨️ 快捷键说明

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