Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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
        }