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

📄 yuvplay.c

📁 Motion JPEG编解码器源代码
💻 C
字号:
/* *  yuvplay - play YUV data using SDL * *  Copyright (C) 2000, Ronald Bultje <rbultje@ronald.bitfreak.net> * *  This program is free software; you can redistribute it and/or *  modify it under the terms of the GNU General Public License *  as published by the Free Software Foundation; either version 2 *  of the License, or (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdio.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>#include "yuv4mpeg.h"#include "mjpeg_logging.h"#include <mpegconsts.h>#include <mpegtimecode.h>#include <SDL/SDL.h>#include <sys/time.h>/* SDL variables */SDL_Surface *screen;SDL_Overlay *yuv_overlay;SDL_Rect rect;static int got_sigint = 0;static void usage (void) {  fprintf(stdout, "Usage: lavpipe/lav2yuv... | yuvplay [options]\n"	  "  -s : display size, width x height\n"	  "  -t : set window title\n"	  "  -f : frame rate (overrides rate in stream header)\n"          "  -c : don't sync on frames - plays at stream speed\n"	  "  -v : verbosity {0, 1, 2} [default: 1]\n"	  );}static void sigint_handler (int signal) {   mjpeg_warn("Caught SIGINT, exiting...");   got_sigint = 1;}static long get_time_diff(struct timeval time_now) {   struct timeval time_now2;   gettimeofday(&time_now2,0);   return time_now2.tv_sec*1.e6 - time_now.tv_sec*1.e6 + time_now2.tv_usec - time_now.tv_usec;}static char *print_status(int frame, double framerate) {   MPEG_timecode_t tc;   static char temp[256];   mpeg_timecode(&tc, frame,		 mpeg_framerate_code(mpeg_conform_framerate(framerate)),		 framerate);   sprintf(temp, "%d:%2.2d:%2.2d.%2.2d", tc.h, tc.m, tc.s, tc.f);   return temp;}int main(int argc, char *argv[]){   int verbosity = 1;   double time_between_frames = 0.0;   double frame_rate = 0.0;   struct timeval time_now;   int n, frame;   unsigned char *yuv[3];   int in_fd = 0;   int screenwidth=0, screenheight=0;   y4m_stream_info_t streaminfo;   y4m_frame_info_t frameinfo;   int frame_width;   int frame_height;   int wait_for_sync = 1;   char *window_title = NULL;   while ((n = getopt(argc, argv, "hs:t:f:cv:")) != EOF) {      switch (n) {         case 'c':            wait_for_sync = 0;            break;         case 's':            if (sscanf(optarg, "%dx%d", &screenwidth, &screenheight) != 2) {               mjpeg_error_exit1( "-s option needs two arguments: -s 10x10");               exit(1);            }            break;	  case 't':	    window_title = optarg;	    break;	  case 'f':		  frame_rate = atof(optarg);		  if( frame_rate <= 0.0 || frame_rate > 200.0 )			  mjpeg_error_exit1( "-f option needs argument > 0.0 and < 200.0");		  break;          case 'v':	    verbosity = atoi(optarg);	    if ((verbosity < 0) || (verbosity > 2))	      mjpeg_error_exit1("-v needs argument from {0, 1, 2} (not %d)",				verbosity);	    break;	  case 'h':	  case '?':            usage();            exit(1);            break;         default:            usage();            exit(1);      }   }   mjpeg_default_handler_verbosity(verbosity);   y4m_accept_extensions(1);   y4m_init_stream_info(&streaminfo);   y4m_init_frame_info(&frameinfo);   if ((n = y4m_read_stream_header(in_fd, &streaminfo)) != Y4M_OK) {      mjpeg_error("Couldn't read YUV4MPEG2 header: %s!",         y4m_strerr(n));      exit (1);   }   switch (y4m_si_get_chroma(&streaminfo)) {   case Y4M_CHROMA_420JPEG:   case Y4M_CHROMA_420MPEG2:   case Y4M_CHROMA_420PALDV:     break;   default:     mjpeg_error_exit1("Cannot handle non-4:2:0 streams yet!");   }   frame_width = y4m_si_get_width(&streaminfo);   frame_height = y4m_si_get_height(&streaminfo);   if ((screenwidth <= 0) || (screenheight <= 0)) {     /* no user supplied screen size, so let's use the stream info */     y4m_ratio_t aspect = y4m_si_get_sampleaspect(&streaminfo);            if (!(Y4M_RATIO_EQL(aspect, y4m_sar_UNKNOWN))) {       /* if pixel aspect ratio present, use it */#if 1       /* scale width, but maintain height (line count) */       screenheight = frame_height;       screenwidth = frame_width * aspect.n / aspect.d;#else       if ((frame_width * aspect.d) < (frame_height * aspect.n)) {	 screenwidth = frame_width;	 screenheight = frame_width * aspect.d / aspect.n;       } else {	 screenheight = frame_height;	 screenwidth = frame_height * aspect.n / aspect.d;       }#endif     } else {       /* unknown aspect ratio -- assume square pixels */       screenwidth = frame_width;       screenheight = frame_height;     }   }   /* Initialize the SDL library */   if( SDL_Init(SDL_INIT_VIDEO) < 0 ) {      mjpeg_error("Couldn't initialize SDL: %s", SDL_GetError());      exit(1);   }   /* set window title */   SDL_WM_SetCaption(window_title, NULL);   /* yuv params */   yuv[0] = malloc(frame_width * frame_height * sizeof(unsigned char));   yuv[1] = malloc(frame_width * frame_height / 4 * sizeof(unsigned char));   yuv[2] = malloc(frame_width * frame_height / 4 * sizeof(unsigned char));   screen = SDL_SetVideoMode(screenwidth, screenheight, 0, SDL_SWSURFACE);   if ( screen == NULL ) {      mjpeg_error("SDL: Couldn't set %dx%d: %s",		  screenwidth, screenheight, SDL_GetError());      exit(1);   }   else {      mjpeg_debug("SDL: Set %dx%d @ %d bpp",		  screenwidth, screenheight, screen->format->BitsPerPixel);   }   /* since IYUV ordering is not supported by Xv accel on maddog's system    *  (Matrox G400 --- although, the alias I420 is, but this is not    *  recognized by SDL), we use YV12 instead, which is identical,    *  except for ordering of Cb and Cr planes...    * we swap those when we copy the data to the display buffer...    */   yuv_overlay = SDL_CreateYUVOverlay(frame_width, frame_height,				      SDL_YV12_OVERLAY,				      screen);   if ( yuv_overlay == NULL ) {      mjpeg_error("SDL: Couldn't create SDL_yuv_overlay: %s",		      SDL_GetError());      exit(1);   }   if ( yuv_overlay->hw_overlay )      mjpeg_debug("SDL: Using hardware overlay.");   rect.x = 0;   rect.y = 0;   rect.w = screenwidth;   rect.h = screenheight;   SDL_DisplayYUVOverlay(yuv_overlay, &rect);   signal (SIGINT, sigint_handler);   frame = 0;   if ( frame_rate == 0.0 )    {	   /* frame rate has not been set from command-line... */	   if (Y4M_RATIO_EQL(y4m_fps_UNKNOWN, y4m_si_get_framerate(&streaminfo))) {	     mjpeg_info("Frame-rate undefined in stream... assuming 25Hz!" );	     frame_rate = 25.0;	   } else {	     frame_rate = Y4M_RATIO_DBL(y4m_si_get_framerate(&streaminfo));	   }   }   time_between_frames = 1.e6 / frame_rate;   gettimeofday(&time_now,0);   while ((n = y4m_read_frame(in_fd, &streaminfo, &frameinfo, yuv)) == Y4M_OK && (!got_sigint)) {      /* Lock SDL_yuv_overlay */      if ( SDL_MUSTLOCK(screen) ) {         if ( SDL_LockSurface(screen) < 0 ) break;      }      if (SDL_LockYUVOverlay(yuv_overlay) < 0) break;      /* let's draw the data (*yuv[3]) on a SDL screen (*screen) */      memcpy(yuv_overlay->pixels[0], yuv[0], frame_width * frame_height);      memcpy(yuv_overlay->pixels[1], yuv[2], frame_width * frame_height / 4);      memcpy(yuv_overlay->pixels[2], yuv[1], frame_width * frame_height / 4);      /* Unlock SDL_yuv_overlay */      if ( SDL_MUSTLOCK(screen) ) {         SDL_UnlockSurface(screen);      }      SDL_UnlockYUVOverlay(yuv_overlay);      /* Show, baby, show! */      SDL_DisplayYUVOverlay(yuv_overlay, &rect);      mjpeg_info("Playing frame %4.4d - %s",		 frame, print_status(frame, frame_rate));      if (wait_for_sync)         while(get_time_diff(time_now) < time_between_frames) {            usleep(1000);         }      frame++;      gettimeofday(&time_now,0);   }   if ((n != Y4M_OK) && (n != Y4M_ERR_EOF))      mjpeg_error("Couldn't read frame: %s", y4m_strerr(n));   for (n=0; n<3; n++) {      free(yuv[n]);   }   mjpeg_info("Played %4.4d frames (%s)",	      frame, print_status(frame, frame_rate));   SDL_FreeYUVOverlay(yuv_overlay);   SDL_Quit();   y4m_fini_frame_info(&frameinfo);   y4m_fini_stream_info(&streaminfo);   return 0;}

⌨️ 快捷键说明

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