6 #include <libavformat/avformat.h>
7 #include <libavcodec/avcodec.h>
8 #include <libswscale/swscale.h>
16 int si
; /* stream index */
17 long ts
; /* frame timestamp (ms) */
18 long seq
; /* frame number among packets of this stream */
19 long allseq
; /* frame number among all packets */
21 /* decoding video frames */
22 struct SwsContext
*swsc
;
27 struct ffs
*ffs_alloc(char *path
, int video
)
30 int codec_type
= video
? CODEC_TYPE_VIDEO
: CODEC_TYPE_AUDIO
;
32 ffs
= malloc(sizeof(*ffs
));
33 memset(ffs
, 0, sizeof(*ffs
));
35 if (av_open_input_file(&ffs
->fc
, path
, NULL
, 0, NULL
))
37 if (av_find_stream_info(ffs
->fc
) < 0)
39 for (i
= 0; i
< ffs
->fc
->nb_streams
; i
++)
40 if (ffs
->fc
->streams
[i
]->codec
->codec_type
== codec_type
)
44 ffs
->cc
= ffs
->fc
->streams
[ffs
->si
]->codec
;
45 avcodec_open(ffs
->cc
, avcodec_find_decoder(ffs
->cc
->codec_id
));
52 void ffs_free(struct ffs
*ffs
)
55 sws_freeContext(ffs
->swsc
);
61 avcodec_close(ffs
->cc
);
63 av_close_input_file(ffs
->fc
);
67 static AVPacket
*ffs_pkt(struct ffs
*ffs
)
69 AVPacket
*pkt
= &ffs
->pkt
;
70 while (av_read_frame(ffs
->fc
, pkt
) >= 0) {
72 if (pkt
->stream_index
== ffs
->si
) {
81 static long ts_ms(void)
84 gettimeofday(&tv
, NULL
);
85 return tv
.tv_sec
* 1000 + tv
.tv_usec
/ 1000;
88 static void wait(long ts
, int vdelay
)
91 if (ts
+ vdelay
> nts
)
92 usleep((ts
+ vdelay
- nts
) * 1000);
95 void ffs_wait(struct ffs
*ffs
)
99 AVRational
*r
= &ffs
->fc
->streams
[ffs
->si
]->time_base
;
100 int vdelay
= 1000 * r
->num
/ r
->den
;
101 wait(ffs
->ts
, vdelay
);
106 long ffs_pos(struct ffs
*ffs
, int diff
)
108 return (ffs
->si
<< 28) | (ffs
->seq
+ diff
);
111 void ffs_seek(struct ffs
*ffs
, long pos
, int perframe
)
113 long idx
= pos
>> 28;
114 long seq
= pos
& 0x0fffffff;
115 av_seek_frame(ffs
->fc
, idx
, seq
* perframe
,
116 perframe
== 1 ? AVSEEK_FLAG_FRAME
: 0);
122 long ffs_seq(struct ffs
*ffs
, int all
)
124 return all
? ffs
->allseq
: ffs
->seq
;
127 void ffs_vinfo(struct ffs
*ffs
, int *w
, int *h
)
129 *h
= ffs
->cc
->height
;
133 void ffs_ainfo(struct ffs
*ffs
, int *rate
, int *bps
, int *ch
)
135 *rate
= ffs
->cc
->sample_rate
;
136 *ch
= ffs
->cc
->channels
;
140 int ffs_vdec(struct ffs
*ffs
, char **buf
)
142 AVCodecContext
*vcc
= ffs
->cc
;
143 AVPacket
*pkt
= ffs_pkt(ffs
);
147 avcodec_decode_video2(vcc
, ffs
->tmp
, &fine
, pkt
);
150 sws_scale(ffs
->swsc
, ffs
->tmp
->data
, ffs
->tmp
->linesize
,
151 0, vcc
->height
, ffs
->dst
->data
, ffs
->dst
->linesize
);
152 *buf
= (void *) ffs
->dst
->data
[0];
153 return ffs
->dst
->linesize
[0];
158 int ffs_adec(struct ffs
*ffs
, char *buf
, int blen
)
162 AVPacket
*pkt
= ffs_pkt(ffs
);
165 tmppkt
.size
= pkt
->size
;
166 tmppkt
.data
= pkt
->data
;
167 while (tmppkt
.size
> 0) {
168 int size
= blen
- rdec
;
169 int len
= avcodec_decode_audio3(ffs
->cc
, (int16_t *) (buf
+ rdec
),
182 void ffs_vsetup(struct ffs
*ffs
, float zoom
, int pixfmt
)
184 int h
= ffs
->cc
->height
;
185 int w
= ffs
->cc
->width
;
186 int fmt
= ffs
->cc
->pix_fmt
;
189 ffs
->swsc
= sws_getContext(w
, h
, fmt
, w
* zoom
, h
* zoom
,
190 pixfmt
, SWS_FAST_BILINEAR
| SWS_CPU_CAPS_MMX2
,
192 ffs
->dst
= avcodec_alloc_frame();
193 ffs
->tmp
= avcodec_alloc_frame();
194 n
= avpicture_get_size(pixfmt
, w
* zoom
, h
* zoom
);
195 buf
= av_malloc(n
* sizeof(uint8_t));
196 avpicture_fill((AVPicture
*) ffs
->dst
, buf
, pixfmt
, w
* zoom
, h
* zoom
);
199 void ffs_globinit(void)