IfsReturnCode IfsHandleInfo(IfsHandle ifsHandle, // Input IfsInfo ** ppIfsInfo // Output (use IfsFreeInfo() to g_free) ) { IfsReturnCode ifsReturnCode; IfsBoolean retry = IfsTrue; if (ppIfsInfo == NULL) { RILOG_ERROR( "IfsReturnCodeBadInputParameter: ppIfsInfo == NULL in line %d of %s\n", __LINE__, __FILE__); return IfsReturnCodeBadInputParameter; } else *ppIfsInfo = NULL; if (ifsHandle == NULL) { RILOG_ERROR( "IfsReturnCodeBadInputParameter: ifsHandle == NULL in line %d of %s\n", __LINE__, __FILE__); return IfsReturnCodeBadInputParameter; } g_static_mutex_lock(&(ifsHandle->mutex)); do { ifsReturnCode = GetCurrentFileParameters(ifsHandle); if (ifsReturnCode == IfsReturnCodeNoErrorReported) { break; } else if (retry == IfsFalse) { g_static_mutex_unlock(&(ifsHandle->mutex)); return ifsReturnCode; } else { retry = IfsFalse; RILOG_INFO("%s: GetCurrentFileParameters retry at %d of %s\n", __FUNCTION__, __LINE__, __FILE__); } } while (retry == IfsTrue); { // scope IfsInfo * pIfsInfo; const size_t pathSize = strlen(ifsHandle->path) + 1; const size_t nameSize = strlen(ifsHandle->name) + 1; const IfsClock difClock = ifsHandle->endClock - ifsHandle->begClock; pIfsInfo = g_malloc0(sizeof(IfsInfo)); // g_free in IfsFreeInfo() if (pIfsInfo == NULL) { RILOG_CRIT( "IfsReturnCodeMemAllocationError: pIfsInfo == NULL in line %d of %s\n", __LINE__, __FILE__); g_static_mutex_unlock(&(ifsHandle->mutex)); return IfsReturnCodeMemAllocationError; } pIfsInfo->codec = g_malloc0(sizeof(IfsCodecImpl)); // g_free in IfsFreeInfo() pIfsInfo->maxSize = ifsHandle->maxSize; // in seconds, 0 = value not used pIfsInfo->path = NULL; // filled in below pIfsInfo->name = NULL; // filled in below pIfsInfo->mpegSize = ifsHandle->mpegSize; pIfsInfo->ndexSize = ifsHandle->ndexSize; pIfsInfo->begClock = (ifsHandle->maxSize && (difClock > ifsHandle->maxSize * NSEC_PER_SEC) ? ifsHandle->endClock - ifsHandle->maxSize * NSEC_PER_SEC : ifsHandle->begClock); pIfsInfo->endClock = ifsHandle->endClock; // in nanoseconds switch (ifsHandle->codecType) { case IfsCodecTypeH261: case IfsCodecTypeH262: case IfsCodecTypeH263: pIfsInfo->codec->h262 = g_malloc0(sizeof(IfsH262CodecImpl)); // g_free in IfsFreeInfo() pIfsInfo->codec->h262->videoPid = ifsHandle->codec->h262->videoPid; pIfsInfo->codec->h262->audioPid = ifsHandle->codec->h262->audioPid; break; case IfsCodecTypeH264: pIfsInfo->codec->h264 = g_malloc0(sizeof(IfsH264CodecImpl)); // g_free in IfsFreeInfo() break; case IfsCodecTypeH265: pIfsInfo->codec->h265 = g_malloc0(sizeof(IfsH265CodecImpl)); // g_free in IfsFreeInfo() break; default: RILOG_ERROR("IfsReturnCodeBadInputParameter: " "invalid CODEC line %d of %s\n", __LINE__, __FILE__); ifsReturnCode = IfsReturnCodeBadInputParameter; break; } pIfsInfo->path = g_malloc0(pathSize); // g_free in IfsFreeInfo() pIfsInfo->name = g_malloc0(nameSize); // g_free in IfsFreeInfo() if (pIfsInfo->path == NULL) { (void) IfsFreeInfo(pIfsInfo); // Ignore any errors, we already have one... RILOG_CRIT( "IfsReturnCodeMemAllocationError: pIfsInfo->path == NULL in line %d of %s\n", __LINE__, __FILE__); g_static_mutex_unlock(&(ifsHandle->mutex)); return IfsReturnCodeMemAllocationError; } if (pIfsInfo->name == NULL) { (void) IfsFreeInfo(pIfsInfo); // Ignore any errors, we already have one... RILOG_CRIT( "IfsReturnCodeMemAllocationError: pIfsInfo->name == NULL in line %d of %s\n", __LINE__, __FILE__); g_static_mutex_unlock(&(ifsHandle->mutex)); return IfsReturnCodeMemAllocationError; } memcpy(pIfsInfo->path, ifsHandle->path, pathSize); memcpy(pIfsInfo->name, ifsHandle->name, nameSize); *ppIfsInfo = pIfsInfo; } g_static_mutex_unlock(&(ifsHandle->mutex)); return IfsReturnCodeNoErrorReported; }
static IfsReturnCode IfsOpenImpl(IfsBoolean isReading, // Input (if true then path+name must exist and maxSize is ignored) const char * path, // Input const char * name, // Input (if writing and NULL the name is generated) IfsTime maxSize, // Input (in seconds, 0 = no max, ignored if reading) IfsHandle * pIfsHandle // Output (use IfsClose() to g_free) ) { // The various open cases for a writer are: // // case char*name maxSize Found Description // ---- --------- ------- ------ ------------ // // 1 NULL 0 NA Generate directory and create the single 0000000000 file // // 2 NULL not 0 NA Generate directory and create the 0000000001 circular file // // 3 not NULL 0 No Create the specified directory and single 0000000000 file // // 4 not NULL not 0 No Create the specified directory and the 0000000001 circular file // // 5 not NULL 0 Yes If 0000000000 file found open it otherwise report an error // // 6 not NULL not 0 Yes If 0000000000 file found error, otherwise open lowest file name // // The various open cases for a reader are: // // case char*name Found Description // ---- --------- ------ ------------ // // 7 NULL NA Report IfsReturnCodeBadInputParameter // // 8 not NULL No Report IfsReturnCodeFileWasNotFound // // 9 not NULL Yes Open the file for reading IfsReturnCode ifsReturnCode = IfsReturnCodeNoErrorReported; // used to report errors IfsHandle ifsHandle; // IfsHandle being created/opened char temp[256]; // filename only // temporary string storage // Check the input parameters, initialize the output parameters and report any errors if (pIfsHandle == NULL) { RILOG_ERROR( "IfsReturnCodeBadInputParameter: pIfsHandle == NULL in line %d of %s\n", __LINE__, __FILE__); return IfsReturnCodeBadInputParameter; } else *pIfsHandle = NULL; if (path == NULL) { RILOG_ERROR( "IfsReturnCodeBadInputParameter: path == NULL in line %d of %s\n", __LINE__, __FILE__); return IfsReturnCodeBadInputParameter; } // check for NULL or empty string name if ((name == NULL) || ('\0' == name[0])) { if (isReading) // Case 7 - report error { RILOG_ERROR( "IfsReturnCodeBadInputParameter: Reader with name == NULL in line %d of %s\n", __LINE__, __FILE__); return IfsReturnCodeBadInputParameter; } else // Cases 1 and 2 - generate a directory name { // Generated a direcory name of the form XXXXXXXX_xxxx // where XXXXXXXX is the hex representation of the epoch seconds // and xxxx is a unique number static unsigned short uniqueNum = 0u; static GMutex uniqueLock; g_mutex_init(&uniqueLock); unsigned short localUniqueNum = 0u; g_mutex_lock(&uniqueLock); localUniqueNum = uniqueNum++; g_mutex_unlock(&uniqueLock); if (sprintf(temp, "%08lX_%04X", time(NULL), localUniqueNum) != 13) { RILOG_ERROR( "IfsReturnCodeSprintfError: sprintf() != 13 in line %d of %s\n", __LINE__, __FILE__); return IfsReturnCodeSprintfError; } name = temp; } } // Start the process by allocating memory for the IfsHandle ifsHandle = g_try_malloc0(sizeof(IfsHandleImpl)); if (ifsHandle == NULL) { RILOG_CRIT( "IfsReturnCodeMemAllocationError: ifsHandle == NULL in line %d of %s\n", __LINE__, __FILE__); return IfsReturnCodeMemAllocationError; } // Initialize all the pointers in the IfsHandle (except the codec) g_mutex_init(&(ifsHandle->mutex)); // (done by g_try_malloc0) ifsHandle->path = NULL; // current path // (done by g_try_malloc0) ifsHandle->name = NULL; // current name // (done by g_try_malloc0) ifsHandle->both = NULL; // current path + name // (done by g_try_malloc0) ifsHandle->mpeg = NULL; // current path + name + filename.mpg // (done by g_try_malloc0) ifsHandle->ndex = NULL; // current path + name + filename.ndx // (done by g_try_malloc0) ifsHandle->pMpeg = NULL; // current MPEG file // (done by g_try_malloc0) ifsHandle->pNdex = NULL; // current NDEX file // Now fill in all the values of the IfsHandle do { struct stat statBuffer; // Process the input parameters const size_t pathSize = strlen(path) + 1; // path + \000 const size_t nameSize = strlen(name) + 1; // name + \000 const size_t bothSize = pathSize + nameSize; // path + / + name + \000 if (ifsReturnCode != IfsReturnCodeNoErrorReported) break; ifsHandle->numEmptyFreads = 0; ifsHandle->isReading = isReading; ifsHandle->maxSize = maxSize; // in seconds, 0 = value not used ifsHandle->path = g_try_malloc(pathSize); ifsHandle->name = g_try_malloc(nameSize); ifsHandle->both = g_try_malloc(bothSize); if (ifsHandle->path == NULL) { RILOG_CRIT( "IfsReturnCodeMemAllocationError: ifsHandle->path == NULL in line %d of %s\n", __LINE__, __FILE__); ifsReturnCode = IfsReturnCodeMemAllocationError; } if (ifsHandle->name == NULL) { RILOG_CRIT( "IfsReturnCodeMemAllocationError: ifsHandle->name == NULL in line %d of %s\n", __LINE__, __FILE__); ifsReturnCode = IfsReturnCodeMemAllocationError; } if (ifsHandle->both == NULL) { RILOG_CRIT( "IfsReturnCodeMemAllocationError: ifsHandle->both == NULL in line %d of %s\n", __LINE__, __FILE__); ifsReturnCode = IfsReturnCodeMemAllocationError; } if (ifsReturnCode != IfsReturnCodeNoErrorReported) break; memcpy(ifsHandle->path, path, pathSize); memcpy(ifsHandle->name, name, nameSize); memcpy(ifsHandle->both, path, pathSize); strcat(ifsHandle->both, "/"); strcat(ifsHandle->both, name); if (stat(ifsHandle->both, &statBuffer)) // The directory was NOT found { if (isReading) // Case 8 - report error { RILOG_ERROR( "IfsReturnCodeFileWasNotFound: stat(%s) failed (%d) in line %d of %s\n", ifsHandle->both, errno, __LINE__, __FILE__); ifsReturnCode = IfsReturnCodeFileWasNotFound; break; } // Cases 1 through 4 - make the specified (or generated) directory if (makedir(ifsHandle->both)) { RILOG_ERROR( "IfsReturnCodeMakeDirectoryError: makedir(%s) failed (%d) in line %d of %s\n", ifsHandle->both, errno, __LINE__, __FILE__); ifsReturnCode = IfsReturnCodeMakeDirectoryError; break; } // (done by g_try_malloc0) ifsHandle->mpegSize = 0; // (done by g_try_malloc0) ifsHandle->ndexSize = 0; ifsHandle->begFileNumber = ifsHandle->endFileNumber = maxSize ? 1 : 0; // (done by g_try_malloc0) ifsHandle->begClock = // (done by g_try_malloc0) ifsHandle->endClock = // (done by g_try_malloc0) ifsHandle->nxtClock = 0; // nanoseconds ifsReturnCode = IfsOpenActualFiles(ifsHandle, ifsHandle->begFileNumber, "wb+"); } else // The directory was found { // Cases 5, 6 and 9 - open the existing IFS file ifsReturnCode = GetCurrentFileParameters(ifsHandle); } // (done by g_try_malloc0) ifsHandle->realLoc = 0; // offset in packets // (done by g_try_malloc0) ifsHandle->virtLoc = 0; // offset in packets ifsHandle->ifsState = IfsStateInitial; } while (0); if (ifsReturnCode == IfsReturnCodeNoErrorReported) { *pIfsHandle = ifsHandle; if ((indexDumpMode == IfsIndexDumpModeAll) && whatAll) { #ifdef DEBUG_ALL_PES_CODES RILOG_INFO("---- ---------------- = -------- --------------- ------------\n"); RILOG_INFO(" %08lX%08lX\n", (unsigned long)(whatAll>>32), (unsigned long)whatAll); #else RILOG_INFO( "---- -------- = -------- --------------- ------------\n"); RILOG_INFO(" %08X\n", whatAll); #endif }