Revision 78068e21 chunker_player/chunker_player.c

View differences:

chunker_player/chunker_player.c
25 25
#include <SDL_mutex.h>
26 26
#include <SDL_image.h>
27 27
#include <math.h>
28
#include <confuse.h>
28 29

  
29 30
#ifdef __MINGW32__
30 31
#undef main /* Prevents SDL from overriding main() */
......
34 35
#include "chunker_player.h"
35 36
#include "codec_definitions.h"
36 37

  
37
#define SDL_AUDIO_BUFFER_SIZE 1024
38

  
39
#define MAX_TOLLERANCE 40
40
#define AUDIO	1
41
#define VIDEO	2
42
#define QUEUE_MAX_SIZE 3000
43

  
44
#define FULLSCREEN_ICON_FILE "icons/fullscreen32.png"
45
#define NOFULLSCREEN_ICON_FILE "icons/nofullscreen32.png"
46
#define FULLSCREEN_HOVER_ICON_FILE "icons/fullscreen32.png"
47
#define NOFULLSCREEN_HOVER_ICON_FILE "icons/nofullscreen32.png"
48

  
49
#define BUTTONS_LAYER_OFFSET 10
50

  
51
typedef enum Status { STOPPED, RUNNING, PAUSED } Status;
52

  
53
//#define DEBUG_AUDIO
54
//#define DEBUG_VIDEO
55
#define DEBUG_QUEUE
56
#define DEBUG_SOURCE
57
//#define DEBUG_STATS
58
//#define DEBUG_AUDIO_BUFFER
59
//#define DEBUG_CHUNKER
60

  
61

  
62
short int QueueFillingMode=1;
63
short int QueueStopped=0;
64

  
65
typedef struct PacketQueue {
66
	AVPacketList *first_pkt;
67
	AVPacketList *last_pkt;
68
	int nb_packets;
69
	int size;
70
	SDL_mutex *mutex;
71
	short int queueType;
72
	int last_frame_extracted; //HINT THIS SHOULD BE MORE THAN 4 BYTES
73
	int total_lost_frames;
74
	double density;
75
} PacketQueue;
76

  
77
typedef struct threadVal {
78
	int width;
79
	int height;
80
	float aspect_ratio;
81
} ThreadVal;
82

  
83
int AudioQueueOffset=0;
84
PacketQueue audioq;
85
PacketQueue videoq;
86
AVPacket AudioPkt, VideoPkt;
87
int quit = 0;
88
int SaveYUV=0;
89
char YUVFileName[256];
90

  
91
int queue_filling_threshold = 0;
92

  
93
SDL_Surface *screen;
94
SDL_Overlay *yuv_overlay;
95
SDL_Rect    rect;
96
SDL_Rect *initRect = NULL;
97
SDL_AudioSpec spec;
98
Status CurrStatus = STOPPED;
99

  
100
struct SwsContext *img_convert_ctx = NULL;
101
float ratio;
102

  
103
//SDL_mutex *timing_mutex;
104

  
105
int got_sigint = 0;
106

  
107
long long DeltaTime;
108
short int FirstTimeAudio=1, FirstTime = 1;
109

  
110
int dimAudioQ;
111
float deltaAudioQ;
112
float deltaAudioQError=0;
113

  
114
void SaveFrame(AVFrame *pFrame, int width, int height);
115

  
116
// other GUI staff
117
SDL_Cursor *init_system_cursor(const char *image[]);
118
void refresh_fullscreen_button(int hover);
119
void toggle_fullscreen();
120
void aspect_ratio_resize(float aspect_ratio, int width, int height, int* out_width, int* out_height);
121
int fullscreen = 0; // fullscreen vs windowized flag
122
SDL_Rect    fullscreenIconBox;
123
SDL_Surface *fullscreenIcon;
124
SDL_Surface *fullscreenHoverIcon;
125
SDL_Surface *nofullscreenIcon;
126
SDL_Surface *nofullscreenHoverIcon;
127
SDL_Cursor *defaultCursor;
128
SDL_Cursor *handCursor;
129
int fullscreenButtonHover = 0;
130
int silentMode = 0;
131

  
132
/* XPM */
133
static char *handXPM[] = {
134
/* columns rows colors chars-per-pixel */
135
"32 32 3 1",
136
"  c black",
137
". c gray100",
138
"X c None",
139
/* pixels */
140
"XXXXX  XXXXXXXXXXXXXXXXXXXXXXXXX",
141
"XXXX .. XXXXXXXXXXXXXXXXXXXXXXXX",
142
"XXXX .. XXXXXXXXXXXXXXXXXXXXXXXX",
143
"XXXX .. XXXXXXXXXXXXXXXXXXXXXXXX",
144
"XXXX .. XXXXXXXXXXXXXXXXXXXXXXXX",
145
"XXXX ..   XXXXXXXXXXXXXXXXXXXXXX",
146
"XXXX .. ..   XXXXXXXXXXXXXXXXXXX",
147
"XXXX .. .. ..  XXXXXXXXXXXXXXXXX",
148
"XXXX .. .. .. . XXXXXXXXXXXXXXXX",
149
"   X .. .. .. .. XXXXXXXXXXXXXXX",
150
" ..  ........ .. XXXXXXXXXXXXXXX",
151
" ... ........... XXXXXXXXXXXXXXX",
152
"X .. ........... XXXXXXXXXXXXXXX",
153
"XX . ........... XXXXXXXXXXXXXXX",
154
"XX ............. XXXXXXXXXXXXXXX",
155
"XXX ............ XXXXXXXXXXXXXXX",
156
"XXX ........... XXXXXXXXXXXXXXXX",
157
"XXXX .......... XXXXXXXXXXXXXXXX",
158
"XXXX .......... XXXXXXXXXXXXXXXX",
159
"XXXXX ........ XXXXXXXXXXXXXXXXX",
160
"XXXXX ........ XXXXXXXXXXXXXXXXX",
161
"XXXXX          XXXXXXXXXXXXXXXXX",
162
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
163
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
164
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
165
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
166
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
167
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
168
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
169
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
170
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
171
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
172
"0,0"
173
};
38
#ifdef __WIN32__
39
#define KILL_PROCESS(pid) {char command_name[255]; sprintf(command_name, "taskkill /pid %d /F", pid); system(command_name);}
40
#endif
41
#ifdef __LINUX__
42
#define KILL_PROCESS(pid) {char command_name[255]; sprintf(command_name, "kill %d", pid); system(command_name);}
43
#endif
44
#ifdef __MACOS__
45
#define KILL_PROCESS(pid) {char command_name[255]; sprintf(command_name, "kill %d", pid); system(command_name);}
46
#endif
174 47

  
175 48
void packet_queue_init(PacketQueue *q, short int Type) {
176 49
#ifdef DEBUG_QUEUE
......
208 81
		av_free_packet(&(tmp1->pkt));
209 82
		av_free(tmp1);
210 83
#ifdef DEBUG_QUEUE
211
	printf("F ");
84
		printf("F ");
212 85
#endif
213 86
	}
