liblavplay.c

来自「Motion JPEG编解码器源代码」· C语言 代码 · 共 2,022 行 · 第 1/5 页

C
2,022
字号
            strerror(errno));         return 0;      }      /* hack for wrong return value of marvel cards..... */      if (vc.maxwidth!=640 && vc.maxwidth!=768)         vc.maxwidth=720;#ifndef X_DISPLAY_MISSING      XGetWindowAttributes(dpy, DefaultRootWindow(dpy), &wts);      screenwidth = wts.width;      screenheight = wts.height;#else      screenwidth = 1024;      screenheight = 768;#endif      vw.y = info->soft_full_screen ? 0: (screenheight-((bp->norm == 0) ? 576 : 480))/2;      if (info->vw_y_offset != VALUE_NOT_FILLED && !info->soft_full_screen)         vw.y = info->vw_y_offset;      vw.x = info->soft_full_screen ? 0: (screenwidth-vc.maxwidth)/2;      if (info->vw_x_offset != VALUE_NOT_FILLED && !info->soft_full_screen)         vw.x = info->vw_x_offset;      vw.width = info->soft_full_screen ? screenwidth : vc.maxwidth;      if (info->sdl_width > 0 && !info->soft_full_screen)         vw.width = info->sdl_width;      vw.height = info->soft_full_screen ? screenheight : ((bp->norm == 0) ? 576 : 480);      if (info->sdl_height > 0 && !info->soft_full_screen)         vw.height = info->sdl_height;      vw.clips = NULL;      vw.clipcount = 0;      vw.chromakey = -1;      if (info->soft_full_screen ? 0: (screenwidth-vc.maxwidth)/2 < 0)      {         lavplay_msg(LAVPLAY_MSG_ERROR, info,            "X offset (%d) would be < 0",            vw.x);         return 0;      }      if (info->soft_full_screen ? 0: (screenheight-((bp->norm == 0) ? 576 : 480))/2 < 0)      {         lavplay_msg(LAVPLAY_MSG_ERROR, info,            "Y offset (%d) would be < 0",            vw.y);         return 0;      }#ifndef X_DISPLAY_MISSING      if (vw.x + vw.width > wts.width)      {         lavplay_msg(LAVPLAY_MSG_ERROR, info,            "X offset + width (%d+%d) would be > screensize (%d)",            vw.x, vw.width, wts.width);         return 0;      }      if (vw.y + vw.height > wts.height)      {         lavplay_msg(LAVPLAY_MSG_ERROR, info,            "Y offset + height (%d+%d) would be > screensize (%d)",            vw.y, vw.height, wts.height);         return 0;      }#endif      if (ioctl(settings->video_fd, VIDIOCSWIN, &vw) < 0)      {         lavplay_msg(LAVPLAY_MSG_ERROR, info,            "Could not set on-screen window parameters (check framebuffer-params with v4l-conf): %s",            strerror(errno));         return 0;      }      n = 1;      if (ioctl(settings->video_fd, VIDIOCCAPTURE, &n) < 0)      {         lavplay_msg(LAVPLAY_MSG_ERROR, info,            "Could not activate on-screen window: %s", strerror(errno));         return 0;      }      bp->VFIFO_FB = 1;   }#endif   switch (info->playback_mode)   {#ifdef HAVE_V4L      case 'C':      case 'H':         /* All should be set up now, set the parameters */         lavplay_msg(LAVPLAY_MSG_DEBUG, info,            "Hardware video settings: input=%d, norm=%d, fields_per_buf=%d, "            "x=%d, y=%d, width=%d, height=%d, quality=%d",            bp->input, bp->norm, bp->field_per_buff, bp->img_x, bp->img_y,            bp->img_width, bp->img_height, bp->quality);         if (ioctl(settings->video_fd, MJPIOC_S_PARAMS, bp) < 0)         {            lavplay_msg(LAVPLAY_MSG_ERROR, info,               "Error setting video parameters: %s", strerror(errno));            return 0;         }         break;#endif#ifdef HAVE_SDL      case 'S':         settings->show_top = (bp->odd_even) ? 1 : 0; /* odd_even = 1: show top field first */         break;#endif      default:         lavplay_msg(LAVPLAY_MSG_ERROR, info,            "lavplay_mjpeg_set_params(): Unknown playback mode (\'%c\')", info->playback_mode);         return 0;   }   return 1;}/****************************************************** * lavplay_mjpeg_set_frame_rate() *   set the frame rate * * return value: 1 on success, 0 on error ******************************************************/static int lavplay_mjpeg_set_playback_rate(lavplay_t *info, double video_fps, int norm){   int norm_usec_per_frame = 0;   int target_usec_per_frame;   video_playback_setup *settings = (video_playback_setup *)info->settings;   /*EditList *editlist = info->editlist; */   switch (norm)   {      case VIDEO_MODE_PAL:      case VIDEO_MODE_SECAM:         norm_usec_per_frame = 1000000/25; /* 25Hz */         break;      case VIDEO_MODE_NTSC:         norm_usec_per_frame = 1001000/30;  /* 30ish Hz */         break;      default:         if (info->playback_mode != 'S')         {            lavplay_msg(LAVPLAY_MSG_ERROR, info,               "Hardware playback impossible: unknown video norm!");            return 0;         }   }   if( video_fps != 0.0 )      target_usec_per_frame = (int)(1000000.0 / video_fps);   else      target_usec_per_frame = norm_usec_per_frame;   if (info->playback_mode != 'S' &&      abs(target_usec_per_frame - norm_usec_per_frame) > 50)   {      lavplay_msg(LAVPLAY_MSG_ERROR, info,         "Specified frame-rate doesn't match in mode in hardware playback (target: %d, norm: %d)",		target_usec_per_frame, norm_usec_per_frame);      return 0;   }   settings->usec_per_frame = target_usec_per_frame;   return 1;}/****************************************************** * lavplay_mjpeg_queue_buf() *   queue a buffer * * return value: 1 on success, 0 on error ******************************************************/static int lavplay_mjpeg_queue_buf(lavplay_t *info, int frame, int frame_periods){   video_playback_setup *settings = (video_playback_setup *)info->settings;   /*EditList *editlist = info->editlist; */   switch (info->playback_mode)   {#ifdef HAVE_V4L      case 'H':      case 'C':         if (ioctl(settings->video_fd, MJPIOC_QBUF_PLAY, &frame) < 0)         {            lavplay_msg(LAVPLAY_MSG_ERROR, info,               "Error queueing buffer: %s", strerror(errno));            return 0;         }         break;#endif#ifdef HAVE_SDL      case 'S':         /* mark this buffer as playable and tell the software playback thread to wake up if it sleeps */         pthread_mutex_lock(&(settings->valid_mutex));         settings->valid[frame] = frame_periods;         pthread_cond_broadcast(&(settings->buffer_filled[frame]));         pthread_mutex_unlock(&(settings->valid_mutex));      break;#endif      default:         lavplay_msg(LAVPLAY_MSG_ERROR, info,            "lavplay_mjpeg_queue_buf(): Unknown playback mode (\'%c\')", info->playback_mode);         return 0;   }   return 1;}/****************************************************** * lavplay_mjpeg_sync_buf() *   sync on a buffer * * return value: 1 on success, 0 on error ******************************************************/static int lavplay_mjpeg_sync_buf(lavplay_t *info, struct mjpeg_sync *bs){   video_playback_setup *settings = (video_playback_setup *)info->settings;   /*EditList *editlist = info->editlist; */   switch (info->playback_mode)   {#ifdef HAVE_V4L       case 'H':      case 'C':         if (ioctl(settings->video_fd, MJPIOC_SYNC, bs) < 0)         {            lavplay_msg(LAVPLAY_MSG_ERROR, info,               "Error syncing on a buffer: %s", strerror(errno));            return 0;         }         lavplay_msg(LAVPLAY_MSG_DEBUG, info,            "frame=%ld, length=%ld, seq=%ld", bs->frame, bs->length, bs->seq);         break;#endif#ifdef HAVE_SDL      case 'S':         /* Wait until this buffer has been played */         pthread_mutex_lock(&(settings->valid_mutex));         while (settings->valid[settings->currently_synced_frame] != 0)         {            pthread_cond_wait(&(settings->buffer_done[settings->currently_synced_frame]),               &(settings->valid_mutex));         }         pthread_mutex_unlock(&(settings->valid_mutex));         /* copy the relevant sync information */         memcpy(bs, &(settings->syncinfo[settings->currently_synced_frame]),            sizeof(struct mjpeg_sync));         settings->currently_synced_frame = (settings->currently_synced_frame + 1) % settings->br.count;         break;#endif      default:         lavplay_msg(LAVPLAY_MSG_ERROR, info,            "lavplay_mjpeg_sync_buf(): Unknown playback mode (\'%c\')", info->playback_mode);         return 0;   }   return 1;}/****************************************************** * lavplay_mjpeg_close() *   close down * * return value: 1 on success, 0 on error ******************************************************/static int lavplay_mjpeg_close(lavplay_t *info){#ifdef	HAVE_V4L   int n;#endif   video_playback_setup *settings = (video_playback_setup *)info->settings;   /*EditList *editlist = info->editlist; */   lavplay_msg(LAVPLAY_MSG_DEBUG, info,      "Closing down the %s", info->playback_mode=='S'?"threading system":"video device");   switch (info->playback_mode)   {#ifdef HAVE_V4L      case 'C':      case 'H':         n = -1;         if (ioctl(settings->video_fd, MJPIOC_QBUF_PLAY, &n) < 0)         {            lavplay_msg(LAVPLAY_MSG_ERROR, info,               "Error de-queueing the buffers: %s", strerror(errno));            return 0;         }         if (info->playback_mode == 'H')         {            n = 0;            if (ioctl(settings->video_fd, VIDIOCCAPTURE, &n) < 0)            {               lavplay_msg(LAVPLAY_MSG_ERROR, info,                  "Could not deactivate on-screen window: %s", strerror(errno));               return 0;            }         }         break;#endif#ifdef HAVE_SDL      case 'S':         pthread_cancel(settings->software_playback_thread);         if (pthread_join(settings->software_playback_thread, NULL))          {            lavplay_msg(LAVPLAY_MSG_ERROR, info,               "Failure deleting software playback thread");            return 0;         }         break;#endif      default:         lavplay_msg(LAVPLAY_MSG_ERROR, info,            "lavplay_mjpeg_close(): Unknown playback mode (\'%c\')", info->playback_mode);         return 0;   }   return 1;}/****************************************************** * lavplay_init() *   check the given settings and initialize everything * * return value: 1 on success, 0 on error ******************************************************/static int lavplay_init(lavplay_t *info){   long nqueue;   struct mjpeg_params bp;#ifdef HAVE_V4L    struct video_capability vc;#endif    video_playback_setup *settings = (video_playback_setup *)info->settings;   EditList *editlist = info->editlist;   int hn;   if (editlist->video_frames == 0 && !info->get_video_frame)   {      lavplay_msg(LAVPLAY_MSG_ERROR, info,         "No video source!");      return 0;   }   if (editlist->video_frames == 0 && info->editlist->has_audio &&      info->audio && !info->get_audio_sample)   {      lavplay_msg(LAVPLAY_MSG_ERROR, info,         "Audio turned on but no audio source!");      return 0;   }   if (editlist->video_frames > 0 && (info->get_video_frame ||      info->get_audio_sample))   {      lavplay_msg(LAVPLAY_MSG_ERROR, info,         "Manual input as well as file input!");      return 0;   }   /* Set min/max options so that it runs like it should */   settings->min_frame_num = 0;   settings->max_frame_num = editlist->video_frames - 1;   settings->current_frame_num = settings->min_frame_num; /* start with frame 0 */   /* Seconds per video frame: */   settings->spvf = 1.0 / editlist->video_fps;   lavplay_msg(LAVPLAY_MSG_DEBUG, info,      "1.0/SPVF = %4.4f", 1.0 / settings->spvf );   /* Seconds per audio sample: */   if(editlist->has_audio && info->audio)      settings->spas = 1.0 / editlist->audio_rate;   else      settings->spas = 0.;   if (info->flicker_reduction)   {      /* allocate auxiliary video buffer for flicker reduction */      settings->tmpbuff[0] = (uint8_t *)malloc(editlist->max_frame_size);      settings->tmpbuff[1] = (uint8_t *)malloc(editlist->max_frame_size);      if (!settings->tmpbuff[0] || !settings->tmpbuff[1])      {         lavplay_msg (LAVPLAY_MSG_ERROR, info,            "Malloc error, you\'re probably out of memory");         return 0;      }   }   /* initialize the playback threading system (used to be libmjpeg) */   lavplay_mjpeg_open(info);#ifdef HAVE_SDL   /* init SDL if we want SDL */   if (info->playback_mode == 'S')   {      char *env = getenv("LAVPLAY_VIDEO_FORMAT");

⌨️ 快捷键说明

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