📄 xvmc.c
字号:
height, p_vout->p_sys->context_flags, &p_vout->p_sys->context ) ) { p_vout->p_sys->xvmc_mpeg = curCap->mpeg_flags; p_vout->p_sys->xvmc_width = width; p_vout->p_sys->xvmc_height = height; p_vout->p_sys->contextActive = 1; } XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display ); return p_vout->p_sys->contextActive;}static void xvmc_flushsync(picture_t *picture){ vout_thread_t *p_vout = picture->p_sys->p_vout; xvmc_context_reader_lock( &p_vout->p_sys->xvmc_lock ); if( !xxmc_xvmc_surface_valid( p_vout, picture->p_sys->xvmc_surf ) ) { msg_Dbg(p_vout, "xvmc_flushsync 1 : %d", picture->p_sys->xxmc_data.result ); picture->p_sys->xxmc_data.result = 128; xvmc_context_reader_unlock( &p_vout->p_sys->xvmc_lock ); return; } XVMCLOCKDISPLAY( p_vout->p_sys->p_display ); picture->p_sys->xxmc_data.result = XvMCFlushSurface( p_vout->p_sys->p_display, picture->p_sys->xvmc_surf ); XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display ); xvmc_context_reader_unlock( &p_vout->p_sys->xvmc_lock );}static void xvmc_flush(picture_t *picture){ vout_thread_t *p_vout = picture->p_sys->p_vout; xvmc_context_reader_lock( &p_vout->p_sys->xvmc_lock ); if ( !xxmc_xvmc_surface_valid( p_vout, picture->p_sys->xvmc_surf ) ) { msg_Dbg(p_vout, "xvmc flush 1 : %d", picture->p_sys->xxmc_data.result ); picture->p_sys->xxmc_data.result = 128; xvmc_context_reader_unlock( &p_vout->p_sys->xvmc_lock ); return; } XVMCLOCKDISPLAY( p_vout->p_sys->p_display ); picture->p_sys->xxmc_data.result = XvMCFlushSurface( p_vout->p_sys->p_display, picture->p_sys->xvmc_surf ); XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display ); xvmc_context_reader_unlock( &p_vout->p_sys->xvmc_lock );}static int xxmc_frame_updates( vout_thread_t *p_vout, picture_t *picture ){ vlc_xxmc_t *xxmc = &picture->p_sys->xxmc_data; /* * If we have changed context since the surface was updated, xvmc_surf * is either NULL or invalid. If it is invalid. Set it to NULL. * Also if there are other users of this surface, deregister our use of * it and later try to allocate a new, fresh one. */ if( picture->p_sys->xvmc_surf ) { if( !xxmc_xvmc_surface_valid( p_vout, picture->p_sys->xvmc_surf ) ) { xxmc_xvmc_free_surface( p_vout , picture->p_sys->xvmc_surf ); picture->p_sys->xvmc_surf = NULL; } }#if 0 if( picture->p_sys->p_image ) { memset( picture->p_sys->p_image->data, 0, picture->p_sys->p_image->width * picture->p_sys->p_image->height ); }#endif /* * If it is NULL create a new surface. */ if( !picture->p_sys->xvmc_surf ) { picture->p_sys->xvmc_surf = xxmc_xvmc_alloc_surface( p_vout, &p_vout->p_sys->context ); if( !picture->p_sys->xvmc_surf ) { msg_Err( p_vout, "accelerated surface allocation failed.\n" " You are probably out of framebuffer memory.\n" " Falling back to software decoding." ); p_vout->p_sys->xvmc_accel = 0; xxmc_dispose_context( p_vout ); return VLC_EGENERIC; } } xxmc->acceleration = p_vout->p_sys->xvmc_accel; xxmc->proc_xxmc_flush = xvmc_flush; xxmc->proc_xxmc_flushsync = xvmc_flushsync; xxmc->xvmc.proc_macro_block = NULL;#if 0 frame->vo_frame.proc_duplicate_frame_data = xxmc_duplicate_frame_data;#endif xxmc->proc_xxmc_begin = xvmc_vld_frame; xxmc->proc_xxmc_slice = xvmc_vld_slice; return VLC_SUCCESS;}static int xxmc_xvmc_update_context( vout_thread_t *p_vout, picture_t *picture, uint32_t width, uint32_t height ){ vlc_xxmc_t *xxmc = &picture->p_sys->xxmc_data; /* * Are we at all capable of doing XvMC ? */ if( p_vout->p_sys->xvmc_cap == 0 ) return VLC_EGENERIC; msg_Dbg( p_vout, "new format: need to change XvMC context. " "width: %d height: %d mpeg: %d acceleration: %d", width, height, xxmc->mpeg, xxmc->acceleration ); if( picture->p_sys->xvmc_surf ) xxmc_xvmc_free_surface( p_vout , picture->p_sys->xvmc_surf ); picture->p_sys->xvmc_surf = NULL; xxmc_dispose_context( p_vout ); if( xxmc_find_context( p_vout, xxmc, width, height ) ) { xxmc_create_context( p_vout, width, height); xvmc_check_colorkey_properties( p_vout ); xxmc_setup_subpictures(p_vout, width, height); } if( !p_vout->p_sys->contextActive ) { msg_Dbg( p_vout, "using software decoding for this stream" ); p_vout->p_sys->xvmc_accel = 0; } else { msg_Dbg(p_vout, "using hardware decoding for this stream." ); } p_vout->p_sys->xvmc_mpeg = xxmc->mpeg; p_vout->p_sys->xvmc_width = width; p_vout->p_sys->xvmc_height = height; return p_vout->p_sys->contextActive;}void xxmc_do_update_frame( picture_t *picture, uint32_t width, uint32_t height, double ratio, int format, int flags){ vout_thread_t *p_vout = picture->p_sys->p_vout; int indextime = 0; int status = 0; picture->p_sys->xxmc_data.decoded = 0; picture->p_sys->nb_display = 0; picture->b_force = 0; vlc_xxmc_t *xxmc = &picture->p_sys->xxmc_data; xvmc_context_writer_lock( &p_vout->p_sys->xvmc_lock); if( (p_vout->p_sys->last_accel_request != xxmc->acceleration) || (p_vout->p_sys->xvmc_mpeg != xxmc->mpeg) || (p_vout->p_sys->xvmc_width != width) || (p_vout->p_sys->xvmc_height != height)) { p_vout->p_sys->last_accel_request = xxmc->acceleration; xxmc_xvmc_update_context( p_vout, picture, width, height ); } if( p_vout->p_sys->contextActive ) xxmc_frame_updates( p_vout, picture ); if( !p_vout->p_sys->contextActive ) { xxmc->acceleration = 0; xxmc->xvmc.macroblocks = 0; } else { picture->format.i_chroma = format; } xvmc_context_writer_unlock( &p_vout->p_sys->xvmc_lock); XvMCGetSurfaceStatus( p_vout->p_sys->p_display, picture->p_sys->xvmc_surf, &status ); /* Wait a little till frame is being displayed */ while( status & XVMC_DISPLAYING ) { msleep(1); XvMCGetSurfaceStatus( p_vout->p_sys->p_display, picture->p_sys->xvmc_surf, &status ); indextime++; if( indextime > 4 ) break; }}#if 0/* called xlocked */static void dispose_ximage( vout_thread_t *p_vout, XShmSegmentInfo *shminfo, XvImage *myimage ){# ifdef HAVE_SYS_SHM_H if( p_vout->p_sys->i_shm_opcode ) { XShmDetach( p_vout->p_sys->p_display, shminfo ); XFree( myimage ); shmdt( shminfo->shmaddr ); if( shminfo->shmid >= 0 ) { shmctl( shminfo->shmid, IPC_RMID, 0 ); shminfo->shmid = -1; } } else#endif { if( myimage->data ) free(myimage->data); XFree (myimage); }}#endifvoid xvmc_vld_frame( picture_t *picture ){ picture_sys_t *p_sys = picture->p_sys; vout_thread_t *p_vout = p_sys->p_vout; vlc_vld_frame_t *vft = &(p_sys->xxmc_data.vld_frame); picture_t *ff = (picture_t *) vft->forward_reference_picture; picture_t *bf = (picture_t *) vft->backward_reference_picture; XvMCMpegControl ctl; XvMCSurface *fs=0, *bs=0; XvMCQMatrix qmx; ctl.BHMV_range = vft->mv_ranges[0][0]; ctl.BVMV_range = vft->mv_ranges[0][1]; ctl.FHMV_range = vft->mv_ranges[1][0]; ctl.FVMV_range = vft->mv_ranges[1][1]; ctl.picture_structure = vft->picture_structure; ctl.intra_dc_precision = vft->intra_dc_precision; ctl.picture_coding_type = vft->picture_coding_type; ctl.mpeg_coding = (vft->mpeg_coding == 0) ? XVMC_MPEG_1 : XVMC_MPEG_2; ctl.flags = 0; ctl.flags |= (vft->progressive_sequence) ? XVMC_PROGRESSIVE_SEQUENCE : 0; ctl.flags |= (vft->scan) ? XVMC_ALTERNATE_SCAN : XVMC_ZIG_ZAG_SCAN; ctl.flags |= (vft->pred_dct_frame) ? XVMC_PRED_DCT_FRAME : XVMC_PRED_DCT_FIELD; ctl.flags |= (picture->b_top_field_first) ? XVMC_TOP_FIELD_FIRST : XVMC_BOTTOM_FIELD_FIRST; ctl.flags |= (vft->concealment_motion_vectors) ? XVMC_CONCEALMENT_MOTION_VECTORS : 0; ctl.flags |= (vft->q_scale_type) ? XVMC_Q_SCALE_TYPE : 0; ctl.flags |= (vft->intra_vlc_format) ? XVMC_INTRA_VLC_FORMAT : 0; ctl.flags |= (vft->second_field) ? XVMC_SECOND_FIELD : 0; if( ff ) fs = ff->p_sys->xvmc_surf; if( bf ) bs = bf->p_sys->xvmc_surf; /* * Below is for interlaced streams and second_field. */ if( ctl.picture_coding_type == P_TYPE ) /* XVMC_P_PICTURE) */ bs = picture->p_sys->xvmc_surf; if( (qmx.load_intra_quantiser_matrix = vft->load_intra_quantizer_matrix) ) { memcpy( qmx.intra_quantiser_matrix, vft->intra_quantizer_matrix, sizeof(qmx.intra_quantiser_matrix) ); } if( (qmx.load_non_intra_quantiser_matrix = vft->load_non_intra_quantizer_matrix) ) { memcpy( qmx.non_intra_quantiser_matrix, vft->non_intra_quantizer_matrix, sizeof(qmx.non_intra_quantiser_matrix) ); } qmx.load_chroma_intra_quantiser_matrix = 0; qmx.load_chroma_non_intra_quantiser_matrix = 0; xvmc_context_reader_lock( &p_vout->p_sys->xvmc_lock ); if( !xxmc_xvmc_surface_valid( p_vout, picture->p_sys->xvmc_surf ) ) { picture->p_sys->xxmc_data.result = 128; xvmc_context_reader_unlock( &p_vout->p_sys->xvmc_lock ); return; } XVMCLOCKDISPLAY( p_vout->p_sys->p_display ); XvMCLoadQMatrix( p_vout->p_sys->p_display, &p_vout->p_sys->context, &qmx ); do { picture->p_sys->xxmc_data.result = XvMCBeginSurface( p_vout->p_sys->p_display, &p_vout->p_sys->context, picture->p_sys->xvmc_surf, fs, bs, &ctl ); } while( !picture->p_sys->xxmc_data.result ); XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display ); xvmc_context_reader_unlock( &p_vout->p_sys->xvmc_lock );}void xvmc_vld_slice( picture_t *picture ){ picture_sys_t *p_sys = picture->p_sys; vout_thread_t *p_vout = p_sys->p_vout; xvmc_context_reader_lock( &p_vout->p_sys->xvmc_lock ); if( !xxmc_xvmc_surface_valid( p_vout, picture->p_sys->xvmc_surf ) ) { picture->p_sys->xxmc_data.result = 128; xvmc_context_reader_unlock( &p_vout->p_sys->xvmc_lock ); msg_Err(p_vout, "vld slice error" ); return; } XVMCLOCKDISPLAY( p_vout->p_sys->p_display ); picture->p_sys->xxmc_data.result = XvMCPutSlice2( p_vout->p_sys->p_display, &p_vout->p_sys->context, (char *)picture->p_sys->xxmc_data.slice_data, picture->p_sys->xxmc_data.slice_data_size, picture->p_sys->xxmc_data.slice_code ); if( picture->p_sys->xxmc_data.result != 0 ) msg_Err( p_vout, "vlc slice error %d", picture->p_sys->xxmc_data.result ); /* * If CPU-saving mode is enabled, sleep after every xxmc->sleep slice. This will free * up the cpu while the decoder is working on the slice. The value of xxmc->sleep is calculated * so that the decoder thread sleeps at most 50% of the frame delay, * assuming a 2.6 kernel clock of 1000 Hz. */ XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display ); xvmc_context_reader_unlock( &p_vout->p_sys->xvmc_lock );#if 0 if( p_vout->p_sys->cpu_save_enabled ) { p_vout->p_sys->cpu_saver += 1.; if( p_vout->p_sys->cpu_saver >= picture->p_sys->xxmc_data.sleep ) { usleep(1); p_vout->p_sys->cpu_saver -= picture->p_sys->xxmc_data.sleep; } }#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -