#include //#include #include "AVIIndex.h" /////////////////////////////////////////////////////////////////////////// class AVIIndexChainNode { public: enum { ENTS=2048 }; AVIIndexChainNode *next; AVIIndexEntry2 ient[ENTS]; int num_ents; AVIIndexChainNode() { num_ents = 0; next = NULL; } bool add(FOURCC ckid, __int64 pos, long size, bool is_keyframe) { if (num_ents < ENTS) { ient[num_ents].ckid = ckid; ient[num_ents].pos = pos; ient[num_ents].size = is_keyframe ? size : 0x80000000+size; ++num_ents; return true; } return false; } void put(AVIINDEXENTRY *&avieptr) { int i; for(i=0; ickid = ient[i].ckid; avieptr->dwFlags = ient[i].size & 0x80000000 ? 0 : AVIIF_KEYFRAME; avieptr->dwChunkOffset = ient[i].pos; avieptr->dwChunkLength = ient[i].size & 0x7FFFFFFF; ++avieptr; } } void put(AVIIndexEntry2 *&avie2ptr) { int i; for(i=0; idwSizeKeyframe = ient[i].size; avie3ptr->dwOffset = (DWORD)(ient[i].pos - offset); ++avie3ptr; } } }; /////////////////////////////////////////////////////////////////////////// AVIIndexChain::AVIIndexChain() { head = tail = NULL; total_ents = 0; } void AVIIndexChain::delete_chain() { AVIIndexChainNode *aicn = head,*aicn2; while(aicn) { aicn2 = aicn->next; delete aicn; aicn = aicn2; } head = tail = NULL; } AVIIndexChain::~AVIIndexChain() { delete_chain(); } bool AVIIndexChain::add(AVIINDEXENTRY *avie) { if (!tail || !tail->add(avie->ckid, avie->dwChunkOffset, avie->dwChunkLength, !!(avie->dwFlags & AVIIF_KEYFRAME))) { AVIIndexChainNode *aicn = new AVIIndexChainNode(); if (tail) tail->next = aicn; else head=aicn; tail = aicn; if (tail->add(avie->ckid, avie->dwChunkOffset, avie->dwChunkLength, !!(avie->dwFlags & AVIIF_KEYFRAME))) { ++total_ents; return true; } return false; } ++total_ents; return true; } bool AVIIndexChain::add(AVIIndexEntry2 *avie2) { return add(avie2->ckid, avie2->pos, avie2->size & 0x7FFFFFFF, !!(avie2->size & 0x80000000)); } bool AVIIndexChain::add(FOURCC ckid, __int64 pos, long size, bool is_keyframe) { if (!tail || !tail->add(ckid, pos, size, is_keyframe)) { AVIIndexChainNode *aicn = new AVIIndexChainNode(); if (tail) tail->next = aicn; else head=aicn; tail = aicn; if (tail->add(ckid, pos, size, is_keyframe)) { ++total_ents; return true; } return false; } ++total_ents; return true; } void AVIIndexChain::put(AVIINDEXENTRY *avietbl) { AVIIndexChainNode *aicn = head; while(aicn) { aicn->put(avietbl); aicn=aicn->next; } delete_chain(); } void AVIIndexChain::put(AVIIndexEntry2 *avie2tbl) { AVIIndexChainNode *aicn = head; while(aicn) { aicn->put(avie2tbl); aicn=aicn->next; } delete_chain(); } void AVIIndexChain::put(AVIIndexEntry3 *avie3tbl, __int64 offset) { AVIIndexChainNode *aicn = head; while(aicn) { aicn->put(avie3tbl, offset); aicn=aicn->next; } delete_chain(); } AVIIndex::AVIIndex() { index = NULL; index2 = NULL; index3 = NULL; } AVIIndex::~AVIIndex() { delete[] index; delete[] index2; delete[] index3; } bool AVIIndex::makeIndex() { if (!allocateIndex(total_ents)) return false; put(indexPtr()); return true; } bool AVIIndex::makeIndex2() { if (!allocateIndex2(total_ents)) return false; put(index2Ptr()); return true; } bool AVIIndex::makeIndex3(__int64 offset) { if (!allocateIndex3(total_ents)) return false; put(index3Ptr(), offset); return true; } void AVIIndex::clear() { delete_chain(); delete[] index; delete[] index2; delete[] index3; index = NULL; index2 = NULL; index3 = NULL; total_ents = 0; }