6 #include <libavcodec/avcodec.h>
7 #include <libavformat/avformat.h>
8 #include <libswresample/swresample.h>
9 #include <libswscale/swscale.h>
12 #define FFS_SAMPLEFMT AV_SAMPLE_FMT_S16
13 #define FFS_CHLAYOUT AV_CH_LAYOUT_STEREO
15 #define MAX(a, b) ((a) < (b) ? (b) : (a))
16 #define MIN(a, b) ((a) < (b) ? (a) : (b))
24 int si
; /* stream index */
25 long ts
; /* frame timestamp (ms) */
26 long pts
; /* last decoded packet pts in milliseconds */
27 long dur
; /* last decoded packet duration */
29 /* decoding video frames */
30 struct SwsContext
*swsc
;
31 struct SwrContext
*swrc
;
36 struct ffs
*ffs_alloc(char *path
, int flags
)
39 int type
= flags
& FFS_VIDEO
? AVMEDIA_TYPE_VIDEO
: AVMEDIA_TYPE_AUDIO
;
40 int idx
= (flags
& FFS_STRIDX
) - 1;
41 AVDictionary
*opt
= NULL
;
42 ffs
= malloc(sizeof(*ffs
));
43 memset(ffs
, 0, sizeof(*ffs
));
45 if (avformat_open_input(&ffs
->fc
, path
, NULL
, NULL
))
47 if (avformat_find_stream_info(ffs
->fc
, NULL
) < 0)
49 ffs
->si
= av_find_best_stream(ffs
->fc
, type
, idx
, -1, NULL
, 0);
52 ffs
->cc
= ffs
->fc
->streams
[ffs
->si
]->codec
;
53 if (avcodec_open2(ffs
->cc
, avcodec_find_decoder(ffs
->cc
->codec_id
), &opt
))
55 ffs
->st
= ffs
->fc
->streams
[ffs
->si
];
56 ffs
->tmp
= av_frame_alloc();
57 ffs
->dst
= av_frame_alloc();
64 void ffs_free(struct ffs
*ffs
)
69 sws_freeContext(ffs
->swsc
);
75 avcodec_close(ffs
->cc
);
77 avformat_close_input(&ffs
->fc
);
81 static AVPacket
*ffs_pkt(struct ffs
*ffs
)
83 AVPacket
*pkt
= &ffs
->pkt
;
84 while (av_read_frame(ffs
->fc
, pkt
) >= 0) {
85 if (pkt
->stream_index
== ffs
->si
) {
86 long pts
= (pkt
->dts
== AV_NOPTS_VALUE
? 0 : pkt
->dts
) *
87 av_q2d(ffs
->st
->time_base
) * 1000;
88 ffs
->dur
= MIN(MAX(0, pts
- ffs
->pts
), 1000);
89 if (pts
> ffs
->pts
|| pts
+ 200 < ffs
->pts
)
98 static long ts_ms(void)
101 gettimeofday(&tv
, NULL
);
102 return tv
.tv_sec
* 1000 + tv
.tv_usec
/ 1000;
105 static int wait(long ts
, int vdelay
)
108 if (nts
> ts
&& ts
+ vdelay
> nts
) {
109 usleep((ts
+ vdelay
- nts
) * 1000);
115 void ffs_wait(struct ffs
*ffs
)
117 int vdelay
= ffs
->dur
;
118 if (!wait(ffs
->ts
, MAX(vdelay
, 20)))
119 ffs
->ts
+= MAX(vdelay
, 20);
121 ffs
->ts
= ts_ms(); /* out of sync */
124 /* audio/video frame offset difference */
125 int ffs_avdiff(struct ffs
*ffs
, struct ffs
*affs
)
127 return affs
->pts
- ffs
->pts
;
130 long ffs_pos(struct ffs
*ffs
)
135 void ffs_seek(struct ffs
*ffs
, struct ffs
*vffs
, long pos
)
137 av_seek_frame(ffs
->fc
, vffs
->si
,
138 pos
/ av_q2d(vffs
->st
->time_base
) / 1000, 0);
142 void ffs_vinfo(struct ffs
*ffs
, int *w
, int *h
)
144 *h
= ffs
->cc
->height
;
148 void ffs_ainfo(struct ffs
*ffs
, int *rate
, int *bps
, int *ch
)
150 *rate
= ffs
->cc
->sample_rate
;
151 *ch
= av_get_channel_layout_nb_channels(FFS_CHLAYOUT
);
155 int ffs_vdec(struct ffs
*ffs
, void **buf
)
157 AVCodecContext
*vcc
= ffs
->cc
;
158 AVPacket
*pkt
= ffs_pkt(ffs
);
162 avcodec_decode_video2(vcc
, ffs
->tmp
, &fine
, pkt
);
165 sws_scale(ffs
->swsc
, (void *) ffs
->tmp
->data
, ffs
->tmp
->linesize
,
166 0, vcc
->height
, ffs
->dst
->data
, ffs
->dst
->linesize
);
167 *buf
= (void *) ffs
->dst
->data
[0];
168 return ffs
->dst
->linesize
[0];
173 static int ffs_bytespersample(ffs
)
175 return av_get_bytes_per_sample(FFS_SAMPLEFMT
) *
176 av_get_channel_layout_nb_channels(FFS_CHLAYOUT
);
179 int ffs_adec(struct ffs
*ffs
, void *buf
, int blen
)
182 AVPacket tmppkt
= {0};
183 AVPacket
*pkt
= ffs_pkt(ffs
);
184 uint8_t *out
[] = {NULL
};
187 tmppkt
.size
= pkt
->size
;
188 tmppkt
.data
= pkt
->data
;
189 while (tmppkt
.size
> 0) {
191 len
= avcodec_decode_audio4(ffs
->cc
, ffs
->tmp
, &size
, &tmppkt
);
199 len
= swr_convert(ffs
->swrc
,
200 out
, (blen
- rdec
) / ffs_bytespersample(ffs
),
201 (void *) ffs
->tmp
->extended_data
, ffs
->tmp
->nb_samples
);
203 rdec
+= len
* ffs_bytespersample(ffs
);
209 static int fbm2pixfmt(int fbm
)
211 switch (fbm
& 0x0fff) {
213 return PIX_FMT_RGB32
;
215 return PIX_FMT_RGB565
;
219 fprintf(stderr
, "ffs: unknown fb_mode()\n");
220 return PIX_FMT_RGB32
;
224 void ffs_vconf(struct ffs
*ffs
, float zoom
, int fbm
)
226 int h
= ffs
->cc
->height
;
227 int w
= ffs
->cc
->width
;
228 int fmt
= ffs
->cc
->pix_fmt
;
229 int pixfmt
= fbm2pixfmt(fbm
);
232 ffs
->swsc
= sws_getContext(w
, h
, fmt
, w
* zoom
, h
* zoom
,
233 pixfmt
, SWS_FAST_BILINEAR
| SWS_CPU_CAPS_MMX2
,
235 n
= avpicture_get_size(pixfmt
, w
* zoom
, h
* zoom
);
236 buf
= av_malloc(n
* sizeof(uint8_t));
237 avpicture_fill((AVPicture
*) ffs
->dst
, buf
, pixfmt
, w
* zoom
, h
* zoom
);
240 void ffs_aconf(struct ffs
*ffs
)
243 ffs_ainfo(ffs
, &rate
, &bps
, &ch
);
244 ffs
->swrc
= swr_alloc_set_opts(NULL
,
245 FFS_CHLAYOUT
, FFS_SAMPLEFMT
, rate
,
246 ffs
->cc
->channel_layout
, ffs
->cc
->sample_fmt
, ffs
->cc
->sample_rate
,
251 void ffs_globinit(void)
254 avformat_network_init();
257 long ffs_duration(struct ffs
*ffs
)
259 if (ffs
->st
->duration
== AV_NOPTS_VALUE
)
261 return ffs
->st
->duration
* av_q2d(ffs
->st
->time_base
) * 1000;