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

📄 ig_api.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                            {
                                IGStats.TotalAddDataTicks += OS_GetTicks() - TickStart;
                            }
#endif
                            OS_SemGive(IGInfo.StateLock);
                            return IG_STATUS_ERROR;
                        }

                        /* 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 */
                        memcpy(&IGInfo.IGParseBuffer[IGInfo.PESWritePtr], &Buffer[BytesRead], AssembleBytesRead);
                        IGInfo.PESWriteStart = IGInfo.PESWritePtr;
                        IGInfo.PESWritePtr += AssembleBytesRead;

                        /* say that we read the data */
                        BytesLeft -= AssembleBytesRead;
                        BytesRead += AssembleBytesRead;
                        IGInfo.CurPesInfo.ESRemaining -= AssembleBytesRead;
                        IGInfo.CurPesInfo.SegmentIndex = 0; /* segment header is read */
                    }

                    /* we are now copying multipes data */
                    IGInfo.CopyingMultiPES = 1;
                    IGInfo.fGotStartPtr = 1;
                }
                else
                {
                    /* here we need to skip over some data, it will not be copied to the output buffer, this
                    data is the ODS header without any fragment size info, just the RLE data fragment. */

                    /* say that we read the data */
                    if (OBJECT_DEFINITION == IGInfo.SegmentType)
                    {
                        /* we will skip ODS_HEADER_SIZE_NO_FRAGMENT bytes */
                        BytesLeft -= ODS_HEADER_SIZE_NO_FRAGMENT;
                        BytesRead += ODS_HEADER_SIZE_NO_FRAGMENT;
                        IGInfo.CurPesInfo.ESRemaining -= ODS_HEADER_SIZE_NO_FRAGMENT;
                        IGInfo.CurPesInfo.SegmentIndex = 0; /* segment header is read */
                    }
                    else if (INTERACTIVE_COMPOSITION == IGInfo.SegmentType)
                    {
                        BytesLeft -= ICS_HEADER_SIZE_MULTIPES;
                        BytesRead += ICS_HEADER_SIZE_MULTIPES;
                        IGInfo.CurPesInfo.ESRemaining -= ICS_HEADER_SIZE_MULTIPES;
                        IGInfo.CurPesInfo.SegmentIndex = 0; /* segment header is read */
                    }
                }

                /*  now copy out the data in the PES buffer, as much as we can, either the
                    rest of the PES packet or the rest of the AddData buffer */
                LeftToCopy = MIN(IGInfo.CurPesInfo.ESRemaining, BytesLeft);

                /* copy what ES data we can here */
                memcpy(&IGInfo.IGParseBuffer[IGInfo.PESWritePtr], &Buffer[BytesRead], LeftToCopy);
                IGInfo.PESWritePtr += LeftToCopy;   /* push up the write pointer */
                IGInfo.CurPesInfo.ESRemaining -= LeftToCopy; /* remove some byte from esremaining */
                BytesLeft -= LeftToCopy;        /* less bytes left */
                BytesRead += LeftToCopy;        /* more bytes read */

                /* if this is the end of the multipes segment, then send it along, this is the ONLY
                   place we send multipes to the parser, non multipes are sent in the else below*/
                if ((LAST_IN_SEQUENCE & IGInfo.SequenceDesc) && (IGInfo.CurPesInfo.ESRemaining == 0))
                {
                    IGAddParseMessage(  IGInfo.PESWriteStart,
                                        IGInfo.PESWritePtr - IGInfo.PESWriteStart,
                                        IGInfo.CurPesInfo.DTS,
                                        IGInfo.CurPesInfo.PTS,
                                        IGInfo.CurPesInfo.PTSDTSFlags,
                                        1);

                    /* not copying a pes packet right now */
                    IGInfo.CopyingPES = 0;
                    IGInfo.CopyingMultiPES = 0;
                    IGInfo.fGotStartPtr = 0;
                }
            }
            else  /* this is the rest of some ES data, could be multipes packets  */
            {
                LeftToCopy = MIN(IGInfo.CurPesInfo.ESRemaining, BytesLeft);

                /* copy a packet, it may or may not be all here */
                memcpy(&IGInfo.IGParseBuffer[IGInfo.PESWritePtr], &Buffer[BytesRead], LeftToCopy);

                /* if we haven't gotten the start ptr yet get it */
                if (0 == IGInfo.fGotStartPtr)
                {
                    /* if we are just continuing a copy we don't reget the write ptr */
                    IGInfo.PESWriteStart = IGInfo.PESWritePtr;  /* data start */
                    IGInfo.fGotStartPtr = 1;
                }

                /* update pointers */
                IGInfo.PESWritePtr += LeftToCopy;               /* bump the write ptr */
                BytesRead += LeftToCopy;                        /* we read this much data */
                BytesLeft -= LeftToCopy;                        /* we read this much data */
                IGInfo.CurPesInfo.ESRemaining -= LeftToCopy;    /* copied ES data */

                /* are we done with the PES packet */
                if (IGInfo.CurPesInfo.ESRemaining)
                {
                    continue; /* we need more data */
                }
                else /* yes as long as it's not multipes, those are all sent from the if above this */
                {
                    if (0 == IGInfo.CopyingMultiPES)
                    {
                        IGAddParseMessage(  IGInfo.PESWriteStart,
                                            IGInfo.PESWritePtr - IGInfo.PESWriteStart,
                                            IGInfo.CurPesInfo.DTS,
                                            IGInfo.CurPesInfo.PTS,
                                            IGInfo.CurPesInfo.PTSDTSFlags,
                                            0);

                        /* not copying a pes packet right now */
                        IGInfo.CopyingPES = 0;
                        IGInfo.CopyingMultiPES = 0;
                        IGInfo.fGotStartPtr = 0;
                    }
                    else
                    {
                        if (IGInfo.SequenceDesc & LAST_IN_SEQUENCE)
                        {
                            IGAddParseMessage(  IGInfo.PESWriteStart,
                                                IGInfo.PESWritePtr - IGInfo.PESWriteStart,
                                                IGInfo.CurPesInfo.DTS,
                                                IGInfo.CurPesInfo.PTS,
                                                IGInfo.CurPesInfo.PTSDTSFlags,
                                                1);

                            /* not copying a pes packet right now */
                            IGInfo.CopyingPES = 0;
                            IGInfo.CopyingMultiPES = 0;
                            IGInfo.fGotStartPtr = 0;
                        }
                    }
                }
            }
        }  /* copyingpes */

        /*
            2. look for sync
        */
        Status = IGScanForStartCode(&Buffer[BytesRead], BytesLeft, &StartCodeOffset);
        if (IG_STATUS_SUCCESS != Status)
        {
            /* couldn't get sync on the rest of the packet */
#ifdef ALLOW_IG_PROFILING
            if (IGStats.Profiling == 1)
            {
                IGStats.TotalAddDataTicks += OS_GetTicks() - TickStart;
            }
#endif
            OS_SemGive(IGInfo.StateLock);
            return IG_STATUS_SUCCESS;
        }

        /* assemble the PES header, we need 5 bytes to start */
        IGInfo.CurPesInfo.HeaderNeedBytes = 5;
        IGInfo.CopyingPES = 1;
        BytesLeft -= StartCodeOffset;
        BytesRead += StartCodeOffset;
    }

