6 #include <alsa/asoundlib.h>
7 #include <libavformat/avformat.h>
8 #include <libavcodec/avcodec.h>
9 #include <libswscale/swscale.h>
15 static AVFormatContext
*fc
;
16 static AVFrame
*frame
;
17 static struct SwsContext
*swsc
;
19 static int vsi
= -1; /* video stream index */
20 static AVCodecContext
*vcc
; /* video codec context */
21 static AVCodec
*vc
; /* video codec */
23 static int asi
= -1; /* audio stream index */
24 static AVCodecContext
*acc
; /* audio codec context */
25 static AVCodec
*ac
; /* audio codec */
27 static snd_pcm_t
*alsa
;
28 static int bps
; /* bytes per sample */
30 static struct termios termios
;
32 static void init_streams(void)
35 for (i
= 0; i
< fc
->nb_streams
; i
++) {
36 if (fc
->streams
[i
]->codec
->codec_type
== CODEC_TYPE_VIDEO
)
38 if (fc
->streams
[i
]->codec
->codec_type
== CODEC_TYPE_AUDIO
)
42 vcc
= fc
->streams
[vsi
]->codec
;
43 vc
= avcodec_find_decoder(vcc
->codec_id
);
44 avcodec_open(vcc
, vc
);
47 acc
= fc
->streams
[asi
]->codec
;
48 ac
= avcodec_find_decoder(acc
->codec_id
);
49 avcodec_open(acc
, ac
);
53 static void draw_frame(void)
57 int nr
= MIN(vcc
->height
* ZOOM
, fb_rows() / ZOOM2
);
58 int nc
= MIN(vcc
->width
* ZOOM
, fb_cols() / ZOOM2
);
60 for (r
= 0; r
< nr
; r
++) {
61 unsigned char *row
= frame
->data
[0] + r
* frame
->linesize
[0];
62 for (c
= 0; c
< nc
; c
++) {
63 fbval_t v
= fb_color(row
[c
* 3],
66 for (i
= 0; i
< ZOOM2
; i
++)
67 buf
[c
* ZOOM2
+ i
] = v
;
69 for (i
= 0; i
< ZOOM2
; i
++)
70 fb_set(r
* ZOOM2
+ i
, 0, buf
, nc
* ZOOM2
);
74 static void decode_video_frame(AVFrame
*main_frame
, AVPacket
*packet
)
77 avcodec_decode_video2(vcc
, main_frame
, &fine
, packet
);
79 sws_scale(swsc
, main_frame
->data
, main_frame
->linesize
,
80 0, vcc
->height
, frame
->data
, frame
->linesize
);
85 #define AUDIOBUFSIZE (1 << 20)
87 static void decode_audio_frame(AVPacket
*pkt
)
89 char buf
[AUDIOBUFSIZE
];
91 tmppkt
.size
= pkt
->size
;
92 tmppkt
.data
= pkt
->data
;
93 while (tmppkt
.size
> 0) {
94 int size
= sizeof(buf
);
95 int len
= avcodec_decode_audio3(acc
, (int16_t *) buf
,
101 if (snd_pcm_writei(alsa
, buf
, size
/ bps
) < 0)
102 snd_pcm_prepare(alsa
);
107 static int readkey(void)
110 if (read(STDIN_FILENO
, &b
, 1) <= 0)
115 static int execkey(void)
118 while ((c
= readkey()) != -1) {
127 count
= count
* 10 + c
- '0';
133 static void read_frames(void)
135 AVFrame
*main_frame
= avcodec_alloc_frame();
138 int n
= AUDIOBUFSIZE
;
140 n
= avpicture_get_size(PIX_FMT_RGB24
, vcc
->width
* ZOOM
,
142 buf
= av_malloc(n
* sizeof(uint8_t));
144 avpicture_fill((AVPicture
*) frame
, buf
, PIX_FMT_RGB24
,
145 vcc
->width
* ZOOM
, vcc
->height
* ZOOM
);
146 while (av_read_frame(fc
, &pkt
) >= 0) {
147 if (vcc
&& pkt
.stream_index
== vsi
)
148 decode_video_frame(main_frame
, &pkt
);
149 if (acc
&& pkt
.stream_index
== asi
)
150 decode_audio_frame(&pkt
);
151 av_free_packet(&pkt
);
159 #define ALSADEV "default"
161 static void alsa_init(void)
163 int format
= SND_PCM_FORMAT_S16_LE
;
164 if (snd_pcm_open(&alsa
, ALSADEV
, SND_PCM_STREAM_PLAYBACK
, 0) < 0)
166 snd_pcm_set_params(alsa
, format
, SND_PCM_ACCESS_RW_INTERLEAVED
,
167 acc
->channels
, acc
->sample_rate
, 1, 500000);
168 bps
= acc
->channels
* snd_pcm_format_physical_width(format
) / 8;
169 snd_pcm_prepare(alsa
);
172 static void alsa_close(void)
177 static void term_setup(void)
179 struct termios newtermios
;
180 tcgetattr(STDIN_FILENO
, &termios
);
181 newtermios
= termios
;
182 cfmakeraw(&newtermios
);
183 tcsetattr(STDIN_FILENO
, TCSAFLUSH
, &newtermios
);
184 fcntl(STDIN_FILENO
, F_SETFL
, fcntl(STDIN_FILENO
, F_GETFL
) | O_NONBLOCK
);
187 static void term_cleanup(void)
189 tcsetattr(STDIN_FILENO
, 0, &termios
);
192 int main(int argc
, char *argv
[])
195 printf("usage: %s filename\n", argv
[0]);
199 if (av_open_input_file(&fc
, argv
[1], NULL
, 0, NULL
))
201 if (av_find_stream_info(fc
) < 0)
204 frame
= avcodec_alloc_frame();
208 swsc
= sws_getContext(vcc
->width
, vcc
->height
, vcc
->pix_fmt
,
209 vcc
->width
* ZOOM
, vcc
->height
* ZOOM
,
210 PIX_FMT_RGB24
, SWS_FAST_BILINEAR
| SWS_CPU_CAPS_MMX2
,
221 sws_freeContext(swsc
);
229 av_close_input_file(fc
);