liblavplay.c
来自「Motion JPEG编解码器源代码」· C语言 代码 · 共 2,022 行 · 第 1/5 页
C
2,022 行
if (info->state_changed) info->state_changed(new_state);}/****************************************************** * lavplay_set_speed() * set the playback speed (<0 is play backwards) * * return value: 1 on success, 0 on error ******************************************************/int lavplay_set_speed(lavplay_t *info, int speed){ video_playback_setup *settings = (video_playback_setup *)info->settings; /*EditList *editlist = info->editlist; */ int changed = 0; if ((settings->current_frame_num == settings->max_frame_num && speed > 0) || (settings->current_frame_num == settings->min_frame_num && speed < 0)) { lavplay_msg(LAVPLAY_MSG_WARNING, info, "We are already at the %s", speed<0?"beginning":"end"); return 0; } if ((speed==0 && settings->current_playback_speed!=0) || (speed!=0 && settings->current_playback_speed==0)) changed = 1; settings->current_playback_speed = speed; if (changed) { if (speed==0) lavplay_change_state(info, LAVPLAY_STATE_PAUSED); else lavplay_change_state(info, LAVPLAY_STATE_PLAYING); } return 1;}/****************************************************** * lavplay_increase_frame() * increase (or decrease) a num of frames * * return value: 1 on succes, 0 if we had to change state ******************************************************/int lavplay_increase_frame(lavplay_t *info, long num){ video_playback_setup *settings = (video_playback_setup *)info->settings; /*EditList *editlist = info->editlist; */ settings->current_frame_num += num; if (settings->current_frame_num < settings->min_frame_num) { settings->current_frame_num = settings->min_frame_num; if (settings->current_playback_speed < 0) lavplay_set_speed(info, 0); return 0; } if (settings->current_frame_num > settings->max_frame_num) { settings->current_frame_num = settings->max_frame_num; if (settings->current_playback_speed > 0) lavplay_set_speed(info, 0); return 0; } return 1;}/****************************************************** * lavplay_set_frame() * set the current framenum * * return value: 1 on success, 0 if we had to change state ******************************************************/int lavplay_set_frame(lavplay_t *info, long framenum){ video_playback_setup *settings = (video_playback_setup *)info->settings; /*EditList *editlist = info->editlist; */ return lavplay_increase_frame(info, framenum - settings->current_frame_num);}/****************************************************** * lavplay_get_video() * get video data * * return value: length of frame on success, -1 on error ******************************************************/static int lavplay_get_video(lavplay_t *info, uint8_t *buff, long frame_num){ if (info->get_video_frame) { int length; info->get_video_frame(buff, &length, frame_num); return length; } else { return el_get_video_frame(buff, frame_num, info->editlist); }}/****************************************************** * lavplay_get_audio() * get audio data * * return value: number of samples on success, -1 on error ******************************************************/static int lavplay_get_audio(lavplay_t *info, uint8_t *buff, long frame_num, int mute) { int num_samps; if (info->get_audio_sample) info->get_audio_sample(buff, &num_samps, frame_num); else num_samps = el_get_audio_data(buff, frame_num, info->editlist, mute);/* fprintf(stderr, "get_audio_sample %x num_samps %x frame_num %x\n", info->get_audio_sample, num_samps, frame_num); */ return(num_samps); }/****************************************************** * lavplay_queue_next_frame() * queues a frame (video + audio) * * return value: 1 on succes, 0 on error ******************************************************/static int lavplay_queue_next_frame(lavplay_t *info, uint8_t *vbuff, int data_format, int skip_video, int skip_audio, int skip_incr){ int res, mute, i, jpeg_len1, jpeg_len2, new_buff_no; char hlp[16]; video_playback_setup *settings = (video_playback_setup *)info->settings; EditList *editlist = info->editlist; /* Read next frame */ if (!skip_video) { if (info->flicker_reduction && editlist->video_inter && data_format == DATAFORMAT_MJPG && settings->current_playback_speed <= 0) { if (settings->current_playback_speed == 0) { if ((res = lavplay_get_video(info, vbuff, settings->current_frame_num)) < 0) return 0; jpeg_len1 = lav_get_field_size(vbuff, res); /* Found seperate fields? */ if (jpeg_len1 < res) { memcpy(vbuff+jpeg_len1, vbuff, jpeg_len1); settings->old_field_len = 0; } } else /* play_speed < 0, play old first field + actual second field */ { new_buff_no = 1 - settings->old_buff_no; if ((res = lavplay_get_video(info, settings->tmpbuff[new_buff_no], settings->current_frame_num)) < 0) return 0; jpeg_len1 = lav_get_field_size(settings->tmpbuff[new_buff_no], res); if (jpeg_len1 < res) { jpeg_len2 = res - jpeg_len1; if (settings->old_field_len==0) { /* no old first field, duplicate second field */ memcpy(vbuff,settings->tmpbuff[new_buff_no]+jpeg_len1,jpeg_len2); settings->old_field_len = jpeg_len2; } else { /* copy old first field into vbuff */ memcpy(vbuff,settings->tmpbuff[settings->old_buff_no],settings->old_field_len); } /* copy second field */ memcpy(vbuff+settings->old_field_len,settings->tmpbuff[new_buff_no]+jpeg_len1,jpeg_len2); /* save first field */ settings->old_field_len = jpeg_len1; settings->old_buff_no = new_buff_no; } } } else { if (lavplay_get_video(info, vbuff, settings->current_frame_num) < 0) return 0; settings->old_field_len = 0; } } /* Read audio, if present */ if (editlist->has_audio && !skip_audio && info->audio) { mute = (settings->audio_mute || !((settings->current_playback_speed == 1 && (info->audio & 1)) || (settings->current_playback_speed == -1 && (info->audio & 2)) || (settings->current_playback_speed == 0 && (info->audio & 8)) || (1 < settings->current_playback_speed && (info->audio & (1|4)) == (1|4)) || (settings->current_playback_speed < -1 && (info->audio & (2|4)) == (2|4)))); res = lavplay_get_audio(info, settings->abuff, settings->current_frame_num, mute); if (settings->current_playback_speed < 0) { /* reverse audio */ for(i=0;i<res/2;i+=editlist->audio_bps) { memcpy(hlp,settings->abuff+i, editlist->audio_bps); memcpy(settings->abuff+i,settings->abuff+res-i-editlist->audio_bps, editlist->audio_bps); memcpy(settings->abuff+res-i-editlist->audio_bps,hlp, editlist->audio_bps); } } res = audio_write(settings->abuff,res,0); if (res < 0) { lavplay_msg(LAVPLAY_MSG_ERROR, info, "Error playing audio: %s",audio_strerror()); return 0; } } /* Increment frames */ if(!skip_incr) { res = lavplay_increase_frame(info, settings->current_playback_speed); if (!info->continuous) return res; } return 1;}/****************************************************** * lavplay_SDL_lock() * when using software playback - lock the SDL screen * * return value: 1 on success, 0 on error ******************************************************/#ifdef HAVE_SDLstatic int lavplay_SDL_lock(lavplay_t *info){ video_playback_setup *settings = (video_playback_setup *)info->settings; /* lock the screen for current decompression */ if (SDL_MUSTLOCK(settings->screen)) { if (SDL_LockSurface(settings->screen) < 0) { lavplay_msg(LAVPLAY_MSG_ERROR, info, "Error locking output screen: %s", SDL_GetError()); return 0; } } if (SDL_LockYUVOverlay(settings->yuv_overlay) < 0) { lavplay_msg(LAVPLAY_MSG_ERROR, info, "Error locking yuv overlay: %s", SDL_GetError()); return 0; } return 1;}#endif/****************************************************** * lavplay_SDL_unlock() * when using software playback - unlock the SDL screen * * return value: 1 on success, 0 on error ******************************************************/#ifdef HAVE_SDLstatic int lavplay_SDL_unlock(lavplay_t *info){ video_playback_setup *settings = (video_playback_setup *)info->settings; if (SDL_MUSTLOCK(settings->screen)) { SDL_UnlockSurface(settings->screen); } SDL_UnlockYUVOverlay(settings->yuv_overlay); return 1;}#endif/****************************************************** * lavplay_SDL_update() * when using software playback - there's a new frame * * return value: 1 on success, 0 on error ******************************************************/#ifdef HAVE_SDLstatic int lavplay_SDL_update(lavplay_t *info, uint8_t *jpeg_buffer, int data_format, int buf_len){ video_playback_setup *settings = (video_playback_setup *)info->settings; uint8_t *output[3]; EditList *editlist = info->editlist; if (!lavplay_SDL_lock(info)) return 0; /* decode frame to yuv */ switch (data_format) { case DATAFORMAT_MJPG: decode_jpeg_raw(jpeg_buffer, buf_len, editlist->video_inter>0&&info->exchange_fields?(editlist->video_inter+1)%2+1:editlist->video_inter, CHROMA422, editlist->video_width, editlist->video_height, settings->yuvbuff[0], settings->yuvbuff[1], settings->yuvbuff[2]); frame_planar_to_packed(settings->yuv_overlay->pixels[0], settings->yuvbuff, editlist->video_width, editlist->video_height, settings->yuvformat, FOURCC_I422, 1); break; case DATAFORMAT_YUV420: output[0] = jpeg_buffer; output[1] = jpeg_buffer + (editlist->video_width * editlist->video_height); output[2] = jpeg_buffer + (editlist->video_width * editlist->video_height * 5 / 4); frame_planar_to_packed(settings->yuv_overlay->pixels[0], output, editlist->video_width, editlist->video_height, settings->yuvformat, FOURCC_I420, 1); break;# ifdef HAVE_LIBDV case DATAFORMAT_DV2: dv_parse_header(settings->decoder, jpeg_buffer); switch(settings->decoder->sampling) { /* FIXME: not implemented, do default: */ case e_dv_sample_420: break; case e_dv_sample_411: case e_dv_sample_422: /* libdv decodes NTSC DV (native 411) and by default also PAL * DV (native 420) as packed YUV 422 (YUY2 or 4CC 0x32595559) * where the U and V information is repeated. This can be * transformed to planar 420 (YV12 or 4CC 0x32315659). * For NTSC DV this transformation is lossy. */ settings->pitches[0] = settings->decoder->width * 2; settings->pitches[1] = 0; settings->pitches[2] = 0; dv_decode_full_frame(settings->decoder, jpeg_buffer, e_dv_color_yuv, settings->yuv_overlay->pixels, settings->pitches); break; case e_dv_sample_none: /* FIXME */ break; } break; # endif default: return 0; } if (!lavplay_SDL_unlock(info)) return 0; SDL_DisplayYUVOverlay(settings->yuv_overlay, &(settings->jpegdims)); return 1;}#endif /* HAVE_SDL *//****************************************************** * lavplay_SDL_init() * when using software playback - initialize SDL * * return value: 1 on success, 0 on error ******************************************************/#ifdef HAVE_SDLstatic int lavplay_SDL_init(lavplay_t *info){ char *sbuffer; int i; video_playback_setup *settings = (video_playback_setup *)info->settings; EditList *editlist = info->editlist; lavplay_msg(LAVPLAY_MSG_INFO, info, "Initialising SDL"); if (SDL_Init (SDL_INIT_VIDEO) < 0) { lavplay_msg(LAVPLAY_MSG_ERROR, info,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?