24 |
24 |
#include <SDL_thread.h>
|
25 |
25 |
#include <SDL_mutex.h>
|
26 |
26 |
#include <SDL_image.h>
|
|
27 |
#include <SDL_video.h>
|
27 |
28 |
#include <math.h>
|
28 |
29 |
#include <confuse.h>
|
29 |
30 |
|
... | ... | |
623 |
624 |
// resolution must be a multiple of two
|
624 |
625 |
pCodecCtx->width = tval->width;//176;//352;
|
625 |
626 |
pCodecCtx->height = tval->height;//144;//288;
|
|
627 |
|
626 |
628 |
// frames per second
|
627 |
629 |
//pCodecCtx->time_base = (AVRational){1,25};
|
628 |
630 |
//pCodecCtx->gop_size = 10; // emit one intra frame every ten frames
|
... | ... | |
643 |
645 |
printf("Memory error!!!\n");
|
644 |
646 |
return -1;
|
645 |
647 |
}
|
646 |
|
|
647 |
|
while(!quit) {
|
|
648 |
|
|
649 |
#ifdef DEBUG_VIDEO
|
|
650 |
printf("VIDEO: video_callback entering main cycle\n");
|
|
651 |
#endif
|
|
652 |
while(AVPlaying && !quit) {
|
648 |
653 |
if(QueueFillingMode || QueueStopped)
|
649 |
654 |
{
|
650 |
655 |
//SDL_LockMutex(timing_mutex);
|
... | ... | |
792 |
797 |
|
793 |
798 |
usleep(5000);
|
794 |
799 |
}
|
|
800 |
|
795 |
801 |
av_free(pCodecCtx);
|
796 |
802 |
//fclose(frecon);
|
797 |
803 |
#ifdef DEBUG_VIDEO
|
... | ... | |
800 |
806 |
return 1;
|
801 |
807 |
}
|
802 |
808 |
|
803 |
|
|
|
809 |
/**
|
|
810 |
* Updates the overlay surface size, mantaining the aspect ratio
|
|
811 |
*/
|
804 |
812 |
void aspect_ratio_rect(float aspect_ratio, int width, int height)
|
805 |
813 |
{
|
806 |
814 |
int h = 0, w = 0, x, y;
|
807 |
815 |
aspect_ratio_resize(aspect_ratio, width, height, &w, &h);
|
808 |
816 |
x = (width - w) / 2;
|
809 |
817 |
y = (height - h) / 2;
|
810 |
|
rect.x = x;//x;
|
811 |
|
rect.y = y;//y;
|
|
818 |
rect.x = x;
|
|
819 |
rect.y = y;
|
812 |
820 |
rect.w = w;
|
813 |
821 |
rect.h = h;
|
814 |
|
|
815 |
|
// printf("setting video mode %dx%d\n", rect.w, rect.h);
|
816 |
822 |
}
|
817 |
823 |
|
818 |
|
|
819 |
824 |
void audio_callback(void *userdata, Uint8 *stream, int len) {
|
820 |
825 |
|
821 |
826 |
//AVCodecContext *aCodecCtx = (AVCodecContext *)userdata;
|
... | ... | |
841 |
846 |
printf("IMG_Init: %s\n", IMG_GetError());
|
842 |
847 |
exit(1);
|
843 |
848 |
}
|
|
849 |
|
|
850 |
SDL_VideoInfo* InitialVideoInfo = SDL_GetVideoInfo();
|
|
851 |
FullscreenWidth = InitialVideoInfo->current_w;
|
|
852 |
FullscreenHeight = InitialVideoInfo->current_h;
|
|
853 |
|
|
854 |
// SDL_GetDesktopDisplayMode(&DesktopDisplayMode);
|
844 |
855 |
|
845 |
856 |
SDL_Surface *temp;
|
846 |
857 |
int screen_w = 0, screen_h = 0;
|
... | ... | |
953 |
964 |
Buttons[NO_FULLSCREEN_BUTTON_INDEX].ButtonIconBox.h = Buttons[NO_FULLSCREEN_BUTTON_INDEX].ButtonIcon->h;
|
954 |
965 |
Buttons[NO_FULLSCREEN_BUTTON_INDEX].ButtonIconBox.y = screen_h - Buttons[NO_FULLSCREEN_BUTTON_INDEX].ButtonIconBox.h - (BUTTONS_LAYER_OFFSET/2);
|
955 |
966 |
|
956 |
|
Buttons[CHANNEL_UP_BUTTON_INDEX].XOffset = -50;
|
|
967 |
Buttons[CHANNEL_UP_BUTTON_INDEX].XOffset = -61;
|
957 |
968 |
Buttons[CHANNEL_UP_BUTTON_INDEX].ButtonIconBox.w = Buttons[CHANNEL_UP_BUTTON_INDEX].ButtonIcon->w;
|
958 |
969 |
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);
|
|
970 |
Buttons[CHANNEL_UP_BUTTON_INDEX].ButtonIconBox.x = (screen_w + Buttons[CHANNEL_UP_BUTTON_INDEX].XOffset);
|
960 |
971 |
Buttons[CHANNEL_UP_BUTTON_INDEX].ButtonIconBox.y = screen_h - Buttons[CHANNEL_UP_BUTTON_INDEX].ButtonIconBox.h - (BUTTONS_LAYER_OFFSET/2);
|
961 |
972 |
|
962 |
|
Buttons[CHANNEL_DOWN_BUTTON_INDEX].XOffset = -25;
|
|
973 |
Buttons[CHANNEL_DOWN_BUTTON_INDEX].XOffset = -36;
|
963 |
974 |
Buttons[CHANNEL_DOWN_BUTTON_INDEX].ButtonIconBox.w = Buttons[CHANNEL_DOWN_BUTTON_INDEX].ButtonIcon->w;
|
964 |
975 |
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);
|
|
976 |
Buttons[CHANNEL_DOWN_BUTTON_INDEX].ButtonIconBox.x = (screen_w + Buttons[CHANNEL_DOWN_BUTTON_INDEX].XOffset);
|
966 |
977 |
Buttons[CHANNEL_DOWN_BUTTON_INDEX].ButtonIconBox.y = screen_h - Buttons[CHANNEL_DOWN_BUTTON_INDEX].ButtonIconBox.h - (BUTTONS_LAYER_OFFSET/2);
|
967 |
978 |
|
968 |
979 |
/** Setting up buttons events */
|
... | ... | |
1060 |
1071 |
memset((void*)Channels, 0, (255*sizeof(SChannel)));
|
1061 |
1072 |
|
1062 |
1073 |
int y;
|
1063 |
|
|
1064 |
|
uint8_t *outbuf,*outbuf_audio;
|
1065 |
|
uint8_t *outbuf_audi_audio;
|
1066 |
1074 |
int httpPort = -1;
|
|
1075 |
struct MHD_Daemon *daemon = NULL;
|
1067 |
1076 |
|
1068 |
|
AVFormatContext *pFormatCtx;
|
1069 |
|
|
1070 |
|
AVCodec *pCodec,*aCodec;
|
1071 |
|
AVFrame *pFrame;
|
1072 |
|
|
1073 |
|
AVPicture pict;
|
1074 |
|
SDL_Thread *video_thread;//exit_thread,*exit_thread2;
|
1075 |
1077 |
SDL_Event event;
|
1076 |
|
SDL_AudioSpec wanted_spec;
|
1077 |
|
|
1078 |
|
struct MHD_Daemon *daemon = NULL;
|
1079 |
1078 |
|
1080 |
1079 |
char buf[1024],outfile[1024], basereadfile[1024],readfile[1024];
|
1081 |
1080 |
FILE *fp;
|
1082 |
1081 |
int width,height,asample_rate,achannels;
|
1083 |
|
|
1084 |
|
ThreadVal *tval;
|
1085 |
|
tval = (ThreadVal *)malloc(sizeof(ThreadVal));
|
1086 |
1082 |
|
1087 |
|
if(argc<9) {
|
1088 |
|
printf("chunker_player width height aspect_ratio audio_sample_rate audio_channels queue_thresh httpd_port silentMode <YUVFilename>\n");
|
|
1083 |
if(argc<7) {
|
|
1084 |
printf("chunker_player width height aspect_ratio queue_thresh httpd_port silentMode <YUVFilename>\n");
|
1089 |
1085 |
exit(1);
|
1090 |
1086 |
}
|
1091 |
1087 |
sscanf(argv[1],"%d",&width);
|
1092 |
1088 |
sscanf(argv[2],"%d",&height);
|
1093 |
1089 |
sscanf(argv[3],"%f",&ratio);
|
1094 |
|
sscanf(argv[4],"%d",&asample_rate);
|
1095 |
|
sscanf(argv[5],"%d",&achannels);
|
1096 |
|
sscanf(argv[6],"%d",&queue_filling_threshold);
|
1097 |
|
sscanf(argv[7],"%d",&httpPort);
|
1098 |
|
sscanf(argv[8],"%d",&silentMode);
|
|
1090 |
sscanf(argv[4],"%d",&queue_filling_threshold);
|
|
1091 |
sscanf(argv[5],"%d",&httpPort);
|
|
1092 |
sscanf(argv[6],"%d",&silentMode);
|
1099 |
1093 |
|
1100 |
|
if(argc==10)
|
|
1094 |
if(argc==8)
|
1101 |
1095 |
{
|
1102 |
|
sscanf(argv[9],"%s",YUVFileName);
|
|
1096 |
sscanf(argv[7],"%s",YUVFileName);
|
1103 |
1097 |
printf("YUVFile: %s\n",YUVFileName);
|
1104 |
1098 |
FILE* fp=fopen(YUVFileName, "wb");
|
1105 |
1099 |
if(fp)
|
... | ... | |
1111 |
1105 |
printf("ERROR: Unable to create YUVFile\n");
|
1112 |
1106 |
}
|
1113 |
1107 |
|
1114 |
|
if(parse_conf())
|
1115 |
|
{
|
1116 |
|
printf("Error while parsing configuration file, exiting...\n");
|
1117 |
|
exit(1);
|
1118 |
|
}
|
1119 |
|
SelectedChannel = 0;
|
|
1108 |
//calculate aspect ratio and put updated values in rect
|
|
1109 |
aspect_ratio_rect(ratio, width, height);
|
1120 |
1110 |
|
1121 |
|
switch_channel(&(Channels[SelectedChannel]));
|
1122 |
|
|
1123 |
|
tval->width = width;
|
1124 |
|
tval->height = height;
|
1125 |
|
tval->aspect_ratio = ratio;
|
1126 |
|
|
1127 |
|
// Register all formats and codecs
|
1128 |
|
av_register_all();
|
1129 |
1111 |
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
|
1130 |
1112 |
fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
|
1131 |
1113 |
return -1;
|
1132 |
1114 |
}
|
1133 |
|
|
1134 |
|
aCodecCtx = avcodec_alloc_context();
|
1135 |
|
//aCodecCtx->bit_rate = 64000;
|
1136 |
|
aCodecCtx->sample_rate = asample_rate;
|
1137 |
|
aCodecCtx->channels = achannels;
|
1138 |
|
#ifdef MP3_AUDIO_ENCODER
|
1139 |
|
aCodec = avcodec_find_decoder(CODEC_ID_MP3); // codec audio
|
1140 |
|
#else
|
1141 |
|
aCodec = avcodec_find_decoder(CODEC_ID_MP2);
|
1142 |
|
#endif
|
1143 |
|
printf("MP2 codec id %d MP3 codec id %d\n",CODEC_ID_MP2,CODEC_ID_MP3);
|
1144 |
|
if(!aCodec) {
|
1145 |
|
printf("Codec not found!\n");
|
1146 |
|
return -1;
|
1147 |
|
}
|
1148 |
|
if(avcodec_open(aCodecCtx, aCodec)<0) {
|
1149 |
|
fprintf(stderr, "could not open codec\n");
|
1150 |
|
return -1; // Could not open codec
|
1151 |
|
}
|
1152 |
|
printf("using audio Codecid: %d ",aCodecCtx->codec_id);
|
1153 |
|
printf("samplerate: %d ",aCodecCtx->sample_rate);
|
1154 |
|
printf("channels: %d\n",aCodecCtx->channels);
|
1155 |
|
wanted_spec.freq = aCodecCtx->sample_rate;
|
1156 |
|
wanted_spec.format = AUDIO_S16SYS;
|
1157 |
|
wanted_spec.channels = aCodecCtx->channels;
|
1158 |
|
wanted_spec.silence = 0;
|
1159 |
|
wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
|
1160 |
|
wanted_spec.callback = audio_callback;
|
1161 |
|
wanted_spec.userdata = aCodecCtx;
|
|
1115 |
|
|
1116 |
RedrawMutex = SDL_CreateMutex();
|
1162 |
1117 |
if(!silentMode)
|
1163 |
|
if(SDL_OpenAudio(&wanted_spec,&spec)<0) {
|
1164 |
|
fprintf(stderr,"SDL_OpenAudio: %s\n",SDL_GetError());
|
1165 |
|
return -1;
|
1166 |
|
}
|
1167 |
|
dimAudioQ = spec.size;
|
1168 |
|
deltaAudioQ = (float)((float)spec.samples)*1000/spec.freq;
|
1169 |
|
|
1170 |
|
#ifdef DEBUG_AUDIO
|
1171 |
|
printf("freq:%d\n",spec.freq);
|
1172 |
|
printf("format:%d\n",spec.format);
|
1173 |
|
printf("channels:%d\n",spec.channels);
|
1174 |
|
printf("silence:%d\n",spec.silence);
|
1175 |
|
printf("samples:%d\n",spec.samples);
|
1176 |
|
printf("size:%d\n",spec.size);
|
1177 |
|
printf("deltaAudioQ: %f\n",deltaAudioQ);
|
1178 |
|
#endif
|
1179 |
|
|
1180 |
|
pFrame=avcodec_alloc_frame();
|
1181 |
|
if(pFrame==NULL) {
|
1182 |
|
printf("Memory error!!!\n");
|
1183 |
|
return -1;
|
|
1118 |
SetupGUI();
|
|
1119 |
|
|
1120 |
if(parse_conf())
|
|
1121 |
{
|
|
1122 |
printf("Error while parsing configuration file, exiting...\n");
|
|
1123 |
exit(1);
|
1184 |
1124 |
}
|
1185 |
|
outbuf_audio = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
|
1186 |
|
|
1187 |
|
//initialize the audio and the video queues
|
1188 |
|
packet_queue_init(&audioq, AUDIO);
|
1189 |
|
packet_queue_init(&videoq, VIDEO);
|
1190 |
|
|
1191 |
|
//calculate aspect ratio and put updated values in rect
|
1192 |
|
aspect_ratio_rect(ratio, width, height);
|
|
1125 |
|
|
1126 |
SelectedChannel = 0;
|
|
1127 |
switch_channel(&(Channels[SelectedChannel]));
|
1193 |
1128 |
|
1194 |
1129 |
initRect = (SDL_Rect*) malloc(sizeof(SDL_Rect));
|
1195 |
1130 |
if(!initRect)
|
... | ... | |
1202 |
1137 |
initRect->w = rect.w;
|
1203 |
1138 |
initRect->h = rect.h;
|
1204 |
1139 |
|
1205 |
|
RedrawMutex = SDL_CreateMutex();
|
1206 |
|
if(!silentMode)
|
1207 |
|
SetupGUI();
|
1208 |
|
|
1209 |
|
// Init audio and video buffers
|
1210 |
|
av_init_packet(&AudioPkt);
|
1211 |
|
av_init_packet(&VideoPkt);
|
1212 |
|
AudioPkt.data=(uint8_t *)malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
|
1213 |
|
if(!AudioPkt.data) return 0;
|
1214 |
|
VideoPkt.data=(uint8_t *)malloc(width*height*3/2);
|
1215 |
|
if(!VideoPkt.data) return 0;
|
1216 |
|
|
1217 |
|
SDL_PauseAudio(0);
|
1218 |
|
video_thread = SDL_CreateThread(video_callback,tval);
|
1219 |
|
|
1220 |
1140 |
//this thread fetches chunks from the network by listening to the following path, port
|
1221 |
1141 |
daemon = initChunkPuller(UL_DEFAULT_EXTERNALPLAYER_PATH, httpPort);
|
1222 |
|
CurrStatus = RUNNING;
|
|
1142 |
|
|
1143 |
if(daemon == NULL)
|
|
1144 |
{
|
|
1145 |
printf("CANNOT START MICROHTTPD SERVICE, EXITING...\n");
|
|
1146 |
exit(2);
|
|
1147 |
}
|
1223 |
1148 |
|
1224 |
1149 |
// Wait for user input
|
1225 |
1150 |
while(!quit) {
|
... | ... | |
1293 |
1218 |
case SDL_ACTIVEEVENT:
|
1294 |
1219 |
//printf("\tSDL_ACTIVEEVENT\n");
|
1295 |
1220 |
// if the window was iconified or restored
|
1296 |
|
/*if(event.active.state & SDL_APPACTIVE)
|
|
1221 |
if(event.active.state & SDL_APPACTIVE)
|
1297 |
1222 |
{
|
1298 |
1223 |
//If the application is being reactivated
|
1299 |
1224 |
if( event.active.gain != 0 )
|
1300 |
1225 |
{
|
1301 |
1226 |
//SDL_WM_SetCaption( "Window Event Test restored", NULL );
|
|
1227 |
redraw_buttons();
|
1302 |
1228 |
}
|
1303 |
1229 |
}
|
1304 |
1230 |
|
... | ... | |
1308 |
1234 |
//If the application gained keyboard focus
|
1309 |
1235 |
if( event.active.gain != 0 )
|
1310 |
1236 |
{
|
|
1237 |
redraw_buttons();
|
1311 |
1238 |
}
|
1312 |
1239 |
}
|
1313 |
1240 |
//If something happened to the mouse focus
|
... | ... | |
1316 |
1243 |
//If the application gained mouse focus
|
1317 |
1244 |
if( event.active.gain != 0 )
|
1318 |
1245 |
{
|
|
1246 |
redraw_buttons();
|
1319 |
1247 |
}
|
1320 |
|
}*/
|
|
1248 |
}
|
1321 |
1249 |
break;
|
1322 |
1250 |
case SDL_MOUSEMOTION:
|
1323 |
1251 |
//printf("\tSDL_MOUSEMOTION\n");
|
... | ... | |
1373 |
1301 |
|
1374 |
1302 |
//TERMINATE
|
1375 |
1303 |
IMG_Quit();
|
1376 |
|
|
1377 |
|
// Stop audio&video playback
|
1378 |
|
SDL_WaitThread(video_thread,NULL);
|
1379 |
|
SDL_PauseAudio(1);
|
1380 |
|
SDL_CloseAudio();
|
1381 |
|
//SDL_DestroyMutex(timing_mutex);
|
1382 |
1304 |
SDL_Quit();
|
1383 |
|
|
1384 |
|
if(child_pid > 0)
|
1385 |
|
KILL_PROCESS(child_pid);
|
1386 |
|
|
1387 |
|
av_free(aCodecCtx);
|
1388 |
|
free(AudioPkt.data);
|
1389 |
|
free(VideoPkt.data);
|
1390 |
|
free(outbuf_audio);
|
1391 |
1305 |
finalizeChunkPuller(daemon);
|
1392 |
|
free(tval);
|
1393 |
1306 |
free(initRect);
|
1394 |
1307 |
return 0;
|
1395 |
1308 |
}
|
... | ... | |
1602 |
1515 |
{
|
1603 |
1516 |
//Set the screen to fullscreen
|
1604 |
1517 |
#ifndef __DARWIN__
|
1605 |
|
screen = SDL_SetVideoMode(FULLSCREEN_WIDTH, FULLSCREEN_HEIGHT, 0, SDL_SWSURFACE | SDL_NOFRAME | SDL_FULLSCREEN);
|
|
1518 |
screen = SDL_SetVideoMode(FullscreenWidth, FullscreenHeight, 0, SDL_SWSURFACE | SDL_NOFRAME | SDL_FULLSCREEN);
|
1606 |
1519 |
#else
|
1607 |
|
screen = SDL_SetVideoMode(FULLSCREEN_WIDTH, FULLSCREEN_HEIGHT, 24, SDL_SWSURFACE | SDL_NOFRAME | SDL_FULLSCREEN);
|
|
1520 |
screen = SDL_SetVideoMode(FullscreenWidth, FullscreenHeight, 24, SDL_SWSURFACE | SDL_NOFRAME | SDL_FULLSCREEN);
|
1608 |
1521 |
#endif
|
1609 |
1522 |
|
1610 |
1523 |
//If there's an error
|
... | ... | |
1615 |
1528 |
}
|
1616 |
1529 |
|
1617 |
1530 |
// update the overlay surface size, mantaining the aspect ratio
|
1618 |
|
aspect_ratio_rect(ratio, FULLSCREEN_WIDTH, FULLSCREEN_HEIGHT - BUTTONS_LAYER_OFFSET - BUTTONS_CONTAINER_HEIGHT);
|
|
1531 |
aspect_ratio_rect(ratio, FullscreenWidth, FullscreenHeight - BUTTONS_LAYER_OFFSET - BUTTONS_CONTAINER_HEIGHT);
|
1619 |
1532 |
|
1620 |
1533 |
// update each button coordinates
|
1621 |
1534 |
for(i=0; i<NBUTTONS; i++)
|
... | ... | |
1623 |
1536 |
if(Buttons[i].XOffset > 0)
|
1624 |
1537 |
Buttons[i].ButtonIconBox.x = Buttons[i].XOffset;
|
1625 |
1538 |
else
|
1626 |
|
Buttons[i].ButtonIconBox.x = (FULLSCREEN_WIDTH + Buttons[i].XOffset);
|
|
1539 |
Buttons[i].ButtonIconBox.x = (FullscreenWidth + Buttons[i].XOffset);
|
1627 |
1540 |
|
1628 |
|
Buttons[i].ButtonIconBox.y = FULLSCREEN_HEIGHT - Buttons[i].ButtonIconBox.h - (BUTTONS_LAYER_OFFSET/2);
|
|
1541 |
Buttons[i].ButtonIconBox.y = FullscreenHeight - Buttons[i].ButtonIconBox.h - (BUTTONS_LAYER_OFFSET/2);
|
1629 |
1542 |
}
|
1630 |
1543 |
|
1631 |
1544 |
//Set the window state flag
|
... | ... | |
1651 |
1564 |
fprintf(stderr, "SDL_SetVideoMode returned null: could not toggle fullscreen mode - exiting\n");
|
1652 |
1565 |
exit(1);
|
1653 |
1566 |
}
|
|
1567 |
// CurrentVideoInfo = SDL_GetVideoInfo();
|
1654 |
1568 |
|
1655 |
1569 |
// update the overlay surface size, mantaining the aspect ratio
|
1656 |
1570 |
aspect_ratio_rect(ratio, window_width, window_height - BUTTONS_LAYER_OFFSET - BUTTONS_CONTAINER_HEIGHT);
|
... | ... | |
1687 |
1601 |
{
|
1688 |
1602 |
CFG_STR("Title", "", CFGF_NONE),
|
1689 |
1603 |
CFG_STR("LaunchString", "", CFGF_NONE),
|
|
1604 |
CFG_INT("AudioChannels", 2, CFGF_NONE),
|
|
1605 |
CFG_INT("SampleRate", 48000, CFGF_NONE),
|
|
1606 |
CFG_INT("Width", 176, CFGF_NONE),
|
|
1607 |
CFG_INT("Height", 144, CFGF_NONE),
|
|
1608 |
CFG_FLOAT("Ratio", 1.22, CFGF_NONE),
|
1690 |
1609 |
CFG_END()
|
1691 |
1610 |
};
|
1692 |
1611 |
cfg_opt_t opts[] =
|
... | ... | |
1711 |
1630 |
// printf("parsing channel %s...", Channels[j].Title);
|
1712 |
1631 |
// printf(", %s\n", cfg_getstr(cfg_channel, "LaunchString"));
|
1713 |
1632 |
sprintf(Channels[j].LaunchString, "%s", cfg_getstr(cfg_channel, "LaunchString"));
|
|
1633 |
Channels[j].Width = cfg_getint(cfg_channel, "Width");
|
|
1634 |
Channels[j].Height = cfg_getint(cfg_channel, "Height");
|
|
1635 |
Channels[j].AudioChannels = cfg_getint(cfg_channel, "AudioChannels");
|
|
1636 |
Channels[j].SampleRate = cfg_getint(cfg_channel, "SampleRate");
|
|
1637 |
Channels[j].Ratio = cfg_getfloat(cfg_channel, "Ratio");
|
1714 |
1638 |
NChannels++;
|
1715 |
1639 |
}
|
1716 |
1640 |
cfg_free(cfg);
|
... | ... | |
1721 |
1645 |
void zap_down()
|
1722 |
1646 |
{
|
1723 |
1647 |
SelectedChannel = ((SelectedChannel+1) %NChannels);
|
1724 |
|
packet_queue_reset(&audioq, AUDIO);
|
1725 |
|
packet_queue_reset(&videoq, VIDEO);
|
1726 |
1648 |
switch_channel(&(Channels[SelectedChannel]));
|
1727 |
1649 |
}
|
1728 |
1650 |
|
... | ... | |
1731 |
1653 |
SelectedChannel--;
|
1732 |
1654 |
if(SelectedChannel < 0)
|
1733 |
1655 |
SelectedChannel = NChannels-1;
|
1734 |
|
|
1735 |
|
packet_queue_reset(&audioq, AUDIO);
|
1736 |
|
packet_queue_reset(&videoq, VIDEO);
|
|
1656 |
|
1737 |
1657 |
switch_channel(&(Channels[SelectedChannel]));
|
1738 |
1658 |
}
|
1739 |
1659 |
|
1740 |
1660 |
int switch_channel(SChannel* channel)
|
1741 |
1661 |
{
|
|
1662 |
if(AVPlaying)
|
|
1663 |
StopAVPlaying();
|
|
1664 |
|
1742 |
1665 |
if(child_pid > 0)
|
1743 |
1666 |
KILL_PROCESS(child_pid);
|
1744 |
1667 |
|
|
1668 |
InitCodecs(channel);
|
|
1669 |
|
1745 |
1670 |
char* parameters_vector[255];
|
1746 |
1671 |
char argv0[255], parameters_string[255];
|
1747 |
1672 |
sprintf(argv0, "%s%s", OfferStreamerPath, OfferStreamerFilename);
|
... | ... | |
1820 |
1745 |
}
|
1821 |
1746 |
}
|
1822 |
1747 |
}
|
|
1748 |
|
|
1749 |
int InitCodecs(SChannel* channel)
|
|
1750 |
{
|
|
1751 |
SDL_AudioSpec wanted_spec;
|
|
1752 |
|
|
1753 |
AVFormatContext *pFormatCtx;
|
|
1754 |
AVCodec *aCodec;
|
|
1755 |
AVFrame *pFrame;
|
|
1756 |
|
|
1757 |
AVPicture pict;
|
|
1758 |
|
|
1759 |
uint8_t *outbuf;
|
|
1760 |
uint8_t *outbuf_audi_audio;
|
|
1761 |
|
|
1762 |
memset(&VideoCallbackThreadParams, 0, sizeof(ThreadVal));
|
|
1763 |
|
|
1764 |
VideoCallbackThreadParams.width = channel->Width;
|
|
1765 |
VideoCallbackThreadParams.height = channel->Height;
|
|
1766 |
VideoCallbackThreadParams.aspect_ratio = channel->Ratio;
|
|
1767 |
|
|
1768 |
// Register all formats and codecs
|
|
1769 |
av_register_all();
|
|
1770 |
|
|
1771 |
aCodecCtx = avcodec_alloc_context();
|
|
1772 |
//aCodecCtx->bit_rate = 64000;
|
|
1773 |
aCodecCtx->sample_rate = channel->SampleRate;
|
|
1774 |
aCodecCtx->channels = channel->AudioChannels;
|
|
1775 |
#ifdef MP3_AUDIO_ENCODER
|
|
1776 |
aCodec = avcodec_find_decoder(CODEC_ID_MP3); // codec audio
|
|
1777 |
#else
|
|
1778 |
aCodec = avcodec_find_decoder(CODEC_ID_MP2);
|
|
1779 |
#endif
|
|
1780 |
printf("MP2 codec id %d MP3 codec id %d\n",CODEC_ID_MP2,CODEC_ID_MP3);
|
|
1781 |
if(!aCodec) {
|
|
1782 |
printf("Codec not found!\n");
|
|
1783 |
return -1;
|
|
1784 |
}
|
|
1785 |
if(avcodec_open(aCodecCtx, aCodec)<0) {
|
|
1786 |
fprintf(stderr, "could not open codec\n");
|
|
1787 |
return -1; // Could not open codec
|
|
1788 |
}
|
|
1789 |
printf("using audio Codecid: %d ",aCodecCtx->codec_id);
|
|
1790 |
printf("samplerate: %d ",aCodecCtx->sample_rate);
|
|
1791 |
printf("channels: %d\n",aCodecCtx->channels);
|
|
1792 |
wanted_spec.freq = aCodecCtx->sample_rate;
|
|
1793 |
wanted_spec.format = AUDIO_S16SYS;
|
|
1794 |
wanted_spec.channels = aCodecCtx->channels;
|
|
1795 |
wanted_spec.silence = 0;
|
|
1796 |
wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
|
|
1797 |
wanted_spec.callback = audio_callback;
|
|
1798 |
wanted_spec.userdata = aCodecCtx;
|
|
1799 |
if(!silentMode)
|
|
1800 |
if(SDL_OpenAudio(&wanted_spec,&spec)<0) {
|
|
1801 |
fprintf(stderr,"SDL_OpenAudio: %s\n",SDL_GetError());
|
|
1802 |
return -1;
|
|
1803 |
}
|
|
1804 |
dimAudioQ = spec.size;
|
|
1805 |
deltaAudioQ = (float)((float)spec.samples)*1000/spec.freq;
|
|
1806 |
|
|
1807 |
#ifdef DEBUG_AUDIO
|
|
1808 |
printf("freq:%d\n",spec.freq);
|
|
1809 |
printf("format:%d\n",spec.format);
|
|
1810 |
printf("channels:%d\n",spec.channels);
|
|
1811 |
printf("silence:%d\n",spec.silence);
|
|
1812 |
printf("samples:%d\n",spec.samples);
|
|
1813 |
printf("size:%d\n",spec.size);
|
|
1814 |
printf("deltaAudioQ: %f\n",deltaAudioQ);
|
|
1815 |
#endif
|
|
1816 |
|
|
1817 |
pFrame=avcodec_alloc_frame();
|
|
1818 |
if(pFrame==NULL) {
|
|
1819 |
printf("Memory error!!!\n");
|
|
1820 |
return -1;
|
|
1821 |
}
|
|
1822 |
outbuf_audio = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
|
|
1823 |
|
|
1824 |
//initialize the audio and the video queues
|
|
1825 |
packet_queue_init(&audioq, AUDIO);
|
|
1826 |
packet_queue_init(&videoq, VIDEO);
|
|
1827 |
|
|
1828 |
// Init audio and video buffers
|
|
1829 |
av_init_packet(&AudioPkt);
|
|
1830 |
av_init_packet(&VideoPkt);
|
|
1831 |
AudioPkt.data=(uint8_t *)malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
|
|
1832 |
if(!AudioPkt.data) return 0;
|
|
1833 |
VideoPkt.data=(uint8_t *)malloc(channel->Width*channel->Height*3/2);
|
|
1834 |
if(!VideoPkt.data) return 0;
|
|
1835 |
|
|
1836 |
SDL_PauseAudio(0);
|
|
1837 |
|
|
1838 |
AVPlaying = 1;
|
|
1839 |
video_thread = SDL_CreateThread(video_callback, &VideoCallbackThreadParams);
|
|
1840 |
|
|
1841 |
return 0;
|
|
1842 |
}
|
|
1843 |
|
|
1844 |
int StopAVPlaying()
|
|
1845 |
{
|
|
1846 |
AVPlaying = 0;
|
|
1847 |
|
|
1848 |
// Stop audio&video playback
|
|
1849 |
SDL_WaitThread(video_thread, NULL);
|
|
1850 |
SDL_PauseAudio(1);
|
|
1851 |
SDL_CloseAudio();
|
|
1852 |
//SDL_DestroyMutex(timing_mutex);
|
|
1853 |
|
|
1854 |
packet_queue_reset(&audioq, AUDIO);
|
|
1855 |
packet_queue_reset(&videoq, VIDEO);
|
|
1856 |
|
|
1857 |
av_free(aCodecCtx);
|
|
1858 |
free(AudioPkt.data);
|
|
1859 |
free(VideoPkt.data);
|
|
1860 |
free(outbuf_audio);
|
|
1861 |
|
|
1862 |
return 0;
|
|
1863 |
}
|