lqtplay.c
来自「这个库实现了录象功能」· C语言 代码 · 共 1,866 行 · 第 1/4 页
C
1,866 行
} shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0); if ((void *)-1 == shminfo->shmaddr) { perror("shmat"); goto shm_error; } xvimage->data = shminfo->shmaddr; shminfo->readOnly = False; XShmAttach(dpy, shminfo); XSync(dpy, False); if (no_mitshm) goto shm_error; shmctl(shminfo->shmid, IPC_RMID, 0); XSetErrorHandler(old_handler); return xvimage;shm_error: if (xvimage) { XFree(xvimage); xvimage = NULL; } if ((void *)-1 != shminfo->shmaddr && NULL != shminfo->shmaddr) shmdt(shminfo->shmaddr); free(shminfo); XSetErrorHandler(old_handler); no_mitshm = 1; no_mitshm: if (NULL == (ximage_data = malloc(width * height * 2))) { fprintf(stderr,_("out of memory\n")); exit(1); } xvimage = XvCreateImage(dpy, port, format, ximage_data, width, height); return xvimage;}static void x11_blit(Window win, GC gc, XImage *xi, int width, int height){ if (no_mitshm) XPutImage(dpy,win,gc,xi, 0,0,0,0, width,height); else XShmPutImage(dpy,win,gc,xi, 0,0,0,0, width,height, True);}static void xv_blit(Window win, GC gc, XvImage *xi, int iw, int ih, int ww, int wh){ if (no_mitshm) XvPutImage(dpy,xv_port,win,gc,xi, 0,0,iw,ih, 0,0,ww,wh); else XvShmPutImage(dpy,xv_port,win,gc,xi, 0,0,iw,ih, 0,0,ww,wh, True);}/* ------------------------------------------------------------------------ *//* OpenGL code */#ifdef HAVE_GLstatic int gl_texture_width,gl_texture_height;static GLuint gl_texture;static int gl_attrib[] = { GLX_RGBA, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_DEPTH_SIZE, 8, GLX_DOUBLEBUFFER, None };static void gl_resize(Widget widget, int width, int height){ glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0, width, 0.0, height, -1.0, 1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity();}static void gl_blit(Widget widget, uint8_t *rgbbuf, int iw, int ih, int ww, int wh){ char *dummy; float x,y; if (0 == gl_texture) { glGenTextures(1,&gl_texture); glBindTexture(GL_TEXTURE_2D,gl_texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); dummy = malloc(gl_texture_width*gl_texture_height*3); memset(dummy,128,gl_texture_width*gl_texture_height*3); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,gl_texture_width, gl_texture_height,0, GL_RGB,GL_UNSIGNED_BYTE,dummy); free(dummy); } glTexSubImage2D(GL_TEXTURE_2D, 0, 0,0,iw,ih, GL_RGB,GL_UNSIGNED_BYTE,rgbbuf); x = (float)iw/gl_texture_width; y = (float)ih/gl_texture_height; glEnable(GL_TEXTURE_2D); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); glBegin(GL_QUADS); glTexCoord2f(0,y); glVertex3f(0,0,0); glTexCoord2f(0,0); glVertex3f(0,wh,0); glTexCoord2f(x,0); glVertex3f(ww,wh,0); glTexCoord2f(x,y); glVertex3f(ww,0,0); glEnd(); glXSwapBuffers(XtDisplay(widget), XtWindow(widget)); glDisable(GL_TEXTURE_2D);}static void gl_init(Widget widget, int iw, int ih){ XVisualInfo *visinfo; GLXContext ctx; int i = 0; visinfo = glXChooseVisual(XtDisplay(widget), DefaultScreen(XtDisplay(widget)), gl_attrib); if (!visinfo) { fprintf(stderr,_("WARNING: gl: can't get visual (rgb,db)\n")); return; } ctx = glXCreateContext(dpy, visinfo, NULL, True); glXMakeCurrent(XtDisplay(widget),XtWindow(widget),ctx); fprintf(stderr, _("INFO: gl: DRI=%s\n"), glXIsDirect(dpy, ctx) ? _("Yes") : _("No")); if (!glXIsDirect(dpy, ctx)) { fprintf(stderr, _("WARNING: gl: Direct rendering missing\n")); return; }#if 0 /* check against max size */ glGetIntegerv(GL_MAX_TEXTURE_SIZE,&i); fprintf(stderr,_("INFO: gl: texture max size: %d\n"),i); if ((iw > i) || (ih > i)) { fprintf(stderr, _("WARNING: gl: Maximum texture size too small (got %dx%d, needed %dx%d)\n"), i, i, iw, ih); return; }#endif /* textures have power-of-two x,y dimensions */ for (i = 0; iw >= (1 << i); i++) ; gl_texture_width = (1 << i); for (i = 0; ih >= (1 << i); i++) ; gl_texture_height = (1 << i); fprintf(stderr,_("INFO: gl: frame=%dx%d, texture=%dx%d\n"),iw,ih, gl_texture_width,gl_texture_height); glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel(GL_FLAT); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); use_gl = 1;}#endif // HAVE_GLstatic int oss_sr,oss_hr;/* ------------------------------------------------------------------------ *//* alsa code */#ifdef HAVE_ALSA/* Enable alsa */static int use_alsa = 1;#ifndef SND_PCM_FORMAT_S16_NE# ifdef WORDS_BIGENDIAN# define SND_PCM_FORMAT_S16_NE SND_PCM_FORMAT_S16_BE# else# define SND_PCM_FORMAT_S16_NE SND_PCM_FORMAT_S16_LE# endif#endif//static int periods = 32; /* number of periods == fragments */static snd_pcm_uframes_t periodsize = 1024; /* Periodsize (bytes) */static unsigned int buffer_time = 500000; static unsigned int period_time = 125000; /* period time in us *//* Handle for the PCM device */ static snd_pcm_t *pcm_handle;/* This structure contains information about *//* the hardware and can be used to specify the *//* configuration to be used for the PCM stream. */static snd_pcm_hw_params_t *hwparams;snd_pcm_uframes_t buffer_size;#else/* Disable Alsa */static int use_alsa = 0;#endif /* HAVE_ALSA */static int alsa_init(char *dev, int channels, int rate){#ifdef HAVE_ALSA int dir; // int exact_param; /* parameter returned by */ /* snd_pcm_hw_params_set_*_near */ unsigned int tmprate; int err = 0; tmprate = rate; oss_hr = rate; if (snd_pcm_open(&pcm_handle, dev, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0) { fprintf(stderr, _("Error opening PCM device %s\n"), dev); return 1; }#if 1 /* Allocate the snd_pcm_hw_params_t structure on the stack. */ snd_pcm_hw_params_alloca(&hwparams); if ((err = snd_pcm_hw_params_any(pcm_handle, hwparams)) < 0) { fprintf(stderr, _("Can not configure this PCM device. (%s)\n"), snd_strerror(err)); return 1; } if ((err = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { fprintf(stderr, _("Error setting access. (%s)\n"), snd_strerror(err)); return 1; } /* put checks here */ /* Only needed when sampling format not supported by hardware .. unlikely */ /* Set sample format */ if ((err = snd_pcm_hw_params_set_format(pcm_handle, hwparams, SND_PCM_FORMAT_S16_NE)) < 0) { fprintf(stderr, _("Error setting format.(%s)\n"), snd_strerror(err)); return 1; } /* Set number of channels */ // weird 1 channel mode doesn't work if ((err = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, channels)) < 0) { fprintf(stderr, _("Error setting channels. %i (%s)\n"), channels, snd_strerror(err)); return 1; } /* Let Alsa resample */ snd_pcm_hw_params_set_rate_resample(pcm_handle, hwparams, 1); /* Set sample rate. If the exact rate is not supported */ /* by the hardware, use nearest possible rate. */ #if 1 if ((err = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &tmprate, NULL)) < 0 ) { fprintf(stderr, _("Error setting sample rate (%s)\n"), snd_strerror(err)); return 1; }#else if ((err = snd_pcm_hw_params_set_rate(pcm_handle, hwparams, tmprate, 0)) < 0 ) { fprintf(stderr, _("Error setting sample rate (%s)\n"), snd_strerror(err)); return 1; }#endif if (tmprate != rate) fprintf(stderr,_("WARNING: Using %i Hz instead of requested rate %i Hz\n "), tmprate, rate); oss_sr = tmprate; dir = 0; if ((err = snd_pcm_hw_params_set_buffer_time_near(pcm_handle, hwparams, &buffer_time, &dir)) < 0) { printf("Unable to set buffer time %i for playback: %s\n", buffer_time, snd_strerror(err)); return 1; } /* period time */ dir = 0; if ((err = snd_pcm_hw_params_set_period_time_near(pcm_handle, hwparams, &period_time, &dir)) < 0) { fprintf(stderr, _("Error setting periods.(%s)\n"), snd_strerror(err)); return 1; } if ((err = snd_pcm_hw_params_get_buffer_size(hwparams, &buffer_size))< 0) { fprintf(stderr, _("Unable to get buffer size for playback: %s\n"), snd_strerror(err)); return 1; } dir = 0; err = snd_pcm_hw_params_get_period_size(hwparams, &periodsize, &dir); if (err < 0) { fprintf(stderr, _("Unable to get period size for playback: %s\n"), snd_strerror(err)); return 1; } /* Apply HW parameter settings to */ /* PCM device and prepare device */ if ((err = snd_pcm_hw_params(pcm_handle, hwparams)) < 0) { fprintf(stderr, _("Error setting HW params.(%s)\n"), snd_strerror(err)); return 1; }#else /* Simple pcm */ snd_spcm_init(pcm_handle, rate, channels, SND_PCM_FORMAT_S16_NE, SND_PCM_SUBFORMAT_STD, SND_SPCM_LATENCY_STANDARD, SND_PCM_ACCESS_RW_INTERLEAVED, SND_SPCM_XRUN_IGNORE); #endif if ((err = snd_pcm_prepare(pcm_handle)) < 0) { fprintf(stderr, _("Error in pcm_prepare.(%s)\n"), snd_strerror(err)); return 1; } #endifreturn 0;}/* ------------------------------------------------------------------------ *//* oss code */#ifndef AFMT_S16_NE# ifdef WORDS_BIGENDIAN# define AFMT_S16_NE AFMT_S16_BE# else# define AFMT_S16_NE AFMT_S16_LE# endif#endifstatic int oss_fd = -1;static int oss_sr,oss_hr;static intoss_setformat(int chan, int rate){#ifdef SNDCTL_DSP_SETFMT int hw_afmt = AFMT_S16_NE; int hw_chan = chan; int hw_rate = rate; ioctl(oss_fd, SNDCTL_DSP_SETFMT, &hw_afmt); if (AFMT_S16_LE != hw_afmt) { fprintf(stderr,_("ERROR: can't set sound format\n")); exit(1); } ioctl(oss_fd, SNDCTL_DSP_CHANNELS, &hw_chan); if (chan != hw_chan) { fprintf(stderr,_("ERROR: can't set sound channels\n")); exit(1); } ioctl(oss_fd, SNDCTL_DSP_SPEED, &hw_rate); if (rate != hw_rate) { oss_sr = rate; oss_hr = hw_rate; fprintf(stderr,_("WARNING: sample rate mismatch (need %d, got %d)\n"), rate,hw_rate); } return 0;#else return 1;#endif}static int oss_init(char *dev, int channels, int rate){#ifdef SNDCTL_DSP_SETTRIGGER int trigger;#endif oss_fd = open(dev,O_WRONLY | O_NONBLOCK); if (-1 == oss_fd) { fprintf(stderr,_("WARNING: open %s: %s\n"),dev,strerror(errno)); return -1; } oss_setformat(channels,rate);#ifdef SNDCTL_DSP_SETTRIGGER trigger = PCM_ENABLE_OUTPUT; ioctl(oss_fd,SNDCTL_DSP_SETTRIGGER,&trigger); return 0;#else return 1;#endif}/* ------------------------------------------------------------------------ *//* quicktime code *//* Audio stuff *//* Interleaved audio buffer */static int16_t *qt_audio = (int16_t*)0; //,*qt1,*qt2;static int16_t *qt_audio_ptr; /* Pointer to the sample buffer for the next write() call */static int qt_audio_samples_in_buffer;/* Non interleaved audio buffer */static int16_t **qt_audion = (int16_t**)0;/* One decode call will decode this many samples */#define AUDIO_BLOCK_SIZE (10*1024)static int qt_channels,qt_sample_rate;static int qt_audio_eof = 0; /* No more samples can be decoded */static int qt_hasvideo,qt_hasaudio,qt_isqtvr;static int qt_width = 320, qt_height = 32, qt_drop = 0, qt_droptotal = 0, qtvr_dwidth = 0, qtvr_dheight = 0;static int64_t qt_frame_time; /* Timestamp of the decoded frame */static int qt_timescale = 0;static unsigned char *qt_frame, *qt_frame_row, **qt_rows;static unsigned char *qt_panorama_buffer;static unsigned int *qt_frame_tmp[2];static XImage *qt_ximage;static XvImage *qt_xvimage;static GC qt_gc;static void qt_init(FILE *fp, char *filename){ int ipos; float minpan, maxpan; /* audio device */ char *adev_name; /* default */ // adev_name = strdup("plughw"); //adev_name = strdup("plughw:0,0"); adev_name = strdup("default"); /* open file */ qt = quicktime_open(filename,1,0); if (NULL == qt) { fprintf(fp,_("ERROR: can't open file: %s\n"),filename); exit(1); } /* print misc info */ fprintf(fp,_("INFO: playing %s\n"),filename); quicktime_print_info(qt); qt_isqtvr = lqt_is_qtvr(qt); if (qt_isqtvr) { if (qt_isqtvr != QTVR_OBJ && qt_isqtvr != QTVR_PAN) { fprintf(stderr, _("'%s' is no QTVR file or an unsupported variant.\n"), filename); exit(1); } ipos = lqt_qtvr_get_initial_position(qt); lqt_qtvr_get_pan(qt, &(minpan), &(maxpan), NULL); qtvr_dwidth = lqt_qtvr_get_display_width(qt); qtvr_dheight = lqt_qtvr_get_display_height(qt); fprintf(stderr, _("startpos :%i\n"), ipos); fprintf(stderr, _("movietype :%i\n"), lqt_qtvr_get_movietype(qt)); fprintf(stderr, _("panning :%f %f\n"), minpan, maxpan); fprintf(stderr, _("rows :%i\n"), lqt_qtvr_get_rows(qt)); fprintf(stderr, _("colums :%i\n"), lqt_qtvr_get_columns(qt)); fprintf(stderr, _("disp width :%i\n"), qtvr_dwidth); fprintf(stderr, _("disp height :%i\n"), qtvr_dheight); fprintf(stderr, _("width :%i\n"), lqt_qtvr_get_width(qt));
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?