/***************************************************************************** * Render: display previously rendered output ***************************************************************************** * This function sends the currently rendered image to Crop image, waits * until it is displayed and switches the two rendering buffers, preparing next * frame. *****************************************************************************/ static void Render( vout_thread_t *p_vout, picture_t *p_pic ) { picture_t *p_outpic = NULL; int i_plane; if( p_vout->p_sys->b_changed ) { return; } while( ( p_outpic = vout_CreatePicture( p_vout->p_sys->p_vout, 0, 0, 0 ) ) == NULL ) { if( !vlc_object_alive (p_vout) || p_vout->b_error ) { vout_DestroyPicture( p_vout->p_sys->p_vout, p_outpic ); return; } msleep( VOUT_OUTMEM_SLEEP ); } p_outpic->date = p_pic->date; vout_LinkPicture( p_vout->p_sys->p_vout, p_outpic ); for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ ) { uint8_t *p_in, *p_out, *p_out_end; int i_in_pitch = p_pic->p[i_plane].i_pitch; const int i_out_pitch = p_outpic->p[i_plane].i_pitch; const int i_copy_pitch = p_outpic->p[i_plane].i_visible_pitch; p_in = p_pic->p[i_plane].p_pixels /* Skip the right amount of lines */ + i_in_pitch * ( p_pic->p[i_plane].i_visible_lines * p_vout->p_sys->i_y / p_vout->output.i_height ) /* Skip the right amount of columns */ + i_in_pitch * p_vout->p_sys->i_x / p_vout->output.i_width; p_out = p_outpic->p[i_plane].p_pixels; p_out_end = p_out + i_out_pitch * p_outpic->p[i_plane].i_visible_lines; while( p_out < p_out_end ) { vlc_memcpy( p_out, p_in, i_copy_pitch ); p_in += i_in_pitch; p_out += i_out_pitch; } } vout_UnlinkPicture( p_vout->p_sys->p_vout, p_outpic ); vout_DisplayPicture( p_vout->p_sys->p_vout, p_outpic ); /* The source image may still be in the cache ... parse it! */ vlc_mutex_lock( &p_vout->p_sys->lock ); if( p_vout->p_sys->b_autocrop ) UpdateStats( p_vout, p_pic ); vlc_mutex_unlock( &p_vout->p_sys->lock ); }
/***************************************************************************** * Render: displays previously rendered output ***************************************************************************** * This function send the currently rendered image to Clone image, waits * until it is displayed and switch the two rendering buffers, preparing next * frame. *****************************************************************************/ static void Render( vout_thread_t *p_vout, picture_t *p_pic ) { picture_t *p_outpic = NULL; int i_vout, i_plane; for( i_vout = 0; i_vout < p_vout->p_sys->i_clones; i_vout++ ) { while( ( p_outpic = vout_CreatePicture( p_vout->p_sys->pp_vout[ i_vout ], 0, 0, 0 ) ) == NULL ) { if( p_vout->b_die || p_vout->b_error ) { vout_DestroyPicture( p_vout->p_sys->pp_vout[ i_vout ], p_outpic ); return; } msleep( VOUT_OUTMEM_SLEEP ); } vout_DatePicture( p_vout->p_sys->pp_vout[ i_vout ], p_outpic, p_pic->date ); vout_LinkPicture( p_vout->p_sys->pp_vout[ i_vout ], p_outpic ); for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ ) { uint8_t *p_in, *p_in_end, *p_out; int i_in_pitch = p_pic->p[i_plane].i_pitch; const int i_out_pitch = p_outpic->p[i_plane].i_pitch; const int i_copy_pitch = p_outpic->p[i_plane].i_visible_pitch; p_in = p_pic->p[i_plane].p_pixels; p_out = p_outpic->p[i_plane].p_pixels; if( i_in_pitch == i_copy_pitch && i_out_pitch == i_copy_pitch ) { p_vout->p_vlc->pf_memcpy( p_out, p_in, i_in_pitch * p_outpic->p[i_plane].i_visible_lines ); } else { p_in_end = p_in + i_in_pitch * p_outpic->p[i_plane].i_visible_lines; while( p_in < p_in_end ) { p_vout->p_vlc->pf_memcpy( p_out, p_in, i_copy_pitch ); p_in += i_in_pitch; p_out += i_out_pitch; } } } vout_UnlinkPicture( p_vout->p_sys->pp_vout[ i_vout ], p_outpic ); vout_DisplayPicture( p_vout->p_sys->pp_vout[ i_vout ], p_outpic ); } }
/***************************************************************************** * Render: displays previously rendered output ***************************************************************************** * This function send the currently rendered image to the internal opencv * filter for processing. *****************************************************************************/ static void Render( vout_thread_t *p_vout, picture_t *p_pic ) { picture_t *p_outpic = NULL; clock_t start, finish; double duration; while( ( p_outpic = vout_CreatePicture( p_vout->p_sys->p_vout, 0, 0, 0 ) ) == NULL ) { if( !vlc_object_alive (p_vout) || p_vout->b_error ) { return; } msleep( VOUT_OUTMEM_SLEEP ); } vout_LinkPicture( p_vout->p_sys->p_vout, p_outpic ); start = clock(); if (p_vout->p_sys->i_wrapper_output == VINPUT) //output = input video { //This copy is a bit unfortunate but image_Convert can't write into an existing image so it is better to copy the //(say) 16bit YUV image here than a 32bit RGB image somehwere else. //It is also not that expensive in time. picture_Copy( p_outpic, p_pic ); VlcPictureToIplImage( p_vout, p_pic); //pass the image to the internal opencv filter for processing if ((p_vout->p_sys->p_opencv) && (p_vout->p_sys->p_opencv->p_module)) p_vout->p_sys->p_opencv->pf_video_filter( p_vout->p_sys->p_opencv, &(p_vout->p_sys->hacked_pic)); } else //output = processed video (NONE option not working yet) { VlcPictureToIplImage( p_vout, p_pic); //pass the image to the internal opencv filter for processing if ((p_vout->p_sys->p_opencv) && (p_vout->p_sys->p_opencv->p_module)) p_vout->p_sys->p_opencv->pf_video_filter( p_vout->p_sys->p_opencv, &(p_vout->p_sys->hacked_pic)); //copy the processed image into the output image if ((p_vout->p_sys->p_proc_image) && (p_vout->p_sys->p_proc_image->i_planes > 0)) picture_Copy( p_outpic, p_vout->p_sys->p_proc_image ); } //calculate duration finish = clock(); duration = (double)(finish - start) / CLOCKS_PER_SEC; if (p_vout->p_sys->i_verbosity > VERB_WARN) msg_Dbg( p_vout, "Render took %2.4f seconds", duration ); ReleaseImages(p_vout); p_outpic->date = p_pic->date; vout_UnlinkPicture( p_vout->p_sys->p_vout, p_outpic ); vout_DisplayPicture( p_vout->p_sys->p_vout, p_outpic ); }
/***************************************************************************** * Render: render the logo onto the video *****************************************************************************/ static void Render( vout_thread_t *p_vout, picture_t *p_pic ) { vout_sys_t *p_sys = p_vout->p_sys; picture_t *p_outpic; /* This is a new frame. Get a structure from the video_output. */ while( !(p_outpic = vout_CreatePicture( p_sys->p_vout, 0, 0, 0 )) ) { if( p_vout->b_die || p_vout->b_error ) return; msleep( VOUT_OUTMEM_SLEEP ); } vout_CopyPicture( p_vout, p_outpic, p_pic ); vout_DatePicture( p_sys->p_vout, p_outpic, p_pic->date ); p_sys->p_blend->pf_video_blend( p_sys->p_blend, p_outpic, p_outpic, p_sys->p_pic, p_sys->posx, p_sys->posy, 255 ); vout_DisplayPicture( p_sys->p_vout, p_outpic ); }
/***************************************************************************** * Render: displays previously rendered output ***************************************************************************** * This function send the currently rendered image to Transform image, waits * until it is displayed and switch the two rendering buffers, preparing next * frame. *****************************************************************************/ static void Render( vout_thread_t *p_vout, picture_t *p_pic ) { picture_t *p_outpic; /* This is a new frame. Get a structure from the video_output. */ while( ( p_outpic = vout_CreatePicture( p_vout->p_sys->p_vout, 0, 0, 0 ) ) == NULL ) { if( !vlc_object_alive (p_vout) || p_vout->b_error ) { return; } msleep( VOUT_OUTMEM_SLEEP ); } p_outpic->date = p_pic->date; p_vout->p_sys->pf_filter( p_vout, p_pic, p_outpic ); vout_DisplayPicture( p_vout->p_sys->p_vout, p_outpic ); }
/***************************************************************************** * DoWork: convert a buffer ***************************************************************************** * Audio part pasted from trivial.c ****************************************************************************/ static block_t *DoWork( filter_t *p_filter, block_t *p_in_buf ) { filter_sys_t *p_sys = p_filter->p_sys; picture_t *p_outpic; int i; /* First, get a new picture */ while( ( p_outpic = vout_CreatePicture( p_sys->p_vout, 0, 0, 3 ) ) == NULL) { /* XXX: This looks like a bad idea. Don't run to me for sympathy if it * dead locks... */ if( !vlc_object_alive (p_sys->p_vout) ) return NULL; msleep( VOUT_OUTMEM_SLEEP ); } /* Blank the picture */ for( i = 0 ; i < p_outpic->i_planes ; i++ ) { memset( p_outpic->p[i].p_pixels, i > 0 ? 0x80 : 0x00, p_outpic->p[i].i_visible_lines * p_outpic->p[i].i_pitch ); } /* We can now call our visualization effects */ for( i = 0; i < p_sys->i_effect; i++ ) { #define p_effect p_sys->effect[i] if( p_effect->pf_run ) { p_effect->pf_run( p_effect, VLC_OBJECT(p_filter), p_in_buf, p_outpic ); } #undef p_effect } p_outpic->date = p_in_buf->i_pts + (p_in_buf->i_length / 2); vout_DisplayPicture( p_sys->p_vout, p_outpic ); return p_in_buf; }
/***************************************************************************** * Render: displays previously rendered output ***************************************************************************** * This function send the currently rendered image to Transform image, waits * until it is displayed and switch the two rendering buffers, preparing next * frame. *****************************************************************************/ static void Render( vout_thread_t *p_vout, picture_t *p_pic ) { picture_t *p_outpic; int i_index; /* This is a new frame. Get a structure from the video_output. */ while( ( p_outpic = vout_CreatePicture( p_vout->p_sys->p_vout, 0, 0, 0 ) ) == NULL ) { if( p_vout->b_die || p_vout->b_error ) { return; } msleep( VOUT_OUTMEM_SLEEP ); } vout_DatePicture( p_vout->p_sys->p_vout, p_outpic, p_pic->date ); vout_LinkPicture( p_vout->p_sys->p_vout, p_outpic ); switch( p_vout->p_sys->i_mode ) { case TRANSFORM_MODE_90: for( i_index = 0 ; i_index < p_pic->i_planes ; i_index++ ) { int i_pitch = p_pic->p[i_index].i_pitch; uint8_t *p_in = p_pic->p[i_index].p_pixels; uint8_t *p_out = p_outpic->p[i_index].p_pixels; uint8_t *p_out_end = p_out + p_outpic->p[i_index].i_visible_lines * p_outpic->p[i_index].i_pitch; for( ; p_out < p_out_end ; ) { uint8_t *p_line_end; p_out_end -= p_outpic->p[i_index].i_pitch - p_outpic->p[i_index].i_visible_pitch; p_line_end = p_in + p_pic->p[i_index].i_visible_lines * i_pitch; for( ; p_in < p_line_end ; ) { p_line_end -= i_pitch; *(--p_out_end) = *p_line_end; } p_in++; } } break; case TRANSFORM_MODE_180: for( i_index = 0 ; i_index < p_pic->i_planes ; i_index++ ) { uint8_t *p_in = p_pic->p[i_index].p_pixels; uint8_t *p_in_end = p_in + p_pic->p[i_index].i_visible_lines * p_pic->p[i_index].i_pitch; uint8_t *p_out = p_outpic->p[i_index].p_pixels; for( ; p_in < p_in_end ; ) { uint8_t *p_line_start = p_in_end - p_pic->p[i_index].i_pitch; p_in_end -= p_pic->p[i_index].i_pitch - p_pic->p[i_index].i_visible_pitch; for( ; p_line_start < p_in_end ; ) { *p_out++ = *(--p_in_end); } p_out += p_outpic->p[i_index].i_pitch - p_outpic->p[i_index].i_visible_pitch; } } break; case TRANSFORM_MODE_270: for( i_index = 0 ; i_index < p_pic->i_planes ; i_index++ ) { int i_pitch = p_pic->p[i_index].i_pitch; uint8_t *p_in = p_pic->p[i_index].p_pixels; uint8_t *p_out = p_outpic->p[i_index].p_pixels; uint8_t *p_out_end = p_out + p_outpic->p[i_index].i_visible_lines * p_outpic->p[i_index].i_pitch; for( ; p_out < p_out_end ; ) { uint8_t *p_in_end; p_in_end = p_in + p_pic->p[i_index].i_visible_lines * i_pitch; for( ; p_in < p_in_end ; ) { p_in_end -= i_pitch; *p_out++ = *p_in_end; } p_out += p_outpic->p[i_index].i_pitch - p_outpic->p[i_index].i_visible_pitch; p_in++; } } break; case TRANSFORM_MODE_HFLIP: for( i_index = 0 ; i_index < p_pic->i_planes ; i_index++ ) { uint8_t *p_in = p_pic->p[i_index].p_pixels; uint8_t *p_in_end = p_in + p_pic->p[i_index].i_visible_lines * p_pic->p[i_index].i_pitch; uint8_t *p_out = p_outpic->p[i_index].p_pixels; for( ; p_in < p_in_end ; ) { p_in_end -= p_pic->p[i_index].i_pitch; p_vout->p_vlc->pf_memcpy( p_out, p_in_end, p_pic->p[i_index].i_visible_pitch ); p_out += p_pic->p[i_index].i_pitch; } } break; case TRANSFORM_MODE_VFLIP: for( i_index = 0 ; i_index < p_pic->i_planes ; i_index++ ) { uint8_t *p_in = p_pic->p[i_index].p_pixels; uint8_t *p_in_end = p_in + p_pic->p[i_index].i_visible_lines * p_pic->p[i_index].i_pitch; uint8_t *p_out = p_outpic->p[i_index].p_pixels; for( ; p_in < p_in_end ; ) { uint8_t *p_line_end = p_in + p_pic->p[i_index].i_visible_pitch; for( ; p_in < p_line_end ; ) { *p_out++ = *(--p_line_end); } p_in += p_pic->p[i_index].i_pitch; } } break; default: break; } vout_UnlinkPicture( p_vout->p_sys->p_vout, p_outpic ); vout_DisplayPicture( p_vout->p_sys->p_vout, p_outpic ); }
/***************************************************************************** * Render: displays previously rendered output ***************************************************************************** * This function send the currently rendered image to Wall image, waits * until it is displayed and switch the two rendering buffers, preparing next * frame. *****************************************************************************/ static void Render( vout_thread_t *p_vout, picture_t *p_pic ) { picture_t *p_outpic = NULL; int i_col, i_row, i_vout, i_plane; int pi_left_skip[VOUT_MAX_PLANES], pi_top_skip[VOUT_MAX_PLANES]; i_vout = 0; for( i_row = 0; i_row < p_vout->p_sys->i_row; i_row++ ) { for( i_col = 0; i_col < p_vout->p_sys->i_col; i_col++ ) { for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ ) { pi_left_skip[i_plane] = p_vout->p_sys->pp_vout[ i_vout ].i_left * p_pic->p[ i_plane ].i_pitch / p_vout->output.i_width; pi_top_skip[i_plane] = (p_vout->p_sys->pp_vout[ i_vout ].i_top * p_pic->p[ i_plane ].i_lines / p_vout->output.i_height)*p_pic->p[i_plane].i_pitch; } if( !p_vout->p_sys->pp_vout[ i_vout ].b_active ) { i_vout++; continue; } while( ( p_outpic = vout_CreatePicture( p_vout->p_sys->pp_vout[ i_vout ].p_vout, 0, 0, 0 ) ) == NULL ) { if( p_vout->b_die || p_vout->b_error ) { vout_DestroyPicture( p_vout->p_sys->pp_vout[ i_vout ].p_vout, p_outpic ); return; } msleep( VOUT_OUTMEM_SLEEP ); } vout_DatePicture( p_vout->p_sys->pp_vout[ i_vout ].p_vout, p_outpic, p_pic->date ); vout_LinkPicture( p_vout->p_sys->pp_vout[ i_vout ].p_vout, p_outpic ); for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ ) { uint8_t *p_in, *p_in_end, *p_out; int i_in_pitch = p_pic->p[i_plane].i_pitch; int i_out_pitch = p_outpic->p[i_plane].i_pitch; int i_copy_pitch = p_outpic->p[i_plane].i_visible_pitch; p_in = p_pic->p[i_plane].p_pixels + pi_top_skip[i_plane] + pi_left_skip[i_plane]; p_in_end = p_in + p_outpic->p[i_plane].i_visible_lines * p_pic->p[i_plane].i_pitch; p_out = p_outpic->p[i_plane].p_pixels; while( p_in < p_in_end ) { p_vout->p_vlc->pf_memcpy( p_out, p_in, i_copy_pitch ); p_in += i_in_pitch; p_out += i_out_pitch; } // pi_left_skip[i_plane] += i_copy_pitch; } vout_UnlinkPicture( p_vout->p_sys->pp_vout[ i_vout ].p_vout, p_outpic ); vout_DisplayPicture( p_vout->p_sys->pp_vout[ i_vout ].p_vout, p_outpic ); i_vout++; } /* for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ ) */ /* { */ /* pi_top_skip[i_plane] += p_vout->p_sys->pp_vout[ i_vout ].i_height */ /* * p_pic->p[i_plane].i_visible_lines */ /* / p_vout->output.i_height */ /* * p_pic->p[i_plane].i_pitch; */ /* } */ } }
/***************************************************************************** * Thread: *****************************************************************************/ static void Thread( vlc_object_t *p_this ) { goom_thread_t *p_thread = (goom_thread_t*)p_this; vlc_value_t width, height, speed; audio_date_t i_pts; int16_t p_data[2][512]; int i_data = 0, i_count = 0; PluginInfo *p_plugin_info; var_Get( p_this, "goom-width", &width ); var_Get( p_this, "goom-height", &height ); var_Create( p_thread, "goom-speed", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT ); var_Get( p_thread, "goom-speed", &speed ); speed.i_int = MAX_SPEED - speed.i_int; if( speed.i_int < 0 ) speed.i_int = 0; p_plugin_info = goom_init( width.i_int, height.i_int ); while( !p_thread->b_die ) { uint32_t *plane; picture_t *p_pic; /* goom_update is damn slow, so just copy data and release the lock */ vlc_mutex_lock( &p_thread->lock ); if( FillBuffer( (int16_t *)p_data, &i_data, &i_pts, &p_thread->date, p_thread ) != VLC_SUCCESS ) vlc_cond_wait( &p_thread->wait, &p_thread->lock ); vlc_mutex_unlock( &p_thread->lock ); /* Speed selection */ if( speed.i_int && (++i_count % (speed.i_int+1)) ) continue; /* Frame dropping if necessary */ if( aout_DateGet( &i_pts ) + GOOM_DELAY <= mdate() ) continue; plane = goom_update( p_plugin_info, p_data, 0, 0.0, p_thread->psz_title, NULL ); if( p_thread->psz_title ) { free( p_thread->psz_title ); p_thread->psz_title = NULL; } while( !( p_pic = vout_CreatePicture( p_thread->p_vout, 0, 0, 0 ) ) && !p_thread->b_die ) { msleep( VOUT_OUTMEM_SLEEP ); } if( p_pic == NULL ) break; memcpy( p_pic->p[0].p_pixels, plane, width.i_int * height.i_int * 4 ); vout_DatePicture( p_thread->p_vout, p_pic, aout_DateGet( &i_pts ) + GOOM_DELAY ); vout_DisplayPicture( p_thread->p_vout, p_pic ); } goom_close( p_plugin_info ); }