liblavplay.c

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

C
2,022
字号
   if (info->state_changed)      info->state_changed(new_state);}/****************************************************** * lavplay_set_speed() *   set the playback speed (<0 is play backwards) * * return value: 1 on success, 0 on error ******************************************************/int lavplay_set_speed(lavplay_t *info, int speed){   video_playback_setup *settings = (video_playback_setup *)info->settings;   /*EditList *editlist = info->editlist; */   int changed = 0;   if ((settings->current_frame_num == settings->max_frame_num && speed > 0) ||      (settings->current_frame_num == settings->min_frame_num && speed < 0))   {      lavplay_msg(LAVPLAY_MSG_WARNING, info,         "We are already at the %s", speed<0?"beginning":"end");      return 0;   }   if ((speed==0 && settings->current_playback_speed!=0) ||      (speed!=0 && settings->current_playback_speed==0))      changed = 1;   settings->current_playback_speed = speed;   if (changed)   {      if (speed==0)         lavplay_change_state(info, LAVPLAY_STATE_PAUSED);      else         lavplay_change_state(info, LAVPLAY_STATE_PLAYING);   }   return 1;}/****************************************************** * lavplay_increase_frame() *   increase (or decrease) a num of frames * * return value: 1 on succes, 0 if we had to change state ******************************************************/int lavplay_increase_frame(lavplay_t *info, long num){   video_playback_setup *settings = (video_playback_setup *)info->settings;   /*EditList *editlist = info->editlist; */   settings->current_frame_num += num;   if (settings->current_frame_num < settings->min_frame_num)   {      settings->current_frame_num = settings->min_frame_num;      if (settings->current_playback_speed < 0) lavplay_set_speed(info, 0);      return 0;   }   if (settings->current_frame_num > settings->max_frame_num)   {      settings->current_frame_num = settings->max_frame_num;      if (settings->current_playback_speed > 0) lavplay_set_speed(info, 0);      return 0;   }   return 1;}/****************************************************** * lavplay_set_frame() *   set the current framenum * * return value: 1 on success, 0 if we had to change state ******************************************************/int lavplay_set_frame(lavplay_t *info, long framenum){   video_playback_setup *settings = (video_playback_setup *)info->settings;   /*EditList *editlist = info->editlist; */   return lavplay_increase_frame(info, framenum - settings->current_frame_num);}/****************************************************** * lavplay_get_video() *   get video data * * return value: length of frame on success, -1 on error ******************************************************/static int lavplay_get_video(lavplay_t *info, uint8_t *buff, long frame_num){   if (info->get_video_frame)   {      int length;      info->get_video_frame(buff, &length, frame_num);      return length;   }   else   {      return el_get_video_frame(buff, frame_num, info->editlist);   }}/****************************************************** * lavplay_get_audio() *   get audio data * * return value: number of samples on success, -1 on error ******************************************************/static int lavplay_get_audio(lavplay_t *info, uint8_t *buff, long frame_num, int mute)   {   int num_samps;   if (info->get_audio_sample)      info->get_audio_sample(buff, &num_samps, frame_num);   else      num_samps =  el_get_audio_data(buff, frame_num, info->editlist, mute);/* fprintf(stderr, "get_audio_sample %x num_samps %x frame_num %x\n", info->get_audio_sample, num_samps, frame_num); */   return(num_samps);   }/****************************************************** * lavplay_queue_next_frame() *   queues a frame (video + audio) * * return value: 1 on succes, 0 on error ******************************************************/static int lavplay_queue_next_frame(lavplay_t *info, uint8_t *vbuff,				    int data_format,				    int skip_video, int skip_audio, int skip_incr){   int res, mute, i, jpeg_len1, jpeg_len2, new_buff_no;   char hlp[16];   video_playback_setup *settings = (video_playback_setup *)info->settings;   EditList *editlist = info->editlist;   /* Read next frame */   if (!skip_video)   {      if (info->flicker_reduction && editlist->video_inter &&	  data_format == DATAFORMAT_MJPG &&	  settings->current_playback_speed <= 0)      {         if (settings->current_playback_speed == 0)         {            if ((res = lavplay_get_video(info, vbuff, settings->current_frame_num)) < 0)               return 0;            jpeg_len1 = lav_get_field_size(vbuff, res);            /* Found seperate fields? */            if (jpeg_len1 < res)            {               memcpy(vbuff+jpeg_len1, vbuff, jpeg_len1);               settings->old_field_len = 0;            }         }         else /* play_speed < 0, play old first field + actual second field */         {            new_buff_no = 1 - settings->old_buff_no;            if ((res = lavplay_get_video(info, settings->tmpbuff[new_buff_no],               settings->current_frame_num)) < 0)               return 0;            jpeg_len1 = lav_get_field_size(settings->tmpbuff[new_buff_no], res);            if (jpeg_len1 < res)            {               jpeg_len2 = res - jpeg_len1;               if (settings->old_field_len==0)               {                  /* no old first field, duplicate second field */                  memcpy(vbuff,settings->tmpbuff[new_buff_no]+jpeg_len1,jpeg_len2);                  settings->old_field_len = jpeg_len2;               }               else               {                  /* copy old first field into vbuff */                  memcpy(vbuff,settings->tmpbuff[settings->old_buff_no],settings->old_field_len);               }               /* copy second field */               memcpy(vbuff+settings->old_field_len,settings->tmpbuff[new_buff_no]+jpeg_len1,jpeg_len2);               /* save first field */               settings->old_field_len = jpeg_len1;               settings->old_buff_no = new_buff_no;            }         }      }      else      {         if (lavplay_get_video(info, vbuff, settings->current_frame_num) < 0)            return 0;         settings->old_field_len = 0;      }   }   /* Read audio, if present */   if (editlist->has_audio && !skip_audio && info->audio)   {      mute = (settings->audio_mute ||	      !((settings->current_playback_speed ==  1 && (info->audio & 1)) ||		(settings->current_playback_speed == -1 && (info->audio & 2)) ||		(settings->current_playback_speed ==  0 && (info->audio & 8)) ||		(1 < settings->current_playback_speed   && (info->audio & (1|4)) == (1|4)) ||		(settings->current_playback_speed < -1  && (info->audio & (2|4)) == (2|4))));      res = lavplay_get_audio(info, settings->abuff,         settings->current_frame_num, mute);      if (settings->current_playback_speed < 0)      {         /* reverse audio */         for(i=0;i<res/2;i+=editlist->audio_bps)         {            memcpy(hlp,settings->abuff+i, editlist->audio_bps);            memcpy(settings->abuff+i,settings->abuff+res-i-editlist->audio_bps, editlist->audio_bps);            memcpy(settings->abuff+res-i-editlist->audio_bps,hlp, editlist->audio_bps);         }      }      res = audio_write(settings->abuff,res,0);      if (res < 0)      {         lavplay_msg(LAVPLAY_MSG_ERROR, info,            "Error playing audio: %s",audio_strerror());         return 0;      }   }   /* Increment frames */   if(!skip_incr)   {      res = lavplay_increase_frame(info, settings->current_playback_speed);      if (!info->continuous) return res;   }   return 1;}/****************************************************** * lavplay_SDL_lock() *   when using software playback - lock the SDL screen * * return value: 1 on success, 0 on error ******************************************************/#ifdef HAVE_SDLstatic int lavplay_SDL_lock(lavplay_t *info){   video_playback_setup *settings = (video_playback_setup *)info->settings;   /* lock the screen for current decompression */   if (SDL_MUSTLOCK(settings->screen))    {      if (SDL_LockSurface(settings->screen) < 0)      {         lavplay_msg(LAVPLAY_MSG_ERROR, info,            "Error locking output screen: %s", SDL_GetError());         return 0;      }   }   if (SDL_LockYUVOverlay(settings->yuv_overlay) < 0)   {      lavplay_msg(LAVPLAY_MSG_ERROR, info,         "Error locking yuv overlay: %s", SDL_GetError());      return 0;   }   return 1;}#endif/****************************************************** * lavplay_SDL_unlock() *   when using software playback - unlock the SDL screen * * return value: 1 on success, 0 on error ******************************************************/#ifdef HAVE_SDLstatic int lavplay_SDL_unlock(lavplay_t *info){   video_playback_setup *settings = (video_playback_setup *)info->settings;   if (SDL_MUSTLOCK(settings->screen))    {      SDL_UnlockSurface(settings->screen);   }   SDL_UnlockYUVOverlay(settings->yuv_overlay);   return 1;}#endif/****************************************************** * lavplay_SDL_update() *   when using software playback - there's a new frame * * return value: 1 on success, 0 on error ******************************************************/#ifdef HAVE_SDLstatic int lavplay_SDL_update(lavplay_t *info, uint8_t *jpeg_buffer,			      int data_format,			      int buf_len){   video_playback_setup *settings = (video_playback_setup *)info->settings;   uint8_t *output[3];   EditList *editlist = info->editlist;   if (!lavplay_SDL_lock(info)) return 0;   /* decode frame to yuv */   switch (data_format) {   case DATAFORMAT_MJPG:      decode_jpeg_raw(jpeg_buffer, buf_len,		      editlist->video_inter>0&&info->exchange_fields?(editlist->video_inter+1)%2+1:editlist->video_inter,		      CHROMA422,		      editlist->video_width, editlist->video_height,		      settings->yuvbuff[0],		      settings->yuvbuff[1],		      settings->yuvbuff[2]);      frame_planar_to_packed(settings->yuv_overlay->pixels[0], settings->yuvbuff,			     editlist->video_width, editlist->video_height,			     settings->yuvformat, FOURCC_I422, 1);      break;   case DATAFORMAT_YUV420:      output[0] = jpeg_buffer;      output[1] = jpeg_buffer + (editlist->video_width * editlist->video_height);      output[2] = jpeg_buffer + (editlist->video_width * editlist->video_height * 5 / 4);      frame_planar_to_packed(settings->yuv_overlay->pixels[0], output,			     editlist->video_width, editlist->video_height,			     settings->yuvformat, FOURCC_I420, 1);      break;# ifdef HAVE_LIBDV   case DATAFORMAT_DV2:      dv_parse_header(settings->decoder, jpeg_buffer);      switch(settings->decoder->sampling) {      /* FIXME: not implemented, do default: */      case e_dv_sample_420:	  break;      case e_dv_sample_411:      case e_dv_sample_422:         /* libdv decodes NTSC DV (native 411) and by default also PAL          * DV (native 420) as packed YUV 422 (YUY2 or 4CC 0x32595559)          * where the U and V information is repeated.  This can be          * transformed to planar 420 (YV12 or 4CC 0x32315659).          * For NTSC DV this transformation is lossy.          */         settings->pitches[0] = settings->decoder->width * 2;         settings->pitches[1] = 0;         settings->pitches[2] = 0;	 dv_decode_full_frame(settings->decoder, jpeg_buffer, e_dv_color_yuv,		settings->yuv_overlay->pixels, settings->pitches);	 break;      case e_dv_sample_none:	 /* FIXME */	 break;     }     break;	# endif   default:     return 0;   }   if (!lavplay_SDL_unlock(info)) return 0;   SDL_DisplayYUVOverlay(settings->yuv_overlay, &(settings->jpegdims));   return 1;}#endif /* HAVE_SDL *//****************************************************** * lavplay_SDL_init() *   when using software playback - initialize SDL * * return value: 1 on success, 0 on error ******************************************************/#ifdef HAVE_SDLstatic int lavplay_SDL_init(lavplay_t *info){   char *sbuffer;   int i;   video_playback_setup *settings = (video_playback_setup *)info->settings;   EditList *editlist = info->editlist;   lavplay_msg(LAVPLAY_MSG_INFO, info,      "Initialising SDL");   if (SDL_Init (SDL_INIT_VIDEO) < 0)   {      lavplay_msg(LAVPLAY_MSG_ERROR, info,

⌨️ 快捷键说明

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