#ifdef ALLOW_IG_PROFILING
    if (IGStats.Profiling == 1)
    {
        IGStats.TotalAddDataTicks += OS_GetTicks() - TickStart;
    }
#endif

    OS_SemGive(IGInfo.StateLock);
    return IG_STATUS_SUCCESS;
}


/**
 * IGClearAddDataVars - Clear out state vars related to AddData(), this is called on AddData errors
 *
 * @return void
 */
void IGClearAddDataVars()
{
    /* clear data vars, not all of them, keep the write ptr, but put it back to before any data was received */
    IGInfo.CurPTS             = 0;
    IGInfo.CopyingPES         = 0;
    IGInfo.CopyingMultiPES    = 0;
    IGInfo.SequenceDesc       = 0;
    IGInfo.fGotStartPtr       = 0;

    /* put the pes write pointer back to where it was before
       we received packet data for a pes packet. */
    if (IGInfo.PESWriteStart != 0)
    {
        IGInfo.PESWritePtr = IGInfo.PESWriteStart;
    }

    IGInfo.PESWriteStart      = 1;

    memset(&IGInfo.CurPesInfo, 0, sizeof(PES_HDR_INFO));
}

/**
 * IGSynchronize - Queue a message to the IGParse task for it to decode segment data
 *
 * @param IG_HANDLE handle - handle to the IG module
 * @param IG_SYNC_TYPE type - IG_DECODE_SYNC or IG_DECODE_ASYNC
 *
 * @return IG_STATUS
 */
