10 #define AUDIOBUF (1 << 14)
11 #define SEEKBYTES (1 << 12)
16 int si
; /* stream index */
18 int fmt
; /* video pixel format */
19 int bpp
; /* video bytes per pixel */
20 long ts
; /* frame timestamp (ms) */
21 float zoom
; /* video zoom */
22 char vbuf
[1 << 22]; /* video buffer */
25 struct ffs
*ffs_alloc(char *path
, int flags
)
28 int video
= flags
& FFS_VIDEO
;
29 ffs
= malloc(sizeof(*ffs
));
30 memset(ffs
, 0, sizeof(*ffs
));
31 ffs
->file
= mpeg3_open(path
, NULL
);
34 if ((video
&& !mpeg3_has_video(ffs
->file
)) || !mpeg3_has_audio(ffs
->file
))
36 mpeg3_set_cpus(ffs
->file
, 1);
43 void ffs_free(struct ffs
*ffs
)
46 mpeg3_close(ffs
->file
);
50 static long ts_ms(void)
53 gettimeofday(&tv
, NULL
);
54 return tv
.tv_sec
* 1000 + tv
.tv_usec
/ 1000;
57 static int wait(long ts
, int vdelay
)
60 if (nts
> ts
&& ts
+ vdelay
> nts
) {
61 usleep((ts
+ vdelay
- nts
) * 1000);
67 void ffs_wait(struct ffs
*ffs
)
69 int vdelay
= 1000 / mpeg3_frame_rate(ffs
->file
, ffs
->si
);
70 if (!wait(ffs
->ts
, MAX(vdelay
, 20)))
71 ffs
->ts
+= MAX(vdelay
, 20);
73 ffs
->ts
= ts_ms(); /* out of sync */
76 long ffs_pos(struct ffs
*ffs
, int diff
)
78 return mpeg3_tell_byte(ffs
->file
) + diff
* SEEKBYTES
;
81 void ffs_seek(struct ffs
*ffs
, long pos
, int perframe
)
83 mpeg3_seek_byte(ffs
->file
, pos
);
86 /* can more video packets be read */
87 int ffs_avdiff(struct ffs
*ffs
, struct ffs
*affs
)
89 return mpeg3_get_time(affs
->file
) - mpeg3_get_time(ffs
->file
);
92 void ffs_vinfo(struct ffs
*ffs
, int *w
, int *h
)
94 *h
= mpeg3_video_height(ffs
->file
, ffs
->si
);
95 *w
= mpeg3_video_width(ffs
->file
, ffs
->si
);
98 void ffs_ainfo(struct ffs
*ffs
, int *rate
, int *bps
, int *ch
)
100 *rate
= mpeg3_sample_rate(ffs
->file
, ffs
->si
);
101 *ch
= mpeg3_audio_channels(ffs
->file
, ffs
->si
) == 1 ? 1 : 2;
105 int ffs_vdec(struct ffs
*ffs
, void **buf
)
107 unsigned char *rows
[1 << 11];
111 if (mpeg3_end_of_video(ffs
->file
, ffs
->si
))
113 ffs_vinfo(ffs
, &mw
, &mh
);
116 for (i
= 0; i
< h
; i
++)
117 rows
[i
] = (void *) ffs
->vbuf
+ i
* w
* ffs
->bpp
;
118 ret
= mpeg3_read_frame(ffs
->file
, rows
, 0, 0, mw
, mh
, w
, h
, ffs
->fmt
, ffs
->si
);
120 return ret
? 0 : w
* ffs
->bpp
;
123 int ffs_adec(struct ffs
*ffs
, void *buf
, int blen
)
125 int16_t ch1
[AUDIOBUF
];
126 int16_t ch2
[AUDIOBUF
];
128 int ch
= mpeg3_audio_channels(ffs
->file
, ffs
->si
) == 1 ? 1 : 2;
130 if (mpeg3_end_of_audio(ffs
->file
, ffs
->si
))
132 if (mpeg3_read_audio(ffs
->file
, NULL
, ch1
, 0, AUDIOBUF
, ffs
->si
))
135 if (mpeg3_reread_audio(ffs
->file
, NULL
, ch2
, 1, AUDIOBUF
, ffs
->si
))
137 for (i
= 0; i
< AUDIOBUF
; i
++) {
138 out
[i
* ch
] = ch1
[i
];
140 out
[i
* ch
+ 1] = ch2
[i
];
145 static int fbm2pixfmt(int fbm
)
147 switch (fbm
& 0x0fff) {
149 return MPEG3_BGRA8888
;
153 fprintf(stderr
, "ffs: unknown fb_mode()\n");
158 void ffs_vconf(struct ffs
*ffs
, float zoom
, int fbm
)
160 ffs
->fmt
= fbm2pixfmt(fbm
);
162 ffs
->bpp
= (fbm
>> 16) & 0x0f;
165 void ffs_aconf(struct ffs
*ffs
)
169 void ffs_globinit(void)