My Video Player
 All Data Structures Files Functions Variables Macros Pages
video_player.c
Go to the documentation of this file.
1 /*
2  Author : Milind G. Padalkar ( milind.padalkar@gamil.com )
3  Purpose : a. Successful use of most commonly used OpenCV functions
4  b. Developing a simple test application that can be used for displaying a video
5  Frist Created : 15-09-2010
6  Last Modified : 28-02-2011
7 */
8 
27 #include<highgui.h>
28 #include<cv.h>
29 #include<stdio.h>
30 #include<string.h>
31 
32 //dimensions of vairous sub-images
34 
37 #define sldr_btn_width 15
38 
40 
43 #define sldr_height 10
44 
46 
49 #define ctrl_pnl_height 200
50 
52 
56 #define p_width 840
57 
59 
62 #define scrn_height 480
63 
65 
69 #define p_height ( scrn_height + sldr_height + ctrl_pnl_height )
70 
71 
72 //alias for source of callbacks
74 
77 #define MOUSE_CALLBACK 0
78 
80 
83 #define OTHER_CALLS 1
84 
86 
89 #define EDIT_CALLS 2
90 
91 //alies for type of text field
93 
96 #define STATIC_TEXT 0
97 
99 
102 #define EDIT_TEXT 1
103 
104 //alies for button type
106 
109 #define PLAY_BTN 0
110 
112 
115 #define PAUSE_BTN 1
116 
118 
121 #define STOP_BTN 2
122 
124 
127 #define STEPUP_BTN 3
128 
130 
133 #define STEPDOWN_BTN 4
134 
135 //alies for button state
137 
140 #define BTN_ACTIVE 0
141 
143 
146 #define BTN_INACTIVE 1
147 
149 
152 typedef struct{
153  int x1;
154  int y1;
155  int x2;
156  int y2;
157 } Field_Area;
158 
159 
160 //Global Variables
162 
166 CvCapture *vid;
167 
169 
174 IplImage *player;
175 
177 
188 IplImage *pnl;
189 
191 
202 IplImage *slider;
203 
205 
216 IplImage *sldr_btn;
217 
219 
230 IplImage *sldr_val;
231 
233 
244 IplImage *oslider;
245 
247 
258 IplImage *frame_area;
259 
261 
266 IplImage *frame;
267 
269 
274 IplImage *old_frame;
275 
277 
281 IplImage *cur_frame_no;
282 
284 
289 IplImage *fps_edit;
290 
292 
297 IplImage *four_cc_edit;
298 
300 
305 IplImage *status_edit;
306 
308 
313 IplImage *numFrames;
314 
316 
321 IplImage *step_edit;
322 
323 
325 
330 IplImage *play_pause_btn;
331 
333 
338 IplImage *stop_btn;
339 
341 
346 IplImage *stepup_btn;
347 
349 
354 IplImage *stepdown_btn;
355 
356 
359 
361 
364 int step_val = 1;
365 
366 char line[ 20 ];
367 
369 
372 char edit_text[ 20 ];
373 
374 char status_line[ 15 ];
375 char four_cc_str[4];
376 
378 
381 double fps;
382 
384 
387 long fourcc_l;
389 
392 char *fourcc;
393 
395 
400 int blink_count = 0;
401 
402 int blink_max = 5;
403 char blink_char = '|' ;
404 
413 
414 //Controllers
415 bool sldr_moving = false;
416 bool playing = false;
417 bool processing = false;
418 bool typing_step = false;
419 bool blinking = false;
420 
421 
422 //Colors
423 CvScalar red = cvScalar( 0, 0, 255 );
424 CvScalar green = cvScalar( 0, 255, 0 );
425 CvScalar blue = cvScalar( 255, 0, 0 );
426 CvScalar black = cvScalar( 0, 0, 0 );
427 CvScalar white = cvScalar( 255, 255, 255 );
428 CvScalar light_yellow = cvScalar( 242, 255, 255 );
429 CvScalar yellow = cvScalar( 0, 255, 255 );
430 CvScalar gray = cvScalar( 242, 242, 242 );
431 CvScalar orange = cvScalar( 0, 242, 255 );
432 CvScalar voilet = cvScalar( 255, 0, 127 );
433 CvScalar brown = cvScalar( 0, 0, 127 );
434 
435 //Font Parameters
436 CvFont font;
437 CvFont font_italic;
438 CvFont font_bold;
440 int font_face_italic = CV_FONT_HERSHEY_SIMPLEX|CV_FONT_ITALIC;
441 int font_face = CV_FONT_HERSHEY_SIMPLEX;
442 double hscale = 0.5;
443 double vscale = 0.5;
444 double shear = 0;
445 int thickness = 1;
446 int line_type = 8;
447 
448 //Various
450 void resetField( IplImage* image, int text_type );
451 
453 void initialize_pnl( char* filename );
454 
456 int moveSlider( int pos, int call_from );
457 
459 void my_mouse_callback( int event, int x, int y, int flags, void* param );
460 
462 void getButton( IplImage* image, int btn_type, int btn_state );
463 
465 void getSpectrumVert( IplImage* image, CvScalar color1, CvScalar color2 );
466 
468 void getSpectrumHorz( IplImage* image, CvScalar color1, CvScalar color2 );
469 
471 void draw_triangle( IplImage* image, CvScalar color );
472 
474 void draw_square( IplImage* image, CvScalar color );
475 
477 void draw_pause( IplImage* image, CvScalar color );
478 
480 void draw_stepup( IplImage* image, CvScalar color );
481 
483 void draw_stepdown( IplImage* image, CvScalar color );
484 
486 void fill_color( IplImage* image, CvScalar color );
487 
489 void change_status();
490 
492 void type_step( char c, int frame_val );
493 
495 void resetAllEdits();
496 
497 /*
498 width 840 (display)
499 height 480(display) + 10(slider) + 200(ctrl pnl)
500 */
501 //Main function
502 //argv[1] : video-file path
505 int main( int argc, char** argv ){
506 
507  //Initialize the font
510  cvInitFont( &font, font_face, hscale, vscale, shear, thickness, line_type );
512  cvInitFont( &font_bold, font_face, hscale, vscale, shear, thickness+1, line_type );
514 
515  //Create the player image
518  player = cvCreateImage( cvSize( p_width, p_height ), IPL_DEPTH_8U, 3 );
519 
520  //Create Control Pannel
523  pnl = cvCreateImageHeader( cvSize( p_width, ctrl_pnl_height ), IPL_DEPTH_8U, 3 );
524  pnl->origin = player->origin;
525  pnl->widthStep = player->widthStep;
526  pnl->imageData = player->imageData + ( p_height - ctrl_pnl_height )*player->widthStep;
527  for( int row=0; row<pnl->height; row++ ){
528  uchar* ptr = ( uchar* )( pnl->imageData + row*pnl->widthStep );
529  for( int col=0; col<pnl->width; col++ ){
530  ptr[ col*pnl->nChannels + 0 ] = 226;
531  ptr[ col*pnl->nChannels + 1 ] = 235;
532  ptr[ col*pnl->nChannels + 2 ] = 240;
533  }
534  }
535  //Add text & buttons
538  initialize_pnl( argv[1] );
539 
540  //create custom slider (non-opencv)
543  slider = cvCreateImageHeader( cvSize( p_width, 10 ), IPL_DEPTH_8U, 3 );
544  slider->origin = player->origin;
545  slider->widthStep = player->widthStep;
546  slider->imageData = player->imageData + ( p_height - sldr_height - ctrl_pnl_height )*player->widthStep;
547  for( int row=0; row<slider->height; row++ ){
548  uchar* ptr = ( uchar* )( slider->imageData + row*slider->widthStep );
549  for( int col=0; col<slider->width; col++ ){
550  ptr[ col*slider->nChannels + 0 ] = 94;
551  ptr[ col*slider->nChannels + 1 ] = 118;
552  ptr[ col*slider->nChannels + 2 ] = 254;
553  }
554  }
555  oslider = cvCloneImage( slider );
556  sldr_btn = cvCreateImage( cvSize( 15, sldr_height ), IPL_DEPTH_8U, 3 );
557  for( int row=0; row<sldr_btn->height; row++ ){
558  uchar* ptr = ( uchar* )( sldr_btn->imageData + row*sldr_btn->widthStep );
559  for( int col=0; col<sldr_btn->width; col++ ){
560  ptr[ col*slider->nChannels + 0 ] = 100;
561  ptr[ col*slider->nChannels + 1 ] = 150;
562  ptr[ col*slider->nChannels + 2 ] = 100;
563  }
564  }
565  sldr_val = cvCreateImageHeader( cvSize( sldr_btn_width, sldr_height ), IPL_DEPTH_8U, 3 );
566  sldr_val->origin = slider->origin;
567  sldr_val->widthStep = slider->widthStep;
568  sldr_val->imageData = slider->imageData;
569  cvCopy( sldr_btn, sldr_val );
570 
571  //display window
575  cvNamedWindow( "Video Player", CV_WINDOW_AUTOSIZE );
576 
577  //install mouse callback
581  cvSetMouseCallback(
582  "Video Player",
584  ( void* )NULL
585  );
586 
587 
588  //load the video
592  vid = cvCaptureFromFile( argv[1] );
593  //check the video
594  if( !vid ){
595  printf( "Error loading the video file. Either missing file or codec not installed\n" );
596  return( 1 );
597  }
598  frame_area = cvCreateImageHeader( cvSize( p_width, scrn_height ), IPL_DEPTH_8U, 3 );
599  frame_area->origin = player->origin;
600  frame_area->widthStep = player->widthStep;
601  frame_area->imageData = player->imageData;
602  fps = cvGetCaptureProperty( vid, CV_CAP_PROP_FPS );
603  sldr_start = cvGetCaptureProperty( vid, CV_CAP_PROP_POS_FRAMES );
604  fourcc_l = cvGetCaptureProperty( vid, CV_CAP_PROP_FOURCC );
605  fourcc = ( char* )( &fourcc_l );
606  sprintf( four_cc_str, "%c%c%c%c", fourcc[0], fourcc[1], fourcc[2], fourcc[3] );
607  //printf( "FPS : %f\n", fps );
608  sldr_maxval = cvGetCaptureProperty( vid, CV_CAP_PROP_FRAME_COUNT ); //check this property
609  if( sldr_maxval<1 ){
610  printf( "Number of frames < 1. Cannot continue...\n" );
611  return( 1 );
612  }
613  cvSetCaptureProperty(
614  vid,
615  CV_CAP_PROP_POS_FRAMES,
616  sldr_start
617  );
618  sprintf( line, "%d", sldr_maxval );
619  cvPutText( numFrames, line, cvPoint( 3, numFrames->height - 4 ), &font, black );
620  sprintf( line, "%d", ( int )cvRound( fps ) );
621  cvPutText( fps_edit, line, cvPoint( 3, fps_edit->height - 4 ), &font, black );
622  sprintf( line, "%d", sldr_start );
623  cvPutText( cur_frame_no, line, cvPoint( 3, cur_frame_no->height - 4 ), &font, black );
624  sprintf( line, "%s", four_cc_str );
625  cvPutText( four_cc_edit, line, cvPoint( 3, four_cc_edit->height - 8 ), &font, black );
627 
631  frame = cvQueryFrame( vid );
632  old_frame = cvCloneImage( frame );
633  if( !frame ){
634  printf( "Cannot load video. Missing Codec : %s\n", four_cc_str );
635  return( 1 );
636  }
637  cvShowImage( "Video Player", player );
638 
642  char c;
643  int cur_frame;
644  while( 1 ){
645  if( ( c = cvWaitKey( 1000/fps ) )==27 ){
646  break;
647  }
648  if( !processing ){
649  if( playing ){
650  for( int i = 0; i < ( step_val - 1 ); i++ ){
651  cvQueryFrame( vid );
652  }
653  frame = cvQueryFrame( vid );
654  if( !frame ){
655  playing = false;
656  }
657  else{
658  cvCopy( frame, old_frame );
659  }
660  }
661  //to avoid any negative value of cur_frame
662  while( 1 ){
663  if( ( cur_frame = ( int )cvGetCaptureProperty( vid, CV_CAP_PROP_POS_FRAMES ) )>=0 ){
664  break;
665  }
666  //for some unknown reason cvQueryFrame was needed to be called twice to get to the desired frame.
667  frame = cvQueryFrame( vid );
668  cvCopy( frame, old_frame );
669  }
670  //defines the task to be carried out when editing a text-field
671  if( typing_step ){
672  type_step( c, cur_frame );
673  }
674  //this takes care if for some reason the cur_frame overshoots the sldr_maxval.
675  if( cur_frame == ( sldr_maxval-1 ) ){
677  sprintf( status_line, "End reached" );
678  change_status();
679  }
680  cvResize( old_frame, frame_area );
681  //printf( "Current frame : %d\n", cur_frame );
682  moveSlider( cur_frame, OTHER_CALLS );
683  }
684  cvShowImage( "Video Player", player );
685  }
686 
690  //destory window
691  cvDestroyWindow( "Video Player" );
692 
693  //Release image
694  cvReleaseImageHeader( &stepdown_btn );
695  cvReleaseImageHeader( &stepup_btn );
696  cvReleaseImageHeader( &stop_btn );
697  cvReleaseImageHeader( &play_pause_btn );
698  cvReleaseImageHeader( &step_edit );
699  cvReleaseImageHeader( &four_cc_edit );
700  cvReleaseImageHeader( &fps_edit );
701  cvReleaseImageHeader( &numFrames );
702  cvReleaseImageHeader( &cur_frame_no );
703  cvReleaseImageHeader( &pnl );
704  cvReleaseImageHeader( &sldr_val );
705  cvReleaseImageHeader( &slider );
706  cvReleaseImageHeader( &frame_area );
707  cvReleaseImage( &old_frame );
708  cvReleaseImage( &sldr_btn );
709  cvReleaseImage( &oslider );
710  cvReleaseImage( &player );
711 
712  //Release the video
713  cvReleaseCapture( &vid );
714 
715  return( 0 );
721 }
722 
723 
724 
725 //Function to move the custom built slider
729 int moveSlider( int pos, int call_from ){
730  int frame_val;
731  //Scaling to obtain the current frame number
735  float scale = ( sldr_maxval )/( float )( p_width );
736  //printf( "Pos : %d\tScale : %f\n", pos, scale );
737  if( call_from == MOUSE_CALLBACK ){
738  frame_val = cvCeil( scale*pos );
739  }
743  if( call_from == OTHER_CALLS ){
744  frame_val = pos;
745  }
746  //Scaling to set the slider button at an appropriate location between 0 and (p_width - sldr_btn_width)
750  scale = ( p_width - sldr_btn_width )/( float )( sldr_maxval );
751  //printf( "Frame slider : %d\n", frame_val );
752  int new_pos = cvCeil( scale*frame_val );
753  //frame_val should be an integral multiple of step_val
757  if( frame_val%step_val != 0 ){
758  frame_val = step_val*( ( int )frame_val/( int )step_val );
759  }
764  sprintf( line, "%d", frame_val );
765  cvPutText( cur_frame_no, line, cvPoint( 3, cur_frame_no->height - 4 ), &font, black );
766  cvCopy( oslider, slider );
767  sldr_val->imageData = slider->imageData + new_pos*slider->nChannels;
768  cvCopy( sldr_btn, sldr_val );
769  return( frame_val );
776 }
777 
778 //Function for mouse callback events
784 void my_mouse_callback( int event, int x, int y, int flags, void* param ){
785  IplImage* image = ( IplImage* )param;
786  switch( event ){
790  case CV_EVENT_MOUSEMOVE: {
791  if( sldr_moving ){
792  // mouse on slider
793  if( ( y > scrn_height ) && ( y <= scrn_height + sldr_height ) ){
794  int cur_frame = moveSlider( x, MOUSE_CALLBACK );
795  if( vid ){
796  cvSetCaptureProperty( vid, CV_CAP_PROP_POS_FRAMES, ( double )( cur_frame-1 ) );
797  cvQueryFrame( vid );
798  cvCopy( cvQueryFrame( vid ), old_frame );
799  }
800  }
801  }
802  }
803  break;
807  case CV_EVENT_LBUTTONDOWN: {
808  sldr_moving = true;
809  resetAllEdits();
810  // mouse on slider
811  if( ( y > scrn_height ) && ( y <= scrn_height + sldr_height ) ){
812  int cur_frame = moveSlider( x, MOUSE_CALLBACK );
813  if( vid ){
814  cvSetCaptureProperty( vid, CV_CAP_PROP_POS_FRAMES, ( double )( cur_frame-1 + step_val -1 ) );
815  cvQueryFrame( vid );
816  cvCopy( cvQueryFrame( vid ), old_frame );
817  //printf( "Before val : %f\n", cvGetCaptureProperty( vid, CV_CAP_PROP_POS_FRAMES ) );
818  }
819  if( !playing ){
820  sprintf( status_line, "Slider moved" );
821  change_status();
822  }
823  }
824  // mouse on play/pause button
825  if(
826  ( y > play_pause_btn_area.y1 ) &&
827  ( y <= play_pause_btn_area.y2 ) &&
828  ( x > play_pause_btn_area.x1 ) &&
829  ( x <= play_pause_btn_area.x2 )
830  ){
831  //printf( "Frame val : %d\n", ( int )cvGetCaptureProperty( vid, CV_CAP_PROP_POS_FRAMES ) );
832  if( playing ){
833  playing = false;
835  sprintf( status_line, "Paused" );
836  change_status();
837  }
838  else{
839  playing = true;
841  sprintf( status_line, "Playing" );
842  change_status();
843  }
844  }
845  // mouse on stop button
846  if(
847  ( y > stop_btn_area.y1 ) &&
848  ( y <= stop_btn_area.y2 ) &&
849  ( x > stop_btn_area.x1 ) &&
850  ( x <= stop_btn_area.x2 )
851  ){
852  playing = false;
854  if( vid ){
855  cvSetCaptureProperty( vid, CV_CAP_PROP_POS_FRAMES, ( double )( sldr_start-1 ) );
856  cvQueryFrame( vid );
857  cvCopy( cvQueryFrame( vid ), old_frame );
858  }
860  sprintf( status_line, "Stopped" );
861  change_status();
862  }
863  // mouse on stepup button
864  if(
865  ( y > stepup_btn_area.y1 ) &&
866  ( y <= stepup_btn_area.y2 ) &&
867  ( x > stepup_btn_area.x1 ) &&
868  ( x <= stepup_btn_area.x2 )
869  ){
870  int cur_frame = ( int )cvGetCaptureProperty( vid, CV_CAP_PROP_POS_FRAMES );
871  //printf( "Frame val : %d\n", cur_frame );
872  if( cur_frame + 1 + step_val - 1 < sldr_maxval ){
873  for( int i=0; i < ( step_val - 1 ); i++ ){
874  cvQueryFrame( vid );
875  }
876  frame = cvQueryFrame( vid );
877  if( frame ){
878  cvCopy( frame, old_frame );
879  }
880  }
881  if( !playing ){
882  sprintf( status_line, "Stepped Up" );
883  change_status();
884  }
885  //printf( "Stepup pressed \n" );
886  }
887  // mouse on stepdown button
888  if(
889  ( y > stepdown_btn_area.y1 ) &&
890  ( y <= stepdown_btn_area.y2 ) &&
891  ( x > stepdown_btn_area.x1 ) &&
892  ( x <= stepdown_btn_area.x2 )
893  ){
894  processing = true;
895  int cur_frame = ( int )cvGetCaptureProperty( vid, CV_CAP_PROP_POS_FRAMES );
896  //printf( "Frame val : %d\n", cur_frame );
897  if( cur_frame - 1 - ( step_val - 1 ) >= sldr_start ){
898  moveSlider( ( cur_frame - 1 - ( step_val - 1 ) ), OTHER_CALLS );
899  cvSetCaptureProperty( vid, CV_CAP_PROP_POS_FRAMES, ( double )( cur_frame - 1 - ( step_val - 1 ) ) );
900  cvQueryFrame( vid );
901  cvCopy( cvQueryFrame( vid ), old_frame );
902  //printf( "New Frame val : %d\n", ( int )cvGetCaptureProperty( vid, CV_CAP_PROP_POS_FRAMES ) );
903  }
904  if( !playing ){
905  sprintf( status_line, "Stepped Down" );
906  change_status();
907  }
908  processing = false;
909  //printf( "Stepdown pressed \n" );
910  }
911  // mouse on step_edit field
912  if(
913  ( y > step_edit_area.y1 ) &&
914  ( y <= step_edit_area.y2 ) &&
915  ( x > step_edit_area.x1 ) &&
916  ( x <= step_edit_area.x2 )
917  ){
918  sprintf( edit_text, "" );
919  typing_step = true;
920  }
921  }
922  break;
926  case CV_EVENT_LBUTTONUP: {
927  sldr_moving = false;
928  }
929  break;
930  }
939 }
940 
941 
942 //Function to reset any field
952 void resetField( IplImage* image, int text_type ){
953  if( text_type == STATIC_TEXT ){
954  for( int row=0; row<image->height; row++ ){
955  uchar *ptr = ( uchar* )( image->imageData + row*image->widthStep );
956  for( int col=0; col<image->width; col++ ){
957  ptr[ col*image->nChannels + 0 ] = 226;
958  ptr[ col*image->nChannels + 1 ] = 235;
959  ptr[ col*image->nChannels + 2 ] = 240;
960  }
961  }
962  }
963  else{
964  for( int row=0; row<image->height; row++ ){
965  uchar *ptr = ( uchar* )( image->imageData + row*image->widthStep );
966  for( int col=0; col<image->width; col++ ){
967  if( row==0 || row==image->height-1 || col==0 || col==image->width-1 ){
968  ptr[ col*image->nChannels + 0 ] = 0;
969  ptr[ col*image->nChannels + 1 ] = 0;
970  ptr[ col*image->nChannels + 2 ] = 0;
971  }
972  else
973  {
974  ptr[ col*image->nChannels + 0 ] = 255;
975  ptr[ col*image->nChannels + 1 ] = 255;
976  ptr[ col*image->nChannels + 2 ] = 255;
977  }
978  }
979  }
980  }
981 }
982 
983 //Function to get new buttons
991 void getButton( IplImage* image, int btn_type, int btn_state ){
992  getSpectrumVert( image, voilet, black );
993  if( btn_type==PLAY_BTN ){
994  draw_triangle( image, green );
995  }
996  if( btn_type==STOP_BTN ){
997  draw_square( image, green );
998  }
999  if( btn_type==PAUSE_BTN ){
1000  draw_pause( image, green );
1001  }
1002  if( btn_type==STEPUP_BTN ){
1003  draw_stepup( image, green );
1004  }
1005  if( btn_type==STEPDOWN_BTN ){
1006  draw_stepdown( image, green );
1007  }
1008 }
1009 
1010 //Function to vertically color a button
1029 void getSpectrumVert( IplImage* image, CvScalar color1, CvScalar color2 ){
1030  for( int row=0; row<image->height; row++ ){
1031  //If topmost row is selected
1032  if( row==0 ){
1033  uchar *ptr = ( uchar* )( image->imageData + row*image->widthStep );
1034  for( int col=0; col<image->width; col++ ){
1035  for( int chl=0; chl<image->nChannels; chl++ ){
1036  ptr[ col*image->nChannels + chl] = color1.val[chl];
1037  }
1038  }
1039  }
1040  //If bottommost row is selected
1041  if( row==image->height-1 ){
1042  uchar *ptr = ( uchar* )( image->imageData + row*image->widthStep );
1043  for( int col=0; col<image->width; col++ ){
1044  for( int chl=0; chl<image->nChannels; chl++ ){
1045  ptr[ col*image->nChannels + chl] = color2.val[chl];
1046  }
1047  }
1048  }
1049  }
1050 
1051  //Interpolation is applied
1052  //b_a_L => (B-A)/L... (X-A)/l = (B-A)/L :: => X = (((B-A)/L)*l + A)
1053  for( int row=1; row<image->height-1; row++ ){
1054  uchar *ptr = ( uchar* )( image->imageData );
1055  for( int col=0; col<image->width; col++ ){
1056  for( int chl=0; chl<image->nChannels; chl++ ){
1057  ptr[ row*image->widthStep + col*image->nChannels + chl ] = (
1058  ptr[ ( image->height-1 )*image->widthStep + col*image->nChannels + chl ] - ptr[ col*image->nChannels + chl ] )*(
1059  row/( float )image->height ) + ptr[ col*image->nChannels + chl ];
1060  }
1061  }
1062  }
1063 }
1064 
1065 //Function to get the horizontal spectrum
1084 void getSpectrumHorz( IplImage* image, CvScalar color1, CvScalar color2 ){
1085  //Color the leftmost and rightmost pixels of each row with with color1 and color2 respectively
1086  for( int row=0; row<image->height; row++ ){
1087  uchar *ptr = ( uchar* )( image->imageData + row*image->widthStep );
1088  for( int chl=0; chl<image->nChannels; chl++ ){
1089  ptr[chl] = color1.val[chl];
1090  ptr[ ( image->width-1 )*image->nChannels + chl ] = color2.val[ chl ];
1091  }
1092  }
1093  //Interploation applied here
1094  //b_a_L => (B-A)/L... (X-A)/l = (B-A)/L :: => X = (((B-A)/L)*l + A)
1095  for( int row=0; row<image->height; row++ ){
1096  uchar *ptr = ( uchar* )( image->imageData + row*image->widthStep );
1097  for( int col=0; col<image->width; col++ ){
1098  for( int chl=0; chl<image->nChannels; chl++ ){
1099  ptr[ col*image->nChannels + chl ] = ( ptr[ ( image->width - 1 )*image->nChannels + chl ] - ptr[ chl ] )*( col/( float )image->width ) + ptr[ chl ];
1100  }
1101  }
1102  }
1103 }
1104 
1105 //Function to initialize the control pannel...adding text & buttons
1122 void initialize_pnl( char *filename ){
1123  int row, col;
1124  cvPutText( pnl, "Step : ", cvPoint( 3, 60 ), &font, black );
1125  cvPutText( pnl, "File : ", cvPoint( 3, 140 ), &font, black );
1126  cvPutText( pnl, filename, cvPoint( 65, 140 ), &font, black );
1127  cvPutText( pnl, "Control Pannel", cvPoint( 3, 15 ), &font_bold_italic, black );
1128  cvPutText( pnl, "FPS : ", cvPoint( 700, 100 ), &font, black );
1129  cvPutText( pnl, "Current Frame : ", cvPoint( 3, 100 ), &font, black );
1130  cvPutText( pnl, "Total Frames : ", cvPoint( 300, 100 ), &font, black );
1131  cvPutText( pnl, "FOURCC : ", cvPoint( 668, 60 ), &font, black );
1132  cvPutText( pnl, "Status : ", cvPoint( 325, 30 ), &font, black );
1133  //Current Frame field
1134  row = 88;
1135  col = 150;
1136  cur_frame_no = cvCreateImageHeader( cvSize( 120, 18), IPL_DEPTH_8U, 3 );
1137  cur_frame_no->origin = pnl->origin;
1138  cur_frame_no->widthStep = pnl->widthStep;
1139  cur_frame_no->imageData = pnl->imageData + row*pnl->widthStep + col*pnl->nChannels;
1141  //number of frames field
1142  row = 88;
1143  col = 430;
1144  numFrames = cvCreateImageHeader( cvSize( 120, 18), IPL_DEPTH_8U, 3 );
1145  numFrames->origin = pnl->origin;
1146  numFrames->widthStep = pnl->widthStep;
1147  numFrames->imageData = pnl->imageData + row*pnl->widthStep + col*pnl->nChannels;
1149  //Step field
1150  row = 48;
1151  col = 65;
1152  step_edit = cvCreateImageHeader( cvSize( 50, 18), IPL_DEPTH_8U, 3 );
1153  step_edit->origin = pnl->origin;
1154  step_edit->widthStep = pnl->widthStep;
1155  step_edit->imageData = pnl->imageData + row*pnl->widthStep + col*pnl->nChannels;
1157  step_edit_area.x1 = col;
1158  step_edit_area.x2 = col + step_edit->width;
1159  step_edit_area.y1 = p_height - ctrl_pnl_height + row;
1160  step_edit_area.y2 = p_height - ctrl_pnl_height + step_edit->height + row;
1161  sprintf( line, "%d", step_val );
1162  cvPutText( step_edit, line, cvPoint( 3, step_edit->height - 4 ), &font, black );
1163  //FPS field
1164  row = 88;
1165  col = 755;
1166  fps_edit = cvCreateImageHeader( cvSize( 50, 18), IPL_DEPTH_8U, 3 );
1167  fps_edit->origin = pnl->origin;
1168  fps_edit->widthStep = pnl->widthStep;
1169  fps_edit->imageData = pnl->imageData + row*pnl->widthStep + col*pnl->nChannels;
1171  fps_edit_area.x1 = col;
1172  fps_edit_area.x2 = col + fps_edit->width;
1173  fps_edit_area.y1 = p_height - ctrl_pnl_height + row;
1174  fps_edit_area.y2 = p_height - ctrl_pnl_height + fps_edit->height + row;
1175  //FOURCC field
1176  row = 48;
1177  col = 755;
1178  four_cc_edit = cvCreateImageHeader( cvSize( 50, 22), IPL_DEPTH_8U, 3 );
1179  four_cc_edit->origin = pnl->origin;
1180  four_cc_edit->widthStep = pnl->widthStep;
1181  four_cc_edit->imageData = pnl->imageData + row*pnl->widthStep + col*pnl->nChannels;
1183  four_cc_edit_area.x1 = col;
1184  four_cc_edit_area.x2 = col + four_cc_edit->width;
1185  four_cc_edit_area.y1 = p_height - ctrl_pnl_height + row;
1186  four_cc_edit_area.y2 = p_height - ctrl_pnl_height + four_cc_edit->height + row;
1187  //Play/Pause button
1188  row = 48;
1189  col = 350;
1190  play_pause_btn = cvCreateImageHeader( cvSize( 60, 18), IPL_DEPTH_8U, 3 );
1191  play_pause_btn->origin = pnl->origin;
1192  play_pause_btn->widthStep = pnl->widthStep;
1193  play_pause_btn->imageData = pnl->imageData + row*pnl->widthStep + col*pnl->nChannels;
1195  play_pause_btn_area.x1 = col;
1196  play_pause_btn_area.x2 = col + play_pause_btn->width;
1197  play_pause_btn_area.y1 = p_height - ctrl_pnl_height + row;
1198  play_pause_btn_area.y2 = p_height - ctrl_pnl_height + play_pause_btn->height + row;
1199  //Stop button
1200  row = 48;
1201  col = 415;
1202  stop_btn = cvCreateImageHeader( cvSize( 60, 18), IPL_DEPTH_8U, 3 );
1203  stop_btn->origin = pnl->origin;
1204  stop_btn->widthStep = pnl->widthStep;
1205  stop_btn->imageData = pnl->imageData + row*pnl->widthStep + col*pnl->nChannels;
1207  stop_btn_area.x1 = col;
1208  stop_btn_area.x2 = col + stop_btn->width;
1209  stop_btn_area.y1 = p_height - ctrl_pnl_height + row;
1210  stop_btn_area.y2 = p_height - ctrl_pnl_height + stop_btn->height + row;
1211  //Stepup button
1212  row = 48;
1213  col = 480;
1214  stepup_btn = cvCreateImageHeader( cvSize( 60, 18), IPL_DEPTH_8U, 3 );
1215  stepup_btn->origin = pnl->origin;
1216  stepup_btn->widthStep = pnl->widthStep;
1217  stepup_btn->imageData = pnl->imageData + row*pnl->widthStep + col*pnl->nChannels;
1219  stepup_btn_area.x1 = col;
1220  stepup_btn_area.x2 = col + stepup_btn->width;
1221  stepup_btn_area.y1 = p_height - ctrl_pnl_height + row;
1222  stepup_btn_area.y2 = p_height - ctrl_pnl_height + stepup_btn->height + row;
1223  //Stepdown button
1224  row = 48;
1225  col = 285;
1226  stepdown_btn = cvCreateImageHeader( cvSize( 60, 18), IPL_DEPTH_8U, 3 );
1227  stepdown_btn->origin = pnl->origin;
1228  stepdown_btn->widthStep = pnl->widthStep;
1229  stepdown_btn->imageData = pnl->imageData + row*pnl->widthStep + col*pnl->nChannels;
1231  stepdown_btn_area.x1 = col;
1232  stepdown_btn_area.x2 = col + stepdown_btn->width;
1233  stepdown_btn_area.y1 = p_height - ctrl_pnl_height + row;
1234  stepdown_btn_area.y2 = p_height - ctrl_pnl_height + stepdown_btn->height + row;
1235  //Status Field
1236  row = 18;
1237  col = 395;
1238  status_edit = cvCreateImageHeader( cvSize( 130, 22), IPL_DEPTH_8U, 3 );
1239  status_edit->origin = pnl->origin;
1240  status_edit->widthStep = pnl->widthStep;
1241  status_edit->imageData = pnl->imageData + row*pnl->widthStep + col*pnl->nChannels;
1243  status_edit_area.x1 = col;
1244  status_edit_area.x2 = col + status_edit->width;
1245  status_edit_area.y1 = p_height - ctrl_pnl_height + row;
1246  status_edit_area.y2 = p_height - ctrl_pnl_height + status_edit->height + row;
1247  sprintf( status_line, "Stopped" );
1248  change_status();
1249 }
1250 
1251 //Draw triangle in the image
1261 void draw_triangle( IplImage* image, CvScalar color ){
1262  CvPoint pt1, pt2, pt3;
1263  pt1.x = image->width/3;
1264  pt1.y = 3;
1265  pt2.x = pt1.x;
1266  pt2.y = image->height - pt1.y;
1267  pt3.x = 2*pt1.x;
1268  pt3.y = image->height/2;
1269  cvLine( image, pt1, pt2, color );
1270  cvLine( image, pt3, pt2, color );
1271  cvLine( image, pt1, pt3, color );
1272  fill_color( image, color );
1273 }
1274 
1275 //Draw square in the image
1285 void draw_square( IplImage* image, CvScalar color ){
1286  CvPoint pt1, pt2;
1287  pt1.x = 3*image->width/8;
1288  pt1.y = 3;
1289  pt2.x = 5*image->width/8;
1290  pt2.y = image->height - pt1.y;
1291  cvRectangle( image, pt1, pt2, color );
1292  fill_color( image, color );
1293 }
1294 
1295 //Draw pause symbol in the image
1305 void draw_pause( IplImage* image, CvScalar color ){
1306  int y_start = 3;
1307  int y_end = image->height - y_start;
1308  int dist = 3;
1309  CvPoint pt1, pt2, tmp1, tmp2;
1310  pt1.x = image->width/2;
1311  pt1.y = y_start;
1312  pt2.x = pt1.x;
1313  pt2.y = y_end;
1314  for( int col=0; col<5; col++ ){
1315  tmp1.x = pt1.x + dist + col;
1316  tmp1.y = pt1.y;
1317  tmp2.x = pt2.x + dist + col;
1318  tmp2.y = pt2.y;
1319  cvLine( image, tmp1, tmp2, color );
1320  tmp1.x = pt1.x - dist - col;
1321  tmp1.y = pt1.y;
1322  tmp2.x = pt2.x - dist - col;
1323  tmp2.y = pt2.y;
1324  cvLine( image, tmp1, tmp2, color );
1325  }
1326 }
1327 
1328 
1329 
1330 //Function to fill color in the area bounded by the given color
1331 void fill_color( IplImage* image, CvScalar color ){
1332  bool start_fill = false;
1333  for( int row=0; row<image->height; row++ ){
1334  uchar *ptr = ( uchar* )( image->imageData + row*image->widthStep );
1335  for( int col=0; col<image->width; col++ ){
1336  if(
1337  ( ptr[ col*image->nChannels + 0 ] == color.val[0] ) &&
1338  ( ptr[ col*image->nChannels + 1 ] == color.val[1] ) &&
1339  ( ptr[ col*image->nChannels + 2 ] == color.val[2] )
1340  ){
1341  if( !start_fill ){
1342  start_fill = true;
1343  }
1344  else{
1345  start_fill = false;
1346  break;
1347  }
1348  }
1349  if( start_fill ){
1350  ptr[ col*image->nChannels + 0 ] = color.val[0];
1351  ptr[ col*image->nChannels + 1 ] = color.val[1];
1352  ptr[ col*image->nChannels + 2 ] = color.val[2];
1353  }
1354  }
1355  }
1356 }
1357 
1358 //Draw stepup symbol
1359 void draw_stepup( IplImage* image, CvScalar color ){
1360  CvPoint pt1, pt2, pt3, pt4;
1361  pt1.x = 2*image->width/8;
1362  pt2.x = 4*image->width/8;
1363  pt3.x = pt1.x;
1364  pt4.x = pt2.x;
1365  int y_start = 3;
1366  int y_end = image->height/2 ;
1367  for( int row=y_start; row<=y_end; row++ ){
1368  pt1.x = pt1.x + row - y_start;
1369  pt2.x = pt2.x + row - y_start;
1370  pt1.y = row;
1371  pt2.y = row;
1372  pt3.x = pt1.x;
1373  pt4.x = pt2.x;
1374  pt3.y = image->height - row;
1375  pt4.y = pt3.y;
1376  cvLine( image, pt1, pt2, color );
1377  cvLine( image, pt3, pt4, color );
1378  }
1379 }
1380 
1381 //Draw stepdown_symbol
1382 void draw_stepdown( IplImage* image, CvScalar color ){
1383  CvPoint pt1, pt2, pt3, pt4;
1384  pt1.x = 4*image->width/8;
1385  pt2.x = 6*image->width/8;
1386  pt3.x = pt1.x;
1387  pt4.x = pt2.x;
1388  int y_start = 3;
1389  int y_end = image->height/2 ;
1390  for( int row=y_start; row<=y_end; row++ ){
1391  pt1.x = pt1.x - row + y_start;
1392  pt2.x = pt2.x - row + y_start;
1393  pt1.y = row;
1394  pt2.y = row;
1395  pt3.x = pt1.x;
1396  pt4.x = pt2.x;
1397  pt3.y = image->height - row;
1398  pt4.y = pt3.y;
1399  cvLine( image, pt1, pt2, color );
1400  cvLine( image, pt3, pt4, color );
1401  }
1402 }
1403 
1404 //Function to change the status
1407  cvPutText( status_edit, status_line, cvPoint( 3, status_edit->height - 8 ), &font, black );
1408 }
1409 
1410 //Function for editing the step_edit field
1411 void type_step( char c, int frame_val ){
1413  char temp_text[ 20 ];
1414  int cur_frame;
1415  sprintf( temp_text, "" );
1416  if( blinking ){
1417  if( blink_count<blink_max ){
1418  blink_count++;
1419  }
1420  else{
1421  blinking = false;
1422  blink_char = ' ';
1423  blink_count = 0;
1424  }
1425  //printf( "Blinking...\n" );
1426  }
1427  else{
1428  if( blink_count<blink_max ){
1429  blink_count++;
1430  }
1431  else{
1432  blinking = true;
1433  blink_char = '|';
1434  blink_count = 0;
1435  }
1436  //printf( "Not blinking...\n" );
1437  }
1438  //valid number
1439  if( c>=48 && c<=57 ){
1440  sprintf( temp_text, "%s%c", edit_text, c );
1441  if( ( frame_val + atoi( temp_text ) )>=0 && ( frame_val + atoi( temp_text ) )<=sldr_maxval && ( atoi( temp_text )!=0 ) ){
1442  sprintf( edit_text, "%s", temp_text );
1443  }
1444  }
1445  //backspace
1446  if( c==8 ){
1447  if( strcmp( edit_text, "" )!=0 ){
1448  for( int count=0; count<( strlen( edit_text )-1 ); count++ ){
1449  sprintf( temp_text, "%s%c", temp_text, edit_text[ count ] );
1450  }
1451  sprintf( edit_text, "%s", temp_text );
1452  }
1453  }
1454  sprintf( temp_text, "%s%c", edit_text, blink_char );
1455  cvPutText( step_edit, temp_text, cvPoint( 3, step_edit->height - 4 ), &font, black );
1456  if( c==10 ){
1458  cvPutText( step_edit, edit_text, cvPoint( 3, step_edit->height - 4 ), &font, black );
1459  step_val = atoi( edit_text );
1460  //printf( "Step : %d\n", step );
1461  typing_step = false;
1462  }
1463 }
1464 
1465 //Function to reset all edit fields after mouse-left-click is performed
1468  sprintf( edit_text, "%d", step_val );
1469  cvPutText( step_edit, edit_text, cvPoint( 3, step_edit->height - 4 ), &font, black );
1470  typing_step = false;
1471 }
#define sldr_btn_width
Default value for the Slider Button's width.
Definition: video_player.c:37
int thickness
Font's Thickness parameter.
Definition: video_player.c:445
Field_Area stepup_btn_area
Step Up Button coordinates.
Definition: video_player.c:407
void fill_color(IplImage *image, CvScalar color)
Function to fill a symbol with a given color.
#define p_height
Height of the video player.
Definition: video_player.c:69
#define STEPDOWN_BTN
Alias for step-down button.
Definition: video_player.c:133
#define PAUSE_BTN
Alias for pause button.
Definition: video_player.c:115
void type_step(char c, int frame_val)
Function to edit a textbox.
IplImage * step_edit
Pointer to the Step textbox.
Definition: video_player.c:321
CvScalar black
Black color.
Definition: video_player.c:426
void resetField(IplImage *image, int text_type)
Function to reset a given text field.
Definition: video_player.c:952
IplImage * slider
Pointer to the slider-strip sub-image.
Definition: video_player.c:202
CvScalar brown
Brown color.
Definition: video_player.c:433
#define STATIC_TEXT
Alias for static-text field.
Definition: video_player.c:96
int line_type
Font's Line-type parameter.
Definition: video_player.c:446
IplImage * cur_frame_no
Pointer to current frame number static-text.
Definition: video_player.c:281
CvScalar green
Green color.
Definition: video_player.c:424
CvScalar gray
Gray color.
Definition: video_player.c:430
IplImage * numFrames
Pointer to Total Frames static-text.
Definition: video_player.c:313
IplImage * fps_edit
Pointer to FPS (Frames Per Second) static-text.
Definition: video_player.c:289
CvFont font_bold
Bold font.
Definition: video_player.c:438
IplImage * stepdown_btn
Pointer to step_down button area.
Definition: video_player.c:354
bool processing
True when some processing is carried out.
Definition: video_player.c:417
char four_cc_str[4]
Memory to hold the Four Character Code (FOUR_CC).
Definition: video_player.c:375
IplImage * four_cc_edit
Pointer to FOUR_CC static-text.
Definition: video_player.c:297
void initialize_pnl(char *filename)
Function to initialise the control pannel.
int sldr_maxval
The maximum number of frames in the video.
Definition: video_player.c:358
IplImage * frame_area
Pointer to the frame-area sub-image.
Definition: video_player.c:258
#define ctrl_pnl_height
Default value for Control Pannel's height.
Definition: video_player.c:49
#define PLAY_BTN
Alias for play button.
Definition: video_player.c:109
bool playing
True when the video is being played.
Definition: video_player.c:416
#define STOP_BTN
Alias for stop button.
Definition: video_player.c:121
int moveSlider(int pos, int call_from)
Custome slider's callback function.
Definition: video_player.c:729
CvScalar yellow
Yellow color.
Definition: video_player.c:429
void draw_square(IplImage *image, CvScalar color)
Function to draw a square on a given image.
CvScalar voilet
Voilet color.
Definition: video_player.c:432
CvCapture * vid
Pointer to CvCapture structure.
Definition: video_player.c:166
int blink_max
Definition: video_player.c:402
IplImage * stop_btn
Pointer to stop button area.
Definition: video_player.c:338
int x2
x coordinate of the bottom-right corrner.
Definition: video_player.c:155
char blink_char
Threshold to toogle the blink_char.
Definition: video_player.c:403
char * fourcc
Four_CC temporary string.
Definition: video_player.c:392
int main(int argc, char **argv)
Definition: video_player.c:505
void draw_pause(IplImage *image, CvScalar color)
Function to draw a pause symbol on a given image.
#define p_width
Width of the video player.
Definition: video_player.c:56
double fps
Frames per second.
Definition: video_player.c:381
CvFont font_bold_italic
Bold Italic font.
Definition: video_player.c:439
CvFont font_italic
Italic font.
Definition: video_player.c:437
double vscale
Font's Vertical Scale parameter.
Definition: video_player.c:443
IplImage * oslider
Pointer to temporary slider-value static-text sub-image.
Definition: video_player.c:244
void getSpectrumVert(IplImage *image, CvScalar color1, CvScalar color2)
Function to vertically color a button.
Field_Area stop_btn_area
Stop Button coordinates.
Definition: video_player.c:406
#define STEPUP_BTN
Alias for step-up button.
Definition: video_player.c:127
#define OTHER_CALLS
Alias for function call made by any function other than MOUSE's callback or Textbox Editor's function...
Definition: video_player.c:83
IplImage * status_edit
Pointer to "Status" static-text.
Definition: video_player.c:305
long fourcc_l
Four Character Code.
Definition: video_player.c:387
bool sldr_moving
Ture when slider is moving.
Definition: video_player.c:415
Field_Area fps_edit_area
FPS static-text coordinates.
Definition: video_player.c:409
int y2
y coordinate of the bottom-right corrner.
Definition: video_player.c:156
IplImage * sldr_val
Pointer to the slider-value static-text sub-image.
Definition: video_player.c:230
void getSpectrumHorz(IplImage *image, CvScalar color1, CvScalar color2)
Function to horizontaly color a button.
CvScalar red
Red color.
Definition: video_player.c:423
IplImage * sldr_btn
Pointer to the slider-button sub-image.
Definition: video_player.c:216
IplImage * player
Pointer to the main image.
Definition: video_player.c:174
int blink_count
Blinker count.
Definition: video_player.c:400
char line[20]
Memory to hold any string temporarily.
Definition: video_player.c:366
bool blinking
True when blinking character is set.
Definition: video_player.c:419
int y1
y coordinate of the top-left corrner.
Definition: video_player.c:154
#define MOUSE_CALLBACK
Alias for function call made by the MOUSE's callback.
Definition: video_player.c:77
#define EDIT_TEXT
Alias for text-box field.
Definition: video_player.c:102
Field_Area four_cc_edit_area
FOUR_CC static-text coordinates.
Definition: video_player.c:410
CvScalar light_yellow
Light Yellow color.
Definition: video_player.c:428
void draw_stepdown(IplImage *image, CvScalar color)
Function to draw a step-down symbol on a given image.
int font_face
Font face.
Definition: video_player.c:441
void my_mouse_callback(int event, int x, int y, int flags, void *param)
Mouse's callback function.
Definition: video_player.c:784
Field_Area play_pause_btn_area
The blinking character, toogled with an underscore (_).
Definition: video_player.c:405
CvScalar blue
Blue color.
Definition: video_player.c:425
void getButton(IplImage *image, int btn_type, int btn_state)
Function to get a new button.
Definition: video_player.c:991
int font_face_italic
Font face.
Definition: video_player.c:440
IplImage * play_pause_btn
Pointer to play/pause button area.
Definition: video_player.c:330
double hscale
Font's Horizontal Scale parameter.
Definition: video_player.c:442
char edit_text[20]
Memory to hold a textbox string temporarily.
Definition: video_player.c:372
Field_Area stepdown_btn_area
Step Down Button coordinates.
Definition: video_player.c:408
char status_line[15]
Memory to hold the "status" string.
Definition: video_player.c:374
#define sldr_height
Default value for the Slider Button's height.
Definition: video_player.c:43
void change_status()
Function to change the status message.
IplImage * old_frame
Pointer to the previously fetched frame.
Definition: video_player.c:274
bool typing_step
True when any textbox value is being edited.
Definition: video_player.c:418
void resetAllEdits()
Function to reset all fields to their previous contents.
int sldr_start
Indicates the starting position (frame number) of the slider.
Definition: video_player.c:357
#define BTN_ACTIVE
Alias for an active button.
Definition: video_player.c:140
CvScalar white
White color.
Definition: video_player.c:427
Structure to store the top-left and botton-right corner coordinates of various fields & buttons...
Definition: video_player.c:152
IplImage * frame
Pointer to the fetched frame sub-image.
Definition: video_player.c:266
CvFont font
Normal font.
Definition: video_player.c:436
void draw_triangle(IplImage *image, CvScalar color)
Function to draw a triangle on a given image.
Field_Area step_edit_area
Step textbox coordinates.
Definition: video_player.c:412
int step_val
Step size.
Definition: video_player.c:364
#define scrn_height
Height of the video-display area.
Definition: video_player.c:62
double shear
Font's Shear parameter.
Definition: video_player.c:444
CvScalar orange
Orange color.
Definition: video_player.c:431
IplImage * pnl
Pointer to the control-pannel sub-image.
Definition: video_player.c:188
IplImage * stepup_btn
Pointer to step_up button area.
Definition: video_player.c:346
Field_Area status_edit_area
Status string coordinates.
Definition: video_player.c:411
int x1
x coordinate of the top-left corrner.
Definition: video_player.c:153
void draw_stepup(IplImage *image, CvScalar color)
Function to draw a step-up symbol on a given image.