214 87
#ifdef DEBUG_QUEUE
......
389 262
	return ret; //problems occurred
390 263
}
391 264

  
392

  
393 265
//removes a packet from the list and returns the next
394 266
AVPacketList *remove_from_queue(PacketQueue *q, AVPacketList *p) {
395 267
	AVPacketList *retpk = p->next;
......
882 754
						}
883 755
						continue;
884 756
					}
757
					
885 758
					pict.data[0] = yuv_overlay->pixels[0];
886 759
					pict.data[1] = yuv_overlay->pixels[2];
887 760
					pict.data[2] = yuv_overlay->pixels[1];
......
901 774
					sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, tval->height, pict.data, pict.linesize);
902 775
					SDL_UnlockYUVOverlay(yuv_overlay);
903 776
					// Show, baby, show!
777
					SDL_LockMutex(RedrawMutex);
904 778
					SDL_DisplayYUVOverlay(yuv_overlay, &rect);
779
					SDL_UnlockMutex(RedrawMutex);
905 780

  
906 781
					//redisplay logo
907 782
					/**SDL_BlitSurface(image, NULL, screen, &dest);*/
908 783
					/* Update the screen area just changed */
909 784
					/**SDL_UpdateRects(screen, 1, &dest);*/
910
					
911
					refresh_fullscreen_button(fullscreenButtonHover);
