亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? cpi_playlist.c

?? VC++視頻開發實例集錦(包括“遠程視頻監控”"語音識別系統"等13個經典例子)
?? C
?? 第 1 頁 / 共 5 頁
字號:

////////////////////////////////////////////////////////////////////////////////



#include "stdafx.h"
#include "globals.h"
#include "CPI_Playlist.h"
#include "CPI_PlaylistItem.h"
#include "CPI_PlaylistItem_Internal.h"
#include "CPI_Player.h"


#define CPC_TRACKSTACK_BUFFER_QUANTISATION	32
typedef int (__cdecl *wp_SortFN)(const void *elem1, const void *elem2);
int __cdecl exp_CompareStrings(const void *elem1, const void *elem2);
DWORD WINAPI CPI_PlaylistWorkerThreadEP(void* pCookie);
////////////////////////////////////////////////////////////////////////////////
//
typedef struct _CPs_PlaylistWorkerThreadInfo
{
    DWORD m_dwHostThreadID;
    DWORD m_dwCurrentBatchID;

} CPs_PlaylistWorkerThreadInfo;
//
//
typedef struct _CPs_Playlist
{
    CP_HPLAYLISTITEM m_hFirst;
    CP_HPLAYLISTITEM m_hLast;
    CP_HPLAYLISTITEM m_hCurrent;

    CP_HPLAYLISTITEM* m_pTrackStack;
    unsigned int m_iTrackStackSize;
    unsigned int m_iTrackStackBufferSize;
    unsigned int m_iTrackStackCursor;

    HANDLE m_hWorkerThread;
    DWORD m_dwWorkerThreadID;
    CPs_PlaylistWorkerThreadInfo m_WorkerThreadInfo;
    BOOL m_bSyncLoadNextFile;
    BOOL m_bAutoActivateInitial;

} CPs_Playlist;
//
//
typedef enum _CPe_PlayListFileType
{
    pftUnknown,
    pftPLS,
    pftM3U
} CPe_PlayListFileType;
//
typedef struct _CPs_FilenameLLItem
{
    char* m_pcFilename;
    void* m_pNextItem;
} CPs_FilenameLLItem;
//
//
#define CPC_PLAYLISTWORKER_NOTIFYCHUNKSIZE	32
typedef struct _CPs_NotifyChunk
{
    int m_iNumberInChunk;
    CP_HPLAYLISTITEM m_aryItems[CPC_PLAYLISTWORKER_NOTIFYCHUNKSIZE];
    DWORD m_aryBatchIDs[CPC_PLAYLISTWORKER_NOTIFYCHUNKSIZE];

} CPs_NotifyChunk;
//
////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////
//
//
//
CP_HPLAYLIST CPL_CreatePlaylist()
{
    CPs_Playlist* pNewPlaylist = (CPs_Playlist*)malloc(sizeof(CPs_Playlist));
    pNewPlaylist->m_hFirst = NULL;
    pNewPlaylist->m_hLast = NULL;
    pNewPlaylist->m_hCurrent = NULL;

    pNewPlaylist->m_pTrackStack = NULL;
    pNewPlaylist->m_iTrackStackSize = 0;
    pNewPlaylist->m_iTrackStackBufferSize = 0;
    pNewPlaylist->m_iTrackStackCursor = 0;
    pNewPlaylist->m_bSyncLoadNextFile = FALSE;
    pNewPlaylist->m_bAutoActivateInitial = FALSE;

    pNewPlaylist->m_WorkerThreadInfo.m_dwHostThreadID = GetCurrentThreadId();
    pNewPlaylist->m_WorkerThreadInfo.m_dwCurrentBatchID = 0;

    // Create worker thread
    pNewPlaylist->m_hWorkerThread = CreateThread(NULL, 0, CPI_PlaylistWorkerThreadEP, &pNewPlaylist->m_WorkerThreadInfo, 0, &(pNewPlaylist->m_dwWorkerThreadID) );
    CP_ASSERT(pNewPlaylist->m_hWorkerThread);

    return pNewPlaylist;
}
//
//
//
void CPL_DestroyPlaylist(CP_HPLAYLIST hPlaylist)
{
    CPs_Playlist* pPlaylist = (CPs_Playlist*)hPlaylist;
    CP_CHECKOBJECT(pPlaylist);

    // Stop the worker thread from processing any more pending ID3 reads
    pPlaylist->m_WorkerThreadInfo.m_dwCurrentBatchID++;

    // Request worker thread to shutdown
    PostThreadMessage(pPlaylist->m_dwWorkerThreadID, CPPLWT_TERMINATE, 0, 0);

    // Clean up list
    CPL_Empty(hPlaylist);

    // Delete an unattached active item
    if(pPlaylist->m_hCurrent && CPLII_DECODEHANDLE(pPlaylist->m_hCurrent)->m_bDestroyOnDeactivate)
        CPLII_DestroyItem(pPlaylist->m_hCurrent);

    // Wait for shutdown to actually happen
    WaitForSingleObject(pPlaylist->m_hWorkerThread, INFINITE);
    CloseHandle(pPlaylist->m_hWorkerThread);

    // Remove any read ID3s from our message queue
    {
        MSG msg;
        while(PeekMessage(&msg, NULL, CPPLNM_TAGREAD, CPPLNM_TAGREAD, PM_REMOVE) )
        {
            CPs_NotifyChunk* pChunk = (CPs_NotifyChunk*)msg.wParam;
            int iChunkItemIDX;

            // Add all of the items in the chunk
            for(iChunkItemIDX = 0; iChunkItemIDX < pChunk->m_iNumberInChunk; iChunkItemIDX++)
                CPLII_DestroyItem(pChunk->m_aryItems[iChunkItemIDX]);
            free(pChunk);
        }
    }

    // Clean up object
    free(pPlaylist);
}
//
//
//
void CPL_UnlinkItem(CP_HPLAYLIST hPlaylist, CP_HPLAYLISTITEM hItem)
{
    CPs_Playlist* pPlaylist = (CPs_Playlist*)hPlaylist;
    CPs_PlaylistItem* pItemToUnlink = CPLII_DECODEHANDLE(hItem);
    CP_CHECKOBJECT(pPlaylist);

    // Remove item from list
    if(pItemToUnlink->m_hPrev)
        CPLII_DECODEHANDLE(pItemToUnlink->m_hPrev)->m_hNext = pItemToUnlink->m_hNext;
    else
    {
        CP_ASSERT(pPlaylist->m_hFirst == hItem);
        pPlaylist->m_hFirst = pItemToUnlink->m_hNext;
    }

    if(pItemToUnlink->m_hNext)
        CPLII_DECODEHANDLE(pItemToUnlink->m_hNext)->m_hPrev = pItemToUnlink->m_hPrev;
    else
    {
        CP_ASSERT(pPlaylist->m_hLast == hItem);
        pPlaylist->m_hLast = pItemToUnlink->m_hPrev;
    }
}
//
//
//
void CPL_Empty(CP_HPLAYLIST hPlaylist)
{
    CPs_Playlist* pPlaylist = (CPs_Playlist*)hPlaylist;
    CP_HPLAYLISTITEM hCursor, hNext;

    CP_CHECKOBJECT(pPlaylist);

    // Stop the worker thread from processing any more pending ID3 reads
    pPlaylist->m_WorkerThreadInfo.m_dwCurrentBatchID++;

    // Unlink the active item
    if(pPlaylist->m_hCurrent)
    {
        // This is the active item - clear it's next and prev entries and mark it
        // so that it's destroyed when activation next changes
        CPs_PlaylistItem* pActiveItem = CPLII_DECODEHANDLE(pPlaylist->m_hCurrent);
        if(pActiveItem->m_bDestroyOnDeactivate == FALSE)
        {
            CPL_UnlinkItem(hPlaylist, pPlaylist->m_hCurrent);
            pActiveItem->m_hNext = NULL;
            pActiveItem->m_hPrev = NULL;
            pActiveItem->m_bDestroyOnDeactivate = TRUE;
            CPL_cb_OnPlaylistActivationChange(pPlaylist->m_hCurrent, FALSE);
            pActiveItem->m_iCookie = CPC_INVALIDITEM;
        }
    }

    // Callback
    CPL_cb_OnPlaylistEmpty();

    // Clean up items
    hCursor = pPlaylist->m_hFirst;
    while(hCursor)
    {
        hNext = CPLI_Next(hCursor);
        CPLII_DestroyItem(hCursor);
        hCursor = hNext;
    }

    // Reset state
    pPlaylist->m_hFirst = NULL;
    pPlaylist->m_hLast = NULL;

    // Clean up the trackstack
    if(pPlaylist->m_pTrackStack)
        free(pPlaylist->m_pTrackStack);
    pPlaylist->m_pTrackStack = NULL;
    pPlaylist->m_iTrackStackSize = 0;
    pPlaylist->m_iTrackStackBufferSize = 0;
    pPlaylist->m_iTrackStackCursor = 0;
}
//
//
//
void CPL_AddSingleFile_pt2(CP_HPLAYLIST hPlaylist, CP_HPLAYLISTITEM hNewFile, const DWORD dwBatchID)
{
    CPs_Playlist* pPlaylist = (CPs_Playlist*)hPlaylist;
    const char* pcPath = CPLI_GetPath(hNewFile);

    CP_CHECKOBJECT(pPlaylist);

    // Batch has changed since this message was sent
    if(dwBatchID != pPlaylist->m_WorkerThreadInfo.m_dwCurrentBatchID)
    {
        CPLII_DestroyItem(hNewFile);
        return;
    }

    // If items are only allowed once - look for another instance of this item
    // and skip this add if it is found
    if(options.allow_file_once_in_playlist)
    {
        CP_HPLAYLISTITEM hCursor;
        hCursor = pPlaylist->m_hFirst;
        while(hCursor)
        {
            // Is this item in the list already?
            if(stricmp(CPLII_DECODEHANDLE(hCursor)->m_pcPath, pcPath) == 0)
            {
                CPLII_DestroyItem(hNewFile);
                return;
            }

            hCursor = CPLI_Next(hCursor);
        }
    }

    // Add item to the list
    CPLII_DECODEHANDLE(hNewFile)->m_hPrev = pPlaylist->m_hLast;
    if(pPlaylist->m_hLast)
        CPLII_DECODEHANDLE(pPlaylist->m_hLast)->m_hNext = hNewFile;
    pPlaylist->m_hLast = hNewFile;
    if(pPlaylist->m_hFirst == NULL)
        pPlaylist->m_hFirst = hNewFile;

    // If there is no track name (ID3 read off or failed) - create one from the path
    if(CPLII_DECODEHANDLE(hNewFile)->m_pcTrackName == NULL)
    {
        int iNumChars;
        int iCharIDX;
        int iLastSlashIDX = CPC_INVALIDCHAR;
        int iLastDotIDX = CPC_INVALIDCHAR;
        int iLastCharIDX = CPC_INVALIDCHAR;
		if(strnicmp(pcPath,CIC_HTTPHEADER,strlen(CIC_HTTPHEADER)) == 0)
            iLastCharIDX = strlen(pcPath);
		else
        for(iCharIDX=0; pcPath[iCharIDX]; iCharIDX++)
        {
            if(pcPath[iCharIDX] == '\\')
                iLastSlashIDX = iCharIDX;
            if(pcPath[iCharIDX] == '.')
                iLastDotIDX = iCharIDX;
            iLastCharIDX = iCharIDX;
        }

        // Correct indices
        if(iLastSlashIDX == CPC_INVALIDCHAR)
            iLastSlashIDX = 0;
        else
            iLastSlashIDX++; // We want the char after the last slash
        if(iLastDotIDX == CPC_INVALIDCHAR || iLastDotIDX < iLastSlashIDX)
            iLastDotIDX = iLastCharIDX;
        else
            iLastDotIDX--; // We want the string up to the char before the last dot

        // Create title buffer
        iNumChars = (iLastDotIDX-iLastSlashIDX)+1;
        CPLII_DECODEHANDLE(hNewFile)->m_pcTrackName = (char*)malloc(iNumChars+1);
        memcpy(CPLII_DECODEHANDLE(hNewFile)->m_pcTrackName, pcPath+iLastSlashIDX, iNumChars);
        CPLII_DECODEHANDLE(hNewFile)->m_pcTrackName[iNumChars] = '\0';
    }

    // Add to track stack
    CPL_Stack_Append(hPlaylist, hNewFile);

    // Callback
    CPL_cb_OnPlaylistAppend(hNewFile);
}
//
//
//
void CPL_AddSingleFile(CP_HPLAYLIST hPlaylist, const char* pcPath, const char* pcTitle)
{
    CPs_Playlist* pPlaylist = (CPs_Playlist*)hPlaylist;
    CP_HPLAYLISTITEM hNewFile;
    CP_CHECKOBJECT(pPlaylist);

    hNewFile = CPLII_CreateItem(pcPath);

    // There was a title passed - setup the item accordingly
    if(pcTitle && pcTitle[0])
        STR_AllocSetString(&CPLII_DECODEHANDLE(hNewFile)->m_pcTrackName, pcTitle, FALSE);

    // Defer this add to the worker thread if we are reading tags
    if(options.read_id3_tag && options.read_id3_tag_in_background && !pPlaylist->m_bSyncLoadNextFile)
    {
        while(!PostThreadMessage(pPlaylist->m_dwWorkerThreadID, CPPLWT_READTAG, (WPARAM)pPlaylist->m_WorkerThreadInfo.m_dwCurrentBatchID, (LPARAM)hNewFile))
        { 
			Sleep(50); 
		}       
		if(pPlaylist->m_bAutoActivateInitial && stricmp(pcPath, options.initial_file) == 0)
            PostThreadMessage(pPlaylist->m_dwWorkerThreadID, CPPLWT_SETACTIVE, (WPARAM)pPlaylist->m_WorkerThreadInfo.m_dwCurrentBatchID, (LPARAM)hNewFile);
    }
    else
    {
        pPlaylist->m_bSyncLoadNextFile = FALSE;
        if(options.read_id3_tag)
            CPLI_ReadTag(hNewFile);

        // If we didn't get a track length from the tag - work it out
        if(CPLI_GetTrackLength(hNewFile) == 0
                && options.work_out_track_lengths)
        {
            CPLI_CalculateLength(hNewFile);
        }

        CPL_AddSingleFile_pt2(hPlaylist, hNewFile, pPlaylist->m_WorkerThreadInfo.m_dwCurrentBatchID);
    }
}
//
//
//
void CPL_HandleAsyncNotify(CP_HPLAYLIST hPlaylist, WPARAM wParam, LPARAM lParam)
{
    CPs_NotifyChunk* pChunk = (CPs_NotifyChunk*)wParam;
    int iChunkItemIDX;

    // Add all of the items in the chunk
    CLV_BeginBatch(globals.m_hPlaylistViewControl);
    for(iChunkItemIDX = 0; iChunkItemIDX < pChunk->m_iNumberInChunk; iChunkItemIDX++)
        CPL_AddSingleFile_pt2(globals.m_hPlaylist, pChunk->m_aryItems[iChunkItemIDX], pChunk->m_aryBatchIDs[iChunkItemIDX]);
    CLV_EndBatch(globals.m_hPlaylistViewControl);

    // Cleanup
    free(pChunk);
}
//
//
//
void CPL_RemoveDuplicates(CP_HPLAYLIST hPlaylist)
{
    CPs_Playlist* pPlaylist = (CPs_Playlist*)hPlaylist;
    CP_HPLAYLISTITEM hCursor;
    CP_CHECKOBJECT(pPlaylist);

    // Scan the playlist removing duplicates
    hCursor = pPlaylist->m_hFirst;
    while(hCursor)
    {
        CP_HPLAYLISTITEM hCursor_Scan;

        // Look for duplicates after this item (as all items will be scanned
        // in this way there is no need to look for duplicates before this item)
        hCursor_Scan = CPLI_Next(hCursor);
        while(hCursor_Scan)
        {
            // Is this a duplicate
            if(stricmp(	CPLII_DECODEHANDLE(hCursor_Scan)->m_pcPath,
                        CPLII_DECODEHANDLE(hCursor)->m_pcPath) == 0)
            {
                CPL_RemoveItem(hPlaylist, hCursor_Scan);

                // Items before the current are already unique - stop scanning

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产欧美精品区一区二区三区 | 精品1区2区在线观看| 日本高清视频一区二区| 91在线视频免费91| 91在线看国产| 色欲综合视频天天天| 在线观看av一区二区| 欧美视频你懂的| 在线影院国内精品| 欧美色精品天天在线观看视频| 91福利资源站| 欧美影院一区二区三区| 5858s免费视频成人| 精品粉嫩超白一线天av| 久久精品亚洲麻豆av一区二区| 国产区在线观看成人精品| 国产精品久久久久国产精品日日 | 韩国在线一区二区| 欧美a级理论片| 国产精品18久久久久久久久久久久 | 亚洲高清久久久| 婷婷夜色潮精品综合在线| 久久精品国产精品青草| 国产成人精品亚洲日本在线桃色 | 久久这里只有精品视频网| 国产欧美日韩亚州综合| 亚洲欧洲av在线| 亚洲成av人片一区二区梦乃| 老司机免费视频一区二区| 成熟亚洲日本毛茸茸凸凹| 日本韩国欧美一区二区三区| 欧美日韩精品免费观看视频| 精品国精品国产| 国产精品国产三级国产普通话三级| 亚洲精品福利视频网站| 日韩不卡手机在线v区| 成人丝袜18视频在线观看| 在线观看日韩国产| 久久久.com| 午夜精品久久久| 成人黄色一级视频| 91精品一区二区三区在线观看| xnxx国产精品| 天天影视色香欲综合网老头| 国产91综合一区在线观看| 欧美剧情片在线观看| 国产精品理论片| 国模套图日韩精品一区二区| 欧美性高清videossexo| 国产精品美女久久久久高潮| 免费在线看一区| 在线观看欧美日本| 中文字幕在线观看一区| 国产在线精品一区二区不卡了| 91豆麻精品91久久久久久| 中文字幕不卡一区| 国产在线视频一区二区三区| 欧美亚洲动漫精品| 亚洲欧洲韩国日本视频| 国产成人午夜视频| 精品国产伦一区二区三区观看体验 | 亚洲欧美精品午睡沙发| 国产成人免费av在线| 精品卡一卡二卡三卡四在线| 午夜成人免费视频| 欧美午夜精品久久久久久孕妇| 国产精品色婷婷久久58| 国产成人精品免费| 国产女人18毛片水真多成人如厕| 蜜桃一区二区三区在线| 欧美精品v日韩精品v韩国精品v| 夜夜精品视频一区二区| 色婷婷综合中文久久一本| 成人免费在线观看入口| 99视频精品全部免费在线| 国产精品久久午夜| 99精品欧美一区二区三区综合在线| 国产日韩精品一区二区浪潮av| 国内精品国产成人国产三级粉色| 日韩亚洲欧美在线观看| 久久精品国产成人一区二区三区 | 欧美电影免费观看高清完整版 | 成人性视频网站| 欧美韩国日本不卡| 99r国产精品| 亚洲精品久久嫩草网站秘色| 在线免费观看日本欧美| 亚洲成人av一区二区三区| 欧美肥妇毛茸茸| 老司机免费视频一区二区| 久久综合国产精品| 丰满少妇久久久久久久| 《视频一区视频二区| 在线观看成人小视频| 天天色综合成人网| 精品久久久三级丝袜| 国产91精品免费| 亚洲精品视频一区| 欧美一区二区三区免费观看视频 | www.性欧美| 亚洲一区二区3| 欧美大片一区二区| 国产美女精品在线| 一区2区3区在线看| 日韩欧美的一区二区| 国产成人精品影院| 亚洲国产精品一区二区尤物区| 欧美一区二区三区在线观看| 国产成人午夜精品影院观看视频| 综合欧美一区二区三区| 日韩一区二区三区电影在线观看 | 亚洲精品中文字幕在线观看| 在线不卡免费av| 国产成人午夜视频| 亚洲国产一区二区在线播放| 精品剧情v国产在线观看在线| 成人动漫一区二区在线| 午夜激情综合网| 欧美激情一区二区三区蜜桃视频 | 国产乱码精品一区二区三| 一个色综合网站| 国产欧美一区二区在线| 日韩一区二区三区视频在线| 成年人国产精品| 美女被吸乳得到大胸91| 夜夜操天天操亚洲| 久久久www成人免费无遮挡大片| 一本一道波多野结衣一区二区| 麻豆精品视频在线| 一区二区三区美女| 国产精品网站在线播放| 欧美精品欧美精品系列| 色又黄又爽网站www久久| 国产成都精品91一区二区三| 奇米精品一区二区三区四区 | 欧美吞精做爰啪啪高潮| 成人亚洲精品久久久久软件| 久久疯狂做爰流白浆xx| 日韩在线一区二区三区| 亚洲午夜精品网| 综合av第一页| 中文字幕精品一区二区精品绿巨人| 欧美一级在线视频| 欧美视频完全免费看| 欧美亚洲另类激情小说| 在线观看欧美日本| 91麻豆.com| 91蜜桃免费观看视频| 成人丝袜18视频在线观看| 国产99久久久精品| 成人一区二区三区视频在线观看| 国产一区二区三区不卡在线观看 | 91久久精品一区二区三| 99久久婷婷国产| 成人高清视频在线观看| 不卡的av在线播放| av一区二区三区在线| 91免费视频网址| 91福利在线看| 欧美日韩高清影院| 91精品综合久久久久久| 91精品国产手机| 26uuu久久综合| 欧美激情在线看| 最好看的中文字幕久久| 一区二区三区日韩欧美| 亚洲一区二区三区四区的| 五月开心婷婷久久| 另类小说图片综合网| 国产乱码精品一区二区三区忘忧草| 国产成人免费视频一区| 91蜜桃网址入口| 欧美久久一二区| 26uuu亚洲婷婷狠狠天堂| 国产网站一区二区三区| |精品福利一区二区三区| 午夜日韩在线电影| 韩国女主播成人在线观看| av亚洲精华国产精华精| 欧美精品丝袜久久久中文字幕| 日韩欧美不卡一区| 国产精品国产自产拍高清av王其| 亚洲综合丝袜美腿| 老司机免费视频一区二区| 岛国精品在线播放| 欧美日本免费一区二区三区| 精品奇米国产一区二区三区| 国产精品久久三| 日产精品久久久久久久性色| 国产91色综合久久免费分享| 欧美色倩网站大全免费| 欧美国产一区二区在线观看| 午夜精品在线看| 国产suv精品一区二区三区| 在线视频国内自拍亚洲视频| 久久久久青草大香线综合精品| 一区二区三区四区亚洲| 国产一区在线视频| 欧美区一区二区三区| 中文字幕一区二区三区av|