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 + -
显示快捷键?