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

多媒体编程

开发平台:

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 "VirtualDub.h"
  18. #include <string.h>
  19. #include <stdio.h>
  20. #include <ctype.h>
  21. #include <windows.h>
  22. #include <vfw.h>
  23. //#include "ProgressDialog.h"
  24. #include "Error.h"
  25. #include "AVIStripeSystem.h"
  26. ///////////////////////////////////////////////////////////////////////////
  27. //
  28. // AVIStripe
  29. //
  30. ///////////////////////////////////////////////////////////////////////////
  31. void *AVIStripe::operator new(size_t stSize, int iNameBytes) {
  32. return malloc(stSize + iNameBytes);
  33. }
  34. ///////////////////////////////////////////////////////////////////////////
  35. //
  36. // AVIStripeSystem
  37. //
  38. ///////////////////////////////////////////////////////////////////////////
  39. void AVIStripeSystem::_construct(int nStripes) {
  40. int i;
  41. this->nStripes = nStripes;
  42. if (!(stripe = new AVIStripe *[nStripes]))
  43. throw MyMemoryError();
  44. for(i=0; i<nStripes; i++)
  45. stripe[i] = NULL;
  46. }
  47. AVIStripeSystem::AVIStripeSystem(int nStripes) {
  48. _construct(nStripes);
  49. }
  50. static bool get_line(char *buf, size_t buf_size, FILE *f) {
  51. char *s;
  52. do {
  53. if (!fgets(buf, buf_size, f))
  54. return false;
  55. s = buf;
  56. while(*s && isspace(*s) && *s!='n')
  57. ++s;
  58. } while(!*s || *s=='n' || buf[0]=='#');
  59. return true;
  60. }
  61. AVIStripeSystem::AVIStripeSystem(char *szFile) {
  62. FILE *f = NULL;
  63. stripe = NULL;
  64. try {
  65. char linebuf[512];
  66. int stripe_cnt, cur;
  67. int lineno = 2;
  68. char *s, *t;
  69. // Type of lines we are trying to parse:
  70. //
  71. // 0   i   131072     65536      e:capture_master.avi
  72. // 0   v   4194304    1048576   "e:capture video stripe 1.avi"
  73. //  -1  v 1048576    524288    "i:capture video stripe 2.avi"
  74. f = fopen(szFile, "r");
  75. if (!f) throw MyError("Couldn't open stripe definition file "%s"", szFile);
  76. if (!get_line(linebuf, sizeof linebuf, f))
  77. throw MyError("Failure reading first line of stripe def file");
  78. if (1!=sscanf(linebuf, " %d n", &stripe_cnt))
  79. throw MyError("First line of stripe definition file must contain stripe count");
  80. if (stripe_cnt<=0)
  81. throw MyError("Invalid number of stripes (%d)", stripe_cnt);
  82. _construct(stripe_cnt);
  83. for(cur=0; cur<stripe_cnt; cur++) {
  84. int iPri, iName;
  85. long lBuffer, lChunk;
  86. char cMode[2];
  87. int match_count;
  88. if (!get_line(linebuf, sizeof linebuf, f))
  89. throw MyError("Failure reading stripe definition file");
  90. match_count = sscanf(linebuf, " %d %1s %ld %ld %n", &iPri, cMode, &lBuffer, &lChunk, &iName);
  91. if (match_count != 4)
  92. throw MyError("Stripe definition parse error: line %d", lineno);
  93. t = s = linebuf + iName;
  94. if (*s=='"') {
  95. ++s, ++t;
  96. while(*t && *t!='n' && *t!='"') ++t;
  97. } else
  98. while(*t && *t!='n' && !isspace(*t)) ++t;
  99. if (t<=s)
  100. throw MyError("Stripe definition parse error: line %d -- no stripe filename!", lineno);
  101. switch(tolower(cMode[0])) {
  102. case 'm': cMode[0] = AVIStripe::MODE_MASTER; break;
  103. case 'i': cMode[0] = AVIStripe::MODE_INDEX; break;
  104. case 'v': cMode[0] = AVIStripe::MODE_VIDEO; break;
  105. case 'a': cMode[0] = AVIStripe::MODE_AUDIO; break;
  106. case 'b': cMode[0] = AVIStripe::MODE_BOTH; break;
  107. default:
  108. throw MyError("Invalid stripe mode '%c'", cMode[0]);
  109. };
  110. // Allocate a stripe structure and copy the data into it
  111. if (!(stripe[cur] = new(t+1-s) AVIStripe))
  112. throw MyMemoryError();
  113. *t=0;
  114. stripe[cur]->lBufferSize = lBuffer;
  115. stripe[cur]->lChunkSize = lChunk;
  116. stripe[cur]->iNameLen = t+1-s;
  117. stripe[cur]->cStripeMode = cMode[0];
  118. stripe[cur]->scPriority = iPri;
  119. strcpy(stripe[cur]->szName, s);
  120. ++lineno;
  121. }
  122. } catch(...) {
  123. if (f) fclose(f);
  124. _destruct();
  125. throw;
  126. }
  127. fclose(f);
  128. }
  129. void AVIStripeSystem::_destruct() {
  130. int i;
  131. if (stripe)
  132. for(i=0; i<nStripes; i++)
  133. delete stripe[i];
  134. delete stripe;
  135. }
  136. AVIStripeSystem::~AVIStripeSystem() {
  137. _destruct();
  138. }
  139. int AVIStripeSystem::getStripeCount() {
  140. return nStripes;
  141. }
  142. AVIStripe *AVIStripeSystem::getStripeInfo(int nStripe) {
  143. return stripe[nStripe];
  144. }
  145. ///////////////////////////////////////////////////////////////////////////
  146. //
  147. // AVIStripeIndexLookup
  148. //
  149. ///////////////////////////////////////////////////////////////////////////
  150. AVIStripeIndexLookup::AVIStripeIndexLookup(IAVIReadStream *pasIndex) {
  151. index_table = NULL;
  152. try {
  153. AVIStripeIndexEntry *asieptr;
  154. LONG lStart, lCur, lEnd;
  155. if (-1 == (lStart = pasIndex->Start())
  156. || -1 == (lEnd = pasIndex->End()))
  157. throw MyError("Stripe index: can't get start/end of index stream");
  158. // ProgressDialog pd(NULL, "AVI Striped Import Filter", "Reading stripe index", lEnd-lStart, true);
  159. // pd.setValueFormat("Frame %ld/%ld");
  160. index_table_size = lEnd - lStart;
  161. if (!(index_table = new AVIStripeIndexEntry[index_table_size]))
  162. throw MyMemoryError();
  163. asieptr = index_table;
  164. pasIndex->BeginStreaming(lStart, lEnd, 100000);
  165. lCur = lStart;
  166. while(lCur < lEnd) {
  167. HRESULT err;
  168. LONG lActualBytes, lActualSamples;
  169. err = pasIndex->Read(lCur, lEnd-lCur, asieptr, sizeof(AVIStripeIndexEntry)*(lEnd-lCur), &lActualBytes, &lActualSamples);
  170. if (err == AVIERR_OK && !lActualSamples)
  171. err = AVIERR_FILEREAD;
  172. if (err != AVIERR_OK) throw MyAVIError("AVIStripeIndex",err);
  173. if (lActualBytes != lActualSamples * sizeof(AVIStripeIndexEntry))
  174. throw MyError("Stripe index: bad index marks! (not 16 bytes)");
  175. lCur += lActualSamples;
  176. asieptr += lActualSamples;
  177. // pd.advance(lCur);
  178. // pd.check();
  179. }
  180. pasIndex->EndStreaming();
  181. } catch(...) {
  182. delete index_table;
  183. throw;
  184. }
  185. }
  186. AVIStripeIndexLookup::~AVIStripeIndexLookup() {
  187. delete index_table;
  188. }
  189. AVIStripeIndexEntry *AVIStripeIndexLookup::lookup(long sample) {
  190. long l, pivot, r;
  191. // _RPT1(0, "AVIStripeIndexEntry: looking up %ldn", sample);
  192. l = 0;
  193. r = index_table_size-1;
  194. while(l <= r) {
  195. pivot = (l+r)/2;
  196. if (sample > index_table[pivot])
  197. l = pivot+1;
  198. else if (sample < index_table[pivot])
  199. r = pivot-1;
  200. else {
  201. // _RPT2(0,"tFound in stripe %ld at %ldn", index_table[pivot].lStripe+1, index_table[pivot].lStripeSample);
  202. return &index_table[pivot];
  203. }
  204. }
  205. _RPT0(0,"tNot found!n");
  206. return NULL;
  207. }