IG_STATUS IGSynchronize(IG_HANDLE handle, IG_SYNC_TYPE type)
{
    if (handle != (PVOID)IG_HANDLE_VALUE)
    {
        return (IG_STATUS_INVALID_HANDLE);
    }

    if ((type == IG_DECODE_SYNC) || (type == IG_DECODE_ASYNC))
    {
        IGInfo.SyncState = type;
        if (IGInfo.SyncState == IG_DECODE_ASYNC)
        {
            /* renderer waiting? */
            if (IGInfo.RenderWait.WaitPTS)
            {
                if (IGInfo.CurPTS >= IGInfo.RenderWait.WaitPTS)
                {
                    OS_SemGive(IGInfo.RenderWait.WaitSem);
                }
            }
            
            /* Parser waiting? */
            if (IGInfo.ParseWait.WaitPTS)
            {
                if (IGInfo.CurPTS >= IGInfo.ParseWait.WaitPTS)
                {
                    OS_SemGive(IGInfo.ParseWait.WaitSem);
                }
            }
        }
        return IG_STATUS_SUCCESS;
    }

    return IG_STATUS_ERROR;
}

/**
 * IGSetColorSpace - set the color space for IG to 601 or 709
 *
 * @param IG_HANDLE handle - handle to the IG module
 * @param COLOR_SPACE ColorSpace - number indicating colorspace
 *
 * @return IG_STATUS
 */
IG_STATUS IGSetColorSpace(IG_HANDLE handle, int ColorSpace)
{
    if (handle != (PVOID)IG_HANDLE_VALUE)
    {
        return (IG_STATUS_INVALID_HANDLE);
    }

    /* store the color space */
    if (ColorSpace == 0)
    {
        IGInfo.ColorSpace = REC_601;
    }
    else
    {
        IGInfo.ColorSpace = REC_709;
    }

    return IG_STATUS_SUCCESS;
}


/**
 * IGUpdateTimeStamp - Queue a message to the IGParse task for it to decode segment data
 *
 * @param IG_HANDLE handle - handle to the IG module
 * @param ULONG PTS - The current Presentation Time Stamp
 * @param ULONG SCR - The current System Clock Reference
 *
 * @return IG_STATUS
 */
IG_STATUS IGUpdateTimeStamp(IG_HANDLE handle, ULONG PTS, ULONG SCR)
{
    BYTE TimerType = TIMER_NONE;

    if (handle != (PVOID)IG_HANDLE_VALUE)
    {
        return (IG_STATUS_INVALID_HANDLE);
    }

    if (IG_STATE_RUNNING != IGInfo.CurrentState)
    {
        return (IG_STATUS_NOT_RUNNING);
    }

    if (PTS == 0xFFFFFFFF)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("IGUpdateTimeStamp - INVALID PTS = 0xffffffff\n"));
        return (IG_STATUS_ERROR);
    }

    DBGPRINT(DBG_ON(DBG_VERBOSE), ("PTS = 0x%x\n", PTS));

    /* grab the new PTS */
    IGInfo.CurPTS = PTS;

    /* are we waiting on selection timeout? */
    if (IGInfo.SelectionTimeoutPTS)
    {
        if (IGInfo.CurPTS >= IGInfo.SelectionTimeoutPTS)
        {
            TimerType |= TIMER_SEL;
        }
    }

    /* are we waiting on composition timeout? */
    if (IGInfo.CompositionTimeoutPTS)
    {
        if (IGInfo.CurPTS >= IGInfo.CompositionTimeoutPTS)
        {
            TimerType |= TIMER_COMP;
        }
    }

    /* if there is a timer to fire, do it */
    if (TIMER_NONE != TimerType)
    {
        /* fire a single timer, either selection or composition */
        IGOnCompSelTimeout(TimerType);
    }

    /* renderer waiting? */
    if (IGInfo.RenderWait.WaitPTS)
    {
        DBGPRINT(DBG_ON(DBG_VERBOSE), ("IGInfo.RenderWait.WaitPTS = 0x%x\n", IGInfo.RenderWait.WaitPTS));

        if (IGInfo.CurPTS >= IGInfo.RenderWait.WaitPTS)
        {
            OS_SemGive(IGInfo.RenderWait.WaitSem);
        }
    }

    /* Parser waiting? */
    if (IGInfo.ParseWait.WaitPTS)
    {
        DBGPRINT(DBG_ON(DBG_VERBOSE), ("IGInfo.RenderWait.WaitPTS = 0x%x\n", IGInfo.ParseWait.WaitPTS));

        if (IGInfo.CurPTS >= IGInfo.ParseWait.WaitPTS)
        {
            OS_SemGive(IGInfo.ParseWait.WaitSem);
        }
    }

⌨️ 快捷键说明

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