⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ig_api.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            "IGTotalCreateSurfaceTime: %u.%u\nIGTotalAddDataTime: %u.%u\nIGTotalFrameDrops: %u\nIGTotalParseMsgDrops: %u\n"
            "IGTotalRLEFailures: %u\nIGPixelDecodeRate: %u.%u\n\n",
                IGStats.TotalBlitTicks/TickRate, IGStats.TotalBlitTicks%TickRate,
                IGStats.TotalFlipTicks/TickRate, IGStats.TotalFlipTicks%TickRate,
                IGStats.TotalRLETicks/TickRate, IGStats.TotalRLETicks%TickRate,
                IGStats.TotalCreateSurfaceTicks/TickRate, IGStats.TotalCreateSurfaceTicks%TickRate,
                IGStats.TotalAddDataTicks/TickRate, IGStats.TotalAddDataTicks%TickRate,
                IGStats.TotalFrameDrops,
                IGStats.TotalParseMsgDrops,
                IGStats.TotalRLEFailures,
                PixelsPerSec,
                PixelsRemain));
        }
#endif
        OS_SemGive(IGInfo.StateLock);
    }
    else if (IG_STATE_INITIALIZED == IGInfo.CurrentState)
    {
        /* we should already be stopped */
        OS_SemTake(IGInfo.StateLock, OS_WAIT_FOREVER);
        IGInfo.CurrentState = IG_STATE_STOPPED;
        OS_SemGive(IGInfo.StateLock);
    }
    else
    {
        return IG_STATUS_ERROR;
    }

    return IG_STATUS_SUCCESS;
}

/**
 * IGAddData - adds data to the IG module, once this call ends the data given can
 *              be free'd.  Note we don't just copy the data, we inspect the PES headers
 *              a bit to pull out ES data and drop it in the parse buffer.  Then fire
 *              a message to the IGParse task so it can parse the new data.
 *
 * @param IG_HANDLE handle - handle to the IG module
 * @param BYTE *Buffer - data buffer to add to module
 * @param ULONG Size - size of Buffer in bytes
 *
 * @return IG_STATUS - IG_STATUS_SUCCESS if data copied successfully
 *                   - IG_STATUS_NOT_RUNNING if we are not in the Run State
 */

IG_STATUS IGAddData(IG_HANDLE handle, BYTE *Buffer, ULONG Size)
{
    IG_STATUS Status;
    ULONG BytesRead=0;
    ULONG RetCode;
    ULONG LeftToCopy=0;
    USHORT AssembleBytesRead=0;
    ULONG ObjectDataSize=0;
    ULONG BytesLeft=0;
    ULONG StartCodeOffset=0;
#ifdef ALLOW_IG_PROFILING
    ULONG TickStart = 0;
#endif

    /* this routine should copy the data given into our IG parse buffer */
    OS_SemTake(IGInfo.StateLock, OS_WAIT_FOREVER);

    /* this routine will just copy data to the buffer looking for full PES
    packets, when it receives full PES packets it will signal the IG parser
    task to go and use the data, if there is a storm of data we should be able to
    copy to our buffer and signal the IG parser one at a time when it has finished
    with the data, to do that we should just mark each point in the buffer that
    contains the start of a PES packet and put it in a list, the IG parser
    should be able to just read from that list (or queue) and run with the data,

    NOTE: WATCH for data wrap arounds, DON'T STORE data in a non contiguous fashion
    in the buffer, make sure there is enough room to work with it in place without wrapping
    the copies

    NOTE 2: the data is dword filled memory the size given to this call is
    NOT the size of the valid data but the size of the chunk, we will need to parse
    PES headers and track whats needed in order to get the correct amount of data */

    // this one has ics which can also be multiPES so watch
#ifdef ALLOW_IG_PROFILING
    if (IGStats.Profiling == 1)
    {
        TickStart = OS_GetTicks();
    }
#endif

    if (handle != (PVOID)IG_HANDLE_VALUE)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGAddData(): IG_STATUS_INVALID_HANDLE\n"));
#ifdef ALLOW_IG_PROFILING
        if (IGStats.Profiling == 1)
        {
            IGStats.TotalAddDataTicks += OS_GetTicks() - TickStart;
        }
#endif
        OS_SemGive(IGInfo.StateLock);
        return IG_STATUS_INVALID_HANDLE;
    }

    if (IG_STATE_RUNNING != IGInfo.CurrentState)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGAddData(): IG_STATUS_NOT_RUNNING\n"));
