📄 video_output.c
字号:
#endif /* Remove reservation flag */ p_subpic->i_status = READY_SUBPICTURE;#ifdef DEBUG_VIDEO /* Send subpicture informations */ intf_DbgMsg("subpicture %p: type=%d, begin date=%s, end date=%s\n", p_subpic, p_subpic->i_type, mstrtime( psz_begin_date, p_subpic->begin_date ), mstrtime( psz_end_date, p_subpic->end_date ) );#endif}/***************************************************************************** * vout_CreateSubPicture: allocate an subpicture in the video output heap. ***************************************************************************** * This function create a reserved subpicture in the video output heap. * A null pointer is returned if the function fails. This method provides an * already allocated zone of memory in the spu data fields. It needs locking * since several pictures can be created by several producers threads. *****************************************************************************/subpicture_t *vout_CreateSubPicture( vout_thread_t *p_vout, int i_type, int i_size ){ int i_subpic; /* subpicture index */ subpicture_t * p_free_subpic = NULL; /* first free subpicture */ subpicture_t * p_destroyed_subpic = NULL; /* first destroyed subpic */ /* Get lock */ vlc_mutex_lock( &p_vout->subpicture_lock ); /* * Look for an empty place */ for( i_subpic = 0; i_subpic < VOUT_MAX_SUBPICTURES; i_subpic++ ) { if( p_vout->p_subpicture[i_subpic].i_status == DESTROYED_SUBPICTURE ) { /* Subpicture is marked for destruction, but is still allocated */ if( (p_vout->p_subpicture[i_subpic].i_type == i_type) && (p_vout->p_subpicture[i_subpic].i_size >= i_size) ) { /* Memory size do match or is smaller : memory will not be * reallocated, and function can end immediately - this is * the best possible case, since no memory allocation needs * to be done */ p_vout->p_subpicture[i_subpic].i_status = RESERVED_SUBPICTURE;#ifdef DEBUG_VIDEO intf_DbgMsg("subpicture %p (in destroyed subpicture slot)\n", &p_vout->p_subpicture[i_subpic] );#endif vlc_mutex_unlock( &p_vout->subpicture_lock ); return( &p_vout->p_subpicture[i_subpic] ); } else if( p_destroyed_subpic == NULL ) { /* Memory size do not match, but subpicture index will be kept in * case no other place are left */ p_destroyed_subpic = &p_vout->p_subpicture[i_subpic]; } } else if( (p_free_subpic == NULL) && (p_vout->p_subpicture[i_subpic].i_status == FREE_SUBPICTURE )) { /* Subpicture is empty and ready for allocation */ p_free_subpic = &p_vout->p_subpicture[i_subpic]; } } /* If no free subpicture is available, use a destroyed subpicture */ if( (p_free_subpic == NULL) && (p_destroyed_subpic != NULL ) ) { /* No free subpicture or matching destroyed subpicture has been * found, but a destroyed subpicture is still avalaible */ free( p_destroyed_subpic->p_data ); p_free_subpic = p_destroyed_subpic; } /* * Prepare subpicture */ if( p_free_subpic != NULL ) { /* Allocate memory */ switch( i_type ) { case TEXT_SUBPICTURE: /* text subpicture */ p_free_subpic->p_data = malloc( i_size + 1 ); break; case DVD_SUBPICTURE: /* DVD subpicture unit */ p_free_subpic->p_data = malloc( i_size ); break;#ifdef DEBUG default: intf_DbgMsg("error: unknown subpicture type %d\n", i_type ); p_free_subpic->p_data = NULL; break;#endif } if( p_free_subpic->p_data != NULL ) { /* Copy subpicture informations, set some default values */ p_free_subpic->i_type = i_type; p_free_subpic->i_status = RESERVED_SUBPICTURE; p_free_subpic->i_size = i_size; p_free_subpic->i_x = 0; p_free_subpic->i_y = 0; p_free_subpic->i_width = 0; p_free_subpic->i_height = 0; p_free_subpic->i_horizontal_align = CENTER_RALIGN; p_free_subpic->i_vertical_align = CENTER_RALIGN; } else { /* Memory allocation failed : set subpicture as empty */ p_free_subpic->i_type = EMPTY_SUBPICTURE; p_free_subpic->i_status = FREE_SUBPICTURE; p_free_subpic = NULL; intf_ErrMsg("warning: %s\n", strerror( ENOMEM ) ); }#ifdef DEBUG_VIDEO intf_DbgMsg("subpicture %p (in free subpicture slot)\n", p_free_subpic );#endif vlc_mutex_unlock( &p_vout->subpicture_lock ); return( p_free_subpic ); } /* No free or destroyed subpicture could be found */ intf_DbgMsg( "warning: heap is full\n" ); vlc_mutex_unlock( &p_vout->subpicture_lock ); return( NULL );}/***************************************************************************** * vout_DestroySubPicture: remove a subpicture from the heap ***************************************************************************** * This function frees a previously reserved subpicture. * It is meant to be used when the construction of a picture aborted. * This function does not need locking since reserved subpictures are ignored * by the output thread. *****************************************************************************/void vout_DestroySubPicture( vout_thread_t *p_vout, subpicture_t *p_subpic ){#ifdef DEBUG /* Check if status is valid */ if( p_subpic->i_status != RESERVED_SUBPICTURE ) { intf_DbgMsg("error: subpicture %p has invalid status %d\n", p_subpic, p_subpic->i_status ); }#endif p_subpic->i_status = DESTROYED_SUBPICTURE;#ifdef DEBUG_VIDEO intf_DbgMsg("subpicture %p\n", p_subpic);#endif}/***************************************************************************** * vout_DisplayPicture: display a picture ***************************************************************************** * Remove the reservation flag of a picture, which will cause it to be ready for * display. The picture won't be displayed until vout_DatePicture has been * called. *****************************************************************************/void vout_DisplayPicture( vout_thread_t *p_vout, picture_t *p_pic ){ vlc_mutex_lock( &p_vout->picture_lock ); switch( p_pic->i_status ) { case RESERVED_PICTURE: p_pic->i_status = RESERVED_DISP_PICTURE; break; case RESERVED_DATED_PICTURE: p_pic->i_status = READY_PICTURE; break;#ifdef DEBUG default: intf_DbgMsg("error: picture %p has invalid status %d\n", p_pic, p_pic->i_status ); break;#endif }#ifdef DEBUG_VIDEO intf_DbgMsg("picture %p\n", p_pic);#endif vlc_mutex_unlock( &p_vout->picture_lock );}/***************************************************************************** * vout_DatePicture: date a picture ***************************************************************************** * Remove the reservation flag of a picture, which will cause it to be ready for * display. The picture won't be displayed until vout_DisplayPicture has been * called. *****************************************************************************/void vout_DatePicture( vout_thread_t *p_vout, picture_t *p_pic, mtime_t date ){#ifdef DEBUG_VIDEO char psz_date[MSTRTIME_MAX_SIZE]; /* date */#endif vlc_mutex_lock( &p_vout->picture_lock ); p_pic->date = date; switch( p_pic->i_status ) { case RESERVED_PICTURE: p_pic->i_status = RESERVED_DATED_PICTURE; break; case RESERVED_DISP_PICTURE: p_pic->i_status = READY_PICTURE; break;#ifdef DEBUG default: intf_DbgMsg("error: picture %p has invalid status %d\n", p_pic, p_pic->i_status ); break;#endif }#ifdef DEBUG_VIDEO intf_DbgMsg("picture %p, display date: %s\n", p_pic, mstrtime( psz_date, p_pic->date) );#endif vlc_mutex_unlock( &p_vout->picture_lock );}/***************************************************************************** * vout_CreatePicture: allocate a picture in the video output heap. ***************************************************************************** * This function create a reserved image in the video output heap. * A null pointer is returned if the function fails. This method provides an * already allocated zone of memory in the picture data fields. It needs locking * since several pictures can be created by several producers threads. *****************************************************************************/picture_t *vout_CreatePicture( vout_thread_t *p_vout, int i_type, int i_width, int i_height ){ int i_picture; /* picture index */ int i_chroma_width = 0; /* chroma width */ picture_t * p_free_picture = NULL; /* first free picture */ picture_t * p_destroyed_picture = NULL; /* first destroyed picture */ /* Get lock */ vlc_mutex_lock( &p_vout->picture_lock ); /* * Look for an empty place */ for( i_picture = 0; i_picture < VOUT_MAX_PICTURES; i_picture++ ) { if( p_vout->p_picture[i_picture].i_status == DESTROYED_PICTURE ) { /* Picture is marked for destruction, but is still allocated - note * that if width and type are the same for two pictures, chroma_width * should also be the same */ if( (p_vout->p_picture[i_picture].i_type == i_type) && (p_vout->p_picture[i_picture].i_height == i_height) && (p_vout->p_picture[i_picture].i_width == i_width) ) { /* Memory size do match : memory will not be reallocated, and function * can end immediately - this is the best possible case, since no * memory allocation needs to be done */ p_vout->p_picture[i_picture].i_status = RESERVED_PICTURE; p_vout->i_pictures++;#ifdef DEBUG_VIDEO intf_DbgMsg("picture %p (in destroyed picture slot)\n", &p_vout->p_picture[i_picture] );#endif vlc_mutex_unlock( &p_vout->picture_lock ); return( &p_vout->p_picture[i_picture] ); } else if( p_destroyed_picture == NULL ) { /* Memory size do not match, but picture index will be kept in * case no other place are left */ p_destroyed_picture = &p_vout->p_picture[i_picture]; } } else if( (p_free_picture == NULL) && (p_vout->p_picture[i_picture].i_status == FREE_PICTURE )) { /* Picture is empty and ready for allocation */ p_free_picture = &p_vout->p_picture[i_picture]; } } /* If no free picture is available, use a destroyed picture */ if( (p_free_picture == NULL) && (p_destroyed_picture != NULL ) ) { /* No free picture or matching destroyed picture has been found, but * a destroyed picture is still avalaible */ free( p_destroyed_picture->p_data ); p_free_picture = p_destroyed_picture; } /* * Prepare picture */ if( p_free_picture != NULL ) { /* Allocate memory */ switch( i_type ) { case YUV_420_PICTURE: /* YUV 420: 1,1/4,1/4 samples per pixel */ i_chroma_width = i_width / 2; p_free_picture->p_data = malloc( i_height * i_chroma_width * 3 * sizeof( yuv_data_t ) ); p_free_picture->p_y = (yuv_data_t *)p_free_picture->p_data; p_free_picture->p_u = (yuv_data_t *)p_free_picture->p_data +i_height*i_chroma_width*4/2; p_free_picture->p_v = (yuv_data_t *)p_free_picture->p_data +i_height*i_chroma_width*5/2; break; case YUV_422_PICTURE: /* YUV 422: 1,1/2,1/2 samples per pixel */ i_chroma_width = i_width / 2; p_free_picture->p_data = malloc( i_height * i_chroma_width * 4 * sizeof( yuv_data_t ) ); p_free_picture->p_y = (yuv_data_t *)p_free_picture->p_data; p_free_picture->p_u = (yuv_data_t *)p_free_picture->p_data +i_height*i_chroma_width*2; p_free_picture->p_v = (yuv_data_t *)p_free_picture->p_data +i_height*i_chroma_width*3; break; case YUV_444_PICTURE: /* YUV 444: 1,1,1 samples per pixel */ i_chroma_width = i_width; p_free_picture->p_data = malloc( i_height * i_chroma_width * 3 * sizeof( yuv_data_t ) ); p_free_picture->p_y = (yuv_data_t *)p_free_picture->p_data; p_free_picture->p_u = (yuv_data_t *)p_free_picture->p_data +i_height*i_chroma_width; p_free_picture->p_v = (yuv_data_t *)p_free_picture->p_data +i_height*i_chroma_width*2; break;#ifdef DEBUG default: intf_DbgMsg("error: unknown picture type %d\n", i_type ); p_free_picture->p_data = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -