Rev 6106 | Rev 6118 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4438 | Serge | 1 | |
2 | |||
3 | |||
4 | #include |
||
5 | #include |
||
6 | #include |
||
7 | |||
8 | |||
9 | #include |
||
10 | #include |
||
11 | #include |
||
12 | #include |
||
13 | #include "winlib/winlib.h" |
||
5021 | Serge | 14 | |
4438 | Serge | 15 | |
16 | #include "fplay.h" |
||
17 | |||
18 | |||
19 | volatile enum player_state decoder_state = PREPARE; |
||
20 | volatile enum player_state sound_state = STOP; |
||
21 | |||
22 | |||
23 | |||
24 | |||
25 | int fplay_init_context(AVCodecContext *avctx); |
||
5592 | serge | 26 | |
4438 | Serge | 27 | |
28 | |||
29 | |||
30 | |||
31 | |||
32 | extern int resampler_size; |
||
33 | |||
34 | |||
35 | char *movie_file; |
||
36 | |||
37 | |||
38 | |||
39 | |||
6117 | serge | 40 | |
4438 | Serge | 41 | |
42 | |||
43 | |||
44 | |||
5603 | serge | 45 | |
46 | |||
4438 | Serge | 47 | |
48 | |||
6117 | serge | 49 | |
50 | { |
||
4438 | Serge | 51 | return (double)av_q2d(vst->fCtx->streams[vst->aStream]->time_base)*1000; |
6117 | serge | 52 | }; |
4438 | Serge | 53 | |
54 | |||
55 | |||
56 | { |
||
57 | static vst_t vst; |
||
6117 | serge | 58 | int i, ret; |
59 | char *file_name, *dot; |
||
4438 | Serge | 60 | |
61 | |||
62 | { |
||
63 | movie_file = get_moviefile(); |
||
64 | if(movie_file == NULL) |
||
65 | { |
||
66 | printf("Please provide a movie file\n"); |
||
67 | return -1; |
||
68 | } |
||
69 | } |
||
70 | else movie_file = argv[1]; |
||
71 | |||
72 | |||
73 | |||
74 | |||
75 | |||
76 | |||
77 | avdevice_register_all(); |
||
78 | av_register_all(); |
||
79 | |||
80 | |||
6117 | serge | 81 | { |
4438 | Serge | 82 | printf("Cannot open file %s\n\r", movie_file); |
83 | return -1; // Couldn't open file |
||
84 | }; |
||
85 | |||
86 | |||
6117 | serge | 87 | |
4438 | Serge | 88 | |
89 | if(avformat_find_stream_info(vst.fCtx, NULL) < 0) |
||
6117 | serge | 90 | { |
4438 | Serge | 91 | printf("Cannot find streams\n\r"); |
92 | return -1; |
||
93 | }; |
||
94 | |||
95 | |||
96 | dot = strrchr(file_name,'.'); |
||
97 | if(dot) |
||
98 | { |
||
99 | movie_file = malloc(dot-file_name+1); |
||
100 | memcpy(movie_file, file_name, dot-file_name); |
||
101 | movie_file[dot-file_name] = 0; |
||
102 | } |
||
103 | else movie_file = file_name; |
||
104 | |||
105 | |||
6117 | serge | 106 | |
4438 | Serge | 107 | |
108 | vst.vStream = -1; |
||
6117 | serge | 109 | vst.aStream = -1; |
110 | |||
111 | |||
112 | { |
||
4438 | Serge | 113 | if(vst.fCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO |
6117 | serge | 114 | && vst.vStream < 0) |
115 | { |
||
4438 | Serge | 116 | vst.vStream = i; |
6117 | serge | 117 | video_time_base = vst.fCtx->streams[i]->time_base; |
118 | if(stream_duration == 0) |
||
4438 | Serge | 119 | stream_duration = vst.fCtx->streams[i]->duration; |
6117 | serge | 120 | } |
121 | |||
4438 | Serge | 122 | |
6117 | serge | 123 | vst.aStream < 0) |
124 | { |
||
4438 | Serge | 125 | vst.aStream = i; |
6117 | serge | 126 | if(stream_duration == 0) |
4438 | Serge | 127 | stream_duration = vst.fCtx->streams[i]->duration; |
6117 | serge | 128 | } |
4438 | Serge | 129 | } |
130 | |||
131 | |||
6117 | serge | 132 | { |
4438 | Serge | 133 | printf("Video stream not detected\n\r"); |
134 | return -1; // Didn't find a video stream |
||
135 | }; |
||
136 | |||
137 | |||
138 | |||
139 | |||
140 | vst.vCtx = vst.fCtx->streams[vst.vStream]->codec; |
||
6117 | serge | 141 | vst.aCtx = vst.fCtx->streams[vst.aStream]->codec; |
142 | |||
4438 | Serge | 143 | |
6117 | serge | 144 | printf("codec id %x name %s\n",vst.vCtx->codec_id, vst.vCodec->name); |
145 | printf("ctx->pix_fmt %d\n", vst.vCtx->pix_fmt); |
||
146 | |||
4438 | Serge | 147 | |
6117 | serge | 148 | { |
149 | printf("Unsupported codec with id %d for input stream %d\n", |
||
4438 | Serge | 150 | vst.vCtx->codec_id, vst.vStream); |
6117 | serge | 151 | return -1; // Codec not found |
4438 | Serge | 152 | } |
153 | |||
154 | |||
6117 | serge | 155 | |
156 | |||
157 | |||
158 | { |
||
4438 | Serge | 159 | printf("Error while opening codec for input stream %d\n", |
160 | vst.vStream); |
||
6117 | serge | 161 | return -1; // Could not open codec |
4438 | Serge | 162 | }; |
163 | |||
164 | |||
165 | |||
6117 | serge | 166 | mutex_init(&vst.q_audio.lock); |
167 | mutex_init(&vst.gpu_lock); |
||
168 | |||
4438 | Serge | 169 | |
6117 | serge | 170 | vst.aCtx->request_channels = FFMIN(2, vst.aCtx->channels); |
171 | else |
||
4438 | Serge | 172 | vst.aCtx->request_channels = 2; |
6117 | serge | 173 | |
4438 | Serge | 174 | |
6117 | serge | 175 | |
4438 | Serge | 176 | |
6117 | serge | 177 | { |
4438 | Serge | 178 | if(avcodec_open2(vst.aCtx, vst.aCodec, NULL) >= 0 ) |
6117 | serge | 179 | { |
4438 | Serge | 180 | WAVEHEADER whdr; |
181 | int fmt; |
||
182 | int channels; |
||
183 | |||
184 | |||
185 | vst.aCtx->sample_rate, vst.aCtx->channels, vst.aCtx->sample_fmt ); |
||
6117 | serge | 186 | whdr.riff_id = 0x46464952; |
4438 | Serge | 187 | whdr.riff_format = 0x45564157; |
188 | whdr.wFormatTag = 0x01; |
||
189 | whdr.nSamplesPerSec = vst.aCtx->sample_rate; |
||
6117 | serge | 190 | whdr.nChannels = 2; |
4438 | Serge | 191 | whdr.wBitsPerSample = 16; |
192 | |||
193 | |||
6117 | serge | 194 | |
4438 | Serge | 195 | |
196 | |||
197 | |||
198 | { |
||
199 | decoder_buffer = (uint8_t*)av_mallocz(192000*2+64); |
||
200 | if( decoder_buffer != NULL ) |
||
201 | { |
||
202 | mutex_init(&astream.lock); |
||
5603 | serge | 203 | astream.count = 0; |
4438 | Serge | 204 | astream.buffer = (char *)av_mallocz(192000*3); |
205 | if( astream.buffer != NULL ) |
||
206 | have_sound = 1; |
||
207 | else |
||
208 | av_free(decoder_buffer); |
||
209 | } |
||
210 | if( have_sound == 0) |
||
211 | { |
||
212 | printf("Not enough memory for audio buffers\n"); |
||
213 | } |
||
214 | } |
||
215 | } |
||
216 | else printf("Cannot open audio codec\n\r"); |
||
217 | } |
||
218 | else printf("Unsupported audio codec!\n"); |
||
219 | |||
220 | |||
6117 | serge | 221 | return 0; |
4438 | Serge | 222 | |
223 | |||
6117 | serge | 224 | |
4438 | Serge | 225 | |
226 | av_free(pFrame); |
||
227 | |||
228 | |||
229 | |||
230 | |||
231 | |||
5603 | serge | 232 | (AUDIO_THREAD | VIDEO_THREAD)) |
233 | delay(1); |
||
234 | |||
4438 | Serge | 235 | |
5603 | serge | 236 | mutex_destroy(&astream.lock); |
237 | |||
4438 | Serge | 238 | |
6117 | serge | 239 | mutex_destroy(&vst.q_audio.lock); |
240 | |||
4438 | Serge | 241 | |
242 | } |
||
243 | |||
244 | |||
245 | |||
6117 | serge | 246 | { |
4438 | Serge | 247 | AVPacket packet; |
248 | int err; |
||
249 | |||
250 | |||
6117 | serge | 251 | if( err == 0) |
4438 | Serge | 252 | { |
253 | if(packet.stream_index == vst->vStream) |
||
6117 | serge | 254 | put_packet(&vst->q_video, &packet); |
255 | else if( (packet.stream_index == vst->aStream) && |
||
256 | (have_sound != 0) ) |
||
4438 | Serge | 257 | { |
258 | put_packet(&vst->q_audio, &packet); |
||
6117 | serge | 259 | if(audio_base == -1.0) |
4438 | Serge | 260 | { |
261 | if (packet.pts != AV_NOPTS_VALUE) |
||
262 | audio_base = get_audio_base(vst) * packet.pts; |
||
6117 | serge | 263 | // printf("audio base %f\n", audio_base); |
4438 | Serge | 264 | }; |
265 | } |
||
266 | else av_free_packet(&packet); |
||
267 | } |
||
268 | else if (err != AVERROR_EOF) |
||
269 | printf("av_read_frame: error %x\n", err); |
||
270 | |||
271 | |||
272 | } |
||
273 | |||
274 | |||
275 | |||
276 | |||
6117 | serge | 277 | { |
4438 | Serge | 278 | int err = 0; |
279 | AVPacket packet; |
||
280 | |||
281 | |||
6117 | serge | 282 | err = load_frame(vst); |
283 | |||
4438 | Serge | 284 | |
285 | }; |
||
286 | |||
287 | |||
288 | |||
6117 | serge | 289 | { |
4438 | Serge | 290 | AVPacket packet; |
291 | |||
292 | |||
6117 | serge | 293 | avcodec_flush_buffers(vst->aCtx); |
294 | while( get_packet(&vst->q_video, &packet) != 0) |
||
295 | av_free_packet(&packet); |
||
4438 | Serge | 296 | |
297 | |||
6117 | serge | 298 | av_free_packet(&packet); |
4438 | Serge | 299 | |
300 | |||
301 | |||
302 | |||
303 | }; |
||
304 | |||
305 | |||
6117 | serge | 306 | { |
4438 | Serge | 307 | int eof; |
308 | AVPacket packet; |
||
309 | int ret, vret, aret; |
||
310 | |||
311 | |||
312 | |||
313 | |||
5592 | serge | 314 | |
315 | |||
4438 | Serge | 316 | { |
317 | int err; |
||
318 | |||
319 | |||
320 | { |
||
321 | case PREPARE: |
||
322 | eof = fill_queue(vst); |
||
6117 | serge | 323 | |
4438 | Serge | 324 | |
325 | { |
||
326 | if( (vst->q_video.size < 4*1024*1024) && |
||
6117 | serge | 327 | (eof == 0) ) |
4438 | Serge | 328 | { |
329 | eof = load_frame(vst); |
||
6117 | serge | 330 | } |
4438 | Serge | 331 | decode_video(vst); |
6117 | serge | 332 | ret = decode_audio(vst->aCtx, &vst->q_audio); |
333 | }while(astream.count < resampler_size*2 && |
||
4438 | Serge | 334 | ret == 1); |
335 | |||
336 | |||
337 | decoder_state = PLAY; |
||
338 | player_state = PLAY; |
||
339 | |||
340 | |||
341 | if( (vst->q_video.size < 4*1024*1024) && |
||
6117 | serge | 342 | (eof == 0) ) |
4438 | Serge | 343 | { |
344 | eof = load_frame(vst); |
||
6117 | serge | 345 | } |
4438 | Serge | 346 | vret = decode_video(vst); |
6117 | serge | 347 | aret = decode_audio(vst->aCtx, &vst->q_audio); |
348 | ret = vret | aret; |
||
4438 | Serge | 349 | |
350 | |||
351 | { |
||
352 | decoder_state = STOP; |
||
353 | continue; |
||
354 | }; |
||
355 | |||
356 | |||
357 | { |
||
358 | if( (vst->q_video.size < 4*1024*1024) && |
||
6117 | serge | 359 | (eof == 0) ) |
4438 | Serge | 360 | { |
361 | eof = load_frame(vst); |
||
6117 | serge | 362 | yield(); |
4438 | Serge | 363 | continue; |
364 | }; |
||
365 | delay(1); |
||
366 | continue; |
||
367 | } |
||
368 | |||
369 | |||
370 | continue; |
||
371 | |||
372 | |||
373 | delay(1); |
||
374 | continue; |
||
375 | |||
376 | |||
377 | |||
378 | while(sound_state != STOP) |
||
379 | delay(1); |
||
380 | |||
381 | |||
6117 | serge | 382 | |
4438 | Serge | 383 | |
6117 | serge | 384 | rewind_pos = vst->fCtx->start_time; |
385 | else |
||
4438 | Serge | 386 | rewind_pos = 0; |
387 | |||
388 | |||
6117 | serge | 389 | rewind_pos, INT64_MAX, 0); |
4438 | Serge | 390 | |
391 | |||
392 | break; |
||
393 | |||
394 | |||
395 | while(sound_state != STOP) |
||
396 | yield(); |
||
397 | |||
398 | |||
6117 | serge | 399 | int opts = 0; |
4438 | Serge | 400 | if(rewind_pos < 0) |
401 | { |
||
402 | rewind_pos = -rewind_pos; |
||
403 | opts = AVSEEK_FLAG_BACKWARD; |
||
404 | }; |
||
405 | |||
406 | |||
6117 | serge | 407 | rewind_pos += vst->fCtx->start_time; |
408 | |||
4438 | Serge | 409 | |
410 | min_pos = rewind_pos - 1000000; |
||
411 | max_pos = rewind_pos + 1000000; |
||
412 | |||
413 | |||
6117 | serge | 414 | rewind_pos, INT64_MAX, 0); |
4438 | Serge | 415 | if (ret < 0) |
416 | { |
||
417 | printf("could not seek to position %f\n", |
||
418 | (double)rewind_pos / AV_TIME_BASE); |
||
419 | } |
||
420 | decoder_state = PREPARE; |
||
421 | break; |
||
422 | } |
||
423 | }; |
||
424 | };>>>>>>>>>>>>>> |
||
425 |