#ifdef ALLOW_IG_PROFILING
        if (IGStats.Profiling == 1)
        {
            IGStats.TotalAddDataTicks += OS_GetTicks() - TickStart;
        }
#endif
        OS_SemGive(IGInfo.StateLock);
        return IG_STATUS_NOT_RUNNING;
    }

    DBGPRINT(DBG_ON(DBG_VERBOSE), ("--IGAddData 0x%p, size=%d\n", Buffer, Size));

    /* loop
    {
        1. finish current pes packet (if any)
        2. look for sync
    }*/

    /* this is how much is left in the packet */
    BytesLeft = Size;

    /* loop over the whole buffer */
    while (BytesLeft > 0)
    {

        if ((IG_FLAGS_STOP == IGInfo.QuitFlags)  || (IG_FLAGS_EXIT == IGInfo.QuitFlags))
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("IGAddData(): Called while in Stop State!\n"));
#ifdef ALLOW_IG_PROFILING
            if (IGStats.Profiling == 1)
            {
                IGStats.TotalAddDataTicks += OS_GetTicks() - TickStart;
            }
#endif
            OS_SemGive(IGInfo.StateLock);
            return IG_STATUS_ERROR;
        }

        /*
            1. finish current pes packet (if any)
        */
        if (IGInfo.CopyingPES)
        {
            /* header not complete */
            if (0 == IGInfo.CurPesInfo.HeaderComplete)
            {
                /* if we ran out of data we will wait till the next adddata to finish the header */
                RetCode = IGAssemblePesHeader(&Buffer[BytesRead], BytesLeft, &AssembleBytesRead);
                if (IG_STATUS_SUCCESS == RetCode)
                {
                    /* packet assembled, read the pes header */
                    if (IG_STATUS_SUCCESS != IGReadPESHeader(IGInfo.CurPesInfo.PesHdrBuff))
                    {
                        /* something is wrong with this pes header, don't try to figure it out
                        drop data and hope we catch up */
                        DBGPRINT(DBG_ON(DBG_ERROR), ("IGAddData(): Error in pes header\n"));
                        IGClearAddDataVars();
#ifdef ALLOW_IG_PROFILING
                        if (IGStats.Profiling == 1)
                        {
                            IGStats.TotalAddDataTicks += OS_GetTicks() - TickStart;
                        }
#endif
                        OS_SemGive(IGInfo.StateLock);
                        return IG_STATUS_ERROR;
                    }

                    /* are we copying a multipes segment already */
                    if (0 == IGInfo.CopyingMultiPES)
                    {
                        /* is this packet full (multipes)? */
                        if (0xFFFF == IGInfo.CurPesInfo.PacketSize)
                        {
                            /* NOTE: here we make an assumption that we need a minimum of the largest sized header
                            we will process which is the ICS header + 3 bytes for it's size, If the segment is
                            really a ICS we will already have the min if we have ICS_HEADER_SIZE */
                            IGInfo.CurPesInfo.NeedSegmentBytes = ICS_HEADER_SIZE;
                            IGInfo.CurPesInfo.SegmentIndex = 0;
                        }
                        else
                        {
                            /* else: not full packet and we aren't currently coping multipes so can't be multipes */
                            /* make sure we have room for the packet */
                            IGWaitForSpaceAvail(IGInfo.CurPesInfo.PacketSize);
                            if (IGInfo.CurrentState != IG_STATE_RUNNING)
                            {
                                OS_SemGive(IGInfo.StateLock);
                                return IG_STATUS_SUCCESS;
                            }
                        }
                    }
                    else
                    {
                        /* we are already copying multipes, we need to look instead for the last in sequence flag,
                        we don't care if the packet is a full 0xffff or not, last_in_sequence will tell us we are done */
                        if (OBJECT_DEFINITION == IGInfo.SegmentType)
                        {
                            IGInfo.CurPesInfo.NeedSegmentBytes = ODS_HEADER_SIZE_NO_FRAGMENT;
                        }
                        else if (INTERACTIVE_COMPOSITION == IGInfo.SegmentType)
                        {
                            IGInfo.CurPesInfo.NeedSegmentBytes = ICS_HEADER_SIZE_MULTIPES;
                        }
                        else
                        {
                            DBGPRINT(DBG_ON(DBG_ERROR), ("IGAddData(): Illegal segment type on rest of MultiPES packet\n"));

                            /* clear and reset here */
                            IGClearAddDataVars();
#ifdef ALLOW_IG_PROFILING
                            if (IGStats.Profiling == 1)
                            {
                                IGStats.TotalAddDataTicks += OS_GetTicks() - TickStart;
                            }
#endif
                            OS_SemGive(IGInfo.StateLock);
                            return IG_STATUS_ERROR;
                        }
                        IGInfo.CurPesInfo.SegmentIndex = 0;
                    }

                    /* move ahead */
                    BytesRead += AssembleBytesRead;
                    BytesLeft -= AssembleBytesRead;
                    AssembleBytesRead = 0;
                }
                else if (IG_MORE_DATA == RetCode)
                {
                    DBGPRINT(DBG_ON(DBG_TRACE), ("IGAddData(): Need more data\n"));
#ifdef ALLOW_IG_PROFILING
                    if (IGStats.Profiling == 1)
                    {
                        IGStats.TotalAddDataTicks += OS_GetTicks() - TickStart;
                    }
#endif
                    OS_SemGive(IGInfo.StateLock);
                    return IG_STATUS_SUCCESS;
                }
                else
                {
                    DBGPRINT(DBG_ON(DBG_ERROR), ("IGAddData(): IG error adddata\n"));
                    IGClearAddDataVars();
#ifdef ALLOW_IG_PROFILING
                    if (IGStats.Profiling == 1)
                    {
                        IGStats.TotalAddDataTicks += OS_GetTicks() - TickStart;
                    }
#endif
                    OS_SemGive(IGInfo.StateLock);
                    return IG_STATUS_ERROR;
                }
            }

            /* we have a multipes segment to handle, get all the bytes of a segment header and buffer
            them, don't continue until we have enough to parse */
            if (IGInfo.CurPesInfo.NeedSegmentBytes)
            {
                RetCode = IGAssembleSegmentData(&Buffer[BytesRead], BytesLeft, &AssembleBytesRead);
                if (IG_STATUS_SUCCESS == RetCode)
                {
                    /* we got ODS_HEADER_SIZE bytes of data in, make sure it's a ODS or ICS
                    NOTE that if it's an ICS we have a few bytes extra in the SegmentTemp buffer
                    on the first in seqence */
                    switch(IGInfo.CurPesInfo.SegmentTemp[0])
                    {
                    case OBJECT_DEFINITION:
                        IGInfo.SegmentType = IGInfo.CurPesInfo.SegmentTemp[0];  /* keep track of what kind this is */
                        IGInfo.SequenceDesc = IGInfo.CurPesInfo.SegmentTemp[6];
                        break;
                    case INTERACTIVE_COMPOSITION:
                        IGInfo.SegmentType = IGInfo.CurPesInfo.SegmentTemp[0];  /* keep track of what kind this is */
                        IGInfo.SequenceDesc = IGInfo.CurPesInfo.SegmentTemp[11];
                        break;
                    default:
                        DBGPRINT(DBG_ON(DBG_ERROR), ("IGAddData(): This data is incorrect, the data must be a Object Definition Segment, skip data to sync\n"));

                        /* clear pes parsing structures and state info and return */
                        IGClearAddDataVars();
#ifdef ALLOW_IG_PROFILING
                        if (IGStats.Profiling == 1)
                        {
                            IGStats.TotalAddDataTicks += OS_GetTicks() - TickStart;
                        }
#endif
                        OS_SemGive(IGInfo.StateLock);
                        return IG_STATUS_ERROR;   /* we got wrong data */
                    }
                }
                else if (IG_MORE_DATA == RetCode)
                {
                    /* we need more data */
                    DBGPRINT(DBG_ON(DBG_TRACE), ("IGAddData(): IG MORE DATA\n"));
                    BytesRead -= AssembleBytesRead;
#ifdef ALLOW_IG_PROFILING
                    if (IGStats.Profiling == 1)
                    {
                        IGStats.TotalAddDataTicks += OS_GetTicks() - TickStart;
                    }
#endif
                    OS_SemGive(IGInfo.StateLock);
                    return IG_STATUS_SUCCESS;
                }

                /* we haven't copied the first of a multipes packet yet */
                if (FIRST_IN_SEQUENCE & IGInfo.SequenceDesc)
                {
                    DBGPRINT(DBG_ON(DBG_VERBOSE), ("First in seq %d\n", IGInfo.SequenceDesc));

                    /*
                        this is the first in a seqence of pes packets
                     */

                    if (OBJECT_DEFINITION == IGInfo.SegmentType)
                    {
                        /* now the size of the object, we need linear space for this */
                        ObjectDataSize = (IGInfo.CurPesInfo.SegmentTemp[7] << 16) |
                                         (IGInfo.CurPesInfo.SegmentTemp[8] << 8)  |
                                         IGInfo.CurPesInfo.SegmentTemp[9];

                        /* copy the whole header - 4 bytes for width and height of ODS */
                        ObjectDataSize += ODS_HEADER_SIZE - 4;

                        /* do we have space for all this data */
                        IGWaitForSpaceAvail(ObjectDataSize);
                        if (IGInfo.CurrentState != IG_STATE_RUNNING)
                        {
                            OS_SemGive(IGInfo.StateLock);
                            return IG_STATUS_SUCCESS;
                        }

                        /* copy over the segment header data to the IGParseBuffer (this includes some extra bytes) */
                        memcpy(&IGInfo.IGParseBuffer[IGInfo.PESWritePtr], &Buffer[BytesRead], AssembleBytesRead);
                        IGInfo.PESWriteStart = IGInfo.PESWritePtr;
                        IGInfo.PESWritePtr += AssembleBytesRead;

                        /* copy some ES data */
                        BytesLeft -= AssembleBytesRead;
                        BytesRead += AssembleBytesRead;
                        IGInfo.CurPesInfo.ESRemaining -= AssembleBytesRead;
                        IGInfo.CurPesInfo.SegmentIndex = 0; /* segment header is read */
                    }
                    else if (INTERACTIVE_COMPOSITION == IGInfo.SegmentType)
                    {
                        if (IGInfo.CurPesInfo.SegmentIndex == ICS_HEADER_SIZE)
                        {
                            /* calc the size of the ICS */
                            ObjectDataSize = (IGInfo.CurPesInfo.SegmentTemp[12] << 16) |
                                             (IGInfo.CurPesInfo.SegmentTemp[13] << 8)  |
                                             IGInfo.CurPesInfo.SegmentTemp[14];

                            /* copy the whole header - 4 bytes for width and height of ODS */
                            ObjectDataSize += ICS_HEADER_SIZE;
                        }
                        else
                        {
                            DBGPRINT(DBG_ON(DBG_ERROR), ("IGAddData(): Error with data size of first ICS in Segment Data\n"));
                            IGClearAddDataVars();
#ifdef ALLOW_IG_PROFILING
                            if (IGStats.Profiling == 1)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -