Rev 2693 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2693 | Rev 3068 | ||
---|---|---|---|
Line 13... | Line 13... | ||
13 | 13 | ||
Line 14... | Line 14... | ||
14 | #include "sound.h" |
14 | #include "sound.h" |
15 | #include "fplay.h" |
15 | #include "fplay.h" |
Line 16... | Line 16... | ||
16 | 16 | ||
- | 17 | volatile enum player_state player_state = STOP; |
|
- | 18 | volatile enum player_state decoder_state = PREPARE; |
|
Line 17... | Line 19... | ||
17 | volatile enum player_state player_state; |
19 | volatile enum player_state sound_state = STOP; |
Line 18... | Line 20... | ||
18 | 20 | ||
Line 31... | Line 33... | ||
31 | 33 | ||
Line 32... | Line 34... | ||
32 | int have_sound = 0; |
34 | int have_sound = 0; |
Line 33... | Line 35... | ||
33 | 35 | ||
- | 36 | uint8_t *decoder_buffer; |
|
- | 37 | extern int resampler_size; |
|
34 | uint8_t *decoder_buffer; |
38 | |
35 | extern int sample_rate; |
39 | extern int sample_rate; |
Line 36... | Line 40... | ||
36 | char *movie_file; |
40 | char *movie_file; |
Line 64... | Line 68... | ||
64 | 68 | ||
Line 65... | Line 69... | ||
65 | movie_file = argv[1]; |
69 | movie_file = argv[1]; |
66 | /* register all codecs, demux and protocols */ |
70 | /* register all codecs, demux and protocols */ |
Line 67... | Line 71... | ||
67 | 71 | ||
Line 68... | Line 72... | ||
68 | // av_log_set_level(AV_LOG_INFO); |
72 | av_log_set_level(AV_LOG_FATAL); |
69 | 73 | ||
70 | avcodec_register_all(); |
74 | avcodec_register_all(); |
Line 131... | Line 135... | ||
131 | printf("Video stream not detected\n\r"); |
135 | printf("Video stream not detected\n\r"); |
132 | return -1; // Didn't find a video stream |
136 | return -1; // Didn't find a video stream |
133 | } |
137 | } |
134 | 138 | ||
Line 135... | Line -... | ||
135 | player_state = PLAY_INIT; |
- | |
136 | - | ||
137 | // __asm__ __volatile__("int3"); |
139 | // __asm__ __volatile__("int3"); |
Line 138... | Line 140... | ||
138 | 140 | ||
139 | // Get a pointer to the codec context for the video stream |
141 | // Get a pointer to the codec context for the video stream |
140 | pCodecCtx=pFormatCtx->streams[videoStream]->codec; |
142 | pCodecCtx=pFormatCtx->streams[videoStream]->codec; |
Line 230... | Line 232... | ||
230 | return 0; |
232 | return 0; |
231 | } |
233 | } |
Line 232... | Line 234... | ||
232 | 234 | ||
233 | 235 | ||
234 | static int fill_queue() |
- | |
235 | { |
236 | static int load_frame() |
236 | int eof = 0; |
- | |
237 | AVPacket packet; |
- | |
238 | - | ||
239 | while( !eof) |
237 | { |
Line 240... | Line -... | ||
240 | { |
- | |
241 | int err; |
- | |
242 | - | ||
243 | // __asm__ __volatile__("int3"); |
- | |
244 | 238 | AVPacket packet; |
|
245 | if(q_video.size+q_audio.size < 2*1024*1024) |
239 | int err; |
246 | { |
240 | |
247 | err = av_read_frame(pFormatCtx, &packet); |
- | |
248 | if( err < 0) |
- | |
249 | { |
- | |
250 | eof = 1; |
- | |
251 | if (err != AVERROR_EOF) |
- | |
252 | printf("av_read_frame: error %x\n", err); |
241 | err = av_read_frame(pFormatCtx, &packet); |
253 | break; |
- | |
254 | } |
242 | if( err == 0) |
255 | if(packet.stream_index==videoStream) |
- | |
256 | { |
243 | { |
257 | put_packet(&q_video, &packet); |
244 | if(packet.stream_index==videoStream) |
258 | } |
245 | put_packet(&q_video, &packet); |
259 | else if( (packet.stream_index == audioStream) && |
246 | else if( (packet.stream_index == audioStream) && |
260 | (have_sound != 0) ) |
247 | (have_sound != 0) ) |
261 | { |
248 | { |
262 | put_packet(&q_audio, &packet); |
249 | put_packet(&q_audio, &packet); |
263 | if(audio_base == -1.0) |
250 | if(audio_base == -1.0) |
264 | { |
251 | { |
265 | if (packet.dts != AV_NOPTS_VALUE) |
252 | if (packet.pts != AV_NOPTS_VALUE) |
266 | audio_base = get_audio_base() * packet.dts; |
253 | audio_base = get_audio_base() * packet.pts; |
267 | // printf("audio base %f\n", audio_base); |
- | |
268 | }; |
- | |
269 | } |
254 | // printf("audio base %f\n", audio_base); |
270 | else |
- | |
271 | { |
255 | }; |
272 | av_free_packet(&packet); |
256 | } |
273 | }; |
257 | else av_free_packet(&packet); |
Line 274... | Line 258... | ||
274 | } |
258 | } |
- | 259 | else if (err != AVERROR_EOF) |
|
Line 275... | Line -... | ||
275 | else break; |
- | |
Line 276... | Line 260... | ||
276 | }; |
260 | printf("av_read_frame: error %x\n", err); |
277 | 261 | ||
278 | return eof; |
262 | return err; |
279 | 263 | } |
|
280 | }; |
- | |
281 | - | ||
282 | - | ||
283 | void decoder() |
- | |
284 | { |
- | |
285 | int eof; |
- | |
286 | AVPacket packet; |
- | |
Line 287... | Line 264... | ||
287 | int ret; |
264 | |
Line 288... | Line 265... | ||
288 | 265 | ||
289 | eof = fill_queue(); |
- | |
290 | 266 | ||
291 | while( player_state != CLOSED && !eof) |
267 | static int fill_queue() |
292 | { |
- | |
293 | int err; |
- | |
294 | - | ||
295 | // __asm__ __volatile__("int3"); |
- | |
296 | - | ||
297 | if( player_state == PAUSE ) |
- | |
298 | { |
- | |
299 | delay(1); |
- | |
Line 300... | Line -... | ||
300 | continue; |
- | |
301 | }; |
268 | { |
Line 302... | Line -... | ||
302 | - | ||
- | 269 | int err = 0; |
|
Line 303... | Line -... | ||
303 | if( player_state == REWIND ) |
- | |
304 | { |
- | |
305 | // int64_t timestamp = 0; |
- | |
306 | // int stream_index = av_find_default_stream_index(pFormatCtx); |
- | |
307 | - | ||
Line 308... | Line 270... | ||
308 | // __asm__ __volatile__("int3"); |
270 | AVPacket packet; |
309 | - | ||
310 | if (pFormatCtx->start_time != AV_NOPTS_VALUE) |
- | |
311 | rewind_pos += pFormatCtx->start_time; |
- | |
312 | - | ||
313 | printf("rewind %8"PRId64"\n", rewind_pos); |
- | |
314 | 271 | ||
- | 272 | // __asm__ __volatile__("int3"); |
|
- | 273 | ||
315 | ret = avformat_seek_file(pFormatCtx, -1, INT64_MIN, |
274 | while( (q_video.size+q_audio.size < 2*1024*1024) && |
316 | rewind_pos, INT64_MAX, 0); |
275 | !err ) |
317 | // ret = avformat_seek_file(pFormatCtx, -1, 0, |
- | |
318 | // 0, INT64_MAX, 0); |
276 | err = load_frame(); |
319 | // __asm__ __volatile__("int3"); |
277 | |
Line 320... | Line 278... | ||
320 | 278 | return err; |
|
321 | if (ret < 0) |
279 | |
322 | { |
- | |
Line 323... | Line 280... | ||
323 | printf("could not seek to position %f\n", |
280 | }; |
Line 324... | Line 281... | ||
324 | (double)rewind_pos / AV_TIME_BASE); |
281 | |
325 | } |
282 | |
326 | else |
- | |
Line -... | Line 283... | ||
- | 283 | static void flush_all() |
|
- | 284 | { |
|
327 | { |
285 | AVPacket packet; |
- | 286 | ||
- | 287 | avcodec_flush_buffers(pCodecCtx); |
|
- | 288 | avcodec_flush_buffers(aCodecCtx); |
|
Line 328... | Line 289... | ||
328 | avcodec_flush_buffers(pCodecCtx); |
289 | while( get_packet(&q_video, &packet) != 0) |
329 | avcodec_flush_buffers(aCodecCtx); |
- | |
330 | 290 | av_free_packet(&packet); |
|
331 | while( get_packet(&q_video, &packet) != 0) |
291 | |
Line 332... | Line 292... | ||
332 | av_free_packet(&packet); |
292 | while( get_packet(&q_audio, &packet)!= 0) |
- | 293 | av_free_packet(&packet); |
|
- | 294 | ||
333 | 295 | flush_video(); |
|
- | 296 | ||
334 | while( get_packet(&q_audio, &packet)!= 0) |
297 | astream.count = 0; |
- | 298 | }; |
|
335 | av_free_packet(&packet); |
299 | |
336 | audio_base = -1.0; |
300 | void decoder() |
337 | - | ||
338 | // __asm__ __volatile__("int3"); |
- | |
339 | 301 | { |
|
340 | eof = fill_queue(); |
302 | int eof; |
341 | }; |
- | |
342 | yield(); |
- | |
343 | 303 | AVPacket packet; |
|
344 | flush_video(); |
304 | int ret; |
345 | 305 | int64_t min_pos, max_pos; |
|
- | 306 | ||
- | 307 | while( player_state != CLOSED ) |
|
- | 308 | { |
|
- | 309 | int err; |
|
- | 310 | ||
- | 311 | // __asm__ __volatile__("int3"); |
|
- | 312 | ||
- | 313 | switch(decoder_state) |
|
- | 314 | { |
|
- | 315 | case PREPARE: |
|
346 | player_state = REWIND_2_PLAY; |
316 | eof = fill_queue(); |
347 | printf("restart\n"); |
317 | |
348 | continue; |
318 | do |
349 | }; |
319 | { |
- | 320 | if( (q_video.size+q_audio.size < 4*1024*1024) && |
|
350 | 321 | (eof == 0) ) |
|
- | 322 | { |
|
- | 323 | eof = load_frame(); |
|
- | 324 | } |
|
351 | if(q_video.size+q_audio.size < 4*1024*1024) |
325 | decode_video(pCodecCtx, &q_video); |
352 | { |
326 | ret = decode_audio(aCodecCtx, &q_audio); |
353 | err = av_read_frame(pFormatCtx, &packet); |
327 | }while(astream.count < resampler_size*2 && |
354 | if( err < 0) |
- | |
355 | { |
- | |
356 | eof = 1; |
328 | ret == 1); |
357 | if (err != AVERROR_EOF) |
- | |
358 | printf("av_read_frame: error %x\n", err); |
329 | |
359 | continue; |
- | |
- | 330 | sound_state = PREPARE; |
|
360 | } |
331 | decoder_state = PLAY; |
361 | if(packet.stream_index==videoStream) |
332 | player_state = PLAY; |
- | 333 | ||
- | 334 | case PLAY: |
|
- | 335 | if( (q_video.size+q_audio.size < 4*1024*1024) && |
|
- | 336 | (eof == 0) ) |
|
- | 337 | { |
|
- | 338 | eof = load_frame(); |
|
- | 339 | if(eof) printf("eof\n"); |
|
- | 340 | } |
|
- | 341 | ret = decode_video(pCodecCtx, &q_video); |
|
- | 342 | ret|= decode_audio(aCodecCtx, &q_audio); |
|
- | 343 | ||
- | 344 | if( eof && !ret) |
|
- | 345 | { |
|
- | 346 | decoder_state = STOP; |
|
- | 347 | // printf("stop decoder\n"); |
|
- | 348 | }; |
|
- | 349 | ||
- | 350 | case STOP: |
|
- | 351 | delay(1); |
|
- | 352 | break; |
|
- | 353 | ||
- | 354 | case PLAY_2_STOP: |
|
- | 355 | while(sound_state != STOP) |
|
- | 356 | delay(1); |
|
- | 357 | ||
- | 358 | flush_all(); |
|
- | 359 | ||
- | 360 | if (pFormatCtx->start_time != AV_NOPTS_VALUE) |
|
- | 361 | rewind_pos = pFormatCtx->start_time; |
|
- | 362 | else |
|
- | 363 | rewind_pos = 0; |
|
- | 364 | ||
- | 365 | ret = avformat_seek_file(pFormatCtx, -1, INT64_MIN, |
|
- | 366 | rewind_pos, INT64_MAX, 0); |
|
- | 367 | ||
- | 368 | decoder_state = STOP; |
|
- | 369 | break; |
|
- | 370 | ||
- | 371 | case REWIND: |
|
- | 372 | while(sound_state != STOP) |
|
- | 373 | yield(); |
|
- | 374 | ||
- | 375 | flush_all(); |
|
- | 376 | int opts = 0; |
|
- | 377 | if(rewind_pos < 0) |
|
- | 378 | { |
|
- | 379 | rewind_pos = -rewind_pos; |
|
- | 380 | opts = AVSEEK_FLAG_BACKWARD; |
|
- | 381 | }; |
|
- | 382 | ||
- | 383 | if (pFormatCtx->start_time != AV_NOPTS_VALUE) |
|
- | 384 | rewind_pos += pFormatCtx->start_time; |
|
- | 385 | ||
- | 386 | // printf("rewind %8"PRId64"\n", rewind_pos); |
|
- | 387 | min_pos = rewind_pos - 1000000; |
|
362 | { |
388 | max_pos = rewind_pos + 1000000; |
Line 363... | Line 389... | ||
363 | put_packet(&q_video, &packet); |
389 | |
Line 364... | Line 390... | ||
364 | } |
390 | ret = avformat_seek_file(pFormatCtx, -1, INT64_MIN, |