liblavplay.c
来自「Motion JPEG编解码器源代码」· C语言 代码 · 共 2,022 行 · 第 1/5 页
C
2,022 行
strerror(errno)); return 0; } /* hack for wrong return value of marvel cards..... */ if (vc.maxwidth!=640 && vc.maxwidth!=768) vc.maxwidth=720;#ifndef X_DISPLAY_MISSING XGetWindowAttributes(dpy, DefaultRootWindow(dpy), &wts); screenwidth = wts.width; screenheight = wts.height;#else screenwidth = 1024; screenheight = 768;#endif vw.y = info->soft_full_screen ? 0: (screenheight-((bp->norm == 0) ? 576 : 480))/2; if (info->vw_y_offset != VALUE_NOT_FILLED && !info->soft_full_screen) vw.y = info->vw_y_offset; vw.x = info->soft_full_screen ? 0: (screenwidth-vc.maxwidth)/2; if (info->vw_x_offset != VALUE_NOT_FILLED && !info->soft_full_screen) vw.x = info->vw_x_offset; vw.width = info->soft_full_screen ? screenwidth : vc.maxwidth; if (info->sdl_width > 0 && !info->soft_full_screen) vw.width = info->sdl_width; vw.height = info->soft_full_screen ? screenheight : ((bp->norm == 0) ? 576 : 480); if (info->sdl_height > 0 && !info->soft_full_screen) vw.height = info->sdl_height; vw.clips = NULL; vw.clipcount = 0; vw.chromakey = -1; if (info->soft_full_screen ? 0: (screenwidth-vc.maxwidth)/2 < 0) { lavplay_msg(LAVPLAY_MSG_ERROR, info, "X offset (%d) would be < 0", vw.x); return 0; } if (info->soft_full_screen ? 0: (screenheight-((bp->norm == 0) ? 576 : 480))/2 < 0) { lavplay_msg(LAVPLAY_MSG_ERROR, info, "Y offset (%d) would be < 0", vw.y); return 0; }#ifndef X_DISPLAY_MISSING if (vw.x + vw.width > wts.width) { lavplay_msg(LAVPLAY_MSG_ERROR, info, "X offset + width (%d+%d) would be > screensize (%d)", vw.x, vw.width, wts.width); return 0; } if (vw.y + vw.height > wts.height) { lavplay_msg(LAVPLAY_MSG_ERROR, info, "Y offset + height (%d+%d) would be > screensize (%d)", vw.y, vw.height, wts.height); return 0; }#endif if (ioctl(settings->video_fd, VIDIOCSWIN, &vw) < 0) { lavplay_msg(LAVPLAY_MSG_ERROR, info, "Could not set on-screen window parameters (check framebuffer-params with v4l-conf): %s", strerror(errno)); return 0; } n = 1; if (ioctl(settings->video_fd, VIDIOCCAPTURE, &n) < 0) { lavplay_msg(LAVPLAY_MSG_ERROR, info, "Could not activate on-screen window: %s", strerror(errno)); return 0; } bp->VFIFO_FB = 1; }#endif switch (info->playback_mode) {#ifdef HAVE_V4L case 'C': case 'H': /* All should be set up now, set the parameters */ lavplay_msg(LAVPLAY_MSG_DEBUG, info, "Hardware video settings: input=%d, norm=%d, fields_per_buf=%d, " "x=%d, y=%d, width=%d, height=%d, quality=%d", bp->input, bp->norm, bp->field_per_buff, bp->img_x, bp->img_y, bp->img_width, bp->img_height, bp->quality); if (ioctl(settings->video_fd, MJPIOC_S_PARAMS, bp) < 0) { lavplay_msg(LAVPLAY_MSG_ERROR, info, "Error setting video parameters: %s", strerror(errno)); return 0; } break;#endif#ifdef HAVE_SDL case 'S': settings->show_top = (bp->odd_even) ? 1 : 0; /* odd_even = 1: show top field first */ break;#endif default: lavplay_msg(LAVPLAY_MSG_ERROR, info, "lavplay_mjpeg_set_params(): Unknown playback mode (\'%c\')", info->playback_mode); return 0; } return 1;}/****************************************************** * lavplay_mjpeg_set_frame_rate() * set the frame rate * * return value: 1 on success, 0 on error ******************************************************/static int lavplay_mjpeg_set_playback_rate(lavplay_t *info, double video_fps, int norm){ int norm_usec_per_frame = 0; int target_usec_per_frame; video_playback_setup *settings = (video_playback_setup *)info->settings; /*EditList *editlist = info->editlist; */ switch (norm) { case VIDEO_MODE_PAL: case VIDEO_MODE_SECAM: norm_usec_per_frame = 1000000/25; /* 25Hz */ break; case VIDEO_MODE_NTSC: norm_usec_per_frame = 1001000/30; /* 30ish Hz */ break; default: if (info->playback_mode != 'S') { lavplay_msg(LAVPLAY_MSG_ERROR, info, "Hardware playback impossible: unknown video norm!"); return 0; } } if( video_fps != 0.0 ) target_usec_per_frame = (int)(1000000.0 / video_fps); else target_usec_per_frame = norm_usec_per_frame; if (info->playback_mode != 'S' && abs(target_usec_per_frame - norm_usec_per_frame) > 50) { lavplay_msg(LAVPLAY_MSG_ERROR, info, "Specified frame-rate doesn't match in mode in hardware playback (target: %d, norm: %d)", target_usec_per_frame, norm_usec_per_frame); return 0; } settings->usec_per_frame = target_usec_per_frame; return 1;}/****************************************************** * lavplay_mjpeg_queue_buf() * queue a buffer * * return value: 1 on success, 0 on error ******************************************************/static int lavplay_mjpeg_queue_buf(lavplay_t *info, int frame, int frame_periods){ video_playback_setup *settings = (video_playback_setup *)info->settings; /*EditList *editlist = info->editlist; */ switch (info->playback_mode) {#ifdef HAVE_V4L case 'H': case 'C': if (ioctl(settings->video_fd, MJPIOC_QBUF_PLAY, &frame) < 0) { lavplay_msg(LAVPLAY_MSG_ERROR, info, "Error queueing buffer: %s", strerror(errno)); return 0; } break;#endif#ifdef HAVE_SDL case 'S': /* mark this buffer as playable and tell the software playback thread to wake up if it sleeps */ pthread_mutex_lock(&(settings->valid_mutex)); settings->valid[frame] = frame_periods; pthread_cond_broadcast(&(settings->buffer_filled[frame])); pthread_mutex_unlock(&(settings->valid_mutex)); break;#endif default: lavplay_msg(LAVPLAY_MSG_ERROR, info, "lavplay_mjpeg_queue_buf(): Unknown playback mode (\'%c\')", info->playback_mode); return 0; } return 1;}/****************************************************** * lavplay_mjpeg_sync_buf() * sync on a buffer * * return value: 1 on success, 0 on error ******************************************************/static int lavplay_mjpeg_sync_buf(lavplay_t *info, struct mjpeg_sync *bs){ video_playback_setup *settings = (video_playback_setup *)info->settings; /*EditList *editlist = info->editlist; */ switch (info->playback_mode) {#ifdef HAVE_V4L case 'H': case 'C': if (ioctl(settings->video_fd, MJPIOC_SYNC, bs) < 0) { lavplay_msg(LAVPLAY_MSG_ERROR, info, "Error syncing on a buffer: %s", strerror(errno)); return 0; } lavplay_msg(LAVPLAY_MSG_DEBUG, info, "frame=%ld, length=%ld, seq=%ld", bs->frame, bs->length, bs->seq); break;#endif#ifdef HAVE_SDL case 'S': /* Wait until this buffer has been played */ pthread_mutex_lock(&(settings->valid_mutex)); while (settings->valid[settings->currently_synced_frame] != 0) { pthread_cond_wait(&(settings->buffer_done[settings->currently_synced_frame]), &(settings->valid_mutex)); } pthread_mutex_unlock(&(settings->valid_mutex)); /* copy the relevant sync information */ memcpy(bs, &(settings->syncinfo[settings->currently_synced_frame]), sizeof(struct mjpeg_sync)); settings->currently_synced_frame = (settings->currently_synced_frame + 1) % settings->br.count; break;#endif default: lavplay_msg(LAVPLAY_MSG_ERROR, info, "lavplay_mjpeg_sync_buf(): Unknown playback mode (\'%c\')", info->playback_mode); return 0; } return 1;}/****************************************************** * lavplay_mjpeg_close() * close down * * return value: 1 on success, 0 on error ******************************************************/static int lavplay_mjpeg_close(lavplay_t *info){#ifdef HAVE_V4L int n;#endif video_playback_setup *settings = (video_playback_setup *)info->settings; /*EditList *editlist = info->editlist; */ lavplay_msg(LAVPLAY_MSG_DEBUG, info, "Closing down the %s", info->playback_mode=='S'?"threading system":"video device"); switch (info->playback_mode) {#ifdef HAVE_V4L case 'C': case 'H': n = -1; if (ioctl(settings->video_fd, MJPIOC_QBUF_PLAY, &n) < 0) { lavplay_msg(LAVPLAY_MSG_ERROR, info, "Error de-queueing the buffers: %s", strerror(errno)); return 0; } if (info->playback_mode == 'H') { n = 0; if (ioctl(settings->video_fd, VIDIOCCAPTURE, &n) < 0) { lavplay_msg(LAVPLAY_MSG_ERROR, info, "Could not deactivate on-screen window: %s", strerror(errno)); return 0; } } break;#endif#ifdef HAVE_SDL case 'S': pthread_cancel(settings->software_playback_thread); if (pthread_join(settings->software_playback_thread, NULL)) { lavplay_msg(LAVPLAY_MSG_ERROR, info, "Failure deleting software playback thread"); return 0; } break;#endif default: lavplay_msg(LAVPLAY_MSG_ERROR, info, "lavplay_mjpeg_close(): Unknown playback mode (\'%c\')", info->playback_mode); return 0; } return 1;}/****************************************************** * lavplay_init() * check the given settings and initialize everything * * return value: 1 on success, 0 on error ******************************************************/static int lavplay_init(lavplay_t *info){ long nqueue; struct mjpeg_params bp;#ifdef HAVE_V4L struct video_capability vc;#endif video_playback_setup *settings = (video_playback_setup *)info->settings; EditList *editlist = info->editlist; int hn; if (editlist->video_frames == 0 && !info->get_video_frame) { lavplay_msg(LAVPLAY_MSG_ERROR, info, "No video source!"); return 0; } if (editlist->video_frames == 0 && info->editlist->has_audio && info->audio && !info->get_audio_sample) { lavplay_msg(LAVPLAY_MSG_ERROR, info, "Audio turned on but no audio source!"); return 0; } if (editlist->video_frames > 0 && (info->get_video_frame || info->get_audio_sample)) { lavplay_msg(LAVPLAY_MSG_ERROR, info, "Manual input as well as file input!"); return 0; } /* Set min/max options so that it runs like it should */ settings->min_frame_num = 0; settings->max_frame_num = editlist->video_frames - 1; settings->current_frame_num = settings->min_frame_num; /* start with frame 0 */ /* Seconds per video frame: */ settings->spvf = 1.0 / editlist->video_fps; lavplay_msg(LAVPLAY_MSG_DEBUG, info, "1.0/SPVF = %4.4f", 1.0 / settings->spvf ); /* Seconds per audio sample: */ if(editlist->has_audio && info->audio) settings->spas = 1.0 / editlist->audio_rate; else settings->spas = 0.; if (info->flicker_reduction) { /* allocate auxiliary video buffer for flicker reduction */ settings->tmpbuff[0] = (uint8_t *)malloc(editlist->max_frame_size); settings->tmpbuff[1] = (uint8_t *)malloc(editlist->max_frame_size); if (!settings->tmpbuff[0] || !settings->tmpbuff[1]) { lavplay_msg (LAVPLAY_MSG_ERROR, info, "Malloc error, you\'re probably out of memory"); return 0; } } /* initialize the playback threading system (used to be libmjpeg) */ lavplay_mjpeg_open(info);#ifdef HAVE_SDL /* init SDL if we want SDL */ if (info->playback_mode == 'S') { char *env = getenv("LAVPLAY_VIDEO_FORMAT");
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?