912 785

  
913 786
					if(SDL_MUSTLOCK(screen)) {
914 787
						SDL_UnlockSurface(screen);
......
972 845
	SDL_Surface *temp;
973 846
	int screen_w = 0, screen_h = 0;
974 847

  
975
	/* Load a BMP file on a surface */
976
	temp = IMG_Load(FULLSCREEN_ICON_FILE);
977
	if (temp == NULL) {
978
		fprintf(stderr, "Error loading %s: %s\n", FULLSCREEN_ICON_FILE, SDL_GetError());
979
		exit(1);
980
	}
981

  
982
	if(rect.w > temp->w)
848
	if(rect.w > BUTTONS_CONTAINER_WIDTH)
983 849
		screen_w = rect.w;
984 850
	else
985
		screen_w = temp->w;
851
		screen_w = BUTTONS_CONTAINER_WIDTH;
986 852

  
987
		screen_h = rect.h + temp->h + BUTTONS_LAYER_OFFSET;
853
		screen_h = rect.h + BUTTONS_CONTAINER_HEIGHT + BUTTONS_LAYER_OFFSET;
988 854

  
989 855
	SDL_WM_SetCaption("Filling buffer...", NULL);
990 856
	// Make a screen to put our video
......
1001 867
	window_width = screen_w;
1002 868
	window_height = screen_h;
1003 869
	
1004
	fullscreenIcon = SDL_DisplayFormatAlpha(temp);
870
	/** Setting up cursors */
871
	defaultCursor = SDL_GetCursor();
872
	handCursor = init_system_cursor(handXPM);
873
	
874
	/** Init Buttons */
875
	int i;
876
	for(i=0; i<NBUTTONS; i++)
877
	{
878
		SButton* tmp = &(Buttons[i]);
879
		tmp->Hover = 0;
880
		tmp->ToggledButton = NULL;
881
		tmp->Visible = 1;
882
		tmp->HoverCallback = NULL;
883
		tmp->LButtonUpCallback = NULL;
884
	}
885
	
886
	/** Loading icons */
887
	
888
	// fullscreen
889
	temp = IMG_Load(FULLSCREEN_ICON_FILE);
890
	if (temp == NULL) {
891
		fprintf(stderr, "Error loading %s: %s\n", FULLSCREEN_ICON_FILE, SDL_GetError());
892
		exit(1);
893
	}
894
	Buttons[FULLSCREEN_BUTTON_INDEX].ButtonIcon = SDL_DisplayFormatAlpha(temp);
895
	SDL_FreeSurface(temp);
896
	
897
	// fullscreen hover
898
	temp = IMG_Load(FULLSCREEN_HOVER_ICON_FILE);
899
	if (temp == NULL) {
900
		fprintf(stderr, "Error loading %s: %s\n", FULLSCREEN_HOVER_ICON_FILE, SDL_GetError());
901
		exit(1);
902
	}
903
	Buttons[FULLSCREEN_BUTTON_INDEX].ButtonHoverIcon = SDL_DisplayFormatAlpha(temp);
1005 904
	SDL_FreeSurface(temp);
1006 905

  
1007
	// load icon buttons
906
	// no fullscreen
1008 907
	temp = IMG_Load(NOFULLSCREEN_ICON_FILE);
1009 908
	if (temp == NULL) {
1010 909
		fprintf(stderr, "Error loading %s: %s\n", NOFULLSCREEN_ICON_FILE, SDL_GetError());
1011 910
		exit(1);
1012 911
	}
1013
	nofullscreenIcon = SDL_DisplayFormatAlpha(temp);
912
	Buttons[NO_FULLSCREEN_BUTTON_INDEX].ButtonIcon = SDL_DisplayFormatAlpha(temp);
1014 913
	SDL_FreeSurface(temp);
1015 914

  
915
	// no fullscreen hover
1016 916
	temp = IMG_Load(NOFULLSCREEN_HOVER_ICON_FILE);
1017 917
	if (temp == NULL) {
1018 918
		fprintf(stderr, "Error loading %s: %s\n", NOFULLSCREEN_HOVER_ICON_FILE, SDL_GetError());
1019 919
		exit(1);
1020 920
	}
1021
	nofullscreenHoverIcon = SDL_DisplayFormatAlpha(temp);
921
	Buttons[NO_FULLSCREEN_BUTTON_INDEX].ButtonHoverIcon = SDL_DisplayFormatAlpha(temp);
1022 922
	SDL_FreeSurface(temp);
1023

  
1024
	temp = IMG_Load(FULLSCREEN_HOVER_ICON_FILE);
923
	
924
	// channel up
925
	temp = IMG_Load(CHANNEL_UP_ICON_FILE);
1025 926
	if (temp == NULL) {
1026
		fprintf(stderr, "Error loading %s: %s\n", FULLSCREEN_HOVER_ICON_FILE, SDL_GetError());
927
		fprintf(stderr, "Error loading %s: %s\n", CHANNEL_UP_ICON_FILE, SDL_GetError());
1027 928
		exit(1);
1028 929
	}
1029
	fullscreenHoverIcon = SDL_DisplayFormatAlpha(temp);
930
	Buttons[CHANNEL_UP_BUTTON_INDEX].ButtonIcon = SDL_DisplayFormatAlpha(temp);
931
	Buttons[CHANNEL_UP_BUTTON_INDEX].ButtonHoverIcon = SDL_DisplayFormatAlpha(temp);
932
	SDL_FreeSurface(temp);
933
	
934
	// channel down
935
	temp = IMG_Load(CHANNEL_DOWN_ICON_FILE);
936
	if (temp == NULL) {
937
		fprintf(stderr, "Error loading %s: %s\n", CHANNEL_DOWN_ICON_FILE, SDL_GetError());
938
		exit(1);
939
	}
940
	Buttons[CHANNEL_DOWN_BUTTON_INDEX].ButtonIcon = SDL_DisplayFormatAlpha(temp);
941
	Buttons[CHANNEL_DOWN_BUTTON_INDEX].ButtonHoverIcon = SDL_DisplayFormatAlpha(temp);
1030 942
	SDL_FreeSurface(temp);
1031 943

  
1032
	defaultCursor = SDL_GetCursor();
1033
	handCursor = init_system_cursor(handXPM);
1034

  
1035
	/* Copy on the screen surface 
1036
	surface should be blocked now.
1037
	*/
1038
	fullscreenIconBox.x = (screen_w - fullscreenIcon->w) / 2;
1039
	fullscreenIconBox.y = rect.h + (BUTTONS_LAYER_OFFSET/2);
1040
	fullscreenIconBox.w = fullscreenIcon->w;
1041
	fullscreenIconBox.h = fullscreenIcon->h;
1042
	printf("x%d y%d w%d h%d\n", fullscreenIconBox.x, fullscreenIconBox.y, fullscreenIconBox.w, fullscreenIconBox.h);
944
	/** Setting up icon boxes */
945
	Buttons[FULLSCREEN_BUTTON_INDEX].XOffset = Buttons[NO_FULLSCREEN_BUTTON_INDEX].XOffset = 20;
946
	Buttons[FULLSCREEN_BUTTON_INDEX].ButtonIconBox.x = 20;
947
	Buttons[FULLSCREEN_BUTTON_INDEX].ButtonIconBox.w = Buttons[FULLSCREEN_BUTTON_INDEX].ButtonIcon->w;
948
	Buttons[FULLSCREEN_BUTTON_INDEX].ButtonIconBox.h = Buttons[FULLSCREEN_BUTTON_INDEX].ButtonIcon->h;
949
	Buttons[FULLSCREEN_BUTTON_INDEX].ButtonIconBox.y = screen_h - Buttons[FULLSCREEN_BUTTON_INDEX].ButtonIconBox.h - (BUTTONS_LAYER_OFFSET/2);
950
	
951
	Buttons[NO_FULLSCREEN_BUTTON_INDEX].ButtonIconBox.x = 20;
952
	Buttons[NO_FULLSCREEN_BUTTON_INDEX].ButtonIconBox.w = Buttons[NO_FULLSCREEN_BUTTON_INDEX].ButtonIcon->w;
953
	Buttons[NO_FULLSCREEN_BUTTON_INDEX].ButtonIconBox.h = Buttons[NO_FULLSCREEN_BUTTON_INDEX].ButtonIcon->h;
954
	Buttons[NO_FULLSCREEN_BUTTON_INDEX].ButtonIconBox.y = screen_h - Buttons[NO_FULLSCREEN_BUTTON_INDEX].ButtonIconBox.h - (BUTTONS_LAYER_OFFSET/2);
955
	
956
	Buttons[CHANNEL_UP_BUTTON_INDEX].XOffset = -50;
957
	Buttons[CHANNEL_UP_BUTTON_INDEX].ButtonIconBox.w = Buttons[CHANNEL_UP_BUTTON_INDEX].ButtonIcon->w;
958
	Buttons[CHANNEL_UP_BUTTON_INDEX].ButtonIconBox.h = Buttons[CHANNEL_UP_BUTTON_INDEX].ButtonIcon->h;
959
	Buttons[CHANNEL_UP_BUTTON_INDEX].ButtonIconBox.x = (screen_w - 50);
960
	Buttons[CHANNEL_UP_BUTTON_INDEX].ButtonIconBox.y = screen_h - Buttons[CHANNEL_UP_BUTTON_INDEX].ButtonIconBox.h - (BUTTONS_LAYER_OFFSET/2);
961
	
962
	Buttons[CHANNEL_DOWN_BUTTON_INDEX].XOffset = -25;
963
	Buttons[CHANNEL_DOWN_BUTTON_INDEX].ButtonIconBox.w = Buttons[CHANNEL_DOWN_BUTTON_INDEX].ButtonIcon->w;
964
	Buttons[CHANNEL_DOWN_BUTTON_INDEX].ButtonIconBox.h = Buttons[CHANNEL_DOWN_BUTTON_INDEX].ButtonIcon->h;
965
	Buttons[CHANNEL_DOWN_BUTTON_INDEX].ButtonIconBox.x = (screen_w - 25);
966
	Buttons[CHANNEL_DOWN_BUTTON_INDEX].ButtonIconBox.y = screen_h - Buttons[CHANNEL_DOWN_BUTTON_INDEX].ButtonIconBox.h - (BUTTONS_LAYER_OFFSET/2);
967
	
968
	/** Setting up buttons events */
969
	Buttons[FULLSCREEN_BUTTON_INDEX].ToggledButton = &(Buttons[NO_FULLSCREEN_BUTTON_INDEX]);
970
	Buttons[FULLSCREEN_BUTTON_INDEX].LButtonUpCallback = &toggle_fullscreen;
971
	Buttons[NO_FULLSCREEN_BUTTON_INDEX].LButtonUpCallback = &toggle_fullscreen;
972
	Buttons[CHANNEL_UP_BUTTON_INDEX].LButtonUpCallback = &zap_up;
973
	Buttons[CHANNEL_DOWN_BUTTON_INDEX].LButtonUpCallback = &zap_down;
1043 974

  
1044 975
	//create video overlay for display of video frames
1045 976
	yuv_overlay = SDL_CreateYUVOverlay(rect.w, rect.h, SDL_YV12_OVERLAY, screen);
......
1054 985
	rect.x = (screen_w - rect.w) / 2;
1055 986
	SDL_DisplayYUVOverlay(yuv_overlay, &rect);
1056 987

  
1057
	/**SDL_BlitSurface(image, NULL, screen, &dest);*/
1058
	SDL_BlitSurface(fullscreenIcon, NULL, screen, &fullscreenIconBox);
1059
	/* Update the screen area just changed */
1060
	SDL_UpdateRects(screen, 1, &fullscreenIconBox);
988
	redraw_buttons();
1061 989
}
1062 990

  
1063 991
void SaveFrame(AVFrame *pFrame, int width, int height) {
......
1097 1025

  
1098 1026
	Uint32 Now=SDL_GetTicks();
1099 1027
	Uint8* keystate=SDL_GetKeyState(NULL);
1100
	if(keystate[SDLK_SPACE] &&
1028
	/*if(keystate[SDLK_SPACE] &&
1101 1029
	  (LastKey!=SDLK_SPACE || (LastKey==SDLK_SPACE && (Now-LastTime>1000))))
1102 1030
	{
1103 1031
		LastKey=SDLK_SPACE;
......
1105 1033
		QueueStopped=!QueueStopped;
1106 1034
		if(QueueStopped) CurrStatus = PAUSED;
1107 1035
		else CurrStatus = RUNNING;
1108
		refresh_fullscreen_button(0);
1109
	}
1036
		// refresh_fullscreen_button(0);
1037
	}*/
1110 1038
	if(keystate[SDLK_ESCAPE] &&
1111 1039
	  (LastKey!=SDLK_ESCAPE || (LastKey==SDLK_ESCAPE && (Now-LastTime>1000))))
1112 1040
	{
......
1128 1056
	int len1, data_size, stime, cont=0;
1129 1057
	int frameFinished, len_audio;
1130 1058
	int numBytes, outbuf_audio_size, audio_size;
1059
	
1060
	memset((void*)Channels, 0, (255*sizeof(SChannel)));
1131 1061

  
1132 1062
	int y;
1133 1063
	
......
1180 1110
		else
1181 1111
			printf("ERROR: Unable to create YUVFile\n");
1182 1112
	}
1113
	
1114
	if(parse_conf())
1115
	{
1116
		printf("Error while parsing configuration file, exiting...\n");
1117
		exit(1);
1118
	}
1119
	SelectedChannel = 0;
1120
	
1121
	switch_channel(&(Channels[SelectedChannel]));
1183 1122

  
1184 1123
	tval->width = width;
1185 1124
	tval->height = height;
......
1262 1201
	initRect->y = rect.y;
1263 1202
	initRect->w = rect.w;
1264 1203
	initRect->h = rect.h;
1265

  
1266
	//SetupGUI("napalogo_small.bmp");
1204
	
1205
	RedrawMutex = SDL_CreateMutex();
1267 1206
	if(!silentMode)
1268 1207
		SetupGUI();
1269 1208
	
......
1305 1244
		int x = 0, y = 0;
1306 1245
		int resize_w, resize_h;
1307 1246
		int tmp_switch = 0;
1247
		int i;
1308 1248
		//listen for key and mouse
1309 1249
		while(SDL_PollEvent(&event)) {
1310 1250
			switch(event.type) {
1311 1251
				case SDL_QUIT:
1312 1252
					//exit(0);
1313 1253
					quit=1;
1254
					if(child_pid > 0)
1255
						KILL_PROCESS(child_pid);
1314 1256
				break;
1315 1257
				case SDL_VIDEORESIZE:
1316
					//printf("\tSDL_VIDEORESIZE\n");
1317
					
1318
					// if running, pause until resize has done
1319
					if(CurrStatus == RUNNING)
1320
					{
1321
						QueueStopped = 1;
1322
						CurrStatus = PAUSED;
1323
						tmp_switch = 1;
1324
					}
1258
					SDL_LockMutex(RedrawMutex);
1325 1259
#ifndef __DARWIN__
1326 1260
					screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0, SDL_SWSURFACE | SDL_RESIZABLE);
1327 1261
#else
......
1332 1266
						exit(1);
1333 1267
					}
1334 1268
					
1269
					SDL_UnlockMutex(RedrawMutex);
1270
					
1335 1271
					window_width = event.resize.w;
1336 1272
					window_height = event.resize.h;
1337 1273
					
1338
					aspect_ratio_rect(ratio, event.resize.w, event.resize.h - BUTTONS_LAYER_OFFSET - fullscreenIconBox.h);
1339
					
1340
					fullscreenIconBox.x = (event.resize.w - fullscreenIcon->w) / 2;
1341

  
1342
					// put the button just below the video overlay
1343
// 					fullscreenIcon.y = rect.y+rect.h + (BUTTONS_LAYER_OFFSET/2);
1344

  
1345
					// put the button at the bottom edge of the screen
1346
					fullscreenIconBox.y = event.resize.h - fullscreenIconBox.h - (BUTTONS_LAYER_OFFSET/2);
1347
					
1348
					// refresh_fullscreen_button(0);
1274
					// update the overlay surface size, mantaining the aspect ratio
1275
					aspect_ratio_rect(ratio, event.resize.w, event.resize.h - BUTTONS_LAYER_OFFSET - BUTTONS_CONTAINER_HEIGHT);
1349 1276
					
1350
					if(tmp_switch)
1277
					// update each button coordinates
1278
					for(i=0; i<NBUTTONS; i++)
1351 1279
					{
1352
						QueueStopped = 0;
1353
						CurrStatus= RUNNING;
1354
						tmp_switch = 0;
1280
						if(Buttons[i].XOffset > 0)
1281
							Buttons[i].ButtonIconBox.x = Buttons[i].XOffset;
1282
						else
1283
							Buttons[i].ButtonIconBox.x = (event.resize.w + Buttons[i].XOffset);
1284
							
1285
						Buttons[i].ButtonIconBox.y = event.resize.h - Buttons[i].ButtonIconBox.h - (BUTTONS_LAYER_OFFSET/2);
1355 1286
					}
1287
					
1288
					SDL_LockMutex(RedrawMutex);
1289
					redraw_buttons();
1290
					SDL_UnlockMutex(RedrawMutex);
1291
					
1356 1292
				break;
1357 1293
				case SDL_ACTIVEEVENT:
1358 1294
					//printf("\tSDL_ACTIVEEVENT\n");
......
1387 1323
					//printf("\tSDL_MOUSEMOTION\n");
1388 1324
					x = event.motion.x;
1389 1325
					y = event.motion.y;
1390
					//If the mouse is over the button
1391
					if(
1392
						( x > fullscreenIconBox.x ) && ( x < fullscreenIconBox.x + fullscreenIcon->w )
1393
						&& ( y > fullscreenIconBox.y ) && ( y < fullscreenIconBox.y + fullscreenIcon->h )
1394
					)
1395
					{
1396
						fullscreenButtonHover = 1;
1397
						SDL_SetCursor(handCursor);
1398
					}
1399
					//If not
1400
					else
1326
					
1327
					for(i=0; i<NBUTTONS; i++)
1401 1328
					{
1402
						fullscreenButtonHover = 0;
1403
						SDL_SetCursor(defaultCursor);
1329
						//If the mouse is over the button
1330
						if(
1331
							( x > Buttons[i].ButtonIconBox.x ) && ( x < Buttons[i].ButtonIconBox.x + Buttons[i].ButtonIcon->w )
1332
							&& ( y > Buttons[i].ButtonIconBox.y ) && ( y < Buttons[i].ButtonIconBox.y + Buttons[i].ButtonIcon->h )
1333
						)
1334
						{
1335
							Buttons[i].Hover = 1;
1336
							SDL_SetCursor(handCursor);
1337
							break;
1338
						}
1339
						
1340
						else
1341
						{
1342
							Buttons[i].Hover = 0;
1343
							SDL_SetCursor(defaultCursor);
1344
						}
1404 1345
					}
1405 1346
				break;
1406 1347
				case SDL_MOUSEBUTTONUP:
1407 1348
					//printf("\tSDL_MOUSEBUTTONUP\n");
1408 1349
					if( event.button.button != SDL_BUTTON_LEFT )
1409
        					break;
1350
						break;
1410 1351
					
1411 1352
					x = event.motion.x;
1412 1353
					y = event.motion.y;
1413
					//If the mouse is over the button
1414
					if(
1415
						( x > fullscreenIconBox.x ) && ( x < fullscreenIconBox.x + fullscreenIcon->w )
1416
						&& ( y > fullscreenIconBox.y ) && ( y < fullscreenIconBox.y + fullscreenIcon->h )
1417
					)
1354
					
1355
					for(i=0; i<NBUTTONS; i++)
1418 1356
					{
1419
						
1420
						// if running, pause until resize has done
1421
						if(CurrStatus == RUNNING)
1422
						{
1423
							QueueStopped = 1;
1424
							CurrStatus = PAUSED;
1425
							tmp_switch = 1;
1426
						}
1427
						
1428
						toggle_fullscreen();
1429
						
1430
						fullscreenButtonHover = 1;
1431
						
1432
						if(tmp_switch)
1357
						//If the mouse is over the button
1358
						if(
1359
							( x > Buttons[i].ButtonIconBox.x ) && ( x < Buttons[i].ButtonIconBox.x + Buttons[i].ButtonIcon->w )
1360
							&& ( y > Buttons[i].ButtonIconBox.y ) && ( y < Buttons[i].ButtonIconBox.y + Buttons[i].ButtonIcon->h )
1361
						)
1433 1362
						{
1434
							QueueStopped = 0;
1435
							CurrStatus= RUNNING;
1436
							tmp_switch = 0;
1363
							Buttons[i].LButtonUpCallback();
1364
							break;
1437 1365
						}
1438 1366
					}
1439 1367
				break;
......
1452 1380
	SDL_CloseAudio();
1453 1381
	//SDL_DestroyMutex(timing_mutex);
1454 1382
	SDL_Quit();
1383
	
1384
	if(child_pid > 0)
1385
		KILL_PROCESS(child_pid);
1386
	
1455 1387
	av_free(aCodecCtx);
1456 1388
	free(AudioPkt.data);
1457 1389
	free(VideoPkt.data);
......
1642 1574
	return SDL_CreateCursor(data, mask, 32, 32, hot_x, hot_y);
1643 1575
}
1644 1576

  
1645
void refresh_fullscreen_button(int hover)
1646
{
1647
	if(!hover)
1648
	{
1649
		if(!fullscreen)
1650
		{
1651
			SDL_BlitSurface(fullscreenIcon, NULL, screen, &fullscreenIconBox);
1652
			SDL_UpdateRects(screen, 1, &fullscreenIconBox);
1653
		}
1654
		else
1655
		{
1656
			SDL_BlitSurface(nofullscreenIcon, NULL, screen, &fullscreenIconBox);
1657
			SDL_UpdateRects(screen, 1, &fullscreenIconBox);
1658
		}
1659
	}
1660
	else
1661
	{
1662
		if(!fullscreen)
1663
		{
1664
			SDL_BlitSurface(fullscreenHoverIcon, NULL, screen, &fullscreenIconBox);
1665
			SDL_UpdateRects(screen, 1, &fullscreenIconBox);
1666
		}
1667
		else
1668
		{
1669
			SDL_BlitSurface(nofullscreenHoverIcon, NULL, screen, &fullscreenIconBox);
1670
			SDL_UpdateRects(screen, 1, &fullscreenIconBox);
1671
		}
1672
	}
1673
}
1674

  
1675 1577
void aspect_ratio_resize(float aspect_ratio, int width, int height, int* out_width, int* out_height)
1676 1578
{
1677 1579
	int h,w,x,y;
......
1691 1593

  
1692 1594
void toggle_fullscreen()
1693 1595
{
1596
	SDL_LockMutex(RedrawMutex);
1597
	
1598
	int i;
1599
	
1694 1600
	//If the screen is windowed
1695 1601
	if( !fullscreen )
1696 1602
	{
1697 1603
		//Set the screen to fullscreen
1698 1604
#ifndef __DARWIN__
1699
		// screen = SDL_SetVideoMode(FULLSCREEN_WIDTH, FULLSCREEN_HEIGHT, 0, SDL_SWSURFACE | SDL_RESIZABLE | SDL_FULLSCREEN);
1700 1605
		screen = SDL_SetVideoMode(FULLSCREEN_WIDTH, FULLSCREEN_HEIGHT, 0, SDL_SWSURFACE | SDL_NOFRAME | SDL_FULLSCREEN);
1701 1606
#else
1702
		// screen = SDL_SetVideoMode(FULLSCREEN_WIDTH, FULLSCREEN_HEIGHT, 24, SDL_SWSURFACE | SDL_RESIZABLE | SDL_FULLSCREEN);
1703 1607
		screen = SDL_SetVideoMode(FULLSCREEN_WIDTH, FULLSCREEN_HEIGHT, 24, SDL_SWSURFACE | SDL_NOFRAME | SDL_FULLSCREEN);
1704 1608
#endif
1705 1609

  
......
1710 1614
			exit(1);
1711 1615
		}
1712 1616
		
1713
		aspect_ratio_rect(ratio, FULLSCREEN_WIDTH, FULLSCREEN_HEIGHT - BUTTONS_LAYER_OFFSET - fullscreenIconBox.h);
1714
		fullscreenIconBox.x = (FULLSCREEN_WIDTH - fullscreenIcon->w) / 2;
1715
		// fullscreenIcon.y = rect.y+rect.h + (BUTTONS_LAYER_OFFSET/2); // put the button just below the video overlay
1716
		fullscreenIconBox.y = FULLSCREEN_HEIGHT - fullscreenIconBox.h - (BUTTONS_LAYER_OFFSET/2); // put the button at the bottom edge of the screen
1617
		// update the overlay surface size, mantaining the aspect ratio
1618
		aspect_ratio_rect(ratio, FULLSCREEN_WIDTH, FULLSCREEN_HEIGHT - BUTTONS_LAYER_OFFSET - BUTTONS_CONTAINER_HEIGHT);
1717 1619
		
1620
		// update each button coordinates
1621
		for(i=0; i<NBUTTONS; i++)
1622
		{
1623
			if(Buttons[i].XOffset > 0)
1624
				Buttons[i].ButtonIconBox.x = Buttons[i].XOffset;
1625
			else
1626
				Buttons[i].ButtonIconBox.x = (FULLSCREEN_WIDTH + Buttons[i].XOffset);
1627
				
1628
			Buttons[i].ButtonIconBox.y = FULLSCREEN_HEIGHT - Buttons[i].ButtonIconBox.h - (BUTTONS_LAYER_OFFSET/2);
1629
		}
1630

  
1718 1631
		//Set the window state flag
1719 1632
		fullscreen = 1;
1633
		
1634
		Buttons[FULLSCREEN_BUTTON_INDEX].Visible = 0;
1635
		Buttons[NO_FULLSCREEN_BUTTON_INDEX].Visible = 1;
1720 1636
	}
1721 1637
	
1722 1638
	//If the screen is fullscreen
......
1736 1652
			exit(1);
1737 1653
		}
1738 1654
		
1739
		aspect_ratio_rect(ratio, window_width, window_height - BUTTONS_LAYER_OFFSET - fullscreenIconBox.h);
1740
		fullscreenIconBox.x = (window_width - fullscreenIcon->w) / 2;
1741
		// fullscreenIcon.y = rect.y+rect.h + (BUTTONS_LAYER_OFFSET/2); // put the button just below the video overlay
1742
		fullscreenIconBox.y = window_height - fullscreenIconBox.h - (BUTTONS_LAYER_OFFSET/2); // put the button at the bottom edge of the screen
1655
		// update the overlay surface size, mantaining the aspect ratio
1656
		aspect_ratio_rect(ratio, window_width, window_height - BUTTONS_LAYER_OFFSET - BUTTONS_CONTAINER_HEIGHT);
1657
		
1658
		// update each button coordinates
1659
		for(i=0; i<NBUTTONS; i++)
1660
		{
1661
			if(Buttons[i].XOffset > 0)
1662
				Buttons[i].ButtonIconBox.x = Buttons[i].XOffset;
1663
			else
1664
				Buttons[i].ButtonIconBox.x = (window_width + Buttons[i].XOffset);
1665
				
1666
			Buttons[i].ButtonIconBox.y = window_height - Buttons[i].ButtonIconBox.h - (BUTTONS_LAYER_OFFSET/2);
1667
		}
1743 1668
		
1744 1669
		//Set the window state flag
1745 1670
		fullscreen = 0;
1671
		
1672
		Buttons[FULLSCREEN_BUTTON_INDEX].Visible = 1;
1673
		Buttons[NO_FULLSCREEN_BUTTON_INDEX].Visible = 0;
1674
	}
