AVIIndex.cpp
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:5k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. // VirtualDub - Video processing and capture application
  2. // Copyright (C) 1998-2001 Avery Lee
  3. //
  4. // This program is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation; either version 2 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program; if not, write to the Free Software
  16. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. #include <stdio.h>
  18. #include <crtdbg.h>
  19. #include "AVIIndex.h"
  20. ///////////////////////////////////////////////////////////////////////////
  21. class AVIIndexChainNode {
  22. public:
  23. enum { ENTS=2048 };
  24. AVIIndexChainNode *next;
  25. AVIIndexEntry2 ient[ENTS];
  26. int num_ents;
  27. AVIIndexChainNode() {
  28. num_ents = 0;
  29. next = NULL;
  30. }
  31. bool add(FOURCC ckid, __int64 pos, long size, bool is_keyframe) {
  32. if (num_ents < ENTS) {
  33. ient[num_ents].ckid = ckid;
  34. ient[num_ents].pos = pos;
  35. ient[num_ents].size = is_keyframe ? size : 0x80000000+size;
  36. ++num_ents;
  37. return true;
  38. }
  39. return false;
  40. }
  41. void put(AVIINDEXENTRY *&avieptr) {
  42. int i;
  43. for(i=0; i<num_ents; i++) {
  44. avieptr->ckid = ient[i].ckid;
  45. avieptr->dwFlags = ient[i].size & 0x80000000 ? 0 : AVIIF_KEYFRAME;
  46. avieptr->dwChunkOffset = ient[i].pos;
  47. avieptr->dwChunkLength = ient[i].size & 0x7FFFFFFF;
  48. ++avieptr;
  49. }
  50. }
  51. void put(AVIIndexEntry2 *&avie2ptr) {
  52. int i;
  53. for(i=0; i<num_ents; i++)
  54. *avie2ptr++ = ient[i];
  55. }
  56. void put(AVIIndexEntry3 *&avie3ptr, __int64 offset) {
  57. int i;
  58. for(i=0; i<num_ents; i++) {
  59. avie3ptr->dwSizeKeyframe = ient[i].size;
  60. avie3ptr->dwOffset = (DWORD)(ient[i].pos - offset);
  61. ++avie3ptr;
  62. }
  63. }
  64. };
  65. ///////////////////////////////////////////////////////////////////////////
  66. AVIIndexChain::AVIIndexChain() {
  67. head = tail = NULL;
  68. total_ents = 0;
  69. }
  70. void AVIIndexChain::delete_chain() {
  71. AVIIndexChainNode *aicn = head,*aicn2;
  72. while(aicn) {
  73. aicn2 = aicn->next;
  74. delete aicn;
  75. aicn = aicn2;
  76. }
  77. head = tail = NULL;
  78. }
  79. AVIIndexChain::~AVIIndexChain() {
  80. delete_chain();
  81. }
  82. bool AVIIndexChain::add(AVIINDEXENTRY *avie) {
  83. if (!tail || !tail->add(avie->ckid, avie->dwChunkOffset, avie->dwChunkLength, !!(avie->dwFlags & AVIIF_KEYFRAME))) {
  84. AVIIndexChainNode *aicn = new AVIIndexChainNode();
  85. if (tail) tail->next = aicn; else head=aicn;
  86. tail = aicn;
  87. if (tail->add(avie->ckid, avie->dwChunkOffset, avie->dwChunkLength, !!(avie->dwFlags & AVIIF_KEYFRAME))) {
  88. ++total_ents;
  89. return true;
  90. }
  91. return false;
  92. }
  93. ++total_ents;
  94. return true;
  95. }
  96. bool AVIIndexChain::add(AVIIndexEntry2 *avie2) {
  97. return add(avie2->ckid, avie2->pos, avie2->size & 0x7FFFFFFF, !!(avie2->size & 0x80000000));
  98. }
  99. bool AVIIndexChain::add(FOURCC ckid, __int64 pos, long size, bool is_keyframe) {
  100. if (!tail || !tail->add(ckid, pos, size, is_keyframe)) {
  101. AVIIndexChainNode *aicn = new AVIIndexChainNode();
  102. if (tail) tail->next = aicn; else head=aicn;
  103. tail = aicn;
  104. if (tail->add(ckid, pos, size, is_keyframe)) {
  105. ++total_ents;
  106. return true;
  107. }
  108. return false;
  109. }
  110. ++total_ents;
  111. return true;
  112. }
  113. void AVIIndexChain::put(AVIINDEXENTRY *avietbl) {
  114. AVIIndexChainNode *aicn = head;
  115. while(aicn) {
  116. aicn->put(avietbl);
  117. aicn=aicn->next;
  118. }
  119. delete_chain();
  120. }
  121. void AVIIndexChain::put(AVIIndexEntry2 *avie2tbl) {
  122. AVIIndexChainNode *aicn = head;
  123. while(aicn) {
  124. aicn->put(avie2tbl);
  125. aicn=aicn->next;
  126. }
  127. delete_chain();
  128. }
  129. void AVIIndexChain::put(AVIIndexEntry3 *avie3tbl, __int64 offset) {
  130. AVIIndexChainNode *aicn = head;
  131. while(aicn) {
  132. aicn->put(avie3tbl, offset);
  133. aicn=aicn->next;
  134. }
  135. delete_chain();
  136. }
  137. AVIIndex::AVIIndex() {
  138. index = NULL;
  139. index2 = NULL;
  140. index3 = NULL;
  141. }
  142. AVIIndex::~AVIIndex() {
  143. delete[] index;
  144. delete[] index2;
  145. delete[] index3;
  146. }
  147. bool AVIIndex::makeIndex() {
  148. if (!allocateIndex(total_ents)) return false;
  149. put(indexPtr());
  150. return true;
  151. }
  152. bool AVIIndex::makeIndex2() {
  153. if (!allocateIndex2(total_ents)) return false;
  154. put(index2Ptr());
  155. return true;
  156. }
  157. bool AVIIndex::makeIndex3(__int64 offset) {
  158. if (!allocateIndex3(total_ents)) return false;
  159. put(index3Ptr(), offset);
  160. return true;
  161. }
  162. void AVIIndex::clear() {
  163. delete_chain();
  164. delete[] index;
  165. delete[] index2;
  166. delete[] index3;
  167. index = NULL;
  168. index2 = NULL;
  169. index3 = NULL;
  170. total_ents = 0;
  171. }