lqtplay.c

来自「这个库实现了录象功能」· C语言 代码 · 共 1,866 行 · 第 1/4 页

C
1,866
字号
            snd_pcm_prepare(pcm_handle);            fprintf(stderr, _("Warning: buffer underrun\n"));        }        else if (ret < 0) {            fprintf(stderr, _("Warning: %s\n"), snd_strerror(ret));        }        else if (ret >= 0)          done = 1;    }    if (ret > 0 ) {    qt_audio_samples_in_buffer -=ret;    qt_audio_ptr += ret * qt_channels;    }        if (qt_audio_eof && 0 == qt_audio_samples_in_buffer) {        snd_pcm_drain(pcm_handle);        return -1;    }#endif  return 0;}static int qt_oss_audio_write(void){    int rc;    if(!qt_audio_samples_in_buffer)      decode_audio(AUDIO_BLOCK_SIZE);        rc = write(oss_fd,qt_audio_ptr,qt_audio_samples_in_buffer * qt_channels * sizeof(*qt_audio));    switch (rc) {    case -1:	perror("write dsp");	close(oss_fd);	oss_fd = -1;	qt_hasaudio = 0;	break;    case 0:	fprintf(stderr,_("write dsp: Huh? no data written?\n"));	close(oss_fd);	oss_fd = -1;	qt_hasaudio = 0;	break;    default:        qt_audio_samples_in_buffer -= rc / (qt_channels * sizeof(*qt_audio));        qt_audio_ptr += rc / sizeof(*qt_audio);        break;    }    if (qt_audio_eof && 0 == qt_audio_samples_in_buffer) {       return -1;    }    return 0;}/* ------------------------------------------------------------------------ *//* main                                                                     */struct ARGS {    int  xv;    int  gl;    int  alsa;} args;XtResource args_desc[] = {    /* name, class, type, size, offset, default_type, default_addr */    {	/* Integer */	"xv",	XtCValue, XtRInt, sizeof(int),	XtOffset(struct ARGS*,xv),	XtRString, "1"    },{	"gl",	XtCValue, XtRInt, sizeof(int),	XtOffset(struct ARGS*,gl),	XtRString, "1"    },{	"alsa",	XtCValue, XtRInt, sizeof(int),	XtOffset(struct ARGS*,alsa),	XtRString, "1"    }};const int args_count = XtNumber(args_desc);XrmOptionDescRec opt_desc[] = {    { "-noxv",  "xv", XrmoptionNoArg,  "0" },    { "-nogl",  "gl", XrmoptionNoArg,  "0" },    { "-noalsa",  "alsa", XrmoptionNoArg,  "0" },};const int opt_count = (sizeof(opt_desc)/sizeof(XrmOptionDescRec));static void usage(FILE *fp, char *prog){    char *p;    p = strrchr(prog,'/');    if (p) prog = p+1;    fprintf(fp,	    _("\n"              "Very simple quicktime movie player for X11.  Just playes\n"              "the movie and nothing else.  No fancy gui, no controls.\n"              "\n"              "You can quit with 'Q' and 'ESC' keys.\n"              "\n"              "usage: %s [ options ] <file>\n"              "options:\n"              "  -noxv   don't use the Xvideo extention\n"              "  -nogl   don't use OpenGL\n"              "  -noalsa don't use Alsa\n"              "\n"),	    prog);}static void decode_qtvr(){    XEvent event;    int startpos;    startpos = quicktime_video_position(qt, 0);    XFlush(dpy);    if (qt_hasvideo) {	  	if (qt_frame_decode() || qt_frame_blit()) exit(0);    }    for (;;) {		struct timespec time;				//      printf("loop pos :%ld\n",quicktime_video_position(qt,0));		if (quicktime_video_position(qt,0) >= startpos + lqt_qtvr_get_loop_frames(qt))			quicktime_set_video_position(qt, startpos, 0);				if (True == XCheckMaskEvent(dpy, ~0, &event)) {			XtDispatchEvent(&event);		} else {		//	printf("loop pos before decode :%ld\n",quicktime_video_position(qt,0));			XFlush(dpy);			XtAppProcessEvent(app_context, KeyPressMask||KeyReleaseMask);			time.tv_nsec = 10000000;			time.tv_sec = 0;			nanosleep(&time, NULL);		}    }}static void quit_ac(Widget widget, XEvent *event,		    String *params, Cardinal *num_params){    exit(0);}static void resize_ev(Widget widget, XtPointer client_data,		      XEvent *event, Boolean *d){    switch(event->type) {    case MapNotify:    case ConfigureNotify:        XtVaGetValues(widget,XtNheight,&sheight,XtNwidth,&swidth,NULL);        fprintf(stderr,_("INFO: window size is %dx%d\n"),swidth,sheight);#ifdef HAVE_GL	      if (use_gl)	          gl_resize(widget,swidth,sheight);#endif        if (qt_isqtvr != 0) decode_qtvr();        break;    case UnmapNotify:    case DestroyNotify:            exit(0);        break;    }}/* event handlers */static void left_ac(Widget widget, XEvent *event,		    String *params, Cardinal *num_params){    if (qt_isqtvr == QTVR_PAN) {        if (xpos - 10 >= 0 ) xpos -= 10;            if (xpos - 10 < 0) {            xpos = xpos-10 + lqt_qtvr_get_width(qt);        }    }    else if (qt_isqtvr == QTVR_OBJ) {        int vpos = quicktime_video_position(qt, 0);        int lfxcolumns = lqt_qtvr_get_loop_frames(qt) * lqt_qtvr_get_columns(qt);            if (vpos % lfxcolumns == lfxcolumns - lqt_qtvr_get_loop_frames(qt) && vpos != 0) {            quicktime_set_video_position(qt, vpos - (lqt_qtvr_get_columns(qt)-1), 0);         }         else {	            quicktime_set_video_position(qt, vpos + lqt_qtvr_get_loop_frames(qt), 0);        }    }    else        return;//    printf("pos %ld\n",quicktime_video_position(qt,0));    decode_qtvr();}static void right_ac(Widget widget, XEvent *event,		    String *params, Cardinal *num_params){    if (qt_isqtvr == QTVR_PAN) {	  	if (xpos + 10 <= lqt_qtvr_get_width(qt)+oh_width - qtvr_dwidth) xpos += 10;		if (xpos + 10 > lqt_qtvr_get_width(qt)) {			xpos = xpos+10 - lqt_qtvr_get_width(qt);		}    }    else if (qt_isqtvr == QTVR_OBJ) {		int vpos = quicktime_video_position(qt, 0);		int lfxcolumns = lqt_qtvr_get_loop_frames(qt) * lqt_qtvr_get_columns(qt);				if (vpos % lfxcolumns == 0) { 			quicktime_set_video_position(qt, vpos + (lqt_qtvr_get_loop_frames(qt) * lqt_qtvr_get_columns(qt)-1), 0);	} 	else {			quicktime_set_video_position(qt, vpos - lqt_qtvr_get_loop_frames(qt), 0);		}    }    else	  	return;//    printf("pos %ld\n",quicktime_video_position(qt,0));    decode_qtvr();}static void up_ac(Widget widget, XEvent *event,		    String *params, Cardinal *num_params){    if (qt_isqtvr == QTVR_PAN) {	  	if (ypos - 10 >= 0 ) ypos -= 10;    }    else if (qt_isqtvr == QTVR_OBJ) {		int vpos = quicktime_video_position(qt, 0);		if (vpos + lqt_qtvr_get_columns(qt) < lqt_qtvr_get_loop_frames(qt) * lqt_qtvr_get_rows(qt) * lqt_qtvr_get_columns(qt)) {			quicktime_set_video_position(qt ,vpos + lqt_qtvr_get_columns(qt), 0);		}//  printf("pos %ld\n",quicktime_video_position(qt,0));    }    else 	  	return;    decode_qtvr();}static void down_ac(Widget widget, XEvent *event,		    String *params, Cardinal *num_params){    if (qt_isqtvr == QTVR_PAN) {	  	if (ypos + 10 < lqt_qtvr_get_height(qt) - lqt_qtvr_get_display_height(qt)) ypos += 10;    }    else if (qt_isqtvr == QTVR_OBJ) {		if (quicktime_video_position(qt, 0) - lqt_qtvr_get_columns(qt) >= 0) {			quicktime_set_video_position(qt ,quicktime_video_position(qt, 0) - lqt_qtvr_get_columns(qt), 0);		}    }    else 	  	return;//  printf("pos %ld\n",quicktime_video_position(qt,0));    	decode_qtvr();}static void expose_ev(Widget widget, XtPointer client_data,		      XEvent *event, Boolean *d){    if (event->type == Expose)        decode_qtvr();}static XtActionsRec action_table[] = {    { "Quit",  quit_ac },    { "Right", right_ac },    { "Left",  left_ac },    { "Up",    up_ac },    { "Down",  down_ac },};static String res[] = {    "lqtplay.playback.translations:  #override \\n"    "        <Key>Q:                 Quit()    \\n"    "        <Key>Escape:            Quit()    \\n"    "        <Key>Right:             Right()    \\n"    "        <Key>Left:              Left()   \\n"    "        <Key>Up:                Up() \\n"    "        <Key>Down:              Down()",    "lqtplay.playback.background:    black",    NULL};int main(int argc, char *argv[]){    int has_frame = 0, blit_frame = 0;    struct timeval start,wait;    //    int audio_frames;        setlocale(LC_MESSAGES, "");    setlocale(LC_CTYPE, "");        bindtextdomain(PACKAGE, LOCALE_DIR);             app_shell = XtVaAppInitialize(&app_context, "lqtplay",				  opt_desc, opt_count,				  &argc, argv,				  res, NULL);    XtGetApplicationResources(app_shell,&args,			      args_desc,args_count,			      NULL,0);    /* don't use alsa*/			          if (!args.alsa) use_alsa=0;			          /* open file */    if (argc < 2) {	usage(stderr,argv[0]);	exit(1);    }    qt_init(stdout,argv[1]);    /* init x11 stuff */    dpy = XtDisplay(app_shell);        XtAppAddActions(app_context,action_table,		    sizeof(action_table)/sizeof(XtActionsRec));    XtVaSetValues(app_shell, XtNtitle,argv[1],NULL);    if (qt_isqtvr) {	simple = XtVaCreateManagedWidget("playback",simpleWidgetClass,app_shell,			     		 XtNwidth,  qtvr_dwidth,					 XtNheight, qtvr_dheight,					 NULL);	XtAddEventHandler(simple,ExposureMask, True, expose_ev, NULL);    }    else	simple = XtVaCreateManagedWidget("playback",simpleWidgetClass,app_shell,			     		 XtNwidth,  qt_width,					 XtNheight, qt_height,					 NULL);    XtAddEventHandler(simple,StructureNotifyMask, True, resize_ev, NULL);    x11_init();    if (args.xv && qt_hasvideo)	xv_init();    if(qt_hasvideo) {        if (qt_isqtvr == QTVR_PAN) {	    /* cmodel hardcoded for panos */	    lqt_set_cmodel(qt, 0, BC_RGB888);	}	else {	    /* Decide about the colormodel */	    fprintf(stderr, _("Stream colormodel %s, "),                    lqt_colormodel_to_string(lqt_get_cmodel(qt, 0)));	    qt_cmodel = lqt_get_best_colormodel(qt, 0, qt_cmodels);	    fprintf(stderr, _("using %s\n"), lqt_colormodel_to_string(qt_cmodel));	    /* Set decoding colormodel */	    lqt_set_cmodel(qt, 0, qt_cmodel);	}    }    /* use OpenGL? */    XtRealizeWidget(app_shell);#ifdef HAVE_GL    if (BC_RGB888 == qt_cmodel && args.gl && qt_hasvideo) {    	if (qt_isqtvr == QTVR_PAN) {	    gl_init(simple,qtvr_dwidth,qtvr_dheight);	} else 	    gl_init(simple,qt_width,qt_height);    }#endif        /* frames per chunk for alsa */#if 0    if(qt_hasvideo)      audio_frames = ((oss_sr / quicktime_frame_rate(qt,0)) / 2 + 0.5);    else      audio_frames = oss_sr + 1024;#endif    /* Initialize video */    if(qt_hasvideo)	qt_init_video();    if (qt_isqtvr) {	decode_qtvr();    }    else {	/* enter main loop */	gettimeofday(&start,NULL);	for (;;) {	    int rc,max;	    fd_set rd,wr;	    XEvent event;	    if (True == XCheckMaskEvent(dpy, ~0, &event)) {		XtDispatchEvent(&event);	    } 	    else {		XFlush(dpy);		FD_ZERO(&rd);		FD_ZERO(&wr);		FD_SET(ConnectionNumber(dpy),&rd);		max = ConnectionNumber(dpy);		if (qt_hasaudio) {		    if (use_alsa == 0) {			FD_SET(oss_fd,&wr);			if (oss_fd > max)			    max = oss_fd;		    }		}		if (qt_hasvideo) {		    if(!has_frame) {			if(0 != qt_frame_decode()) {			    qt_hasvideo = 0;			    wait.tv_sec  = 0;			    wait.tv_usec = 1000;			} else {			has_frame = 1;			}		    }					qt_frame_delay(&start,&wait);				/* "wait" is the time, we would have to wait.		   If it's longer, than 2 ms, we'll continue feeding the		   soundcard. This prevents audio underruns for frames with a		   VERY long duration */		 if(wait.tv_sec || (wait.tv_usec > 2000)) {		     wait.tv_sec  = 0;		     wait.tv_usec = 2000;		     blit_frame = 0;		 } else		     blit_frame = 1;		    	     } else {		    wait.tv_sec  = 0;		    wait.tv_usec = 1000;		}		rc = select(max+1,&rd,&wr,NULL,&wait);		if (qt_hasaudio) {		    if (use_alsa == 1) {			if (0 != qt_alsa_audio_write()) qt_hasaudio = 0;		    }		    else if (FD_ISSET(oss_fd,&wr)) { 			if (0 != qt_oss_audio_write()) qt_hasaudio = 0;		    }		}		if (qt_hasvideo && 0 == rc && blit_frame) {		    qt_frame_blit();		    has_frame = 0;		}	    }	if(!qt_hasvideo && !qt_hasaudio)	  break;	}    }    qt_cleanup();    fprintf(stderr, _("Decoded %lld samples\n"),            (long long)total_samples_decoded);        return 0;}

⌨️ 快捷键说明

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