MythTV  master
avi.c
Go to the documentation of this file.
1 /*
2  * avi.c: AVI container functions for replex
3  *
4  *
5  * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de>
6  * Metzler Brothers Systementwicklung GbR
7  * Changes to use MythTV logging
8  * Copyright (C) 2011 Gavin Hurlbut <ghurlbut@mythtv.org>
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * General Public License for more details.
20  *
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
26  *
27  */
28 
29 #include <stdlib.h>
30 #include <string.h>
31 
32 #include "mpg_common.h"
33 #include "avi.h"
34 #include "replex.h"
35 #include "pes.h"
36 
37 
38 #define DEBUG 1
39 
40 #ifdef DEBUG
41 #include "mpg_common.h"
42 #endif
43 
44 #include "mythlogging.h"
45 
46 static uint32_t getle32(uint8_t *buf)
47 {
48  return (buf[3]<<24)|(buf[2]<<16)|(buf[1]<<8)|buf[0];
49 }
50 
51 static uint32_t getbe32(uint8_t *buf)
52 {
53  return (buf[0]<<24)|(buf[1]<<16)|(buf[2]<<8)|buf[3];
54 }
55 
56 static void printhead(uint8_t *buf)
57 {
58  LOG(VB_GENERAL, LOG_INFO, "%c%c%c%c ", buf[0], buf[1], buf[2], buf[3]);
59 }
60 
61 static uint32_t getsize(int fd)
62 {
63  int len;
64  uint8_t buf[4];
65 
66  len=read(fd, buf, 4);
67  return getle32(buf);
68 }
69 
70 static uint32_t getsize_buf(uint8_t *buf)
71 {
72  return getle32(buf);
73 }
74 
75 
76 int check_riff(avi_context *ac, uint8_t *buf, int len)
77 {
78  uint32_t tag;
79  int c = 0;
80 
81  if (len < 12) return -1;
82  tag = getle32(buf);
83  if (tag != TAG_IT('R','I','F','F')) return -1;
84  c+=4;
85 
86  ac->riff_end = getle32(buf+c);
87  c+=4;
88 
89  tag = getle32(buf+c);
90  if (tag != TAG_IT('A','V','I',' ') &&
91  tag != TAG_IT('A','V','I','X') ) return -1;
92 
93  return c+4;
94 }
95 
96 static
97 int new_idx_frame( avi_context *ac, uint32_t pos, uint32_t len,
98  uint32_t fl, uint32_t id)
99 {
100  int num = ac->num_idx_frames;
101  if (ac->num_idx_alloc < num+1){
102  avi_index *idx;
103  uint32_t newnum = num + 1024;
104 
105  if (ac->idx){
106  idx = realloc(ac->idx,
107  newnum*sizeof(avi_index));
108  } else {
109  idx = malloc(newnum*sizeof(avi_index));
110  }
111  if (!idx) return -1;
112  ac->idx = idx;
113  ac->num_idx_alloc = newnum;
114  }
115  ac->idx[num].off = pos;
116  ac->idx[num].id = id;
117  ac->idx[num].len = len;
118  ac->idx[num].flags = fl;
119  ac->num_idx_frames++;
120 
121 
122 
123  return 0;
124 }
125 
126 static void print_index(avi_context *ac, int num){
127  char *cc;
128  cc = (char *) &ac->idx[num].id;
129  LOG(VB_GENERAL, LOG_DEBUG,
130  "%d chunkid: %c%c%c%c chunkoff: 0x%04x chunksize: 0x%04x "
131  " chunkflags: 0x%04x", num, *cc,*(cc+1),*(cc+2),*(cc+3),
132  (int)ac->idx[num].off, ac->idx[num].len, ac->idx[num].flags);
133 }
134 
135 int avi_read_index(avi_context *ac, int fd)
136 {
137  uint32_t tag;
138  uint32_t isize;
139  uint32_t c;
140  off_t start;
141  uint8_t buf[16];
142  char *cc;
143 
144  if (!(ac->avih_flags & AVI_HASINDEX)) return -2;
145  LOG(VB_GENERAL, LOG_INFO, "READING INDEX");
146  if ((start = lseek(fd, 0, SEEK_CUR)) < 0) return -3;
147  if (lseek(fd, ac->movi_length+ac->movi_start+4, SEEK_SET) < 0) return -4;
148 
149  read(fd,buf,4);
150  tag = getle32(buf);
151 
152  if (tag != TAG_IT('i','d','x','1')){
153  cc = (char *) &tag;
154  LOG(VB_GENERAL, LOG_INFO, " tag: %c%c%c%c\n ", *cc, *(cc+1),
155  *(cc+2), *(cc+3));
156 
157  if (lseek(fd, start, SEEK_SET) < 0 ) return -5;
158  return -1;
159  }
160  isize = getsize(fd);
161  c = 0;
162 
163  while ( c < isize ){
164  uint32_t chunkid;
165  uint32_t chunkflags;
166  uint32_t chunkoff;
167  uint32_t chunksize;
168 
169  read(fd,buf,16);
170  chunkid = getle32(buf);
171  chunkflags = getle32(buf+4);
172  chunkoff = getle32(buf+8);
173  chunksize = getle32(buf+12);
174 
175  new_idx_frame(ac, chunkoff, chunksize, chunkflags,chunkid);
176  switch(chunkid){
177  case TAG_IT('0','1','w','b'):
178  ac->achunks++;
179  if (!chunksize) ac->zero_achunks++;
180  break;
181 
182  case TAG_IT('0','0','d','c'):
183  ac->vchunks++;
184  if (!chunksize) ac->zero_vchunks++;
185  break;
186  }
187 
188 #ifdef DEBUG
189 /*
190  print_index(ac,ac->num_idx_frames-1);
191 */
192 #endif
193  c+=16;
194  }
195 #ifdef DEBUG
196  LOG(VB_GENERAL, LOG_DEBUG, "Found %d video (%d were empty) and %d "
197  "audio (%d were empty) chunks",
198  (int)ac->vchunks, (int)ac->zero_vchunks, (int)ac->achunks,
199  (int)ac->zero_achunks);
200 
201 #endif
202  lseek(fd, start, SEEK_SET);
203 
204  return 0;
205 }
206 
207 
208 int read_avi_header( avi_context *ac, int fd)
209 {
210  uint8_t buf[256];
211  uint32_t tag;
212  uint32_t size = 0;
213  int c = 0;
214  int skip=0;
215  int n;
216 #ifdef DEBUG
217  char *cc;
218 #endif
219 
220  while ((c=read(fd, buf, 4))==4) {
221  skip=0;
222  tag = getle32(buf);
223 
224 #ifdef DEBUG
225  cc = (char *) &tag;
226  LOG(VB_GENERAL, LOG_DEBUG, "tag: %c%c%c%c",
227  *cc, *(cc+1), *(cc+2), *(cc+3));
228 #endif
229  switch(tag){
230  case TAG_IT('L','I','S','T'):
231  size = getsize(fd);
232  break;
233 
234 
235  case TAG_IT('m','o','v','i'):
236  ac->done=1;
237  ac->movi_start = lseek(fd, 0, SEEK_CUR);
238  ac->movi_length = size-8;
239 #ifdef DEBUG
240  LOG(VB_GENERAL, LOG_DEBUG, " size: %d header done",
241  size);
242 #endif
243  return 0;
244  break;
245 
246  case TAG_IT('h','d','r','l'):
247  break;
248 
249 
250  case TAG_IT('s','t','r','l'):
251  break;
252 
253  case TAG_IT('J','U','N','K'):
254  case TAG_IT('s','t','r','f'):
255  case TAG_IT('s','t','r','d'):
256  case TAG_IT('s','t','r','n'):
257  size = getsize(fd);
258  skip=1;
259  break;
260  case TAG_IT('a','v','i','h'):
261  size = getsize(fd);
262  c=0;
263  read(fd,buf,size);
264  ac->msec_per_frame = getle32(buf+c);
265  c+=12;
266  ac->avih_flags = getle32(buf+c);
267  c+=4;
268  ac->total_frames = getle32(buf+c);
269  c+=4;
270  ac->init_frames = getle32(buf+c);
271  c+=4;
272  ac->nstreams = getle32(buf+c);
273  c+=8;
274  ac->width = getle32(buf+c);
275  c+=4;
276  ac->height = getle32(buf+c);
277  c+=4;
278 
279 
280 #ifdef DEBUG
281  LOG(VB_GENERAL, LOG_DEBUG, " size: %d", size);
282  LOG(VB_GENERAL, LOG_DEBUG, " microsecs per frame %d",
283  ac->msec_per_frame);
284  if (ac->avih_flags & AVI_HASINDEX)
285  LOG(VB_GENERAL, LOG_DEBUG, " AVI has index");
286  if (ac->avih_flags & AVI_USEINDEX)
287  LOG(VB_GENERAL, LOG_DEBUG,
288  " AVI must use index");
289  if (ac->avih_flags & AVI_INTERLEAVED)
290  LOG(VB_GENERAL, LOG_DEBUG,
291  " AVI is interleaved");
292  if(ac->total_frames)
293  LOG(VB_GENERAL, LOG_DEBUG,
294  " total frames: %d", ac->total_frames);
295 
296  LOG(VB_GENERAL, LOG_DEBUG, " number of streams: %d",
297  ac->nstreams);
298  LOG(VB_GENERAL, LOG_DEBUG, " size: %dx%d",
299  ac->width, ac->height);
300 #endif
301  break;
302 
303  case TAG_IT('s','t','r','h'):
304  size = getsize(fd);
305 #ifdef DEBUG
306  LOG(VB_GENERAL, LOG_DEBUG, " size: %d", size);
307 #endif
308 
309  c=0;
310  read(fd,buf,size);
311  tag = getle32(buf);
312  c+=16;
313 #ifdef DEBUG
314  cc = (char *) &tag;
315  LOG(VB_GENERAL, LOG_DEBUG, " tag: %c%c%c%c",
316  *cc, *(cc+1), *(cc+2), *(cc+3));
317 #endif
318  switch ( tag ){
319  case TAG_IT('v','i','d','s'):
320  ac->vhandler = getle32(buf+4);
321 #ifdef DEBUG
322  if (ac->vhandler){
323  cc = (char *) &ac->vhandler;
324  LOG(VB_GENERAL, LOG_DEBUG,
325  " video handler: %c%c%c%c",
326  *cc, *(cc+1), *(cc+2), *(cc+3));
327  }
328 #endif
329  ac->vi.initial_frames = getle32(buf+c);
330  c+=4;
331  ac->vi.dw_scale = getle32(buf+c);
332  c+=4;
333  ac->vi.dw_rate = getle32(buf+c);
334  c+=4;
335  ac->vi.dw_start = getle32(buf+c);
336  c+=4;
337  if (ac->vi.dw_scale)
338  ac->vi.fps = (ac->vi.dw_rate*1000)/
339  ac->vi.dw_scale;
340 
341  LOG(VB_GENERAL, LOG_INFO,
342  "AVI video info: dw_scale %d dw_rate %d "
343  "fps %0.3f ini_frames %d dw_start %d",
344  ac->vi.dw_scale, ac->vi.dw_rate,
345  ac->vi.fps/1000.0,
346  ac->vi.initial_frames, ac->vi.dw_start);
347  break;
348  case TAG_IT('a','u','d','s'):
349  ac->ahandler = getle32(buf+4);
350 #ifdef DEBUG
351  if (ac->ahandler){
352  cc = (char *) &ac->ahandler;
353  LOG(VB_GENERAL, LOG_DEBUG,
354  " audio handler: %c%c%c%c",
355  *cc, *(cc+1), *(cc+2), *(cc+3));
356  }
357 #endif
358 
359  if (ac->ntracks == MAX_TRACK) break;
360  n = ac->ntracks;
361  ac->ai[n].initial_frames = getle32(buf+c);
362  c+=4;
363  ac->ai[n].dw_scale = getle32(buf+c);
364  c+=4;
365  ac->ai[n].dw_rate = getle32(buf+c);
366  c+=4;
367  ac->ai[n].dw_start = getle32(buf+c);
368  c+=16;
369  ac->ai[n].dw_ssize = getle32(buf+c);
370  if (ac->ai[n].dw_scale)
371  ac->ai[n].fps =
372  (ac->ai[n].dw_rate*1000)/
373  ac->ai[n].dw_scale;
374 
375  LOG(VB_GENERAL, LOG_INFO,
376  "AVI audio%d info: dw_scale %d dw_rate "
377  "%d ini_frames %d dw_start %d fps %0.3f "
378  " sam_size %d", n,
379  ac->ai[n].dw_scale, ac->ai[n].dw_rate,
380  ac->ai[n].initial_frames,
381  ac->ai[n].dw_start,
382  ac->ai[n].fps/1000.0,
383  ac->ai[n].dw_ssize);
384 
385  ac->ntracks++;
386  break;
387  }
388  break;
389 
390  case TAG_IT('I','N','F','O'):
391  size -=4;
392  skip =1;
393 #ifdef DEBUG
394  LOG(VB_GENERAL, LOG_DEBUG, " size: %d", size);
395 #endif
396  break;
397 
398  }
399 
400  if (skip){
401  lseek(fd, size, SEEK_CUR);
402  size = 0;
403  }
404 
405  }
406 
407  return -1;
408 }
409 
410 
411 #define MAX_BUF_SIZE 0xffff
413  void (*func)(pes_in_t *p), int insize)
414 {
415  struct replex *rx= (struct replex *) p->priv;
416  avi_index *idx = ac->idx;
417  int cidx = ac->current_idx;
418  uint8_t buf[MAX_BUF_SIZE];
419  uint32_t cid;
420  int c=0;
421  off_t pos=0;
422  int per = 0;
423  static int lastper=0;
424 
425  if (cidx > ac->num_idx_frames) return -2;
426 
427  switch(idx[cidx].id){
428  case TAG_IT('0','1','w','b'):
429  p->type = 1;
430  p->rbuf = &rx->arbuffer[0];
431  break;
432 
433  case TAG_IT('0','0','d','c'):
434  p->type = 0xE0;
435  p->rbuf = &rx->vrbuffer;
436  break;
437 
438  default:
439  LOG(VB_GENERAL, LOG_ERR, "strange chunk :");
440  show_buf((uint8_t *) &idx[cidx].id,4);
441  LOG(VB_GENERAL, LOG_ERR, "offset: 0x%04x length: 0x%04x",
442  (int)idx[cidx].off, (int)idx[cidx].len);
443  ac->current_idx++;
444  p->found=0;
445  return 0;
446  break;
447  }
448 
449  memset(buf, 0, MAX_BUF_SIZE);
450  pos=lseek (fd, idx[cidx].off+ac->movi_start-4, SEEK_SET);
451  read(fd,buf,idx[cidx].len);
452  cid = getle32(buf);
453  c+=4;
454  p->plength = getsize_buf(buf+c);
455 // show_buf(buf,16);
456  if (idx[cidx].len > insize) return 0;
457 
458  if (idx[cidx].len > MAX_BUF_SIZE){
459  LOG(VB_GENERAL, LOG_ERR,
460  "Buffer too small in get_avi_from_index");
461  exit(1);
462  }
463  if (!idx[cidx].len){
464  func(p);
465  ac->current_idx++;
466  p->found=0;
467  return 0;
468  }
469  if (cid != idx[cidx].id){
470  char *cc;
471  cc = (char *)&idx[cidx].id;
472  LOG(VB_GENERAL, LOG_ERR, "wrong chunk id: %c%c%c%c != %c%c%c%c",
473  buf[0], buf[1], buf[2], buf[3],
474  *cc, *(cc+1), *(cc+2), *(cc+3));
475 
476  print_index(ac,cidx);
477  exit(1);
478  }
479  if (p->plength != idx[cidx].len){
480  LOG(VB_GENERAL, LOG_ERR, "wrong chunk size: %d != %d",
481  (int)p->plength, idx[cidx].len);
482  exit(1);
483  }
484  c+=4;
485  p->done = 1;
486  p->ini_pos = ring_wpos(p->rbuf);
487 
488  per = (int)(100*(pos-ac->movi_start)/ac->movi_length);
489  if (per % 10 == 0 && per>lastper)
490  LOG(VB_GENERAL, LOG_INFO, "read %3d%%", per);
491  lastper = per;
492 
493  if (ring_write(p->rbuf, buf+c, p->plength)<0){
494  LOG(VB_GENERAL, LOG_ERR, "ring buffer overflow %d 0x%02x",
495  p->rbuf->size, p->type);
496  exit(1);
497  }
498 
499  func(p);
500  init_pes_in(p, 0, NULL, p->withbuf);
501 
502  ac->current_idx++;
503 
504  return 0;
505 }
506 
507 
508 void get_avi(pes_in_t *p, uint8_t *buf, int count, void (*func)(pes_in_t *p))
509 {
510  int l;
511  int c=0;
512  struct replex *rx= (struct replex *) p->priv;
513 
514 
515 // show_buf(buf,16);
516  while (c < count && p->found < 8
517  && !p->done){
518  switch ( p->found ){
519  case 0:
520  if (buf[c] == '0') p->found++;
521  else p->found = 0;
522  c++;
523  break;
524  case 1:
525  if (buf[c] == '0'|| buf[c] == '1'){
526  p->found++;
527  p->which = buf[c] - '0';
528  } else if (buf[c] == '0'){
529  p->found = 1;
530  } else p->found = 0;
531  c++;
532  break;
533  case 2:
534  switch(buf[c]){
535  case 'w':
536  case 'd':
537  p->found++;
538  p->type=buf[c];
539  break;
540  default:
541  p->found = 0;
542  break;
543  }
544  c++;
545  break;
546 
547  case 3:
548  switch(buf[c]){
549  case 'b':
550  if (p->type == 'w'){
551  p->found++;
552  p->type = 1;
553  } else p->found = 0;
554  break;
555  case 'c':
556  if (p->type == 'd'){
557  p->found++;
558  p->type = 0xE0;
559  } else p->found = 0;
560  break;
561  default:
562  p->found = 0;
563  break;
564  }
565  switch(p->type){
566 
567  case 1:
568  p->rbuf = &rx->arbuffer[0];
569  break;
570 
571  case 0xE0:
572  p->rbuf = &rx->vrbuffer;
573  break;
574  }
575  c++;
576  break;
577 
578  case 4:
579  p->plen[0] = buf[c];
580  c++;
581  p->found++;
582  break;
583 
584  case 5:
585  p->plen[1] = buf[c];
586  c++;
587  p->found++;
588  break;
589 
590  case 6:
591  p->plen[2] = buf[c];
592  c++;
593  p->found++;
594  break;
595 
596  case 7:
597  p->plen[3] = buf[c];
598  c++;
599  p->found++;
600  p->plength = getsize_buf(p->plen);
601  if (!p->plength){
602  func(p);
603  p->found=0;
604  break;
605  }
606  p->done = 1;
607  p->ini_pos = ring_wpos(p->rbuf);
608 #if 0
609  if (p->type == 1)
610  {
611  LOG(VB_GENERAL, LOG_ERR, "audio 0x%x 0x%x",
612  p->plength, ALIGN(p->plength));
613  LOG(VB_GENERAL, LOG_ERR, "video 0x%x 0x%x",
614  p->plength, ALIGN(p->plength));
615 #endif
616  break;
617 
618  default:
619 
620  break;
621  }
622  }
623  if (p->done || p->found > 8){
624  while (c < count && p->found < p->plength+8){
625  l = count -c;
626  if (l+p->found > p->plength+8)
627  l = p->plength+8-p->found;
628  if (ring_write(p->rbuf, buf+c, l)<0){
629  LOG(VB_GENERAL, LOG_ERR,
630  "ring buffer overflow %d", p->rbuf->size);
631  exit(1);
632  }
633  p->found += l;
634  c += l;
635  }
636  if(p->found == p->plength+8){
637  func(p);
638  }
639  }
640 
641  if (p->plength && p->found == p->plength+8) {
642  int a = 0;//ALIGN(p->plength);
643  init_pes_in(p, 0, NULL, p->withbuf);
644  if (c+a < count)
645  get_avi(p, buf+c+a, count-c-a, func);
646  }
647 }
void get_avi(pes_in_t *p, uint8_t *buf, int count, void(*func)(pes_in_t *p))
Definition: avi.c:508
int done
Definition: avi.h:75
uint32_t achunks
Definition: avi.h:92
int read_avi_header(avi_context *ac, int fd)
Definition: avi.c:208
uint32_t dw_rate
Definition: avi.h:49
Definition: cc.h:13
uint32_t dw_scale
Definition: avi.h:49
uint32_t id
Definition: avi.h:42
#define AVI_HASINDEX
Definition: avi.h:37
uint32_t flags
Definition: avi.h:43
#define NULL
Definition: H264Parser.h:62
avi_index * idx
Definition: avi.h:101
void init_pes_in(pes_in_t *p, int t, ringbuffer *rb, int wi)
Definition: pes.c:147
int64_t movi_start
Definition: avi.h:72
int ring_write(ringbuffer *rbuf, uint8_t *data, int count)
Definition: ringbuffer.c:89
uint32_t initial_frames
Definition: avi.h:65
static uint32_t getsize(int fd)
Definition: avi.c:61
int check_riff(avi_context *ac, uint8_t *buf, int len)
Definition: avi.c:76
uint8_t plen[4]
Definition: pes.h:82
int ini_pos
Definition: pes.h:79
#define lseek
uint32_t width
Definition: avi.h:86
#define ALIGN(a)
Definition: avi.h:35
ringbuffer arbuffer[N_AUDIO]
Definition: replex.h:101
void * priv
Definition: pes.h:91
int get_avi_from_index(pes_in_t *p, int fd, avi_context *ac, void(*func)(pes_in_t *p), int insize)
Definition: avi.c:412
#define AVI_INTERLEAVED
Definition: avi.h:39
uint32_t vchunks
Definition: avi.h:91
int type
Definition: pes.h:73
#define off_t
ringbuffer * rbuf
Definition: pes.h:77
def read(device=None, features=[])
Definition: disc.py:35
#define AVI_USEINDEX
Definition: avi.h:38
uint32_t zero_achunks
Definition: avi.h:94
int64_t movi_length
Definition: avi.h:73
uint32_t num_idx_alloc
Definition: avi.h:80
static uint32_t getbe32(uint8_t *buf)
Definition: avi.c:51
avi_video_info vi
Definition: avi.h:98
uint32_t init_frames
Definition: avi.h:85
int avi_read_index(avi_context *ac, int fd)
Definition: avi.c:135
uint32_t nstreams
Definition: avi.h:88
uint32_t len
Definition: avi.h:43
int64_t riff_end
Definition: avi.h:71
uint32_t height
Definition: avi.h:87
uint32_t initial_frames
Definition: avi.h:53
unsigned int found
Definition: pes.h:74
avi_context ac
Definition: replex.h:60
uint32_t num_idx_frames
Definition: avi.h:81
void show_buf(uint8_t *buf, int length)
Definition: mpg_common.c:37
int which
Definition: pes.h:90
static uint32_t getle32(uint8_t *buf)
Definition: avi.c:46
Definition: pes.h:71
uint32_t vhandler
Definition: avi.h:89
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
uint32_t dw_ssize
Definition: avi.h:55
uint32_t dw_rate
Definition: avi.h:62
int withbuf
Definition: pes.h:75
static int ring_wpos(ringbuffer *rbuf)
uint32_t fps
Definition: avi.h:63
#define MAX_BUF_SIZE
Definition: avi.c:411
uint32_t msec_per_frame
Definition: avi.h:82
avi_audio_info ai[MAX_TRACK]
Definition: avi.h:99
static int new_idx_frame(avi_context *ac, uint32_t pos, uint32_t len, uint32_t fl, uint32_t id)
Definition: avi.c:97
uint32_t total_frames
Definition: avi.h:84
uint32_t avih_flags
Definition: avi.h:83
Definition: replex.h:40
ringbuffer vrbuffer
Definition: replex.h:115
int done
Definition: pes.h:89
uint32_t zero_vchunks
Definition: avi.h:93
#define TAG_IT(a, b, c, d)
Definition: avi.h:34
uint32_t dw_start
Definition: avi.h:54
int ntracks
Definition: avi.h:79
#define MAX_TRACK
Definition: avi.h:69
uint32_t dw_start
Definition: avi.h:66
uint32_t off
Definition: avi.h:44
uint32_t fps
Definition: avi.h:51
uint32_t dw_scale
Definition: avi.h:62
uint32_t ahandler
Definition: avi.h:90
static void print_index(avi_context *ac, int num)
Definition: avi.c:126
int lastper
Definition: replex.h:51
uint32_t plength
Definition: pes.h:81
static void printhead(uint8_t *buf)
Definition: avi.c:56
uint32_t current_idx
Definition: avi.h:96
static uint32_t getsize_buf(uint8_t *buf)
Definition: avi.c:70