1675
	
1676
	redraw_buttons();
1677
	
1678
	SDL_UnlockMutex(RedrawMutex);
1679
}
1680

  
1681
int parse_conf()
1682
{
1683
	int j;
1684
	
1685
	// PARSING CONF FILE
1686
	cfg_opt_t channel_opts[] =
1687
	{
1688
		CFG_STR("Title", "", CFGF_NONE),
1689
		CFG_STR("LaunchString", "", CFGF_NONE),
1690
		CFG_END()
1691
	};
1692
	cfg_opt_t opts[] =
1693
	{
1694
		CFG_STR("ExecPath", DEFAULT_CHANNEL_EXEC_PATH, CFGF_NONE),
1695
		CFG_STR("ExecName", DEFAULT_CHANNEL_EXEC_NAME, CFGF_NONE),
1696
		CFG_SEC("Channel", channel_opts, CFGF_TITLE | CFGF_MULTI),
1697
		CFG_END()
1698
	};
1699
	cfg_t *cfg, *cfg_channel;
1700
	cfg = cfg_init(opts, CFGF_NONE);
1701
	if(cfg_parse(cfg, DEFAULT_CONF_FILENAME) == CFG_PARSE_ERROR)
1702
	{
1703
		return 1;
1704
	}
1705
	sprintf(OfferStreamerPath, "%s", cfg_getstr(cfg, "ExecPath"));
1706
	sprintf(OfferStreamerFilename, "%s", cfg_getstr(cfg, "ExecName"));
1707
	for(j = 0; j < cfg_size(cfg, "Channel"); j++)
1708
	{
1709
		cfg_channel = cfg_getnsec(cfg, "Channel", j);
1710
		sprintf(Channels[j].Title, "%s", cfg_title(cfg_channel));
1711
		// printf("parsing channel %s...", Channels[j].Title);
1712
		// printf(", %s\n", cfg_getstr(cfg_channel, "LaunchString"));
1713
		sprintf(Channels[j].LaunchString, "%s", cfg_getstr(cfg_channel, "LaunchString"));
1714
		NChannels++;
1715
	}
1716
	cfg_free(cfg);
1717
	
1718
	return 0;
1719
}
1720

  
1721
void zap_down()
1722
{
1723
	SelectedChannel = ((SelectedChannel+1) %NChannels);
1724
	packet_queue_reset(&audioq, AUDIO);
1725
	packet_queue_reset(&videoq, VIDEO);
1726
	switch_channel(&(Channels[SelectedChannel]));
1727
}
1728

  
1729
void zap_up()
1730
{
1731
	SelectedChannel--;
1732
	if(SelectedChannel < 0)
1733
		SelectedChannel = NChannels-1;
1734
		
1735
	packet_queue_reset(&audioq, AUDIO);
1736
	packet_queue_reset(&videoq, VIDEO);
1737
	switch_channel(&(Channels[SelectedChannel]));
1738
}
1739

  
1740
int switch_channel(SChannel* channel)
1741
{
1742
	if(child_pid > 0)
1743
		KILL_PROCESS(child_pid);
1744
		
1745
	char* parameters_vector[255];
1746
	char argv0[255], parameters_string[255];
1747
	sprintf(argv0, "%s%s", OfferStreamerPath, OfferStreamerFilename);
1748
	
1749
	sprintf(parameters_string, "%s %s", argv0, channel->LaunchString);
1750
	
1751
	int par_count=0;
1752
	
1753
	// split parameters and count them
1754
	char* pch = strtok (parameters_string, " ");
1755
	
1756
	while (pch != NULL)
1757
	{
1758
		if(par_count > 255) break;
1759
		// printf ("%s\n",pch);
1760
		parameters_vector[par_count] = (char*) malloc(sizeof(char)*strlen(pch));
1761
		strcpy(parameters_vector[par_count], pch);
1762
		pch = strtok (NULL, " ");
1763
		par_count++;
1764
	}
1765
	parameters_vector[par_count] = NULL;
1766

  
1767
#ifdef __LINUX__
1768

  
1769
	int d;
1770
	int stdoutS, stderrS;
1771
	FILE* stream;
1772
	stream = fopen("/dev/null", "a+");
1773
	d = fileno(stream);
1774

  
1775
	// create backup descriptors for the current stdout and stderr devices
1776
	stdoutS = dup(STDOUT_FILENO);
1777
	stderrS = dup(STDERR_FILENO);
1778
	
1779
	// redirect child output to /dev/null
1780
	dup2(d, STDOUT_FILENO);
1781
	dup2(d, STDERR_FILENO);
1782

  
1783
	int pid = fork();
1784
	if(pid == 0)
1785
		execv(argv0, parameters_vector);
1786
	else
1787
		child_pid = pid;
1788
	
1789
	// restore backup descriptors in the parent process
1790
	dup2(stdoutS, STDOUT_FILENO);
1791
	dup2(stderrS, STDERR_FILENO);
1792
	
1793
	int i;
1794
	for(i=0; i<par_count; i++)
1795
		free(parameters_vector[i]);
1796
		
1797
	return 0;
1798
#endif
1799

  
1800
	return 1;
1801
}
1802

  
1803
void redraw_buttons()
1804
{
1805
	int i;
1806
	for(i=0; i<NBUTTONS; i++)
1807
	{
1808
		if(Buttons[i].Visible)
1809
		{
1810
			if(!Buttons[i].Hover)
1811
			{
1812
				SDL_BlitSurface(Buttons[i].ButtonIcon, NULL, screen, &Buttons[i].ButtonIconBox);
1813
				SDL_UpdateRects(screen, 1, &Buttons[i].ButtonIconBox);
1814
			}
1815
			else
1816
			{
1817
				SDL_BlitSurface(Buttons[i].ButtonHoverIcon, NULL, screen, &(Buttons[i].ButtonIconBox));
1818
				SDL_UpdateRects(screen, 1, &(Buttons[i].ButtonIconBox));
1819
			}
1820
		}
1746 1821
	}
1747 1822
}

Also available in: Unified diff