| | 65 | |
|---|
| | 66 | /***************************************************************************** |
|---|
| | 67 | * chroma_sys_t: chroma method descriptor |
|---|
| | 68 | ***************************************************************************** |
|---|
| | 69 | * This structure is part of the chroma transformation descriptor, it |
|---|
| | 70 | * describes the chroma plugin specific properties. |
|---|
| | 71 | *****************************************************************************/ |
|---|
| | 72 | struct filter_sys_t |
|---|
| | 73 | { |
|---|
| | 74 | int i_src_vlc_chroma; |
|---|
| | 75 | int i_src_ffmpeg_chroma; |
|---|
| | 76 | int i_dst_vlc_chroma; |
|---|
| | 77 | int i_dst_ffmpeg_chroma; |
|---|
| | 78 | AVPicture tmp_pic; |
|---|
| | 79 | ImgReSampleContext *p_rsc; |
|---|
| | 80 | }; |
|---|
| | 81 | |
|---|
| | 82 | /***************************************************************************** |
|---|
| | 83 | * OpenFilter: allocate a chroma function |
|---|
| | 84 | ***************************************************************************** |
|---|
| | 85 | * This function allocates and initializes a chroma function |
|---|
| | 86 | *****************************************************************************/ |
|---|
| | 87 | int OpenFilter( vlc_object_t *p_this ) |
|---|
| | 88 | { |
|---|
| | 89 | filter_t *p_filter = (filter_t *)p_this; |
|---|
| | 90 | int i_ffmpeg_chroma[2], i_vlc_chroma[2], i; |
|---|
| | 91 | |
|---|
| | 92 | /* |
|---|
| | 93 | * Check the source chroma first, then the destination chroma |
|---|
| | 94 | */ |
|---|
| | 95 | i_vlc_chroma[0] = p_filter->fmt_in.video.i_chroma; |
|---|
| | 96 | i_vlc_chroma[1] = p_filter->fmt_out.video.i_chroma; |
|---|
| | 97 | for( i = 0; i < 2; i++ ) |
|---|
| | 98 | { |
|---|
| | 99 | i_ffmpeg_chroma[i] = GetFfmpegChroma( i_vlc_chroma[i] ); |
|---|
| | 100 | if( i_ffmpeg_chroma[i] < 0 ) return VLC_EGENERIC; |
|---|
| | 101 | } |
|---|
| | 102 | |
|---|
| | 103 | p_filter->pf_video_filter = Conversion_Filter; |
|---|
| | 104 | |
|---|
| | 105 | p_filter->p_sys = malloc( sizeof( filter_sys_t ) ); |
|---|
| | 106 | if( p_filter->p_sys == NULL ) |
|---|
| | 107 | { |
|---|
| | 108 | return VLC_ENOMEM; |
|---|
| | 109 | } |
|---|
| | 110 | |
|---|
| | 111 | p_filter->p_sys->i_src_vlc_chroma = p_filter->fmt_in.video.i_chroma; |
|---|
| | 112 | p_filter->p_sys->i_dst_vlc_chroma = p_filter->fmt_out.video.i_chroma; |
|---|
| | 113 | p_filter->p_sys->i_src_ffmpeg_chroma = i_ffmpeg_chroma[0]; |
|---|
| | 114 | p_filter->p_sys->i_dst_ffmpeg_chroma = i_ffmpeg_chroma[1]; |
|---|
| | 115 | |
|---|
| | 116 | if( ( p_filter->fmt_in.video.i_height != p_filter->fmt_out.video.i_height || |
|---|
| | 117 | p_filter->fmt_in.video.i_width != p_filter->fmt_out.video.i_width ) && |
|---|
| | 118 | ( p_filter->p_sys->i_dst_vlc_chroma == VLC_FOURCC('I','4','2','0') || |
|---|
| | 119 | p_filter->p_sys->i_dst_vlc_chroma == VLC_FOURCC('Y','V','1','2') )) |
|---|
| | 120 | { |
|---|
| | 121 | msg_Dbg( p_filter, "preparing to resample picture" ); |
|---|
| | 122 | p_filter->p_sys->p_rsc = |
|---|
| | 123 | img_resample_init( p_filter->fmt_out.video.i_width, |
|---|
| | 124 | p_filter->fmt_out.video.i_height, |
|---|
| | 125 | p_filter->fmt_in.video.i_width, |
|---|
| | 126 | p_filter->fmt_in.video.i_height ); |
|---|
| | 127 | avpicture_alloc( &p_filter->p_sys->tmp_pic, |
|---|
| | 128 | p_filter->p_sys->i_dst_ffmpeg_chroma, |
|---|
| | 129 | p_filter->fmt_in.video.i_width, |
|---|
| | 130 | p_filter->fmt_in.video.i_height ); |
|---|
| | 131 | } |
|---|
| | 132 | else |
|---|
| | 133 | { |
|---|
| | 134 | msg_Dbg( p_filter, "no resampling" ); |
|---|
| | 135 | p_filter->p_sys->p_rsc = NULL; |
|---|
| | 136 | } |
|---|
| | 137 | |
|---|
| | 138 | return VLC_SUCCESS; |
|---|
| | 139 | } |
|---|
| | 140 | |
|---|
| | 141 | VIDEO_FILTER_WRAPPER( Conversion ) |
|---|
| | 142 | |
|---|
| | 143 | /***************************************************************************** |
|---|
| | 144 | * ChromaConversion: actual chroma conversion function |
|---|
| | 145 | *****************************************************************************/ |
|---|
| | 146 | static void Conversion( filter_t *p_filter, |
|---|
| | 147 | picture_t *p_src, picture_t *p_dest ) |
|---|
| | 148 | { |
|---|
| | 149 | AVPicture src_pic; |
|---|
| | 150 | AVPicture dest_pic; |
|---|
| | 151 | int i; |
|---|
| | 152 | |
|---|
| | 153 | /* Prepare the AVPictures for converion */ |
|---|
| | 154 | for( i = 0; i < p_src->i_planes; i++ ) |
|---|
| | 155 | { |
|---|
| | 156 | src_pic.data[i] = p_src->p[i].p_pixels; |
|---|
| | 157 | src_pic.linesize[i] = p_src->p[i].i_pitch; |
|---|
| | 158 | } |
|---|
| | 159 | for( i = 0; i < p_dest->i_planes; i++ ) |
|---|
| | 160 | { |
|---|
| | 161 | dest_pic.data[i] = p_dest->p[i].p_pixels; |
|---|
| | 162 | dest_pic.linesize[i] = p_dest->p[i].i_pitch; |
|---|
| | 163 | } |
|---|
| | 164 | |
|---|
| | 165 | /* Special cases */ |
|---|
| | 166 | if( p_filter->p_sys->i_src_vlc_chroma == VLC_FOURCC('Y','V','1','2') || |
|---|
| | 167 | p_filter->p_sys->i_src_vlc_chroma == VLC_FOURCC('Y','V','U','9') ) |
|---|
| | 168 | { |
|---|
| | 169 | /* Invert U and V */ |
|---|
| | 170 | src_pic.data[1] = p_src->p[2].p_pixels; |
|---|
| | 171 | src_pic.data[2] = p_src->p[1].p_pixels; |
|---|
| | 172 | } |
|---|
| | 173 | if( p_filter->p_sys->i_dst_vlc_chroma == VLC_FOURCC('Y','V','1','2') || |
|---|
| | 174 | p_filter->p_sys->i_dst_vlc_chroma == VLC_FOURCC('Y','V','U','9') ) |
|---|
| | 175 | { |
|---|
| | 176 | /* Invert U and V */ |
|---|
| | 177 | dest_pic.data[1] = p_dest->p[2].p_pixels; |
|---|
| | 178 | dest_pic.data[2] = p_dest->p[1].p_pixels; |
|---|
| | 179 | } |
|---|
| | 180 | if( p_filter->p_sys->i_src_ffmpeg_chroma == PIX_FMT_RGB24 ) |
|---|
| | 181 | if( p_filter->fmt_in.video.i_bmask == 0x00ff0000 ) |
|---|
| | 182 | p_filter->p_sys->i_src_ffmpeg_chroma = PIX_FMT_BGR24; |
|---|
| | 183 | |
|---|
| | 184 | if( p_filter->p_sys->p_rsc ) |
|---|
| | 185 | { |
|---|
| | 186 | img_convert( &p_filter->p_sys->tmp_pic, |
|---|
| | 187 | p_filter->p_sys->i_dst_ffmpeg_chroma, |
|---|
| | 188 | &src_pic, p_filter->p_sys->i_src_ffmpeg_chroma, |
|---|
| | 189 | p_filter->fmt_in.video.i_width, |
|---|
| | 190 | p_filter->fmt_in.video.i_height ); |
|---|
| | 191 | img_resample( p_filter->p_sys->p_rsc, &dest_pic, |
|---|
| | 192 | &p_filter->p_sys->tmp_pic ); |
|---|
| | 193 | } |
|---|
| | 194 | else |
|---|
| | 195 | { |
|---|
| | 196 | img_convert( &dest_pic, p_filter->p_sys->i_dst_ffmpeg_chroma, |
|---|
| | 197 | &src_pic, p_filter->p_sys->i_src_ffmpeg_chroma, |
|---|
| | 198 | p_filter->fmt_in.video.i_width, |
|---|
| | 199 | p_filter->fmt_in.video.i_height ); |
|---|
| | 200 | } |
|---|
| | 201 | } |
|---|
| | 202 | |
|---|
| | 203 | /***************************************************************************** |
|---|
| | 204 | * CloseFilter: free the chroma function |
|---|
| | 205 | ***************************************************************************** |
|---|
| | 206 | * This function frees the previously allocated chroma function |
|---|
| | 207 | *****************************************************************************/ |
|---|
| | 208 | void CloseFilter( vlc_object_t *p_this ) |
|---|
| | 209 | { |
|---|
| | 210 | filter_t *p_filter = (filter_t *)p_this; |
|---|
| | 211 | if( p_filter->p_sys->p_rsc ) |
|---|
| | 212 | { |
|---|
| | 213 | img_resample_close( p_filter->p_sys->p_rsc ); |
|---|
| | 214 | avpicture_free( &p_filter->p_sys->tmp_pic ); |
|---|
| | 215 | } |
|---|
| | 216 | free( p_filter->p_sys ); |
|---|
| | 217 | } |
|---|