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

📄 mpegsystem.cpp

📁 This code is based on mpeg_play, available from: http://bmrc.berkeley.edu/frame/research/mpeg/
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        if(errno != ESPIPE)        {          errorstream = true;          SetError(strerror(errno));          }        SDL_mutexV(system_mutex);        return(false);      }          if(SDL_RWread(source, buffer, 1, MPEG_BUFFER_SIZE) < 0) break;      /* Search for a valid audio header */      for(p = buffer; p < buffer + MPEG_BUFFER_SIZE; p++)	if(audio_aligned(p, buffer + MPEG_BUFFER_SIZE - p)) break;          file_ptr += MPEG_BUFFER_SIZE;    }    while(p >= MPEG_BUFFER_SIZE + buffer);    /* Extract time info from the first header */    Uint32 framesize;    double frametime;    Uint32 totalsize;    audio_header(p, &framesize, &frametime);    totalsize = TotalSize();    if(framesize)      time = frametime * totalsize / framesize;  }  else  {    bool last_chance = false;    do    {    /* Otherwise search the stream backwards for a valid header */      file_ptr -= MPEG_BUFFER_SIZE;      if ( file_ptr < -(Sint32)TotalSize() ) {          last_chance = true;          file_ptr = -(Sint32)TotalSize();      }           if((size = SDL_RWseek(source, file_ptr, SEEK_END)) < 0)      {        if(errno != ESPIPE)        {          errorstream = true;          SetError(strerror(errno));          }        SDL_mutexV(system_mutex);        return(false);      }            if(SDL_RWread(source, buffer, 1, MPEG_BUFFER_SIZE) < 0) break;            if(stream_list[0]->streamid == SYSTEM_STREAMID)	for(p = buffer + MPEG_BUFFER_SIZE - 1; p >= buffer;)	{	  if(*p-- != 0xba) continue; // Packet header	  if(*p-- != 1) continue;	  if(*p-- != 0) continue;	  if(*p-- != 0) continue;          ++p;	  break;	}      if(stream_list[0]->streamid == VIDEO_STREAMID)	for(p = buffer + MPEG_BUFFER_SIZE - 1; p >= buffer;)	{	  if(*p-- != 0xb8) continue; // GOP header	  if(*p-- != 1) continue;	  if(*p-- != 0) continue;	  if(*p-- != 0) continue;          ++p;	  break;	}    }    while( !last_chance && (p < buffer) );    if ( p >= buffer ) {      /* Extract time info from the last header */      if(stream_list[0]->streamid == SYSTEM_STREAMID)        packet_header(p, buffer + MPEG_BUFFER_SIZE - p, &time);          if(stream_list[0]->streamid == VIDEO_STREAMID)        gop_header(p, buffer + MPEG_BUFFER_SIZE - p, &time);    }  }  delete[] buffer;  /* Get back to saved position */  if((pos = SDL_RWseek(source, pos, SEEK_SET)) < 0)  {    if(errno != ESPIPE)    {      errorstream = true;      SetError(strerror(errno));      }    time = 0;  }  SDL_mutexV(system_mutex);  return(time);}double MPEGsystem::TimeElapsedAudio(int atByte){  off_t size, pos;  off_t file_ptr;  Uint8 * buffer, * p;  double time;    if (atByte < 0)  {      return -1;  }    /* Lock to avoid concurrent access to the stream */  SDL_mutexP(system_mutex);  /* Save current position */  if((pos = SDL_RWtell(source)) < 0)  {    if(errno != ESPIPE)    {      errorstream = true;      SetError(strerror(errno));    }    SDL_mutexV(system_mutex);    return(false);  }  file_ptr = 0;  buffer = new Uint8[MPEG_BUFFER_SIZE];  /* If audio, compute total time according to bitrate of the first header and total size */  /* Note: this doesn't work on variable bitrate streams */  if(stream_list[0]->streamid == AUDIO_STREAMID)  {    do    {      if((size = SDL_RWseek(source, file_ptr, SEEK_SET)) < 0)      {        if(errno != ESPIPE)        {          errorstream = true;          SetError(strerror(errno));          }        SDL_mutexV(system_mutex);        return(false);      }          if(SDL_RWread(source, buffer, 1, MPEG_BUFFER_SIZE) < 0) break;      /* Search for a valid audio header */      for(p = buffer; p < buffer + MPEG_BUFFER_SIZE; p++)	if(audio_aligned(p, buffer + MPEG_BUFFER_SIZE - p)) break;          file_ptr += MPEG_BUFFER_SIZE;    }    while(p >= MPEG_BUFFER_SIZE + buffer);    /* Extract time info from the first header */    Uint32 framesize;    double frametime;    Uint32 totalsize;    audio_header(p, &framesize, &frametime);    totalsize = TotalSize();    if(framesize)      //is there a better way to do this?      time = (frametime * (atByte ? atByte:totalsize)) / framesize;    else      time = 0;  }  else  //This is not a purely audio stream. This doesn't make sense!  {      time = -1;  }  delete buffer;  /* Get back to saved position */  if((pos = SDL_RWseek(source, pos, SEEK_SET)) < 0)  {    if(errno != ESPIPE)    {      errorstream = true;      SetError(strerror(errno));      }    SDL_mutexV(system_mutex);    return(0);  }  SDL_mutexV(system_mutex);  return(time);}void MPEGsystem::Rewind(){  Seek(0);}bool MPEGsystem::Seek(int length){  /* Stop the system thread */  Stop();  /* Lock to avoid concurrent access to the stream */  SDL_mutexP(system_mutex);    /* Get into the stream */  if(SDL_RWseek(source, length, SEEK_SET) < 0)  {    if(errno != ESPIPE)    {      errorstream = true;      SetError(strerror(errno));    }    return(false);  }  /* Reinitialize the read buffer */  pointer = read_buffer;  read_size = 0;  read_total = length;  stream_list[0]->pos += length;  packet_total = 0;  endofstream = false;  errorstream = false;  timestamp = 0.0;  skip_timestamp = -1;  SDL_mutexV(system_mutex);  /* Restart the system thread */  Start();  return(true);}void MPEGsystem::Loop(bool toggle){    looping = toggle;    loop_all_streams(looping);}void MPEGsystem::RequestBuffer(){  SDL_SemPost(request_wait);}void MPEGsystem::Start(){  if(system_thread_running) return;  /* Get the next header */  if(!seek_next_header())  {    if(!Eof())    {      errorstream = true;      SetError("Could not find the beginning of MPEG data\n");    }  }  #ifdef USE_SYSTEM_THREAD  /* Start the system thread */  system_thread = SDL_CreateThread(SystemThread, this);  /* Wait for the thread to start */  while(!system_thread_running && !Eof())    SDL_Delay(1);#else  system_thread_running = true;#endif}void MPEGsystem::Stop(){  if(!system_thread_running) return;  /* Force the system thread to die */  system_thread_running = false;#ifdef USE_SYSTEM_THREAD  SDL_SemPost(request_wait);  SDL_WaitThread(system_thread, NULL);#endif  /* Reset the streams */  reset_all_streams();}bool MPEGsystem::Wait(){  if ( ! errorstream ) {    while(SDL_SemValue(request_wait) != 0)#ifdef USE_SYSTEM_THREAD      SDL_Delay(1);#else      if ( ! SystemLoop(this) ) break;#endif  }  return(!errorstream);}bool MPEGsystem::Eof() const{  return(errorstream || endofstream);}bool MPEGsystem::SystemLoop(MPEGsystem *system){  /* Check for end of file */  if(system->Eof())  {    /* Set the eof mark on all streams */    system->end_all_streams();    /* Get back to the beginning of the stream if possible */    if(SDL_RWseek(system->source, 0, SEEK_SET) < 0)    {      if(errno != ESPIPE)      {        system->errorstream = true;        system->SetError(strerror(errno));      }      return(false);    }    /* Reinitialize the read buffer */    system->pointer = system->read_buffer;    system->read_size = 0;    system->read_total = 0;    system->packet_total = 0;    system->endofstream = false;    system->errorstream = false;    /* Get the first header */    if(!system->seek_first_header())    {      system->errorstream = true;      system->SetError("Could not find the beginning of MPEG data\n");      return(false);    }  }  /* Wait for a buffer request */  SDL_SemWait(system->request_wait);  /* Read the buffer */  system->FillBuffer();  return(true);}int MPEGsystem::SystemThread(void * udata){  MPEGsystem * system = (MPEGsystem *) udata;  system->system_thread_running = true;  while(system->system_thread_running)  {    if ( ! SystemLoop(system) ) {      system->system_thread_running = false;    }  }  return(true);}void MPEGsystem::add_stream(MPEGstream * stream){  register int i;  /* Go to the end of the list */  for(i = 0; stream_list[i]; i++);  /* Resize list */  stream_list =     (MPEGstream **) realloc(stream_list, (i+2)*sizeof(MPEGstream *));  /* Write the stream */  stream_list[i] = stream;  /* Set the looping flag for that stream */  stream->loop(looping);    /* Put the end marker (null) */  stream_list[i+1] = 0;}MPEGstream * MPEGsystem::get_stream(Uint8 stream_id){  register int i;  for(i = 0; stream_list[i]; i++)    if(stream_list[i]->streamid == stream_id)      break;  return(stream_list[i]);}Uint8 MPEGsystem::exist_stream(Uint8 stream_id, Uint8 mask){  register int i;  for(i = 0; stream_list[i]; i++)    if(((stream_list[i]->streamid) & mask) == (stream_id & mask))      return(stream_list[i]->streamid);  return(0);}void MPEGsystem::reset_all_streams(){  register int i;  /* Reset the streams */  for(i = 0; stream_list[i]; i++)    stream_list[i]->reset_stream();}void MPEGsystem::end_all_streams(){  register int i;  /* End the streams */  /* We use a null buffer as the end of stream marker */  for(i = 0; stream_list[i]; i++)    stream_list[i]->insert_packet(0, 0);}void MPEGsystem::loop_all_streams(bool toggle){  register int i;  /* Set loop flag on all streams */  for(i = 0; stream_list[i]; i++)    stream_list[i]->loop(toggle);}bool MPEGsystem::seek_first_header(){  Read();  if(Eof())    return(false);  while(!(audio_aligned(pointer, read_buffer + read_size - pointer) ||	  system_aligned(pointer, read_buffer + read_size - pointer) || 	  Match4(pointer, VIDEO_CODE, VIDEO_MASK)))  {       ++pointer;       stream_list[0]->pos++;      /* Make sure buffer is always full */      Read();      if(Eof())	return(false);  }  return(true);}bool MPEGsystem::seek_next_header(){  Read();  if(Eof())    return(false);  while(!( (stream_list[0]->streamid == AUDIO_STREAMID && audio_aligned(pointer, read_buffer + read_size - pointer)) ||	   (stream_list[0]->streamid == SYSTEM_STREAMID && system_aligned(pointer, read_buffer + read_size - pointer)) ||	   (stream_list[0]->streamid == VIDEO_STREAMID && Match4(pointer, GOP_CODE, GOP_MASK))	 ) )  {       ++pointer;       stream_list[0]->pos++;      /* Make sure buffer is always full */      Read();      if(Eof())	return(false);  }  return(true);}

⌨️ 快捷键说明

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