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

📄 video_sdl.cpp

📁 网络MPEG4IP流媒体开发源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    SDL_UnlockYUVOverlay(m_image);	}  } #ifdef CHECK_SYNC_TIMEelse {#ifdef VIDEO_SYNC_PLAY    video_message(LOG_DEBUG, "Video lagging current time "LLU" "LLU" "LLU, 			 play_this_at, current_time, m_msec_per_frame);#endif    /*     * Else - we're lagging - just skip and hope we catch up...     */    m_skipped_render++;    m_consec_skipped++;  }#endif  /*   * Advance the buffer   */  m_buffer_filled[m_play_index] = 0;#ifdef VIDEO_SYNC_FILL  uint32_t temp;  temp = m_play_index;#endif  m_play_index++;  m_play_index %= MAX_VIDEO_BUFFERS;  m_total_frames++;  //   // okay - we need to signal the decode task to continue...  if (m_decode_waiting) {    m_decode_waiting = 0;    SDL_SemPost(m_decode_sem);#ifdef VIDEO_SYNC_FILL    video_message(LOG_DEBUG, "wait posting %d", temp);#endif  }  if (m_buffer_filled[m_play_index] == 1) {    if (m_play_this_at[m_play_index] < current_time)       return (0);    else {      m_msec_per_frame = m_play_this_at[m_play_index] - current_time;      return (m_msec_per_frame);    }  }  /*   * we don't have next frame decoded yet.  Wait a minimal time - this   * means the decode task will signal   */  m_msec_per_frame = 0;  return (10);}int CSDLVideoSync::get_video_buffer(uint8_t **y,				 uint8_t **u,				 uint8_t **v){    if (m_dont_fill != 0)     return (0);  if (m_buffer_filled[m_fill_index] != 0) {    m_decode_waiting = 1;    SDL_SemWait(m_decode_sem);    if (m_dont_fill != 0)      return 0;    if (m_buffer_filled[m_fill_index] != 0)      return 0;  }  *y = m_y_buffer[m_fill_index];  *u = m_u_buffer[m_fill_index];  *v = m_v_buffer[m_fill_index];  return (1);}void CSDLVideoSync::filled_video_buffers (uint64_t time){  int ix;  if (m_dont_fill == 1)    return;  m_play_this_at[m_fill_index] = time;  m_buffer_filled[m_fill_index] = 1;  ix = m_fill_index;  m_fill_index++;  m_fill_index %= MAX_VIDEO_BUFFERS;  m_filled_frames++;  if (m_msec_per_frame == 0) {    m_msec_per_frame = time - m_last_filled_time;  }  m_last_filled_time = time;  m_psptr->wake_sync_thread();#ifdef VIDEO_SYNC_FILL  video_message(LOG_DEBUG, "Filled %llu %d", time, ix);#endif}/* * CSDLVideoSync::set_video_frame - called from codec to indicate a new * frame is ready. * Inputs - y - pointer to y buffer - should point to first byte to copy *          u - pointer to u buffer *          v - pointer to v buffer *          pixelw_y - width of row in y buffer (may be larger than width *                   set up above. *          pixelw_uv - width of row in u or v buffer. *          time - time to display *          current_time - current time we're displaying - this allows the *            codec to intelligently drop frames if it's falling behind. */void CSDLVideoSync::set_video_frame(const uint8_t *y, 				    const uint8_t*u, 				    const uint8_t *v,				    int pixelw_y, 				    int pixelw_uv, 				    uint64_t time){  uint8_t *dst;  const uint8_t *src;  unsigned int ix;  if (m_dont_fill != 0) {#ifdef VIDEO_SYNC_FILL    video_message(LOG_DEBUG, "Don't fill in video sync");#endif    return;  }  /*   * Do we have a buffer ?  If not, indicate that we're waiting, and wait   */  if (m_buffer_filled[m_fill_index] != 0) {    m_decode_waiting = 1;    SDL_SemWait(m_decode_sem);    if (m_buffer_filled[m_fill_index] != 0) {#ifdef VIDEO_SYNC_FILL      video_message(LOG_DEBUG, "Wait but filled %d", m_fill_index);#endif      return;    }  }    /*   * copy the relevant data to the local buffers   */  m_play_this_at[m_fill_index] = time;  src = y;  dst = m_y_buffer[m_fill_index];  for (ix = 0; ix < m_height; ix++) {    memcpy(dst, src, m_width);    dst += m_width;    src += pixelw_y;  }  src = u;  dst = m_u_buffer[m_fill_index];  unsigned int uvheight = m_height/2;  unsigned int uvwidth = m_width/2;  for (ix = 0; ix < uvheight; ix++) {    memcpy(dst, src, uvwidth);    dst += uvwidth;    src += pixelw_uv;  }  src = v;  dst = m_v_buffer[m_fill_index];  for (ix = 0; ix < uvheight; ix++) {    memcpy(dst, src, uvwidth);    dst += uvwidth;    src += pixelw_uv;  }  /*   * advance the buffer, and post to the sync task   */  m_buffer_filled[m_fill_index] = 1;  ix = m_fill_index;  m_fill_index++;  m_fill_index %= MAX_VIDEO_BUFFERS;  m_filled_frames++;  if (m_msec_per_frame == 0) {    m_msec_per_frame = time - m_last_filled_time;  }  m_last_filled_time = time;  m_psptr->wake_sync_thread();#ifdef VIDEO_SYNC_FILL  video_message(LOG_DEBUG, "filled %llu %d", time, ix);#endif  return;}// called from sync thread.  Don't call on play, or m_dont_fill race// condition may occur.void CSDLVideoSync::flush_sync_buffers (void){  // Just restart decode thread if waiting...  m_dont_fill = 1;  m_eof_found = 0;  m_paused = 1;  if (m_decode_waiting) {    SDL_SemPost(m_decode_sem);    // start debug  }}// called from decode thread on both stop/start.void CSDLVideoSync::flush_decode_buffers (void){  for (int ix = 0; ix < MAX_VIDEO_BUFFERS; ix++) {    m_buffer_filled[ix] = 0;  }  m_fill_index = m_play_index = 0;  m_dont_fill = 0;}void CSDLVideoSync::set_screen_size (int scaletimes2){  m_video_scale = scaletimes2;}void CSDLVideoSync::set_fullscreen (int fullscreen){  m_fullscreen = fullscreen;}void CSDLVideoSync::do_video_resize (int pixel_width, 				     int pixel_height, 				     int max_width, 				     int max_height, 				     bool resize){#if 0  player_debug_message("do_video_resize %d,%d,%d,%d\n",		       pixel_width,pixel_height,max_width,max_height);#endif  // Save values for future use (i.e. -1 values as argument will  // restore an argument.)  if (pixel_width > -1) m_pixel_width = pixel_width;  if (pixel_height > -1) m_pixel_height = pixel_height;  if (max_width > -1) m_max_width = max_width;  if (max_height > -1) m_max_height = max_height;  // Check and see if all we wanted was to transfer values.  if (!resize) {    return;  }  if (m_image) {    SDL_FreeYUVOverlay(m_image);    m_image = NULL;  }  if (m_screen) {    SDL_FreeSurface(m_screen);    m_screen = NULL;  }#ifdef OLD_SURFACE  int mask = SDL_SWSURFACE | SDL_ASYNCBLIT | SDL_RESIZABLE;#else  int mask = SDL_HWSURFACE | SDL_RESIZABLE;#endif  int video_scale = m_video_scale;  if (m_fullscreen != 0) {    mask |= SDL_FULLSCREEN;#ifdef _WIN32	video_scale = 2;#endif  }  int w = m_width * video_scale / 2;  if (m_double_width) w *= 2;  int h = m_height * video_scale / 2;      // Check and see if we should use old values.  if (pixel_width == -1 && m_pixel_width) pixel_width = m_pixel_width;  if (pixel_height == -1 && m_pixel_height) pixel_height = m_pixel_height;  if (max_width == -1 && m_max_width) max_width = m_max_width;  if (max_height == -1 && m_max_height) max_height = m_height;   // It is only when we have positive values larger than zero for  // pixel sizes that we resize  if (pixel_width > 0 && pixel_height > 0) {     // Square pixels needs no resize.    if (pixel_width != pixel_height) {       // enable different handling of full screen versus non full screen      if (m_fullscreen == 0) {	if (pixel_width > pixel_height)	  w = h * pixel_width / pixel_height;	else w = w * pixel_height / pixel_width;      } else { 	// For now we do the same as in non full screen.	if (pixel_width > pixel_height)	  w = h * pixel_width / pixel_height;	else w = w * pixel_height / pixel_width;      }    }  }  if (m_fullscreen == 1) {    if (max_width > 0 && w > max_width) w = max_width;    if (max_height > 0 && h > max_height) h = max_height;  }  video_message(LOG_DEBUG, "Setting video mode %d %d %x", 		w, h, mask);  m_screen = SDL_SetVideoMode(w, h, m_video_bpp, 			      mask);  if (m_screen == NULL) {    m_screen = SDL_SetVideoMode(w, h, m_video_bpp, mask);    if (m_screen == NULL) {      video_message(LOG_CRIT, "sdl error message is %s", SDL_GetError());      abort();    }  }  m_dstrect.x = 0;  m_dstrect.y = 0;  m_dstrect.w = m_screen->w;  m_dstrect.h = m_screen->h;  SDL_FreeYUVOverlay(m_image);#ifdef OLD_SURFACE  if (video_scale == 4) {    m_image = SDL_CreateYUVOverlay(m_width << 1, 				 m_height << 1,				 SDL_YV12_OVERLAY, 				 m_screen);  } else #endif    {    m_image = SDL_CreateYUVOverlay(m_width, 				 m_height,				 SDL_YV12_OVERLAY, 				 m_screen);  }}void CSDLVideoSync::double_width (void){  m_double_width = 1;}static void c_video_configure (void *ifptr,			      int w,			      int h,			      int format){  // asdf - ignore format for now  ((CSDLVideoSync *)ifptr)->config(w, h);}static int c_video_get_buffer (void *ifptr, 			       uint8_t **y,			       uint8_t **u,			       uint8_t **v){  return (((CSDLVideoSync *)ifptr)->get_video_buffer(y, u, v));}static void c_video_filled_buffer(void *ifptr, uint64_t time){  ((CSDLVideoSync *)ifptr)->filled_video_buffers(time);}static void c_video_have_frame (void *ifptr,			       const uint8_t *y,			       const uint8_t *u,			       const uint8_t *v,			       int m_pixelw_y,			       int m_pixelw_uv,			       uint64_t time){  CSDLVideoSync *foo = (CSDLVideoSync *)ifptr;  foo->set_video_frame(y, 		       u, 		       v, 		       m_pixelw_y,		       m_pixelw_uv,		       time);}static video_vft_t video_vft = {  message,  c_video_configure,  c_video_get_buffer,  c_video_filled_buffer,  c_video_have_frame,};video_vft_t *get_video_vft (void){  return (&video_vft);}CVideoSync *create_video_sync (CPlayerSession *psptr) {  return new CSDLVideoSync(psptr);}/* end file video.cpp */

⌨️ 快捷键说明

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