| 101 | | /***************************************************************************** |
|---|
| 102 | | * vout_sys_t: adjust video output method descriptor |
|---|
| 103 | | ***************************************************************************** |
|---|
| 104 | | * This structure is part of the video output thread descriptor. |
|---|
| 105 | | * It describes the adjust specific properties of an output thread. |
|---|
| 106 | | *****************************************************************************/ |
|---|
| 107 | | struct vout_sys_t |
|---|
| | 97 | static const char *ppsz_filter_options[] = { |
|---|
| | 98 | "contrast", "brightness", "hue", "saturation", "gamma", |
|---|
| | 99 | "brightness-threshold", NULL |
|---|
| | 100 | }; |
|---|
| | 101 | |
|---|
| | 102 | /***************************************************************************** |
|---|
| | 103 | * filter_sys_t: adjust filter method descriptor |
|---|
| | 104 | *****************************************************************************/ |
|---|
| | 105 | struct filter_sys_t |
|---|
| 132 | | vout_thread_t *p_vout = (vout_thread_t *)p_this; |
|---|
| | 121 | filter_t *p_filter = (filter_t *)p_this; |
|---|
| | 122 | |
|---|
| | 123 | /* XXX: we might need to add/remove some FOURCCs ... */ |
|---|
| | 124 | if( p_filter->fmt_in.video.i_chroma != VLC_FOURCC('I','4','2','0') |
|---|
| | 125 | && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('I','Y','U','V') |
|---|
| | 126 | && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('J','4','2','0') |
|---|
| | 127 | && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('Y','V','1','2') |
|---|
| | 128 | && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('I','U','Y','V') |
|---|
| | 129 | && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('U','Y','V','Y') |
|---|
| | 130 | && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('U','Y','N','V') |
|---|
| | 131 | && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('Y','4','2','2') |
|---|
| | 132 | && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('c','y','u','v') |
|---|
| | 133 | && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('Y','U','Y','2') |
|---|
| | 134 | && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('Y','U','N','V') |
|---|
| | 135 | && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('Y','V','Y','U') |
|---|
| | 136 | && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('I','4','1','1') |
|---|
| | 137 | && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('I','4','1','0') |
|---|
| | 138 | && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('Y','V','U','9') |
|---|
| | 139 | && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('Y','M','G','A') |
|---|
| | 140 | && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('I','4','2','2') |
|---|
| | 141 | && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('J','4','2','2') |
|---|
| | 142 | && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('I','4','4','4') |
|---|
| | 143 | && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('J','4','4','4') |
|---|
| | 144 | && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('Y','U','V','P') |
|---|
| | 145 | && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('Y','U','V','A') ) |
|---|
| | 146 | { |
|---|
| | 147 | msg_Err( p_filter, "Unsupported input chroma (%4s)", |
|---|
| | 148 | (char*)&(p_filter->fmt_in.video.i_chroma) ); |
|---|
| | 149 | return VLC_EGENERIC; |
|---|
| | 150 | } |
|---|
| | 151 | |
|---|
| | 152 | if( p_filter->fmt_in.video.i_chroma != p_filter->fmt_out.video.i_chroma ) |
|---|
| | 153 | { |
|---|
| | 154 | msg_Err( p_filter, "Input and output chromas don't match" ); |
|---|
| | 155 | return VLC_EGENERIC; |
|---|
| | 156 | } |
|---|
| 142 | | p_vout->pf_init = Init; |
|---|
| 143 | | p_vout->pf_end = End; |
|---|
| 144 | | p_vout->pf_manage = NULL; |
|---|
| 145 | | p_vout->pf_render = Render; |
|---|
| 146 | | p_vout->pf_display = NULL; |
|---|
| 147 | | p_vout->pf_control = Control; |
|---|
| 148 | | |
|---|
| 149 | | var_Create( p_vout, "contrast", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT ); |
|---|
| 150 | | var_Create( p_vout, "brightness", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT ); |
|---|
| 151 | | var_Create( p_vout, "hue", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); |
|---|
| 152 | | var_Create( p_vout, "saturation", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT ); |
|---|
| 153 | | var_Create( p_vout, "gamma", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT ); |
|---|
| 154 | | var_Create( p_vout, "brightness-threshold", |
|---|
| | 166 | p_filter->pf_video_filter = Filter; |
|---|
| | 167 | |
|---|
| | 168 | /* needed to get options passed in transcode using the |
|---|
| | 169 | * adjust{name=value} syntax */ |
|---|
| | 170 | sout_CfgParse( p_filter, "", ppsz_filter_options, |
|---|
| | 171 | p_filter->p_cfg ); |
|---|
| | 172 | |
|---|
| | 173 | var_Create( p_filter, "contrast", |
|---|
| | 174 | VLC_VAR_FLOAT | VLC_VAR_DOINHERIT ); |
|---|
| | 175 | var_Create( p_filter, "brightness", |
|---|
| | 176 | VLC_VAR_FLOAT | VLC_VAR_DOINHERIT ); |
|---|
| | 177 | var_Create( p_filter, "hue", |
|---|
| | 178 | VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); |
|---|
| | 179 | var_Create( p_filter, "saturation", |
|---|
| | 180 | VLC_VAR_FLOAT | VLC_VAR_DOINHERIT ); |
|---|
| | 181 | var_Create( p_filter, "gamma", |
|---|
| | 182 | VLC_VAR_FLOAT | VLC_VAR_DOINHERIT ); |
|---|
| | 183 | var_Create( p_filter, "brightness-threshold", |
|---|
| 158 | | } |
|---|
| 159 | | |
|---|
| 160 | | /***************************************************************************** |
|---|
| 161 | | * Init: initialize adjust video thread output method |
|---|
| 162 | | *****************************************************************************/ |
|---|
| 163 | | static int Init( vout_thread_t *p_vout ) |
|---|
| 164 | | { |
|---|
| 165 | | int i_index; |
|---|
| 166 | | picture_t *p_pic; |
|---|
| 167 | | video_format_t fmt = {0}; |
|---|
| 168 | | |
|---|
| 169 | | I_OUTPUTPICTURES = 0; |
|---|
| 170 | | |
|---|
| 171 | | /* Initialize the output structure */ |
|---|
| 172 | | p_vout->output.i_chroma = p_vout->render.i_chroma; |
|---|
| 173 | | p_vout->output.i_width = p_vout->render.i_width; |
|---|
| 174 | | p_vout->output.i_height = p_vout->render.i_height; |
|---|
| 175 | | p_vout->output.i_aspect = p_vout->render.i_aspect; |
|---|
| 176 | | |
|---|
| 177 | | fmt.i_width = fmt.i_visible_width = p_vout->render.i_width; |
|---|
| 178 | | fmt.i_height = fmt.i_visible_height = p_vout->render.i_height; |
|---|
| 179 | | fmt.i_x_offset = fmt.i_y_offset = 0; |
|---|
| 180 | | fmt.i_chroma = p_vout->render.i_chroma; |
|---|
| 181 | | fmt.i_aspect = p_vout->render.i_aspect; |
|---|
| 182 | | fmt.i_sar_num = p_vout->render.i_aspect * fmt.i_height / fmt.i_width; |
|---|
| 183 | | fmt.i_sar_den = VOUT_ASPECT_FACTOR; |
|---|
| 184 | | |
|---|
| 185 | | /* Try to open the real video output */ |
|---|
| 186 | | msg_Dbg( p_vout, "spawning the real video output" ); |
|---|
| 187 | | |
|---|
| 188 | | p_vout->p_sys->p_vout = vout_Create( p_vout, &fmt ); |
|---|
| 189 | | |
|---|
| 190 | | /* Everything failed */ |
|---|
| 191 | | if( p_vout->p_sys->p_vout == NULL ) |
|---|
| 192 | | { |
|---|
| 193 | | msg_Err( p_vout, "can't open vout, aborting" ); |
|---|
| 194 | | return VLC_EGENERIC; |
|---|
| 195 | | } |
|---|
| 196 | | |
|---|
| 197 | | ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES ); |
|---|
| 198 | | |
|---|
| 199 | | ADD_CALLBACKS( p_vout->p_sys->p_vout, SendEvents ); |
|---|
| 200 | | |
|---|
| 201 | | ADD_PARENT_CALLBACKS( SendEventsToChild ); |
|---|
| 202 | | |
|---|
| 203 | | return VLC_SUCCESS; |
|---|
| 204 | | } |
|---|
| 205 | | |
|---|
| 206 | | /***************************************************************************** |
|---|
| 207 | | * End: terminate adjust video thread output method |
|---|
| 208 | | *****************************************************************************/ |
|---|
| 209 | | static void End( vout_thread_t *p_vout ) |
|---|
| 210 | | { |
|---|
| 211 | | int i_index; |
|---|
| 212 | | |
|---|
| 213 | | /* Free the fake output buffers we allocated */ |
|---|
| 214 | | for( i_index = I_OUTPUTPICTURES ; i_index ; ) |
|---|
| 215 | | { |
|---|
| 216 | | i_index--; |
|---|
| 217 | | free( PP_OUTPUTPICTURE[ i_index ]->p_data_orig ); |
|---|
| 218 | | } |
|---|
| 266 | | /* This is a new frame. Get a structure from the video_output. */ |
|---|
| 267 | | while( ( p_outpic = vout_CreatePicture( p_vout->p_sys->p_vout, 0, 0, 0 ) ) |
|---|
| 268 | | == NULL ) |
|---|
| 269 | | { |
|---|
| 270 | | if( p_vout->b_die || p_vout->b_error ) |
|---|
| 271 | | { |
|---|
| 272 | | return; |
|---|
| 273 | | } |
|---|
| 274 | | msleep( VOUT_OUTMEM_SLEEP ); |
|---|
| 275 | | } |
|---|
| 276 | | |
|---|
| 277 | | vout_DatePicture( p_vout->p_sys->p_vout, p_outpic, p_pic->date ); |
|---|
| 278 | | vout_LinkPicture( p_vout->p_sys->p_vout, p_outpic ); |
|---|
| | 224 | if( !p_pic ) return NULL; |
|---|
| | 225 | |
|---|
| | 226 | p_outpic = p_filter->pf_vout_buffer_new( p_filter ); |
|---|
| | 227 | if( !p_outpic ) |
|---|
| | 228 | { |
|---|
| | 229 | msg_Warn( p_filter, "can't get output picture" ); |
|---|
| | 230 | if( p_pic->pf_release ) |
|---|
| | 231 | p_pic->pf_release( p_pic ); |
|---|
| | 232 | return NULL; |
|---|
| | 233 | } |
|---|
| 414 | | p_in += p_pic->p[1].i_pitch - p_pic->p[1].i_visible_pitch; |
|---|
| 415 | | p_in_v += p_pic->p[2].i_pitch - p_pic->p[2].i_visible_pitch; |
|---|
| 416 | | p_out += p_outpic->p[1].i_pitch - p_outpic->p[1].i_visible_pitch; |
|---|
| 417 | | p_out_v += p_outpic->p[2].i_pitch - p_outpic->p[2].i_visible_pitch; |
|---|
| | 373 | p_in += p_pic->p[U_PLANE].i_pitch |
|---|
| | 374 | - p_pic->p[U_PLANE].i_visible_pitch; |
|---|
| | 375 | p_in_v += p_pic->p[V_PLANE].i_pitch |
|---|
| | 376 | - p_pic->p[V_PLANE].i_visible_pitch; |
|---|
| | 377 | p_out += p_outpic->p[U_PLANE].i_pitch |
|---|
| | 378 | - p_outpic->p[U_PLANE].i_visible_pitch; |
|---|
| | 379 | p_out_v += p_outpic->p[V_PLANE].i_pitch |
|---|
| | 380 | - p_outpic->p[V_PLANE].i_visible_pitch; |
|---|
| 449 | | p_in += p_pic->p[1].i_pitch - p_pic->p[1].i_visible_pitch; |
|---|
| 450 | | p_in_v += p_pic->p[2].i_pitch - p_pic->p[2].i_visible_pitch; |
|---|
| 451 | | p_out += p_outpic->p[1].i_pitch - p_outpic->p[1].i_visible_pitch; |
|---|
| 452 | | p_out_v += p_outpic->p[2].i_pitch - p_outpic->p[2].i_visible_pitch; |
|---|
| 453 | | } |
|---|
| 454 | | } |
|---|
| 455 | | |
|---|
| 456 | | vout_UnlinkPicture( p_vout->p_sys->p_vout, p_outpic ); |
|---|
| 457 | | |
|---|
| 458 | | vout_DisplayPicture( p_vout->p_sys->p_vout, p_outpic ); |
|---|
| | 412 | p_in += p_pic->p[U_PLANE].i_pitch |
|---|
| | 413 | - p_pic->p[U_PLANE].i_visible_pitch; |
|---|
| | 414 | p_in_v += p_pic->p[V_PLANE].i_pitch |
|---|
| | 415 | - p_pic->p[V_PLANE].i_visible_pitch; |
|---|
| | 416 | p_out += p_outpic->p[U_PLANE].i_pitch |
|---|
| | 417 | - p_outpic->p[U_PLANE].i_visible_pitch; |
|---|
| | 418 | p_out_v += p_outpic->p[V_PLANE].i_pitch |
|---|
| | 419 | - p_outpic->p[V_PLANE].i_visible_pitch; |
|---|
| | 420 | } |
|---|
| | 421 | } |
|---|
| | 422 | |
|---|
| | 423 | p_outpic->date = p_pic->date; |
|---|
| | 424 | p_outpic->b_force = p_pic->b_force; |
|---|
| | 425 | p_outpic->i_nb_fields = p_pic->i_nb_fields; |
|---|
| | 426 | p_outpic->b_progressive = p_pic->b_progressive; |
|---|
| | 427 | p_outpic->b_top_field_first = p_pic->b_top_field_first; |
|---|
| | 428 | |
|---|
| | 429 | p_pic->pf_release( p_pic ); |
|---|
| | 430 | |
|---|
| | 431 | return p_outpic; |
|---|
| 460 | | |
|---|
| 461 | | /***************************************************************************** |
|---|
| 462 | | * SendEvents: forward mouse and keyboard events to the parent p_vout |
|---|
| 463 | | *****************************************************************************/ |
|---|
| 464 | | static int SendEvents( vlc_object_t *p_this, char const *psz_var, |
|---|
| 465 | | vlc_value_t oldval, vlc_value_t newval, void *p_data ) |
|---|
| 466 | | { |
|---|
| 467 | | var_Set( (vlc_object_t *)p_data, psz_var, newval ); |
|---|
| 468 | | |
|---|
| 469 | | return VLC_SUCCESS; |
|---|
| 470 | | } |
|---|
| 471 | | |
|---|
| 472 | | /***************************************************************************** |
|---|
| 473 | | * SendEventsToChild: forward events to the child/children vout |
|---|
| 474 | | *****************************************************************************/ |
|---|
| 475 | | static int SendEventsToChild( vlc_object_t *p_this, char const *psz_var, |
|---|
| 476 | | vlc_value_t oldval, vlc_value_t newval, void *p_data ) |
|---|
| 477 | | { |
|---|
| 478 | | vout_thread_t *p_vout = (vout_thread_t *)p_this; |
|---|
| 479 | | var_Set( p_vout->p_sys->p_vout, psz_var, newval ); |
|---|
| 480 | | return VLC_SUCCESS; |
|---|
| 481 | | } |
|---|