static int newThread(pthread_t * thread, const pthread_attr_t * attr, void *(*start_routine)(void*), void * arg) { int status; status = pthread_create(thread, attr, start_routine, arg); if (status) { WPRINT("Thread was not created!"); switch (status) { case EAGAIN: EPRINT("The system lacked the necessary resources to create " "another thread, or the system-imposed limit on the total " "number of threads in a process {PTHREAD_THREADS_MAX} " "would be exceeded."); break; case EINVAL: EPRINT("The value specified by attr is invalid."); break; case EPERM: EPRINT("The caller does not have appropriate permission to " "set the required " "scheduling parameters or scheduling policy."); break; default: EPRINT("Unknown error!"); break; } } return status; }
static int sanity_check_server_events(SServerConfigs *_this,SServerEvents *newevent) { /* Check that compulsory things exist */ if(newevent->eventType==0 ) { EPRINTC(PrintComp_IrcCfg,"Eventtype missing!"); goto ErrgetOutServer; } WPRINTC(PrintComp_IrcCfg,"No proper sanity checks for server event configs written!"); /* Fill non specified defaults */ if(NULL==newevent->event_string) { WPRINT ( "Text event with no event string specified! (eventId %d, server %s)", newevent->eventId, _this->domain ); } return 0; ErrgetOutServer: /* TODO: Find a way if callback for this ID is registered. If so, ignore all checks. */ EPRINTC(PrintComp_IrcCfg,"Invalid config for event %d on server %s",newevent->eventId,_this->domain); return -1; }
/** * Stop current playback. */ void SrvStop( void ) { int loc_going; int loc_fileIdx; int loc_everPlayed; int loc_playtype; LOCK_PLAYMUTEX(); loc_going = going; loc_fileIdx = fileIdx; loc_playtype = playtype; UNLOCK_PLAYMUTEX(); if (loc_going) // if playing, set history before shutdown. { char * path = NULL; char buf[PATH_MAX]; DBGMSG("Stop server playback."); switch (loc_playtype) { case NPT_FILE: LOCK_PLAYMUTEX(); path = strcpy(buf, trackName); UNLOCK_PLAYMUTEX(); break; case NPT_DIR: path = nextFileFromDir(loc_fileIdx,buf,PATH_MAX); break; default: //history not supported. WPRINT("play history not supported."); break; } LOCK_PLAYMUTEX(); loc_fileIdx = fileIdx; loc_everPlayed = everPlayed; UNLOCK_PLAYMUTEX(); if (path) { int mark; LOCK_PLAYMUTEX(); mark = playtime; UNLOCK_PLAYMUTEX(); if (loc_everPlayed) SetPlayHistory(loc_playtype, loc_fileIdx, mark, path); } } stopServer(); LOCK_PLAYMUTEX(); // player has been stop upon user request. errorStatus = NMS_STATUS_PLAYER_STOPPED; UNLOCK_PLAYMUTEX(); }
int aplogd_rambuf_space(int index) { int temp_filled = aplogd_rambuf_bytes_filled(index); if (temp_filled < 0 || temp_filled > aplogd_ram_buff_size) { WPRINT("Could not get bytes filled\n"); return -1; } return (aplogd_ram_buff_size - temp_filled); }
/* aplogd_io_remove_poll_fd() * * Description: This function removes an fd from the poll list * * @num: (int) Poll struct array offset to remove * * Return: None * * Notes: None */ void aplogd_io_remove_poll_fd(int num) { DPRINT("Removing fd %d (fd = %d) from list\n", num, aplogd_io_fd[num].fd); if (num < 0 || num >= APLOGD_MAX_IO_FDS ) { WPRINT("Poll index out of bounds\n"); return; } aplogd_io_fd[num].fd = -1; aplogd_io_fd[num].events = 0; aplogd_io_fd[num].revents = 0; }
int aplogd_rambuf_output(int index) { int ret_val = 0; int need_written = 0; int size_written = 0; /* From here on out we can only manipulate the output list */ VPRINT("output index:%d\n", index ); need_written=aplogd_rambuf_bytes_filled(index); VPRINT("need_written=%d.\n",need_written); if(!aplogd_io_array[index].input_buf_base || !(need_written >0)) { return -1; } if (aplogd_io_array[index].output_fd < 0) { WPRINT("output fd hasn't been initialized.\n"); aplogd_io_array[index].input_buf = aplogd_io_array[index].input_buf_base; ret_val = -1; return ret_val; } while(need_written >0) { size_written = write(aplogd_io_array[index].output_fd, (void*)aplogd_io_array[index].input_buf_base, need_written); if (size_written < 0 ) { EPRINT("output write: size_written=%d, errno=%d\n", size_written, errno); if (ENOSPC == errno) aplogd_close_output(); if (EBADF == errno) aplogd_io_array[index].output_fd=-1; ret_val=-1; return ret_val; } need_written -= size_written; total_write_size+=size_written; } aplogd_io_array[index].input_buf = aplogd_io_array[index].input_buf_base; if (total_write_size >=aplogd_logfile_max) { ALOGI("aplogd_logfile_max=%d, total_write_size=%d\n",aplogd_logfile_max, total_write_size); aplogd_close_output(); aplogd_io_backupall(g_current_storage); aplogd_output_setup(g_current_storage); total_write_size=0; } return ret_val; }
/* aplogd_io_fd_setup() * * Description: This function sets up a unix datagram socket at the path * provided. * * @pathname: (const char *) Desired unix socket path * * Return: (int) Sockets fd on success; -1 on failure * * Notes: None */ int aplogd_io_fd_setup(const char * pathname) { int fd = -1; DPRINT("Entered fd setup.pathname=%s\n",pathname); /* Setup sockaddr */ fd = open(pathname, O_RDONLY |O_NONBLOCK); if (fd < 0) { WPRINT("Couldn't open the file: %s\n",pathname); return -1; } DPRINT("Successfully returning fd: %d\n", fd); return fd; }
/** * Get file path. * */ int SrvGetFilePath(int idx, void * pathbuf,const int bufsize) { int ret = -1; char * pc = (char*)pathbuf; int loc_going; int loc_playtype; LOCK_PLAYMUTEX(); loc_going = going; loc_playtype = playtype; UNLOCK_PLAYMUTEX(); DBGMSG("get file path."); *pc = 0; if (loc_going) { if (loc_playtype == NPT_FILE) { LOCK_PLAYMUTEX(); strcpy(pc, trackName); UNLOCK_PLAYMUTEX(); ret = 0; } else if (loc_playtype == NPT_DIR) { if (idx >= 0) { nextFileFromDir(idx,pc,bufsize); //DBGMSG("filepath = [%s]", path); ret = 0; } } else { //FIXME: WPRINT("unknown play type."); } } return ret; }
int LogfilterAndBuffering( AndroidLogFormat *p_format, const AndroidLogEntry *entry, int index) { char *outBuffer = NULL; size_t totalLen=0; int ret_val=0; size_t len=0; if (0 == android_log_shouldPrintLine(p_format, entry->tag, entry->priority)) { VPRINT("No need to output.\n"); ret_val=0; return ret_val; } outBuffer = android_log_formatLogLine(p_format, defaultBuffer, sizeof(defaultBuffer), entry, &totalLen); if (!outBuffer){ EPRINT("Failed in android_log_formatLogLine.\n"); ret_val=-1; return ret_val; } len= aplogd_rambuf_space(index); if(len > totalLen ){ memcpy(aplogd_io_array[index].input_buf, outBuffer, totalLen); aplogd_io_array[index].input_buf += totalLen; ret_val=totalLen; if(outBuffer !=defaultBuffer) free(outBuffer); }else{ WPRINT("no enough buffer to contain log messages.len=%d totallen=%d.entry->messageLen=%d\n",len, totalLen,entry->messageLen); if(outBuffer !=defaultBuffer) free(outBuffer); ret_val=-1; aplogd_bytes_lost += totalLen; } return ret_val; }
/** * Server command receiver routine. * * @param pkt * packet node. * @return * 15 to exit command thread, all other value * are considered normal. */ int SrvRxCmd( void * pkt ) { int ret = 0; int acked = 0; pkt_node_t * p = (pkt_node_t *)pkt; DBGLOG("command: %d", p->hdr.cmd); switch (p->hdr.cmd) { case CMD_GET_VERSION: DBGLOG("CMD_GET_VERSION."); CoolCmdSendPacket(p->fd, CMD_GET_VERSION|NMS_CMD_ACK, (void*)version, strlen(version)+1); acked = 1; break; // careful: this will be the last command server responds to. case CMD_STOP_SERVER: DBGLOG("CMD_STOP_SERVER."); ret = 15; break; case CMD_SET_INPUT_MODE: DBGLOG("CMD_SET_INPUT_MODE."); EncInputSetMode(*(int*)p->data); break; case CMD_SET_OUTPUT_MODE: DBGLOG("CMD_SET_OUTPUT_MODE."); { OutputSetMode(*(int*)p->data); if (SrvIsMonitorActive()) { SrvStartMonitorInternal(); } else if (SrvIsRecording()) { } else if (SrvIsPlaying()) { OutputActivateMode(0); } } break; case CMD_SET_OUTPUT_PROPORTIONS: DBGLOG("CMD_SET_OUTPUT_PROPORTIONS."); SrvSetProportions((*(int*)p->data)); break; case CMD_GET_OUTPUT_PROPORTIONS: DBGLOG("CMD_GET_OUTPUT_PROPORTIONS."); int proportions = SrvGetProportions(); CoolCmdSendPacket(p->fd, CMD_GET_OUTPUT_PROPORTIONS|NMS_CMD_ACK, (void*)&proportions, sizeof(int)); acked = 1; break; case CMD_START_SLIDE_SHOW: DBGLOG("CMD_START_SLIDE_SHOW."); { int startslideshow; startslideshow = SrvStartSlideShow(); CoolCmdSendPacket(p->fd, CMD_START_SLIDE_SHOW|NMS_CMD_ACK, (void*)&startslideshow, sizeof(int)); acked = 1; DBGLOG("CMD_START_SLIDE_SHOW completed."); } break; case CMD_SET_SLIDE_SHOW_IMAGE: DBGLOG("CMD_SLIDE_SHOW_SET_IMAGE."); { SrvSlideShowSetImage((char *)p->data); } break; case CMD_STOP_SLIDE_SHOW: DBGLOG("CMD_SLIDE_SHOW_STOP."); SrvStopSlideShow(); break; case CMD_PLAY: DBGLOG("CMD_PLAY."); int ret = StartPlay(p->data, p->hdr.dataLen); CoolCmdSendPacket(p->fd, CMD_PLAY|NMS_CMD_ACK, (void*)&ret, sizeof(int)); acked = 1; break; case CMD_PAUSE_UNPAUSE: DBGLOG("CMD_PAUSE_UNPAUSE."); SrvPauseUnpause(); break; case CMD_STOP_PLAY: DBGLOG("CMD_STOP_PLAY."); SrvStop(); break; case CMD_GET_SRV_STATUS: DBGLOG("CMD_GET_SRV_STATUS."); { int status; status = SrvGetSrvStatus(); CoolCmdSendPacket(p->fd, CMD_GET_SRV_STATUS|NMS_CMD_ACK, (void*)&status, sizeof(int)); acked = 1; } break; case CMD_GET_VOLUME: DBGLOG("CMD_GET_VOLUME."); { int vol[2]; SrvGetVolume(&vol[0], &vol[1]); CoolCmdSendPacket(p->fd, CMD_GET_VOLUME|NMS_CMD_ACK, (void*)vol, sizeof(vol)); acked = 1; } break; case CMD_SET_VOLUME: DBGLOG("CMD_SET_VOLUME."); { int vol[2]; int * pv; pv = (int*)p->data; vol[0] = *pv++; vol[1] = *pv; SrvSetVolume(vol[0], vol[1]); } break; case CMD_GET_PLAY_TIME: DBGLOG("CMD_GET_PLAYTIME."); { int t; t = SrvGetPlaytime(); CoolCmdSendPacket(p->fd, CMD_GET_PLAY_TIME|NMS_CMD_ACK, (void*)&t, sizeof(int)); acked = 1; } break; case CMD_SEEK: DBGLOG("CMD_SEEK."); { int t; int *pv; pv = (int*)p->data; t = *pv; t = SrvSeek(t); CoolCmdSendPacket(p->fd, CMD_SEEK|NMS_CMD_ACK, (void*)&t, sizeof(int)); acked = 1; } break; case CMD_TRACK_CHANGE: DBGLOG("CMD_TRACK_CHANGE."); { int track; int *pv; int retv; pv = (int*)p->data; track = *pv; retv = SrvTrackChange(track); CoolCmdSendPacket(p->fd, CMD_TRACK_CHANGE|NMS_CMD_ACK, (void*)&retv, sizeof(int)); acked = 1; } break; case CMD_FF_RW: DBGLOG("CMD_FF_RW."); SrvFfRw(*(int*)p->data); break; case CMD_GET_FFRW_LEVEL: DBGLOG("CMD_GET_FFRW_LEVEL."); { int level = SrvGetFFRWLevel(); CoolCmdSendPacket(p->fd, CMD_GET_FFRW_LEVEL|NMS_CMD_ACK, (void*)&level, sizeof(int)); acked = 1; } break; case CMD_SF_RW: DBGLOG("CMD_SF_RW."); SrvSfRw(*(int*)p->data); break; case CMD_GET_SFRW_LEVEL: DBGLOG("CMD_GET_SFRW_LEVEL."); { int level = SrvGetSFRWLevel(); CoolCmdSendPacket(p->fd, CMD_GET_SFRW_LEVEL|NMS_CMD_ACK, (void*)&level, sizeof(int)); acked = 1; } break; case CMD_FRAME_BY_FRAME: DBGLOG("CMD_FRAME_BY_FRAME."); SrvFrameByFrame(*(int*)p->data); break; case CMD_REPEAT_A_B: DBGLOG("CMD_REPEAT_A_B."); SrvRepeatAB(*(int*)p->data); break; case CMD_GET_REPEAT_AB_STATUS: DBGLOG("CMD_GET_REPEAT_AB_STATUS."); { int status = SrvGetRepeatABStatus(); CoolCmdSendPacket(p->fd, CMD_GET_REPEAT_AB_STATUS|NMS_CMD_ACK, (void*)&status, sizeof(int)); acked = 1; } break; case CMD_IS_PLAYING: DBGLOG("CMD_IS_PLAYING."); { int playing = SrvIsPlaying(); CoolCmdSendPacket(p->fd, CMD_IS_PLAYING|NMS_CMD_ACK, (void*)&playing, sizeof(int)); acked = 1; } break; case CMD_GET_PLAYMODE: DBGLOG("CMD_GET_PLAYMODE."); { int mode = SrvGetPlaymode(); CoolCmdSendPacket(p->fd, CMD_GET_PLAYMODE|NMS_CMD_ACK, (void*)&mode, sizeof(int)); acked = 1; } break; case CMD_SET_PLAYMODE: DBGLOG("CMD_SET_PLAYMODE."); { SrvSetPlaymode(*((int*)p->data)); } break; case CMD_SET_EDITMODE: DBGLOG("CMD_SET_EDITMODE."); { SrvSetEditmode(*((int*)p->data)); } break; case CMD_GET_REPEATMODE: DBGLOG("CMD_GET_REPEATMODE."); { int mode = SrvGetRepeatmode(); CoolCmdSendPacket(p->fd, CMD_GET_REPEATMODE|NMS_CMD_ACK, (void*)&mode, sizeof(int)); acked = 1; } break; case CMD_SET_REPEATMODE: DBGLOG("CMD_SET_REPEATMODE."); { SrvSetRepeatmode(*((int*)p->data)); } break; case CMD_GET_TOTAL_FILES: DBGLOG("CMD_GET_TOTAL_FILES."); { int num = SrvGetTotalFiles(); CoolCmdSendPacket(p->fd, CMD_GET_TOTAL_FILES|NMS_CMD_ACK, (void*)&num, sizeof(int)); acked = 1; } break; case CMD_GET_FILE_INDEX: DBGLOG("CMD_GET_FILE_INDEX."); { int idx = SrvGetFileIndex(); CoolCmdSendPacket(p->fd, CMD_GET_FILE_INDEX|NMS_CMD_ACK, (void*)&idx, sizeof(int)); acked = 1; } break; case CMD_GET_FILE_PATH: DBGLOG("CMD_GET_FILE_PATH."); { char path[PATH_MAX]; int idx; int *pv; pv = (int*)p->data; idx = *pv; SrvGetFilePath(idx, path,PATH_MAX); CoolCmdSendPacket(p->fd, CMD_GET_FILE_PATH|NMS_CMD_ACK, (void*)path, strlen(path)+1); acked = 1; } break; case CMD_MEDIA_INFO: DBGLOG("CMD_MEDIA_INFO."); { media_info_t media_info; memset(&media_info, 0 , sizeof(media_info_t)); SrvGetMediaInfo((char *)p->data, &media_info); CoolCmdSendPacket(p->fd,CMD_MEDIA_INFO|NMS_CMD_ACK, (void *)(&media_info),sizeof(media_info_t)); acked = 1; } break; /* start of encoder interface. */ case CMD_RECORD: DBGLOG("CMD_RECORD."); NMS_SRV_ERROR_DETAIL result; StartRecord(p->data, p->hdr.dataLen, &result); CoolCmdSendPacket(p->fd, CMD_RECORD | NMS_CMD_ACK, (void *)(&result), sizeof(NMS_SRV_ERROR_DETAIL)); acked = 1; break; case CMD_PAUSE_UNPAUSE_RECORD: DBGLOG("CMD_PAUSE_UNPAUSE_RECORD."); SrvPauseRecord(*(int*)p->data); break; case CMD_STOP_RECORD: DBGLOG("CMD_STOP_RECORD."); SrvStopRecord(); break; case CMD_GET_GAIN: DBGLOG("CMD_GET_GAIN."); { int gain[2]; SrvGetGain(&gain[0], &gain[1]); CoolCmdSendPacket(p->fd, CMD_GET_GAIN|NMS_CMD_ACK, (void*)gain, sizeof(gain)); acked = 1; } break; case CMD_SET_GAIN: DBGLOG("CMD_SET_GAIN."); { int gain[2]; int * pg; pg = (int*)p->data; gain[0] = *pg++; gain[1] = *pg; SrvSetGain(gain[0], gain[1]); } break; case CMD_GET_RECORD_TIME: DBGLOG("CMD_GET_RECORD_TIME."); { int t; t = SrvGetRecordtime(); CoolCmdSendPacket(p->fd, CMD_GET_RECORD_TIME|NMS_CMD_ACK, (void*)&t, sizeof(int)); acked = 1; } break; case CMD_GET_RECORD_SIZE: DBGLOG("CMD_GET_RECORD_SIZE."); { unsigned int t; t = SrvGetRecordsize(); CoolCmdSendPacket(p->fd, CMD_GET_RECORD_SIZE|NMS_CMD_ACK, (void*)&t, sizeof(unsigned int)); acked = 1; } break; case CMD_GET_RECORD_ERROR: DBGLOG("CMD_GET_RECORD_ERROR."); { NMS_SRV_ERROR_DETAIL det; SrvGetRecordError(&det); CoolCmdSendPacket(p->fd, CMD_GET_RECORD_ERROR|NMS_CMD_ACK, (void*)&det, sizeof(NMS_SRV_ERROR_DETAIL)); acked = 1; } break; case CMD_IS_RECORDING: DBGLOG("CMD_IS_RECORDING."); { int recording = SrvIsRecording(); CoolCmdSendPacket(p->fd, CMD_IS_RECORDING|NMS_CMD_ACK, (void*)&recording, sizeof(int)); acked = 1; } break; case CMD_START_MONITOR: DBGLOG("CMD_START_MONITOR."); { int startmonitor; int pid = (*(int*)p->data); startmonitor = SrvStartMonitor(pid); CoolCmdSendPacket(p->fd, CMD_START_MONITOR|NMS_CMD_ACK, (void*)&startmonitor, sizeof(int)); acked = 1; DBGLOG("CMD_START_MONITOR completed."); } break; case CMD_STOP_MONITOR: DBGLOG("CMD_STOP_MONITOR."); int pid = (*(int*)p->data); SrvStopMonitor(pid); break; case CMD_IS_MONITOR_ENABLED: DBGLOG("CMD_IS_MONITOR_ENABLED."); { int monitoractive = SrvIsMonitorActive(); CoolCmdSendPacket(p->fd, CMD_IS_MONITOR_ENABLED|NMS_CMD_ACK, (void*)&monitoractive, sizeof(int)); acked = 1; } break; case CMD_CAP_INIT: DBGLOG("CMD_CAP_INIT."); { capture_desc_t desc; capture_ret_t capret; desc.capture_type = (*(int*)p->data); int suc = CaptureInit(&desc); if(suc) { capret.width = -1; capret.height = -1; } else { capret.width = desc.width; capret.height = desc.height; } capret.ret = suc; CoolCmdSendPacket(p->fd,CMD_CAP_INIT|NMS_CMD_ACK, (void *)(&capret),sizeof(capture_ret_t)); acked = 1; } break; case CMD_CAP_GET_FRAME: DBGLOG("CMD_CAP_GET_FRAME."); { frame_desc_t desc; int suc = CaptureGetFrame(&desc); if(suc) { CoolCmdSendPacket(p->fd, CMD_CAP_GET_FRAME|NMS_CMD_ACK, (void *)(&suc), sizeof(int)); } else { CoolCmdSendPacket(p->fd, CMD_CAP_GET_FRAME|NMS_CMD_ACK, (void *)(desc.data), desc.size); CaptureReleaseFrame(); } acked = 1; } break; case CMD_CAP_FINISH: DBGLOG("CMD_CAP_FINISH."); { int suc = CaptureFinish(); CoolCmdSendPacket(p->fd, CMD_CAP_FINISH|NMS_CMD_ACK, (void*)&suc, sizeof(int)); acked = 1; } break; case CMD_PING: DBGLOG("CMD_PING."); break; default: /* retain the data for now. */ WPRINT("unknown command, data retained."); ret = 1; break; } /* send back original command as ack. */ if (!acked) { CoolCmdSendPacket(p->fd, p->hdr.cmd|NMS_CMD_ACK, NULL, 0); DBGLOG("server acked."); } close(p->fd); /* release data. */ if ( 0 == ret ) { if (p->hdr.dataLen) free(p->data); } return ret; }
// initialize directory. // arg: original directory/file name // function shall set up the following, // 1. filter the directory properly // 2. total number of playable contents: totalFiles // 3. current file index: fileIdx static void * dirInit( void * arg ) { LOCK_PLAYMUTEX(); if (CoolBlockOpenDir(dirName, &node) < 0) { WPRINT("unable to open directory."); } else { //DBGMSG("dirPlayAV = [%d]", dirPlayAV); if (dirPlayAV == DPAV_AUDIO_) { CoolFilterDirectory(&node, CoolIsAudioFile, DF_ALL); } else if (dirPlayAV == DPAV_VIDEO_) { CoolFilterDirectory(&node, CoolIsVideoFile, DF_ALL); } else if (dirPlayAV == DPAV_NOT_DETERMINED_) { #ifdef PLAY_VIDEO_FILE_ONLY CoolFilterDirectory(&node, CoolIsVideoFile, DF_ALL); dirPlayAV = DPAV_VIDEO_; #else if (0 == CoolFilterDirectory(&node, CoolIsVideoFile, DF_ALL)) { CoolFilterDirectory(&node, CoolIsAudioFile, DF_ALL); dirPlayAV = DPAV_AUDIO_; } else dirPlayAV = DPAV_VIDEO_; #endif } } // if is playing, get index of currently playback file totalFiles = node.fdnum+node.ffnum; if (playing) { int fi; char path[PATH_MAX]; fileIdx = 0; fi = totalFiles; while(fi--) { if (!strcmp(trackName,CoolCatFilename2Path(path, PATH_MAX, D_PATH, D_NAME(F_INDEX(fi))))) { //DBGMSG("fi = %d", fi); fileIdx = fi; break; } //DBGMSG("fname = [%s]", trackName); //DBGMSG("path = [%s]", path); } } // done with directory init, broadcast. DBGMSG("done with directory initialization."); dirInited = 1; UNLOCK_PLAYMUTEX(); pthread_cond_broadcast(&playdirCond); pthread_exit(NULL); }
static int playFile(const char * file) { int status = -1; media_desc_t mdesc; //DBGLOG("playing file: [%s]", file); memset(&mdesc, 0, sizeof(media_desc_t)); mdesc.ftype = NMS_WP_INVALID; if (!InputIsOurFile(file)) return -1; status = InputInit(file, &mdesc); switch (status) { case 0: //everything is fine break; case 1: WPRINT("InputInit: DM320 is locked by something else. Please try again later."); LOCK_PLAYMUTEX(); errorStatus = NMS_STATUS_OUTPUT_LOCKED; UNLOCK_PLAYMUTEX(); goto bail_clean_input; default: WPRINT("InputInit: Unable to init device!"); LOCK_PLAYMUTEX(); errorStatus = NMS_STATUS_NOT_PLAYABLE; UNLOCK_PLAYMUTEX(); goto bail_clean_input; } LOCK_PLAYMUTEX(); InputGetInfo(file, &info); UNLOCK_PLAYMUTEX(); if (InputStart(file)) { status = -1; goto bail_clean_input; } status = OutputInit(&mdesc,OutputGetMode(),curProportions); switch (status) { case 0: //everything is fine break; case 1: WPRINT("OutputInit: DM320 is locked by something else. Please try again later."); LOCK_PLAYMUTEX(); errorStatus = NMS_STATUS_OUTPUT_LOCKED; UNLOCK_PLAYMUTEX(); goto bail_clean_input; default: WPRINT("OutputInit: Unable to init output !"); LOCK_PLAYMUTEX(); if ((playtype == NPT_FILE) || (totalFiles <= 1) || (repeat == 1)) errorStatus = NMS_STATUS_NOT_PLAYABLE; UNLOCK_PLAYMUTEX(); goto bail_clean_input; } OutputActivateMode(0); LOCK_PLAYMUTEX(); playtime = 0; ffrwLevel = 0; sfrwLevel = 0; sfrwLevelFinal = 0; muted = 0; playing = 1; trackChange = TC_DISABLE; UNLOCK_PLAYMUTEX(); if (newThread(&avThread, NULL, avLoop, NULL)) { status = -1; goto bail_clean_input; } return 0; bail_clean_input: LOCK_PLAYMUTEX(); InputFinish(); UNLOCK_PLAYMUTEX(); return status; }
static void * avLoop( void * arg ) { int loc_frames = 0; int loc_bytes; int loc_quit = 1; NMS_SRV_STATUS_t loc_preState = NMS_STATUS_PLAYER_STOPPED; int loc_cur_t = 0; int loc_next_t = 0; int loc_prev_t = 0; int loc_first_time = 0; int loc_preload; int loc_ffrw_scan_step = 0; media_buf_t loc_buf; long loc_info_duration; LOCK_PLAYMUTEX(); if(editmode) { playState = NMS_STATUS_PLAYER_VF; loc_preload = 1; frameByFrame = 1; } else { playState =NMS_STATUS_PLAYER_PLAY; loc_preload = PRELOAD_FRAMES; frameByFrame = 0; } UNLOCK_PLAYMUTEX(); do { DBGMSG("In avloop now."); /* preload */ while (loc_frames < loc_preload) { if (1 == OutputGetBuffer(&loc_buf, 0, 1)) { WPRINT("GetBuffer failed."); break; } loc_bytes = InputGetData(&loc_buf); if (loc_bytes == 0) continue; if (loc_bytes <0 ) { // hit EOF, set flag to flush. loc_quit = 0; LOCK_PLAYMUTEX(); playing = 0; UNLOCK_PLAYMUTEX(); break; } //DBGMSG("input data returned. "); LOCK_PLAYMUTEX(); playtime = OutputGetPlaytime(); UNLOCK_PLAYMUTEX(); #ifdef LOG_TIME_STAMP__ if (loc_buf.curbuf == &loc_buf.abuf) DBGLOG(" aT = %d\n", loc_buf.curbuf->tsms); else DBGLOG("---vT = %d\n", loc_buf.curbuf->tsms); #endif OutputWrite(&loc_buf); if (loc_buf.curbuf == &loc_buf.abuf) loc_frames++; } DBGMSG("preload finished."); OutputStart(); /* start output */ DBGMSG("output started."); } while(0); LOCK_PLAYMUTEX(); preloaded = 1; everPlayed = 1; UNLOCK_PLAYMUTEX(); main_play_loop: // preloaded... while (1) { int loc_playState; int loc_iSeekFlag; int loc_iBookMark; int loc_sfrwLevelFinal; LOCK_PLAYMUTEX(); if (!playing) { UNLOCK_PLAYMUTEX(); break; } loc_playState = playState; UNLOCK_PLAYMUTEX(); switch (loc_playState) { case NMS_STATUS_PLAYER_PAUSE: if (loc_preState != NMS_STATUS_PLAYER_PAUSE) { OutputPause(1); LOCK_PLAYMUTEX(); playedOrPaused = NMS_STATUS_PLAYER_PAUSE; UNLOCK_PLAYMUTEX(); loc_preState = NMS_STATUS_PLAYER_PAUSE; } continue; case NMS_STATUS_PLAYER_PLAY: { LOCK_PLAYMUTEX(); loc_iSeekFlag = iSeekFlag; loc_iBookMark = iBookMark; UNLOCK_PLAYMUTEX(); if (loc_preState != NMS_STATUS_PLAYER_PLAY || loc_iSeekFlag) { LOCK_PLAYMUTEX(); playedOrPaused = NMS_STATUS_PLAYER_PLAY; loc_info_duration = info.duration; UNLOCK_PLAYMUTEX(); if (loc_preState == NMS_STATUS_PLAYER_PAUSE) { OutputPause(0); LOCK_PLAYMUTEX(); muted = 0; UNLOCK_PLAYMUTEX(); } else if (loc_iSeekFlag) { if (loc_info_duration - loc_iBookMark > 100) { loc_next_t = InputSeek(loc_iBookMark); OutputFlush(loc_next_t); } LOCK_PLAYMUTEX(); iSeekFlag = 0; UNLOCK_PLAYMUTEX(); } else { LOCK_PLAYMUTEX(); if (muted) { muted = 0; OutputMute(muted); } loc_sfrwLevelFinal = sfrwLevelFinal; UNLOCK_PLAYMUTEX(); if (loc_preState == NMS_STATUS_PLAYER_SF) { int loc_cur_tmp; LOCK_PLAYMUTEX(); loc_cur_tmp = playtime; UNLOCK_PLAYMUTEX(); loc_next_t = loc_first_time + (loc_cur_tmp - loc_first_time) / loc_sfrwLevelFinal; loc_next_t = InputSeek(loc_next_t); OutputFlush(loc_next_t); } } loc_preState = NMS_STATUS_PLAYER_PLAY; loc_prev_t = 0; } } break; case NMS_STATUS_PLAYER_FF: case NMS_STATUS_PLAYER_RW: if (loc_preState != loc_playState) { LOCK_PLAYMUTEX(); loc_cur_t = playtime; UNLOCK_PLAYMUTEX(); OutputFlush(loc_cur_t); if (loc_preState == NMS_STATUS_PLAYER_PAUSE) OutputPause(0); LOCK_PLAYMUTEX(); if (!muted) { muted = 1; OutputMute(muted); } loc_cur_t = playtime; loc_first_time = loc_cur_t; loc_next_t = loc_cur_t; loc_prev_t = loc_cur_t; loc_preState = playState; UNLOCK_PLAYMUTEX(); } LOCK_PLAYMUTEX(); if (ffrwLevel == 0) { UNLOCK_PLAYMUTEX(); continue; } else if (ffrwLevel > 2) loc_ffrw_scan_step = SCAN_STEP2_MS; else loc_ffrw_scan_step = SCAN_STEP1_MS; get_new_timestamp: if (loc_preState == NMS_STATUS_PLAYER_FF) { loc_info_duration = info.duration; if (loc_info_duration != 0 && (playtime + ffrwLevel * loc_ffrw_scan_step) >= loc_info_duration) { loc_next_t = loc_info_duration; loc_next_t = InputSeek(loc_next_t); OutputFlush(loc_next_t); if(editmode) { playState = NMS_STATUS_PLAYER_PLAY; UNLOCK_PLAYMUTEX(); break; } else { loc_quit = 0; UNLOCK_PLAYMUTEX(); goto bail; } } else { playtime += ffrwLevel * loc_ffrw_scan_step; loc_next_t = playtime; if (rptState == NMS_PLAYBACK_REPEAT_ON) { if (loc_next_t >= rptB) { loc_next_t = rptB; loc_next_t = InputSeek(loc_next_t); OutputFlush(loc_next_t); UNLOCK_PLAYMUTEX(); continue; } } } } else { if (playtime +ffrwLevel * loc_ffrw_scan_step <= 0) { loc_next_t = 0; loc_next_t = InputSeek(loc_next_t); OutputFlush(loc_next_t); if(editmode) { playState = NMS_STATUS_PLAYER_VF; frameByFrame = 1; loc_preState = NMS_STATUS_PLAYER_PLAY; UNLOCK_PLAYMUTEX(); break; } else playState = NMS_STATUS_PLAYER_PLAY; ffrwLevel = 0; UNLOCK_PLAYMUTEX(); continue; } else { playtime += ffrwLevel * loc_ffrw_scan_step; loc_next_t = playtime; if (rptState == NMS_PLAYBACK_REPEAT_ON) { if (loc_next_t <= rptA) { loc_next_t = rptA; loc_next_t = InputSeek(loc_next_t); OutputFlush(loc_next_t); UNLOCK_PLAYMUTEX(); continue; } } } } loc_next_t = InputSeek(loc_next_t); OutputFlush(loc_next_t); if ((loc_preState == NMS_STATUS_PLAYER_FF && loc_prev_t >= loc_next_t) || (loc_preState == NMS_STATUS_PLAYER_RW && loc_prev_t <= loc_next_t)) { goto get_new_timestamp; } loc_prev_t = loc_cur_t; loc_cur_t = loc_next_t; UNLOCK_PLAYMUTEX(); break; case NMS_STATUS_PLAYER_VF: LOCK_PLAYMUTEX(); DBGLOG("!!!!!!!!!!!!!!!play VF,mute=%d\n",muted); if (frameByFrame == 1) { OutputPause(0); loc_cur_t = playtime; OutputFlush(loc_cur_t); if (!muted) { muted = 1; OutputMute(muted); } } playState = NMS_STATUS_PLAYER_PAUSE; loc_cur_t = playtime; UNLOCK_PLAYMUTEX(); loc_next_t = loc_cur_t; loc_prev_t = loc_cur_t; loc_first_time = loc_cur_t; break; case NMS_STATUS_PLAYER_SF: if (loc_preState != NMS_STATUS_PLAYER_SF) { LOCK_PLAYMUTEX(); loc_cur_t = playtime; OutputFlush(loc_cur_t); if (loc_preState == NMS_STATUS_PLAYER_PAUSE) OutputPause(0); if (!muted) { muted = 1; OutputMute(muted); } loc_cur_t = playtime; UNLOCK_PLAYMUTEX(); loc_next_t = loc_cur_t; loc_prev_t = loc_cur_t; loc_preState = NMS_STATUS_PLAYER_SF; } break; case NMS_STATUS_PLAYER_STOPPED: if (loc_preState == NMS_STATUS_PLAYER_PAUSE) OutputPause(0); loc_preState = NMS_STATUS_PLAYER_STOPPED; loc_quit = 1; goto bail; default: LOCK_PLAYMUTEX(); playState = loc_preState; UNLOCK_PLAYMUTEX(); break; } LOCK_PLAYMUTEX(); if (rptState == NMS_PLAYBACK_REPEAT_ON) { loc_cur_t = playtime; if (loc_cur_t > rptB) { loc_cur_t = InputSeek(rptA); OutputFlush(loc_cur_t); } } UNLOCK_PLAYMUTEX(); if ( 1 == OutputGetBuffer(&loc_buf, 1000, 0)) { //DBGMSG("buffer full or playback paused!"); continue; } loc_bytes = InputGetData(&loc_buf); if (loc_bytes == 0) { WPRINT("zero bytes returned!"); continue; } LOCK_PLAYMUTEX(); if (loc_bytes < 0) { if(editmode) { UNLOCK_PLAYMUTEX(); continue; } else { WPRINT("EOF reached!"); // hit EOF, set flag to flush. loc_quit = 0; UNLOCK_PLAYMUTEX(); break; } } UNLOCK_PLAYMUTEX(); #ifdef LOG_TIME_STAMP__ if (loc_buf.curbuf == &loc_buf.abuf) DBGLOG(" aT = %d\n", loc_buf.curbuf->tsms); else DBGLOG("---vT = %d\n", loc_buf.curbuf->tsms); #endif LOCK_PLAYMUTEX(); playtime = OutputGetPlaytime(); if (loc_buf.curbuf == &loc_buf.abuf) { if (loc_preState != NMS_STATUS_PLAYER_PLAY && rptState != NMS_PLAYBACK_REPEAT_ON) { UNLOCK_PLAYMUTEX(); continue; } } UNLOCK_PLAYMUTEX(); if (loc_preState != NMS_STATUS_PLAYER_PLAY && loc_preState != NMS_STATUS_PLAYER_PAUSE) { if (loc_first_time == 0) { loc_first_time = loc_cur_t; } if (loc_preState == NMS_STATUS_PLAYER_SF) { loc_buf.vbuf.tsms = loc_buf.vbuf.tsms - loc_first_time; LOCK_PLAYMUTEX(); loc_buf.vbuf.tsms *= sfrwLevel; UNLOCK_PLAYMUTEX(); loc_buf.vbuf.tsms += loc_first_time; } loc_prev_t = loc_cur_t; } OutputWrite(&loc_buf); } DBGMSG("Exit main playback loop.\n"); // if quit, re-fetch the lock here bail: LOCK_PLAYMUTEX(); ffrwLevel = 0; sfrwLevel = 0; UNLOCK_PLAYMUTEX(); if (loc_preState == NMS_STATUS_PLAYER_PAUSE) { OutputPause(0); } LOCK_PLAYMUTEX(); if (muted) { muted = 0; OutputMute(muted); } UNLOCK_PLAYMUTEX(); // We used to call InputFinish here, but let's wait a while, because we may be asked to seek again later, // while draining the output buffer. And we'll need input to be active if we want to have something to seek into. if (loc_quit) { LOCK_PLAYMUTEX(); InputFinish(); // If we're quitting the server, we really don't want to wait that video output is drained. // We flush it down the toilet without sending it to the TV. OutputFinish(0); UNLOCK_PLAYMUTEX(); } else { unsigned long remain; // We're at the EOF of a playback. We may have some data left in the dm320 // gargantuan output buffers, and we need to properly make sure it goes all to TV before we're done. // // We can't really call a blocking flush here (like OutputFinish(1)). // This is because the server will freeze otherwise and be unable to process // commands (like STOP or PAUSE) that come in during the final draining of the output buffer. // // This is an improvement over the old way of just waiting some time before calling the // blocking flush: it instead keeps checking the amount of data in the dm320 video output buffer // and doesn't call the blocking flush until it's all drained. It sleeps a small amount of time // between checks, then before the next check it processes commands. // // HACK: // It works better than before, however it's still a bit of an hack, since this // polling is really not elegant at all. It is much better to setup a callback and // have imedia call us when there's no more data in the output buffer. // Or something like that. --nero LOCK_PLAYMUTEX(); playing = 1; //Restore the playback flag, since we're still actually playing. UNLOCK_PLAYMUTEX(); remain = OutputGetBufferedSize(); WPRINT("Entering buffer drain loop (remain %lu bytes).\n", remain); while (remain > 0) { LOCK_PLAYMUTEX(); if (!playing) { UNLOCK_PLAYMUTEX(); break; } DBGMSG("Draining output buffer. Bytes remaining: %lu\n", remain); if (playState == NMS_STATUS_PLAYER_PAUSE) OutputPause(1); else { OutputPause(0); // If we're asked to seek (ffw, rew or point-seek), let's just return in the main loop. // The logic in the loop will take care of everything else, we don't need to do anything more here. if (playState == NMS_STATUS_PLAYER_FF || playState == NMS_STATUS_PLAYER_RW || (playState == NMS_STATUS_PLAYER_PLAY && iSeekFlag != 0)) { DBGMSG("Going back to main playback loop.\n"); UNLOCK_PLAYMUTEX(); goto main_play_loop; } } UNLOCK_PLAYMUTEX(); usleep(DRAIN_POLL_TICK); remain = OutputGetBufferedSize(); } DBGMSG("Exited drain loop. Playing: %d - Remain: %lu\n", playing, remain); LOCK_PLAYMUTEX(); InputFinish(); OutputPause(0); //before finish output must make sure pause flag is cleared //Let's always call a final non-blocking flush. Thus if there are bugs in the above logic, //we notice a clip at end of video (due to flushing to kingdom come the last part of data), //and hopefully we come here to look ;) --nero OutputFinish(0); UNLOCK_PLAYMUTEX(); } // clear playing and ffrw flag, and release lock before // joining ffrw thread. LOCK_PLAYMUTEX(); playing = 0; rptState = NMS_PLAYBACK_REPEAT_OFF; if (playtype == NPT_FILE) playState = NMS_STATUS_PLAYER_STOPPED; else playState = NMS_STATUS_PLAYER_NEXT; DBGMSG("input output finished."); // check to play next file. if ((0 == loc_quit) && (playtype != NPT_FILE)) { DBGMSG("searching for next file."); //if repeat is single and the file is not played, stop nextfile loop if (!((repeat == RM_REPEAT) && (errorStatus == NMS_STATUS_NOT_PLAYABLE))) trackChange = TC_NORMAL; UNLOCK_PLAYMUTEX(); pthread_cond_broadcast(&nextFileCond); } else UNLOCK_PLAYMUTEX(); pthread_exit(NULL); }
/** * Play back specified directory. * If file is specified, start playback that file. * If file is not specified, choose first file based on playmode. * Following playback only plays either video or audio, that is, playback * video only if first playback is video and playback audio only if first * playback is audio. * * @param dir * directory path. * @return * 0 if directory playback started, in other words, at lease one * playable file is found, otherwise nonzero. * 1 if any of the files found that output was locked when trying to play. */ int SrvPlayDir( const char * dir ) { int status = -1; struct stat st; char * fname; char path[PATH_MAX]; char loc_dirName[PATH_MAX]; int isDir = 0; int loc_repeat; DBGMSG("play directory: [%s]", dir); stopServer(); strcpy(loc_dirName, dir); LOCK_PLAYMUTEX(); strcpy(dirName, dir); strcpy(trackName, dir); everPlayed = 0; dirInited = 0; going = 1; fileCnt = 1; playtype = NPT_DIR; dirPlayAV = DPAV_NOT_DETERMINED_; UNLOCK_PLAYMUTEX(); // if dir corresponds to a file, start to play file immediately. // thus to remove the long startup delay. if ( 0 == stat(loc_dirName, &st) ) { if ( S_ISDIR(st.st_mode) ) { isDir = 1; // it is a directory, continue //DBGMSG("directory, continue", dir); } else { char loc_trackName[PATH_MAX]; LOCK_PLAYMUTEX(); strcpy(loc_trackName, trackName); UNLOCK_PLAYMUTEX(); isDir = 0; // it is a file, try to play it first. status = playFile(loc_trackName); if (0 == status) { LOCK_PLAYMUTEX(); dirPlayAV = CoolIsAudioFile(loc_trackName)? 1 : 2; UNLOCK_PLAYMUTEX(); } // get the directory name { int len; char * p; LOCK_PLAYMUTEX(); len = strlen(dirName); p = dirName+len; while(*p != '/') p--; *p = 0; UNLOCK_PLAYMUTEX(); } } } else { WPRINT("Directory status not available!"); return -1; } LOCK_PLAYMUTEX(); strcpy(loc_dirName, dirName); UNLOCK_PLAYMUTEX(); if (stat(loc_dirName, &st) == -1) { LOCK_PLAYMUTEX(); errorStatus = NMS_STATUS_NOT_PLAYABLE; UNLOCK_PLAYMUTEX(); return -1; } if (newThread(&nextFileThread, NULL, nextFileLoop, NULL)) { return -1; } //DBGMSG("create directory init thread", dir); // Create thread to init directory. if (newThread(&dirInitThread, NULL, dirInit, NULL)) { stopServer(); return -1; } // file played? // If not, wait to get first file played, because we have to return // a status here to indicate whether the playback can be successfully // started or not. if (status) { LOCK_PLAYMUTEX(); loc_repeat = repeat; UNLOCK_PLAYMUTEX(); // not single repeat or trackName is directory, wait to get first file played if (loc_repeat != RM_REPEAT || isDir) { int cnt; // counter of retry int idx = 0; //DBGMSG("playback not started yet", dir); // NO, wait till directory is initialized. LOCK_PLAYMUTEX(); while (!dirInited) pthread_cond_wait(&playdirCond, &playMutex); // Now try to get next file and play it. fileIdx = 0; cnt = totalFiles; UNLOCK_PLAYMUTEX(); // try each file at most once. while(cnt--) { fname = nextFileFromDir(idx,path,PATH_MAX); if (!fname) break; status = playFile(fname); //DBGMSG("status = [%d]", status); if (!status) break; else { LOCK_PLAYMUTEX(); idx++; fileIdx++; UNLOCK_PLAYMUTEX(); } } if (cnt <= 0) { LOCK_PLAYMUTEX(); errorStatus = NMS_STATUS_NOT_PLAYABLE; UNLOCK_PLAYMUTEX(); } } } // Stop server to clean up if not able to play. if (status) stopServer(); else { LOCK_PLAYMUTEX(); playState = NMS_STATUS_PLAYER_PLAY; errorStatus = NMS_STATUS_OK; UNLOCK_PLAYMUTEX(); } return status; }