1/* 2 * FFplay : Simple Media Player based on the FFmpeg libraries 3 * Copyright (c) 2003 Fabrice Bellard 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22#include "config.h" 23#include <inttypes.h> 24#include <math.h> 25#include <limits.h> 26#include "libavutil/avstring.h" 27#include "libavutil/pixdesc.h" 28#include "libavformat/avformat.h" 29#include "libavdevice/avdevice.h" 30#include "libswscale/swscale.h" 31#include "libavcodec/audioconvert.h" 32#include "libavcodec/colorspace.h" 33#include "libavcodec/opt.h" 34#include "libavcodec/avfft.h" 35 36#if CONFIG_AVFILTER 37# include "libavfilter/avfilter.h" 38# include "libavfilter/avfiltergraph.h" 39# include "libavfilter/graphparser.h" 40#endif 41 42#include "cmdutils.h" 43 44#include <SDL.h> 45#include <SDL_thread.h> 46 47#ifdef __MINGW32__ 48#undef main /* We don't want SDL to override our main() */ 49#endif 50 51#include <unistd.h> 52#include <assert.h> 53 54const char program_name[] = "FFplay"; 55const int program_birth_year = 2003; 56 57//#define DEBUG_SYNC 58 59#define MAX_QUEUE_SIZE (15 * 1024 * 1024) 60#define MIN_AUDIOQ_SIZE (20 * 16 * 1024) 61#define MIN_FRAMES 5 62 63/* SDL audio buffer size, in samples. Should be small to have precise 64 A/V sync as SDL does not have hardware buffer fullness info. */ 65#define SDL_AUDIO_BUFFER_SIZE 1024 66 67/* no AV sync correction is done if below the AV sync threshold */ 68#define AV_SYNC_THRESHOLD 0.01 69/* no AV correction is done if too big error */ 70#define AV_NOSYNC_THRESHOLD 10.0 71 72#define FRAME_SKIP_FACTOR 0.05 73 74/* maximum audio speed change to get correct sync */ 75#define SAMPLE_CORRECTION_PERCENT_MAX 10 76 77/* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */ 78#define AUDIO_DIFF_AVG_NB 20 79 80/* NOTE: the size must be big enough to compensate the hardware audio buffersize size */ 81#define SAMPLE_ARRAY_SIZE (2*65536) 82 83#if !CONFIG_AVFILTER 84static int sws_flags = SWS_BICUBIC; 85#endif 86 87typedef struct PacketQueue { 88 AVPacketList *first_pkt, *last_pkt; 89 int nb_packets; 90 int size; 91 int abort_request; 92 SDL_mutex *mutex; 93 SDL_cond *cond; 94} PacketQueue; 95 96#define VIDEO_PICTURE_QUEUE_SIZE 2 97#define SUBPICTURE_QUEUE_SIZE 4 98 99typedef struct VideoPicture { 100 double pts; ///<presentation time stamp for this picture 101 double target_clock; ///<av_gettime() time at which this should be displayed ideally 102 int64_t pos; ///<byte position in file 103 SDL_Overlay *bmp; 104 int width, height; /* source height & width */ 105 int allocated; 106 enum PixelFormat pix_fmt; 107 108#if CONFIG_AVFILTER 109 AVFilterPicRef *picref; 110#endif 111} VideoPicture; 112 113typedef struct SubPicture { 114 double pts; /* presentation time stamp for this picture */ 115 AVSubtitle sub; 116} SubPicture; 117 118enum { 119 AV_SYNC_AUDIO_MASTER, /* default choice */ 120 AV_SYNC_VIDEO_MASTER, 121 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */ 122}; 123 124typedef struct VideoState { 125 SDL_Thread *parse_tid; 126 SDL_Thread *video_tid; 127 SDL_Thread *refresh_tid; 128 AVInputFormat *iformat; 129 int no_background; 130 int abort_request; 131 int paused; 132 int last_paused; 133 int seek_req; 134 int seek_flags; 135 int64_t seek_pos; 136 int64_t seek_rel; 137 int read_pause_return; 138 AVFormatContext *ic; 139 int dtg_active_format; 140 141 int audio_stream; 142 143 int av_sync_type; 144 double external_clock; /* external clock base */ 145 int64_t external_clock_time; 146 147 double audio_clock; 148 double audio_diff_cum; /* used for AV difference average computation */ 149 double audio_diff_avg_coef; 150 double audio_diff_threshold; 151 int audio_diff_avg_count; 152 AVStream *audio_st; 153 PacketQueue audioq; 154 int audio_hw_buf_size; 155 /* samples output by the codec. we reserve more space for avsync 156 compensation */ 157 DECLARE_ALIGNED(16,uint8_t,audio_buf1)[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2]; 158 DECLARE_ALIGNED(16,uint8_t,audio_buf2)[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2]; 159 uint8_t *audio_buf; 160 unsigned int audio_buf_size; /* in bytes */ 161 int audio_buf_index; /* in bytes */ 162 AVPacket audio_pkt_temp; 163 AVPacket audio_pkt; 164 enum SampleFormat audio_src_fmt; 165 AVAudioConvert *reformat_ctx; 166 167 int show_audio; /* if true, display audio samples */ 168 int16_t sample_array[SAMPLE_ARRAY_SIZE]; 169 int sample_array_index; 170 int last_i_start; 171 RDFTContext *rdft; 172 int rdft_bits; 173 int xpos; 174 175 SDL_Thread *subtitle_tid; 176 int subtitle_stream; 177 int subtitle_stream_changed; 178 AVStream *subtitle_st; 179 PacketQueue subtitleq; 180 SubPicture subpq[SUBPICTURE_QUEUE_SIZE]; 181 int subpq_size, subpq_rindex, subpq_windex; 182 SDL_mutex *subpq_mutex; 183 SDL_cond *subpq_cond; 184 185 double frame_timer; 186 double frame_last_pts; 187 double frame_last_delay; 188 double video_clock; ///<pts of last decoded frame / predicted pts of next decoded frame 189 int video_stream; 190 AVStream *video_st; 191 PacketQueue videoq; 192 double video_current_pts; ///<current displayed pts (different from video_clock if frame fifos are used) 193 double video_current_pts_drift; ///<video_current_pts - time (av_gettime) at which we updated video_current_pts - used to have running video pts 194 int64_t video_current_pos; ///<current displayed file pos 195 VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE]; 196 int pictq_size, pictq_rindex, pictq_windex; 197 SDL_mutex *pictq_mutex; 198 SDL_cond *pictq_cond; 199#if !CONFIG_AVFILTER 200 struct SwsContext *img_convert_ctx; 201#endif 202 203 // QETimer *video_timer; 204 char filename[1024]; 205 int width, height, xleft, ytop; 206 207 int64_t faulty_pts; 208 int64_t faulty_dts; 209 int64_t last_dts_for_fault_detection; 210 int64_t last_pts_for_fault_detection; 211 212#if CONFIG_AVFILTER 213 AVFilterContext *out_video_filter; ///<the last filter in the video chain 214#endif 215 216 float skip_frames; 217 float skip_frames_index; 218 int refresh; 219} VideoState; 220 221static void show_help(void); 222static int audio_write_get_buf_size(VideoState *is); 223 224/* options specified by the user */ 225static AVInputFormat *file_iformat; 226static const char *input_filename; 227static const char *window_title; 228static int fs_screen_width; 229static int fs_screen_height; 230static int screen_width = 0; 231static int screen_height = 0; 232static int frame_width = 0; 233static int frame_height = 0; 234static enum PixelFormat frame_pix_fmt = PIX_FMT_NONE; 235static int audio_disable; 236static int video_disable; 237static int wanted_stream[AVMEDIA_TYPE_NB]={ 238 [AVMEDIA_TYPE_AUDIO]=-1, 239 [AVMEDIA_TYPE_VIDEO]=-1, 240 [AVMEDIA_TYPE_SUBTITLE]=-1, 241}; 242static int seek_by_bytes=-1; 243static int display_disable; 244static int show_status = 1; 245static int av_sync_type = AV_SYNC_AUDIO_MASTER; 246static int64_t start_time = AV_NOPTS_VALUE; 247static int64_t duration = AV_NOPTS_VALUE; 248static int debug = 0; 249static int debug_mv = 0; 250static int step = 0; 251static int thread_count = 1; 252static int workaround_bugs = 1; 253static int fast = 0; 254static int genpts = 0; 255static int lowres = 0; 256static int idct = FF_IDCT_AUTO; 257static enum AVDiscard skip_frame= AVDISCARD_DEFAULT; 258static enum AVDiscard skip_idct= AVDISCARD_DEFAULT; 259static enum AVDiscard skip_loop_filter= AVDISCARD_DEFAULT; 260static int error_recognition = FF_ER_CAREFUL; 261static int error_concealment = 3; 262static int decoder_reorder_pts= -1; 263static int autoexit; 264static int loop=1; 265static int framedrop=1; 266 267static int rdftspeed=20; 268#if CONFIG_AVFILTER 269static char *vfilters = NULL; 270#endif 271 272/* current context */ 273static int is_full_screen; 274static VideoState *cur_stream; 275static int64_t audio_callback_time; 276 277static AVPacket flush_pkt; 278 279#define FF_ALLOC_EVENT (SDL_USEREVENT) 280#define FF_REFRESH_EVENT (SDL_USEREVENT + 1) 281#define FF_QUIT_EVENT (SDL_USEREVENT + 2) 282 283static SDL_Surface *screen; 284 285static int packet_queue_put(PacketQueue *q, AVPacket *pkt); 286 287/* packet queue handling */ 288static void packet_queue_init(PacketQueue *q) 289{ 290 memset(q, 0, sizeof(PacketQueue)); 291 q->mutex = SDL_CreateMutex(); 292 q->cond = SDL_CreateCond(); 293 packet_queue_put(q, &flush_pkt); 294} 295 296static void packet_queue_flush(PacketQueue *q) 297{ 298 AVPacketList *pkt, *pkt1; 299 300 SDL_LockMutex(q->mutex); 301 for(pkt = q->first_pkt; pkt != NULL; pkt = pkt1) { 302 pkt1 = pkt->next; 303 av_free_packet(&pkt->pkt); 304 av_freep(&pkt); 305 } 306 q->last_pkt = NULL; 307 q->first_pkt = NULL; 308 q->nb_packets = 0; 309 q->size = 0; 310 SDL_UnlockMutex(q->mutex); 311} 312 313static void packet_queue_end(PacketQueue *q) 314{ 315 packet_queue_flush(q); 316 SDL_DestroyMutex(q->mutex); 317 SDL_DestroyCond(q->cond); 318} 319 320static int packet_queue_put(PacketQueue *q, AVPacket *pkt) 321{ 322 AVPacketList *pkt1; 323 324 /* duplicate the packet */ 325 if (pkt!=&flush_pkt && av_dup_packet(pkt) < 0) 326 return -1; 327 328 pkt1 = av_malloc(sizeof(AVPacketList)); 329 if (!pkt1) 330 return -1; 331 pkt1->pkt = *pkt; 332 pkt1->next = NULL; 333 334 335 SDL_LockMutex(q->mutex); 336 337 if (!q->last_pkt) 338 339 q->first_pkt = pkt1; 340 else 341 q->last_pkt->next = pkt1; 342 q->last_pkt = pkt1; 343 q->nb_packets++; 344 q->size += pkt1->pkt.size + sizeof(*pkt1); 345 /* XXX: should duplicate packet data in DV case */ 346 SDL_CondSignal(q->cond); 347 348 SDL_UnlockMutex(q->mutex); 349 return 0; 350} 351 352static void packet_queue_abort(PacketQueue *q) 353{ 354 SDL_LockMutex(q->mutex); 355 356 q->abort_request = 1; 357 358 SDL_CondSignal(q->cond); 359 360 SDL_UnlockMutex(q->mutex); 361} 362 363/* return < 0 if aborted, 0 if no packet and > 0 if packet. */ 364static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block) 365{ 366 AVPacketList *pkt1; 367 int ret; 368 369 SDL_LockMutex(q->mutex); 370 371 for(;;) { 372 if (q->abort_request) { 373 ret = -1; 374 break; 375 } 376 377 pkt1 = q->first_pkt; 378 if (pkt1) { 379 q->first_pkt = pkt1->next; 380 if (!q->first_pkt) 381 q->last_pkt = NULL; 382 q->nb_packets--; 383 q->size -= pkt1->pkt.size + sizeof(*pkt1); 384 *pkt = pkt1->pkt; 385 av_free(pkt1); 386 ret = 1; 387 break; 388 } else if (!block) { 389 ret = 0; 390 break; 391 } else { 392 SDL_CondWait(q->cond, q->mutex); 393 } 394 } 395 SDL_UnlockMutex(q->mutex); 396 return ret; 397} 398 399static inline void fill_rectangle(SDL_Surface *screen, 400 int x, int y, int w, int h, int color) 401{ 402 SDL_Rect rect; 403 rect.x = x; 404 rect.y = y; 405 rect.w = w; 406 rect.h = h; 407 SDL_FillRect(screen, &rect, color); 408} 409 410#if 0 411/* draw only the border of a rectangle */ 412void fill_border(VideoState *s, int x, int y, int w, int h, int color) 413{ 414 int w1, w2, h1, h2; 415 416 /* fill the background */ 417 w1 = x; 418 if (w1 < 0) 419 w1 = 0; 420 w2 = s->width - (x + w); 421 if (w2 < 0) 422 w2 = 0; 423 h1 = y; 424 if (h1 < 0) 425 h1 = 0; 426 h2 = s->height - (y + h); 427 if (h2 < 0) 428 h2 = 0; 429 fill_rectangle(screen, 430 s->xleft, s->ytop, 431 w1, s->height, 432 color); 433 fill_rectangle(screen, 434 s->xleft + s->width - w2, s->ytop, 435 w2, s->height, 436 color); 437 fill_rectangle(screen, 438 s->xleft + w1, s->ytop, 439 s->width - w1 - w2, h1, 440 color); 441 fill_rectangle(screen, 442 s->xleft + w1, s->ytop + s->height - h2, 443 s->width - w1 - w2, h2, 444 color); 445} 446#endif 447 448#define ALPHA_BLEND(a, oldp, newp, s)\ 449((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s)) 450 451#define RGBA_IN(r, g, b, a, s)\ 452{\ 453 unsigned int v = ((const uint32_t *)(s))[0];\ 454 a = (v >> 24) & 0xff;\ 455 r = (v >> 16) & 0xff;\ 456 g = (v >> 8) & 0xff;\ 457 b = v & 0xff;\ 458} 459 460#define YUVA_IN(y, u, v, a, s, pal)\ 461{\ 462 unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\ 463 a = (val >> 24) & 0xff;\ 464 y = (val >> 16) & 0xff;\ 465 u = (val >> 8) & 0xff;\ 466 v = val & 0xff;\ 467} 468 469#define YUVA_OUT(d, y, u, v, a)\ 470{\ 471 ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\ 472} 473 474 475#define BPP 1 476 477static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh) 478{ 479 int wrap, wrap3, width2, skip2; 480 int y, u, v, a, u1, v1, a1, w, h; 481 uint8_t *lum, *cb, *cr; 482 const uint8_t *p; 483 const uint32_t *pal; 484 int dstx, dsty, dstw, dsth; 485 486 dstw = av_clip(rect->w, 0, imgw); 487 dsth = av_clip(rect->h, 0, imgh); 488 dstx = av_clip(rect->x, 0, imgw - dstw); 489 dsty = av_clip(rect->y, 0, imgh - dsth); 490 lum = dst->data[0] + dsty * dst->linesize[0]; 491 cb = dst->data[1] + (dsty >> 1) * dst->linesize[1]; 492 cr = dst->data[2] + (dsty >> 1) * dst->linesize[2]; 493 494 width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1); 495 skip2 = dstx >> 1; 496 wrap = dst->linesize[0]; 497 wrap3 = rect->pict.linesize[0]; 498 p = rect->pict.data[0]; 499 pal = (const uint32_t *)rect->pict.data[1]; /* Now in YCrCb! */ 500 501 if (dsty & 1) { 502 lum += dstx; 503 cb += skip2; 504 cr += skip2; 505 506 if (dstx & 1) { 507 YUVA_IN(y, u, v, a, p, pal); 508 lum[0] = ALPHA_BLEND(a, lum[0], y, 0); 509 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0); 510 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0); 511 cb++; 512 cr++; 513 lum++; 514 p += BPP; 515 } 516 for(w = dstw - (dstx & 1); w >= 2; w -= 2) { 517 YUVA_IN(y, u, v, a, p, pal); 518 u1 = u; 519 v1 = v; 520 a1 = a; 521 lum[0] = ALPHA_BLEND(a, lum[0], y, 0); 522 523 YUVA_IN(y, u, v, a, p + BPP, pal); 524 u1 += u; 525 v1 += v; 526 a1 += a; 527 lum[1] = ALPHA_BLEND(a, lum[1], y, 0); 528 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1); 529 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1); 530 cb++; 531 cr++; 532 p += 2 * BPP; 533 lum += 2; 534 } 535 if (w) { 536 YUVA_IN(y, u, v, a, p, pal); 537 lum[0] = ALPHA_BLEND(a, lum[0], y, 0); 538 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0); 539 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0); 540 p++; 541 lum++; 542 } 543 p += wrap3 - dstw * BPP; 544 lum += wrap - dstw - dstx; 545 cb += dst->linesize[1] - width2 - skip2; 546 cr += dst->linesize[2] - width2 - skip2; 547 } 548 for(h = dsth - (dsty & 1); h >= 2; h -= 2) { 549 lum += dstx; 550 cb += skip2; 551 cr += skip2; 552 553 if (dstx & 1) { 554 YUVA_IN(y, u, v, a, p, pal); 555 u1 = u; 556 v1 = v; 557 a1 = a; 558 lum[0] = ALPHA_BLEND(a, lum[0], y, 0); 559 p += wrap3; 560 lum += wrap; 561 YUVA_IN(y, u, v, a, p, pal); 562 u1 += u; 563 v1 += v; 564 a1 += a; 565 lum[0] = ALPHA_BLEND(a, lum[0], y, 0); 566 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1); 567 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1); 568 cb++; 569 cr++; 570 p += -wrap3 + BPP; 571 lum += -wrap + 1; 572 } 573 for(w = dstw - (dstx & 1); w >= 2; w -= 2) { 574 YUVA_IN(y, u, v, a, p, pal); 575 u1 = u; 576 v1 = v; 577 a1 = a; 578 lum[0] = ALPHA_BLEND(a, lum[0], y, 0); 579 580 YUVA_IN(y, u, v, a, p + BPP, pal); 581 u1 += u; 582 v1 += v; 583 a1 += a; 584 lum[1] = ALPHA_BLEND(a, lum[1], y, 0); 585 p += wrap3; 586 lum += wrap; 587 588 YUVA_IN(y, u, v, a, p, pal); 589 u1 += u; 590 v1 += v; 591 a1 += a; 592 lum[0] = ALPHA_BLEND(a, lum[0], y, 0); 593 594 YUVA_IN(y, u, v, a, p + BPP, pal); 595 u1 += u; 596 v1 += v; 597 a1 += a; 598 lum[1] = ALPHA_BLEND(a, lum[1], y, 0); 599 600 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2); 601 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2); 602 603 cb++; 604 cr++; 605 p += -wrap3 + 2 * BPP; 606 lum += -wrap + 2; 607 } 608 if (w) { 609 YUVA_IN(y, u, v, a, p, pal); 610 u1 = u; 611 v1 = v; 612 a1 = a; 613 lum[0] = ALPHA_BLEND(a, lum[0], y, 0); 614 p += wrap3; 615 lum += wrap; 616 YUVA_IN(y, u, v, a, p, pal); 617 u1 += u; 618 v1 += v; 619 a1 += a; 620 lum[0] = ALPHA_BLEND(a, lum[0], y, 0); 621 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1); 622 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1); 623 cb++; 624 cr++; 625 p += -wrap3 + BPP; 626 lum += -wrap + 1; 627 } 628 p += wrap3 + (wrap3 - dstw * BPP); 629 lum += wrap + (wrap - dstw - dstx); 630 cb += dst->linesize[1] - width2 - skip2; 631 cr += dst->linesize[2] - width2 - skip2; 632 } 633 /* handle odd height */ 634 if (h) { 635 lum += dstx; 636 cb += skip2; 637 cr += skip2; 638 639 if (dstx & 1) { 640 YUVA_IN(y, u, v, a, p, pal); 641 lum[0] = ALPHA_BLEND(a, lum[0], y, 0); 642 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0); 643 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0); 644 cb++; 645 cr++; 646 lum++; 647 p += BPP; 648 } 649 for(w = dstw - (dstx & 1); w >= 2; w -= 2) { 650 YUVA_IN(y, u, v, a, p, pal); 651 u1 = u; 652 v1 = v; 653 a1 = a; 654 lum[0] = ALPHA_BLEND(a, lum[0], y, 0); 655 656 YUVA_IN(y, u, v, a, p + BPP, pal); 657 u1 += u; 658 v1 += v; 659 a1 += a; 660 lum[1] = ALPHA_BLEND(a, lum[1], y, 0); 661 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1); 662 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1); 663 cb++; 664 cr++; 665 p += 2 * BPP; 666 lum += 2; 667 } 668 if (w) { 669 YUVA_IN(y, u, v, a, p, pal); 670 lum[0] = ALPHA_BLEND(a, lum[0], y, 0); 671 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0); 672 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0); 673 } 674 } 675} 676 677static void free_subpicture(SubPicture *sp) 678{ 679 int i; 680 681 for (i = 0; i < sp->sub.num_rects; i++) 682 { 683 av_freep(&sp->sub.rects[i]->pict.data[0]); 684 av_freep(&sp->sub.rects[i]->pict.data[1]); 685 av_freep(&sp->sub.rects[i]); 686 } 687 688 av_free(sp->sub.rects); 689 690 memset(&sp->sub, 0, sizeof(AVSubtitle)); 691} 692 693static void video_image_display(VideoState *is) 694{ 695 VideoPicture *vp; 696 SubPicture *sp; 697 AVPicture pict; 698 float aspect_ratio; 699 int width, height, x, y; 700 SDL_Rect rect; 701 int i; 702 703 vp = &is->pictq[is->pictq_rindex]; 704 if (vp->bmp) { 705#if CONFIG_AVFILTER 706 if (vp->picref->pixel_aspect.num == 0) 707 aspect_ratio = 0; 708 else 709 aspect_ratio = av_q2d(vp->picref->pixel_aspect); 710#else 711 712 /* XXX: use variable in the frame */ 713 if (is->video_st->sample_aspect_ratio.num) 714 aspect_ratio = av_q2d(is->video_st->sample_aspect_ratio); 715 else if (is->video_st->codec->sample_aspect_ratio.num) 716 aspect_ratio = av_q2d(is->video_st->codec->sample_aspect_ratio); 717 else 718 aspect_ratio = 0; 719#endif 720 if (aspect_ratio <= 0.0) 721 aspect_ratio = 1.0; 722 aspect_ratio *= (float)vp->width / (float)vp->height; 723 /* if an active format is indicated, then it overrides the 724 mpeg format */ 725#if 0 726 if (is->video_st->codec->dtg_active_format != is->dtg_active_format) { 727 is->dtg_active_format = is->video_st->codec->dtg_active_format; 728 printf("dtg_active_format=%d\n", is->dtg_active_format); 729 } 730#endif 731#if 0 732 switch(is->video_st->codec->dtg_active_format) { 733 case FF_DTG_AFD_SAME: 734 default: 735 /* nothing to do */ 736 break; 737 case FF_DTG_AFD_4_3: 738 aspect_ratio = 4.0 / 3.0; 739 break; 740 case FF_DTG_AFD_16_9: 741 aspect_ratio = 16.0 / 9.0; 742 break; 743 case FF_DTG_AFD_14_9: 744 aspect_ratio = 14.0 / 9.0; 745 break; 746 case FF_DTG_AFD_4_3_SP_14_9: 747 aspect_ratio = 14.0 / 9.0; 748 break; 749 case FF_DTG_AFD_16_9_SP_14_9: 750 aspect_ratio = 14.0 / 9.0; 751 break; 752 case FF_DTG_AFD_SP_4_3: 753 aspect_ratio = 4.0 / 3.0; 754 break; 755 } 756#endif 757 758 if (is->subtitle_st) 759 { 760 if (is->subpq_size > 0) 761 { 762 sp = &is->subpq[is->subpq_rindex]; 763 764 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) 765 { 766 SDL_LockYUVOverlay (vp->bmp); 767 768 pict.data[0] = vp->bmp->pixels[0]; 769 pict.data[1] = vp->bmp->pixels[2]; 770 pict.data[2] = vp->bmp->pixels[1]; 771 772 pict.linesize[0] = vp->bmp->pitches[0]; 773 pict.linesize[1] = vp->bmp->pitches[2]; 774 pict.linesize[2] = vp->bmp->pitches[1]; 775 776 for (i = 0; i < sp->sub.num_rects; i++) 777 blend_subrect(&pict, sp->sub.rects[i], 778 vp->bmp->w, vp->bmp->h); 779 780 SDL_UnlockYUVOverlay (vp->bmp); 781 } 782 } 783 } 784 785 786 /* XXX: we suppose the screen has a 1.0 pixel ratio */ 787 height = is->height; 788 width = ((int)rint(height * aspect_ratio)) & ~1; 789 if (width > is->width) { 790 width = is->width; 791 height = ((int)rint(width / aspect_ratio)) & ~1; 792 } 793 x = (is->width - width) / 2; 794 y = (is->height - height) / 2; 795 if (!is->no_background) { 796 /* fill the background */ 797 // fill_border(is, x, y, width, height, QERGB(0x00, 0x00, 0x00)); 798 } else { 799 is->no_background = 0; 800 } 801 rect.x = is->xleft + x; 802 rect.y = is->ytop + y; 803 rect.w = width; 804 rect.h = height; 805 SDL_DisplayYUVOverlay(vp->bmp, &rect); 806 } else { 807#if 0 808 fill_rectangle(screen, 809 is->xleft, is->ytop, is->width, is->height, 810 QERGB(0x00, 0x00, 0x00)); 811#endif 812 } 813} 814 815static inline int compute_mod(int a, int b) 816{ 817 a = a % b; 818 if (a >= 0) 819 return a; 820 else 821 return a + b; 822} 823 824static void video_audio_display(VideoState *s) 825{ 826 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels; 827 int ch, channels, h, h2, bgcolor, fgcolor; 828 int16_t time_diff; 829 int rdft_bits, nb_freq; 830 831 for(rdft_bits=1; (1<<rdft_bits)<2*s->height; rdft_bits++) 832 ; 833 nb_freq= 1<<(rdft_bits-1); 834 835 /* compute display index : center on currently output samples */ 836 channels = s->audio_st->codec->channels; 837 nb_display_channels = channels; 838 if (!s->paused) { 839 int data_used= s->show_audio==1 ? s->width : (2*nb_freq); 840 n = 2 * channels; 841 delay = audio_write_get_buf_size(s); 842 delay /= n; 843 844 /* to be more precise, we take into account the time spent since 845 the last buffer computation */ 846 if (audio_callback_time) { 847 time_diff = av_gettime() - audio_callback_time; 848 delay -= (time_diff * s->audio_st->codec->sample_rate) / 1000000; 849 } 850 851 delay += 2*data_used; 852 if (delay < data_used) 853 delay = data_used; 854 855 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE); 856 if(s->show_audio==1){ 857 h= INT_MIN; 858 for(i=0; i<1000; i+=channels){ 859 int idx= (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE; 860 int a= s->sample_array[idx]; 861 int b= s->sample_array[(idx + 4*channels)%SAMPLE_ARRAY_SIZE]; 862 int c= s->sample_array[(idx + 5*channels)%SAMPLE_ARRAY_SIZE]; 863 int d= s->sample_array[(idx + 9*channels)%SAMPLE_ARRAY_SIZE]; 864 int score= a-d; 865 if(h<score && (b^c)<0){ 866 h= score; 867 i_start= idx; 868 } 869 } 870 } 871 872 s->last_i_start = i_start; 873 } else { 874 i_start = s->last_i_start; 875 } 876 877 bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00); 878 if(s->show_audio==1){ 879 fill_rectangle(screen, 880 s->xleft, s->ytop, s->width, s->height, 881 bgcolor); 882 883 fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff); 884 885 /* total height for one channel */ 886 h = s->height / nb_display_channels; 887 /* graph height / 2 */ 888 h2 = (h * 9) / 20; 889 for(ch = 0;ch < nb_display_channels; ch++) { 890 i = i_start + ch; 891 y1 = s->ytop + ch * h + (h / 2); /* position of center line */ 892 for(x = 0; x < s->width; x++) { 893 y = (s->sample_array[i] * h2) >> 15; 894 if (y < 0) { 895 y = -y; 896 ys = y1 - y; 897 } else { 898 ys = y1; 899 } 900 fill_rectangle(screen, 901 s->xleft + x, ys, 1, y, 902 fgcolor); 903 i += channels; 904 if (i >= SAMPLE_ARRAY_SIZE) 905 i -= SAMPLE_ARRAY_SIZE; 906 } 907 } 908 909 fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff); 910 911 for(ch = 1;ch < nb_display_channels; ch++) { 912 y = s->ytop + ch * h; 913 fill_rectangle(screen, 914 s->xleft, y, s->width, 1, 915 fgcolor); 916 } 917 SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height); 918 }else{ 919 nb_display_channels= FFMIN(nb_display_channels, 2); 920 if(rdft_bits != s->rdft_bits){ 921 av_rdft_end(s->rdft); 922 s->rdft = av_rdft_init(rdft_bits, DFT_R2C); 923 s->rdft_bits= rdft_bits; 924 } 925 { 926 FFTSample data[2][2*nb_freq]; 927 for(ch = 0;ch < nb_display_channels; ch++) { 928 i = i_start + ch; 929 for(x = 0; x < 2*nb_freq; x++) { 930 double w= (x-nb_freq)*(1.0/nb_freq); 931 data[ch][x]= s->sample_array[i]*(1.0-w*w); 932 i += channels; 933 if (i >= SAMPLE_ARRAY_SIZE) 934 i -= SAMPLE_ARRAY_SIZE; 935 } 936 av_rdft_calc(s->rdft, data[ch]); 937 } 938 //least efficient way to do this, we should of course directly access it but its more than fast enough 939 for(y=0; y<s->height; y++){ 940 double w= 1/sqrt(nb_freq); 941 int a= sqrt(w*sqrt(data[0][2*y+0]*data[0][2*y+0] + data[0][2*y+1]*data[0][2*y+1])); 942 int b= sqrt(w*sqrt(data[1][2*y+0]*data[1][2*y+0] + data[1][2*y+1]*data[1][2*y+1])); 943 a= FFMIN(a,255); 944 b= FFMIN(b,255); 945 fgcolor = SDL_MapRGB(screen->format, a, b, (a+b)/2); 946 947 fill_rectangle(screen, 948 s->xpos, s->height-y, 1, 1, 949 fgcolor); 950 } 951 } 952 SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height); 953 s->xpos++; 954 if(s->xpos >= s->width) 955 s->xpos= s->xleft; 956 } 957} 958 959static int video_open(VideoState *is){ 960 int flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL; 961 int w,h; 962 963 if(is_full_screen) flags |= SDL_FULLSCREEN; 964 else flags |= SDL_RESIZABLE; 965 966 if (is_full_screen && fs_screen_width) { 967 w = fs_screen_width; 968 h = fs_screen_height; 969 } else if(!is_full_screen && screen_width){ 970 w = screen_width; 971 h = screen_height; 972#if CONFIG_AVFILTER 973 }else if (is->out_video_filter && is->out_video_filter->inputs[0]){ 974 w = is->out_video_filter->inputs[0]->w; 975 h = is->out_video_filter->inputs[0]->h; 976#else 977 }else if (is->video_st && is->video_st->codec->width){ 978 w = is->video_st->codec->width; 979 h = is->video_st->codec->height; 980#endif 981 } else { 982 w = 640; 983 h = 480; 984 } 985 if(screen && is->width == screen->w && screen->w == w 986 && is->height== screen->h && screen->h == h) 987 return 0; 988 989#ifndef __APPLE__ 990 screen = SDL_SetVideoMode(w, h, 0, flags); 991#else 992 /* setting bits_per_pixel = 0 or 32 causes blank video on OS X */ 993 screen = SDL_SetVideoMode(w, h, 24, flags); 994#endif 995 if (!screen) { 996 fprintf(stderr, "SDL: could not set video mode - exiting\n"); 997 return -1; 998 } 999 if (!window_title) 1000 window_title = input_filename; 1001 SDL_WM_SetCaption(window_title, window_title); 1002 1003 is->width = screen->w; 1004 is->height = screen->h; 1005 1006 return 0; 1007} 1008 1009/* display the current picture, if any */ 1010static void video_display(VideoState *is) 1011{ 1012 if(!screen) 1013 video_open(cur_stream); 1014 if (is->audio_st && is->show_audio) 1015 video_audio_display(is); 1016 else if (is->video_st) 1017 video_image_display(is); 1018} 1019 1020static int refresh_thread(void *opaque) 1021{ 1022 VideoState *is= opaque; 1023 while(!is->abort_request){ 1024 SDL_Event event; 1025 event.type = FF_REFRESH_EVENT; 1026 event.user.data1 = opaque; 1027 if(!is->refresh){ 1028 is->refresh=1; 1029 SDL_PushEvent(&event); 1030 } 1031 usleep(is->audio_st && is->show_audio ? rdftspeed*1000 : 5000); //FIXME ideally we should wait the correct time but SDLs event passing is so slow it would be silly 1032 } 1033 return 0; 1034} 1035 1036/* get the current audio clock value */ 1037static double get_audio_clock(VideoState *is) 1038{ 1039 double pts; 1040 int hw_buf_size, bytes_per_sec; 1041 pts = is->audio_clock; 1042 hw_buf_size = audio_write_get_buf_size(is); 1043 bytes_per_sec = 0; 1044 if (is->audio_st) { 1045 bytes_per_sec = is->audio_st->codec->sample_rate * 1046 2 * is->audio_st->codec->channels; 1047 } 1048 if (bytes_per_sec) 1049 pts -= (double)hw_buf_size / bytes_per_sec; 1050 return pts; 1051} 1052 1053/* get the current video clock value */ 1054static double get_video_clock(VideoState *is) 1055{ 1056 if (is->paused) { 1057 return is->video_current_pts; 1058 } else { 1059 return is->video_current_pts_drift + av_gettime() / 1000000.0; 1060 } 1061} 1062 1063/* get the current external clock value */ 1064static double get_external_clock(VideoState *is) 1065{ 1066 int64_t ti; 1067 ti = av_gettime(); 1068 return is->external_clock + ((ti - is->external_clock_time) * 1e-6); 1069} 1070 1071/* get the current master clock value */ 1072static double get_master_clock(VideoState *is) 1073{ 1074 double val; 1075 1076 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) { 1077 if (is->video_st) 1078 val = get_video_clock(is); 1079 else 1080 val = get_audio_clock(is); 1081 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) { 1082 if (is->audio_st) 1083 val = get_audio_clock(is); 1084 else 1085 val = get_video_clock(is); 1086 } else { 1087 val = get_external_clock(is); 1088 } 1089 return val; 1090} 1091 1092/* seek in the stream */ 1093static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes) 1094{ 1095 if (!is->seek_req) { 1096 is->seek_pos = pos; 1097 is->seek_rel = rel; 1098 is->seek_flags &= ~AVSEEK_FLAG_BYTE; 1099 if (seek_by_bytes) 1100 is->seek_flags |= AVSEEK_FLAG_BYTE; 1101 is->seek_req = 1; 1102 } 1103} 1104 1105/* pause or resume the video */ 1106static void stream_pause(VideoState *is) 1107{ 1108 if (is->paused) { 1109 is->frame_timer += av_gettime() / 1000000.0 + is->video_current_pts_drift - is->video_current_pts; 1110 if(is->read_pause_return != AVERROR(ENOSYS)){ 1111 is->video_current_pts = is->video_current_pts_drift + av_gettime() / 1000000.0; 1112 } 1113 is->video_current_pts_drift = is->video_current_pts - av_gettime() / 1000000.0; 1114 } 1115 is->paused = !is->paused; 1116} 1117 1118static double compute_target_time(double frame_current_pts, VideoState *is) 1119{ 1120 double delay, sync_threshold, diff; 1121 1122 /* compute nominal delay */ 1123 delay = frame_current_pts - is->frame_last_pts; 1124 if (delay <= 0 || delay >= 10.0) { 1125 /* if incorrect delay, use previous one */ 1126 delay = is->frame_last_delay; 1127 } else { 1128 is->frame_last_delay = delay; 1129 } 1130 is->frame_last_pts = frame_current_pts; 1131 1132 /* update delay to follow master synchronisation source */ 1133 if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) || 1134 is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) { 1135 /* if video is slave, we try to correct big delays by 1136 duplicating or deleting a frame */ 1137 diff = get_video_clock(is) - get_master_clock(is); 1138 1139 /* skip or repeat frame. We take into account the 1140 delay to compute the threshold. I still don't know 1141 if it is the best guess */ 1142 sync_threshold = FFMAX(AV_SYNC_THRESHOLD, delay); 1143 if (fabs(diff) < AV_NOSYNC_THRESHOLD) { 1144 if (diff <= -sync_threshold) 1145 delay = 0; 1146 else if (diff >= sync_threshold) 1147 delay = 2 * delay; 1148 } 1149 } 1150 is->frame_timer += delay; 1151#if defined(DEBUG_SYNC) 1152 printf("video: delay=%0.3f actual_delay=%0.3f pts=%0.3f A-V=%f\n", 1153 delay, actual_delay, frame_current_pts, -diff); 1154#endif 1155 1156 return is->frame_timer; 1157} 1158 1159/* called to display each frame */ 1160static void video_refresh_timer(void *opaque) 1161{ 1162 VideoState *is = opaque; 1163 VideoPicture *vp; 1164 1165 SubPicture *sp, *sp2; 1166 1167 if (is->video_st) { 1168retry: 1169 if (is->pictq_size == 0) { 1170 //nothing to do, no picture to display in the que 1171 } else { 1172 double time= av_gettime()/1000000.0; 1173 double next_target; 1174 /* dequeue the picture */ 1175 vp = &is->pictq[is->pictq_rindex]; 1176 1177 if(time < vp->target_clock) 1178 return; 1179 /* update current video pts */ 1180 is->video_current_pts = vp->pts; 1181 is->video_current_pts_drift = is->video_current_pts - time; 1182 is->video_current_pos = vp->pos; 1183 if(is->pictq_size > 1){ 1184 VideoPicture *nextvp= &is->pictq[(is->pictq_rindex+1)%VIDEO_PICTURE_QUEUE_SIZE]; 1185 assert(nextvp->target_clock >= vp->target_clock); 1186 next_target= nextvp->target_clock; 1187 }else{ 1188 next_target= vp->target_clock + is->video_clock - vp->pts; //FIXME pass durations cleanly 1189 } 1190 if(framedrop && time > next_target){ 1191 is->skip_frames *= 1.0 + FRAME_SKIP_FACTOR; 1192 if(is->pictq_size > 1 || time > next_target + 0.5){ 1193 /* update queue size and signal for next picture */ 1194 if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE) 1195 is->pictq_rindex = 0; 1196 1197 SDL_LockMutex(is->pictq_mutex); 1198 is->pictq_size--; 1199 SDL_CondSignal(is->pictq_cond); 1200 SDL_UnlockMutex(is->pictq_mutex); 1201 goto retry; 1202 } 1203 } 1204 1205 if(is->subtitle_st) { 1206 if (is->subtitle_stream_changed) { 1207 SDL_LockMutex(is->subpq_mutex); 1208 1209 while (is->subpq_size) { 1210 free_subpicture(&is->subpq[is->subpq_rindex]); 1211 1212 /* update queue size and signal for next picture */ 1213 if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE) 1214 is->subpq_rindex = 0; 1215 1216 is->subpq_size--; 1217 } 1218 is->subtitle_stream_changed = 0; 1219 1220 SDL_CondSignal(is->subpq_cond); 1221 SDL_UnlockMutex(is->subpq_mutex); 1222 } else { 1223 if (is->subpq_size > 0) { 1224 sp = &is->subpq[is->subpq_rindex]; 1225 1226 if (is->subpq_size > 1) 1227 sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE]; 1228 else 1229 sp2 = NULL; 1230 1231 if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000))) 1232 || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000)))) 1233 { 1234 free_subpicture(sp); 1235 1236 /* update queue size and signal for next picture */ 1237 if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE) 1238 is->subpq_rindex = 0; 1239 1240 SDL_LockMutex(is->subpq_mutex); 1241 is->subpq_size--; 1242 SDL_CondSignal(is->subpq_cond); 1243 SDL_UnlockMutex(is->subpq_mutex); 1244 } 1245 } 1246 } 1247 } 1248 1249 /* display picture */ 1250 video_display(is); 1251 1252 /* update queue size and signal for next picture */ 1253 if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE) 1254 is->pictq_rindex = 0; 1255 1256 SDL_LockMutex(is->pictq_mutex); 1257 is->pictq_size--; 1258 SDL_CondSignal(is->pictq_cond); 1259 SDL_UnlockMutex(is->pictq_mutex); 1260 } 1261 } else if (is->audio_st) { 1262 /* draw the next audio frame */ 1263 1264 /* if only audio stream, then display the audio bars (better 1265 than nothing, just to test the implementation */ 1266 1267 /* display picture */ 1268 video_display(is); 1269 } 1270 if (show_status) { 1271 static int64_t last_time; 1272 int64_t cur_time; 1273 int aqsize, vqsize, sqsize; 1274 double av_diff; 1275 1276 cur_time = av_gettime(); 1277 if (!last_time || (cur_time - last_time) >= 30000) { 1278 aqsize = 0; 1279 vqsize = 0; 1280 sqsize = 0; 1281 if (is->audio_st) 1282 aqsize = is->audioq.size; 1283 if (is->video_st) 1284 vqsize = is->videoq.size; 1285 if (is->subtitle_st) 1286 sqsize = is->subtitleq.size; 1287 av_diff = 0; 1288 if (is->audio_st && is->video_st) 1289 av_diff = get_audio_clock(is) - get_video_clock(is); 1290 printf("%7.2f A-V:%7.3f s:%3.1f aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r", 1291 get_master_clock(is), av_diff, FFMAX(is->skip_frames-1, 0), aqsize / 1024, vqsize / 1024, sqsize, is->faulty_dts, is->faulty_pts); 1292 fflush(stdout); 1293 last_time = cur_time; 1294 } 1295 } 1296} 1297 1298/* allocate a picture (needs to do that in main thread to avoid 1299 potential locking problems */ 1300static void alloc_picture(void *opaque) 1301{ 1302 VideoState *is = opaque; 1303 VideoPicture *vp; 1304 1305 vp = &is->pictq[is->pictq_windex]; 1306 1307 if (vp->bmp) 1308 SDL_FreeYUVOverlay(vp->bmp); 1309 1310#if CONFIG_AVFILTER 1311 if (vp->picref) 1312 avfilter_unref_pic(vp->picref); 1313 vp->picref = NULL; 1314 1315 vp->width = is->out_video_filter->inputs[0]->w; 1316 vp->height = is->out_video_filter->inputs[0]->h; 1317 vp->pix_fmt = is->out_video_filter->inputs[0]->format; 1318#else 1319 vp->width = is->video_st->codec->width; 1320 vp->height = is->video_st->codec->height; 1321 vp->pix_fmt = is->video_st->codec->pix_fmt; 1322#endif 1323 1324 vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height, 1325 SDL_YV12_OVERLAY, 1326 screen); 1327 1328 SDL_LockMutex(is->pictq_mutex); 1329 vp->allocated = 1; 1330 SDL_CondSignal(is->pictq_cond); 1331 SDL_UnlockMutex(is->pictq_mutex); 1332} 1333 1334/** 1335 * 1336 * @param pts the dts of the pkt / pts of the frame and guessed if not known 1337 */ 1338static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, int64_t pos) 1339{ 1340 VideoPicture *vp; 1341 int dst_pix_fmt; 1342#if CONFIG_AVFILTER 1343 AVPicture pict_src; 1344#endif 1345 /* wait until we have space to put a new picture */ 1346 SDL_LockMutex(is->pictq_mutex); 1347 1348 if(is->pictq_size>=VIDEO_PICTURE_QUEUE_SIZE && !is->refresh) 1349 is->skip_frames= FFMAX(1.0 - FRAME_SKIP_FACTOR, is->skip_frames * (1.0-FRAME_SKIP_FACTOR)); 1350 1351 while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE && 1352 !is->videoq.abort_request) { 1353 SDL_CondWait(is->pictq_cond, is->pictq_mutex); 1354 } 1355 SDL_UnlockMutex(is->pictq_mutex); 1356 1357 if (is->videoq.abort_request) 1358 return -1; 1359 1360 vp = &is->pictq[is->pictq_windex]; 1361 1362 /* alloc or resize hardware picture buffer */ 1363 if (!vp->bmp || 1364#if CONFIG_AVFILTER 1365 vp->width != is->out_video_filter->inputs[0]->w || 1366 vp->height != is->out_video_filter->inputs[0]->h) { 1367#else 1368 vp->width != is->video_st->codec->width || 1369 vp->height != is->video_st->codec->height) { 1370#endif 1371 SDL_Event event; 1372 1373 vp->allocated = 0; 1374 1375 /* the allocation must be done in the main thread to avoid 1376 locking problems */ 1377 event.type = FF_ALLOC_EVENT; 1378 event.user.data1 = is; 1379 SDL_PushEvent(&event); 1380 1381 /* wait until the picture is allocated */ 1382 SDL_LockMutex(is->pictq_mutex); 1383 while (!vp->allocated && !is->videoq.abort_request) { 1384 SDL_CondWait(is->pictq_cond, is->pictq_mutex); 1385 } 1386 SDL_UnlockMutex(is->pictq_mutex); 1387 1388 if (is->videoq.abort_request) 1389 return -1; 1390 } 1391 1392 /* if the frame is not skipped, then display it */ 1393 if (vp->bmp) { 1394 AVPicture pict; 1395#if CONFIG_AVFILTER 1396 if(vp->picref) 1397 avfilter_unref_pic(vp->picref); 1398 vp->picref = src_frame->opaque; 1399#endif 1400 1401 /* get a pointer on the bitmap */ 1402 SDL_LockYUVOverlay (vp->bmp); 1403 1404 dst_pix_fmt = PIX_FMT_YUV420P; 1405 memset(&pict,0,sizeof(AVPicture)); 1406 pict.data[0] = vp->bmp->pixels[0]; 1407 pict.data[1] = vp->bmp->pixels[2]; 1408 pict.data[2] = vp->bmp->pixels[1]; 1409 1410 pict.linesize[0] = vp->bmp->pitches[0]; 1411 pict.linesize[1] = vp->bmp->pitches[2]; 1412 pict.linesize[2] = vp->bmp->pitches[1]; 1413 1414#if CONFIG_AVFILTER 1415 pict_src.data[0] = src_frame->data[0]; 1416 pict_src.data[1] = src_frame->data[1]; 1417 pict_src.data[2] = src_frame->data[2]; 1418 1419 pict_src.linesize[0] = src_frame->linesize[0]; 1420 pict_src.linesize[1] = src_frame->linesize[1]; 1421 pict_src.linesize[2] = src_frame->linesize[2]; 1422 1423 //FIXME use direct rendering 1424 av_picture_copy(&pict, &pict_src, 1425 vp->pix_fmt, vp->width, vp->height); 1426#else 1427 sws_flags = av_get_int(sws_opts, "sws_flags", NULL); 1428 is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx, 1429 vp->width, vp->height, vp->pix_fmt, vp->width, vp->height, 1430 dst_pix_fmt, sws_flags, NULL, NULL, NULL); 1431 if (is->img_convert_ctx == NULL) { 1432 fprintf(stderr, "Cannot initialize the conversion context\n"); 1433 exit(1); 1434 } 1435 sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize, 1436 0, vp->height, pict.data, pict.linesize); 1437#endif 1438 /* update the bitmap content */ 1439 SDL_UnlockYUVOverlay(vp->bmp); 1440 1441 vp->pts = pts; 1442 vp->pos = pos; 1443 1444 /* now we can update the picture count */ 1445 if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE) 1446 is->pictq_windex = 0; 1447 SDL_LockMutex(is->pictq_mutex); 1448 vp->target_clock= compute_target_time(vp->pts, is); 1449 1450 is->pictq_size++; 1451 SDL_UnlockMutex(is->pictq_mutex); 1452 } 1453 return 0; 1454} 1455 1456/** 1457 * compute the exact PTS for the picture if it is omitted in the stream 1458 * @param pts1 the dts of the pkt / pts of the frame 1459 */ 1460static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1, int64_t pos) 1461{ 1462 double frame_delay, pts; 1463 1464 pts = pts1; 1465 1466 if (pts != 0) { 1467 /* update video clock with pts, if present */ 1468 is->video_clock = pts; 1469 } else { 1470 pts = is->video_clock; 1471 } 1472 /* update video clock for next frame */ 1473 frame_delay = av_q2d(is->video_st->codec->time_base); 1474 /* for MPEG2, the frame can be repeated, so we update the 1475 clock accordingly */ 1476 frame_delay += src_frame->repeat_pict * (frame_delay * 0.5); 1477 is->video_clock += frame_delay; 1478 1479#if defined(DEBUG_SYNC) && 0 1480 printf("frame_type=%c clock=%0.3f pts=%0.3f\n", 1481 av_get_pict_type_char(src_frame->pict_type), pts, pts1); 1482#endif 1483 return queue_picture(is, src_frame, pts, pos); 1484} 1485 1486static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacket *pkt) 1487{ 1488 int len1, got_picture, i; 1489 1490 if (packet_queue_get(&is->videoq, pkt, 1) < 0) 1491 return -1; 1492 1493 if(pkt->data == flush_pkt.data){ 1494 avcodec_flush_buffers(is->video_st->codec); 1495 1496 SDL_LockMutex(is->pictq_mutex); 1497 //Make sure there are no long delay timers (ideally we should just flush the que but thats harder) 1498 for(i=0; i<VIDEO_PICTURE_QUEUE_SIZE; i++){ 1499 is->pictq[i].target_clock= 0; 1500 } 1501 while (is->pictq_size && !is->videoq.abort_request) { 1502 SDL_CondWait(is->pictq_cond, is->pictq_mutex); 1503 } 1504 is->video_current_pos= -1; 1505 SDL_UnlockMutex(is->pictq_mutex); 1506 1507 is->last_dts_for_fault_detection= 1508 is->last_pts_for_fault_detection= INT64_MIN; 1509 is->frame_last_pts= AV_NOPTS_VALUE; 1510 is->frame_last_delay = 0; 1511 is->frame_timer = (double)av_gettime() / 1000000.0; 1512 is->skip_frames= 1; 1513 is->skip_frames_index= 0; 1514 return 0; 1515 } 1516 1517 /* NOTE: ipts is the PTS of the _first_ picture beginning in 1518 this packet, if any */ 1519 is->video_st->codec->reordered_opaque= pkt->pts; 1520 len1 = avcodec_decode_video2(is->video_st->codec, 1521 frame, &got_picture, 1522 pkt); 1523 1524 if (got_picture) { 1525 if(pkt->dts != AV_NOPTS_VALUE){ 1526 is->faulty_dts += pkt->dts <= is->last_dts_for_fault_detection; 1527 is->last_dts_for_fault_detection= pkt->dts; 1528 } 1529 if(frame->reordered_opaque != AV_NOPTS_VALUE){ 1530 is->faulty_pts += frame->reordered_opaque <= is->last_pts_for_fault_detection; 1531 is->last_pts_for_fault_detection= frame->reordered_opaque; 1532 } 1533 } 1534 1535 if( ( decoder_reorder_pts==1 1536 || (decoder_reorder_pts && is->faulty_pts<is->faulty_dts) 1537 || pkt->dts == AV_NOPTS_VALUE) 1538 && frame->reordered_opaque != AV_NOPTS_VALUE) 1539 *pts= frame->reordered_opaque; 1540 else if(pkt->dts != AV_NOPTS_VALUE) 1541 *pts= pkt->dts; 1542 else 1543 *pts= 0; 1544 1545// if (len1 < 0) 1546// break; 1547 if (got_picture){ 1548 is->skip_frames_index += 1; 1549 if(is->skip_frames_index >= is->skip_frames){ 1550 is->skip_frames_index -= FFMAX(is->skip_frames, 1.0); 1551 return 1; 1552 } 1553 1554 } 1555 return 0; 1556} 1557 1558#if CONFIG_AVFILTER 1559typedef struct { 1560 VideoState *is; 1561 AVFrame *frame; 1562 int use_dr1; 1563} FilterPriv; 1564 1565static int input_get_buffer(AVCodecContext *codec, AVFrame *pic) 1566{ 1567 AVFilterContext *ctx = codec->opaque; 1568 AVFilterPicRef *ref; 1569 int perms = AV_PERM_WRITE; 1570 int w, h, stride[4]; 1571 unsigned edge; 1572 1573 if(pic->buffer_hints & FF_BUFFER_HINTS_VALID) { 1574 if(pic->buffer_hints & FF_BUFFER_HINTS_READABLE) perms |= AV_PERM_READ; 1575 if(pic->buffer_hints & FF_BUFFER_HINTS_PRESERVE) perms |= AV_PERM_PRESERVE; 1576 if(pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE) perms |= AV_PERM_REUSE2; 1577 } 1578 if(pic->reference) perms |= AV_PERM_READ | AV_PERM_PRESERVE; 1579 1580 w = codec->width; 1581 h = codec->height; 1582 avcodec_align_dimensions2(codec, &w, &h, stride); 1583 edge = codec->flags & CODEC_FLAG_EMU_EDGE ? 0 : avcodec_get_edge_width(); 1584 w += edge << 1; 1585 h += edge << 1; 1586 1587 if(!(ref = avfilter_get_video_buffer(ctx->outputs[0], perms, w, h))) 1588 return -1; 1589 1590 ref->w = codec->width; 1591 ref->h = codec->height; 1592 for(int i = 0; i < 3; i ++) { 1593 unsigned hshift = i == 0 ? 0 : av_pix_fmt_descriptors[ref->pic->format].log2_chroma_w; 1594 unsigned vshift = i == 0 ? 0 : av_pix_fmt_descriptors[ref->pic->format].log2_chroma_h; 1595 1596 if (ref->data[i]) { 1597 ref->data[i] += (edge >> hshift) + ((edge * ref->linesize[i]) >> vshift); 1598 } 1599 pic->data[i] = ref->data[i]; 1600 pic->linesize[i] = ref->linesize[i]; 1601 } 1602 pic->opaque = ref; 1603 pic->age = INT_MAX; 1604 pic->type = FF_BUFFER_TYPE_USER; 1605 return 0; 1606} 1607 1608static void input_release_buffer(AVCodecContext *codec, AVFrame *pic) 1609{ 1610 memset(pic->data, 0, sizeof(pic->data)); 1611 avfilter_unref_pic(pic->opaque); 1612} 1613 1614static int input_init(AVFilterContext *ctx, const char *args, void *opaque) 1615{ 1616 FilterPriv *priv = ctx->priv; 1617 AVCodecContext *codec; 1618 if(!opaque) return -1; 1619 1620 priv->is = opaque; 1621 codec = priv->is->video_st->codec; 1622 codec->opaque = ctx; 1623 if(codec->codec->capabilities & CODEC_CAP_DR1) { 1624 priv->use_dr1 = 1; 1625 codec->get_buffer = input_get_buffer; 1626 codec->release_buffer = input_release_buffer; 1627 } 1628 1629 priv->frame = avcodec_alloc_frame(); 1630 1631 return 0; 1632} 1633 1634static void input_uninit(AVFilterContext *ctx) 1635{ 1636 FilterPriv *priv = ctx->priv; 1637 av_free(priv->frame); 1638} 1639 1640static int input_request_frame(AVFilterLink *link) 1641{ 1642 FilterPriv *priv = link->src->priv; 1643 AVFilterPicRef *picref; 1644 int64_t pts = 0; 1645 AVPacket pkt; 1646 int ret; 1647 1648 while (!(ret = get_video_frame(priv->is, priv->frame, &pts, &pkt))) 1649 av_free_packet(&pkt); 1650 if (ret < 0) 1651 return -1; 1652 1653 if(priv->use_dr1) { 1654 picref = avfilter_ref_pic(priv->frame->opaque, ~0); 1655 } else { 1656 picref = avfilter_get_video_buffer(link, AV_PERM_WRITE, link->w, link->h); 1657 av_picture_copy((AVPicture *)&picref->data, (AVPicture *)priv->frame, 1658 picref->pic->format, link->w, link->h); 1659 } 1660 av_free_packet(&pkt); 1661 1662 picref->pts = pts; 1663 picref->pos = pkt.pos; 1664 picref->pixel_aspect = priv->is->video_st->codec->sample_aspect_ratio; 1665 avfilter_start_frame(link, picref); 1666 avfilter_draw_slice(link, 0, link->h, 1); 1667 avfilter_end_frame(link); 1668 1669 return 0; 1670} 1671 1672static int input_query_formats(AVFilterContext *ctx) 1673{ 1674 FilterPriv *priv = ctx->priv; 1675 enum PixelFormat pix_fmts[] = { 1676 priv->is->video_st->codec->pix_fmt, PIX_FMT_NONE 1677 }; 1678 1679 avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); 1680 return 0; 1681} 1682 1683static int input_config_props(AVFilterLink *link) 1684{ 1685 FilterPriv *priv = link->src->priv; 1686 AVCodecContext *c = priv->is->video_st->codec; 1687 1688 link->w = c->width; 1689 link->h = c->height; 1690 1691 return 0; 1692} 1693 1694static AVFilter input_filter = 1695{ 1696 .name = "ffplay_input", 1697 1698 .priv_size = sizeof(FilterPriv), 1699 1700 .init = input_init, 1701 .uninit = input_uninit, 1702 1703 .query_formats = input_query_formats, 1704 1705 .inputs = (AVFilterPad[]) {{ .name = NULL }}, 1706 .outputs = (AVFilterPad[]) {{ .name = "default", 1707 .type = AVMEDIA_TYPE_VIDEO, 1708 .request_frame = input_request_frame, 1709 .config_props = input_config_props, }, 1710 { .name = NULL }}, 1711}; 1712 1713static void output_end_frame(AVFilterLink *link) 1714{ 1715} 1716 1717static int output_query_formats(AVFilterContext *ctx) 1718{ 1719 enum PixelFormat pix_fmts[] = { PIX_FMT_YUV420P, PIX_FMT_NONE }; 1720 1721 avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); 1722 return 0; 1723} 1724 1725static int get_filtered_video_frame(AVFilterContext *ctx, AVFrame *frame, 1726 int64_t *pts, int64_t *pos) 1727{ 1728 AVFilterPicRef *pic; 1729 1730 if(avfilter_request_frame(ctx->inputs[0])) 1731 return -1; 1732 if(!(pic = ctx->inputs[0]->cur_pic)) 1733 return -1; 1734 ctx->inputs[0]->cur_pic = NULL; 1735 1736 frame->opaque = pic; 1737 *pts = pic->pts; 1738 *pos = pic->pos; 1739 1740 memcpy(frame->data, pic->data, sizeof(frame->data)); 1741 memcpy(frame->linesize, pic->linesize, sizeof(frame->linesize)); 1742 1743 return 1; 1744} 1745 1746static AVFilter output_filter = 1747{ 1748 .name = "ffplay_output", 1749 1750 .query_formats = output_query_formats, 1751 1752 .inputs = (AVFilterPad[]) {{ .name = "default", 1753 .type = AVMEDIA_TYPE_VIDEO, 1754 .end_frame = output_end_frame, 1755 .min_perms = AV_PERM_READ, }, 1756 { .name = NULL }}, 1757 .outputs = (AVFilterPad[]) {{ .name = NULL }}, 1758}; 1759#endif /* CONFIG_AVFILTER */ 1760 1761static int video_thread(void *arg) 1762{ 1763 VideoState *is = arg; 1764 AVFrame *frame= avcodec_alloc_frame(); 1765 int64_t pts_int; 1766 double pts; 1767 int ret; 1768 1769#if CONFIG_AVFILTER 1770 int64_t pos; 1771 AVFilterContext *filt_src = NULL, *filt_out = NULL; 1772 AVFilterGraph *graph = av_mallocz(sizeof(AVFilterGraph)); 1773 graph->scale_sws_opts = av_strdup("sws_flags=bilinear"); 1774 1775 if(!(filt_src = avfilter_open(&input_filter, "src"))) goto the_end; 1776 if(!(filt_out = avfilter_open(&output_filter, "out"))) goto the_end; 1777 1778 if(avfilter_init_filter(filt_src, NULL, is)) goto the_end; 1779 if(avfilter_init_filter(filt_out, NULL, frame)) goto the_end; 1780 1781 1782 if(vfilters) { 1783 AVFilterInOut *outputs = av_malloc(sizeof(AVFilterInOut)); 1784 AVFilterInOut *inputs = av_malloc(sizeof(AVFilterInOut)); 1785 1786 outputs->name = av_strdup("in"); 1787 outputs->filter = filt_src; 1788 outputs->pad_idx = 0; 1789 outputs->next = NULL; 1790 1791 inputs->name = av_strdup("out"); 1792 inputs->filter = filt_out; 1793 inputs->pad_idx = 0; 1794 inputs->next = NULL; 1795 1796 if (avfilter_graph_parse(graph, vfilters, inputs, outputs, NULL) < 0) 1797 goto the_end; 1798 av_freep(&vfilters); 1799 } else { 1800 if(avfilter_link(filt_src, 0, filt_out, 0) < 0) goto the_end; 1801 } 1802 avfilter_graph_add_filter(graph, filt_src); 1803 avfilter_graph_add_filter(graph, filt_out); 1804 1805 if(avfilter_graph_check_validity(graph, NULL)) goto the_end; 1806 if(avfilter_graph_config_formats(graph, NULL)) goto the_end; 1807 if(avfilter_graph_config_links(graph, NULL)) goto the_end; 1808 1809 is->out_video_filter = filt_out; 1810#endif 1811 1812 for(;;) { 1813#if !CONFIG_AVFILTER 1814 AVPacket pkt; 1815#endif 1816 while (is->paused && !is->videoq.abort_request) 1817 SDL_Delay(10); 1818#if CONFIG_AVFILTER 1819 ret = get_filtered_video_frame(filt_out, frame, &pts_int, &pos); 1820#else 1821 ret = get_video_frame(is, frame, &pts_int, &pkt); 1822#endif 1823 1824 if (ret < 0) goto the_end; 1825 1826 if (!ret) 1827 continue; 1828 1829 pts = pts_int*av_q2d(is->video_st->time_base); 1830 1831#if CONFIG_AVFILTER 1832 ret = output_picture2(is, frame, pts, pos); 1833#else 1834 ret = output_picture2(is, frame, pts, pkt.pos); 1835 av_free_packet(&pkt); 1836#endif 1837 if (ret < 0) 1838 goto the_end; 1839 1840 if (step) 1841 if (cur_stream) 1842 stream_pause(cur_stream); 1843 } 1844 the_end: 1845#if CONFIG_AVFILTER 1846 avfilter_graph_destroy(graph); 1847 av_freep(&graph); 1848#endif 1849 av_free(frame); 1850 return 0; 1851} 1852 1853static int subtitle_thread(void *arg) 1854{ 1855 VideoState *is = arg; 1856 SubPicture *sp; 1857 AVPacket pkt1, *pkt = &pkt1; 1858 int len1, got_subtitle; 1859 double pts; 1860 int i, j; 1861 int r, g, b, y, u, v, a; 1862 1863 for(;;) { 1864 while (is->paused && !is->subtitleq.abort_request) { 1865 SDL_Delay(10); 1866 } 1867 if (packet_queue_get(&is->subtitleq, pkt, 1) < 0) 1868 break; 1869 1870 if(pkt->data == flush_pkt.data){ 1871 avcodec_flush_buffers(is->subtitle_st->codec); 1872 continue; 1873 } 1874 SDL_LockMutex(is->subpq_mutex); 1875 while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE && 1876 !is->subtitleq.abort_request) { 1877 SDL_CondWait(is->subpq_cond, is->subpq_mutex); 1878 } 1879 SDL_UnlockMutex(is->subpq_mutex); 1880 1881 if (is->subtitleq.abort_request) 1882 goto the_end; 1883 1884 sp = &is->subpq[is->subpq_windex]; 1885 1886 /* NOTE: ipts is the PTS of the _first_ picture beginning in 1887 this packet, if any */ 1888 pts = 0; 1889 if (pkt->pts != AV_NOPTS_VALUE) 1890 pts = av_q2d(is->subtitle_st->time_base)*pkt->pts; 1891 1892 len1 = avcodec_decode_subtitle2(is->subtitle_st->codec, 1893 &sp->sub, &got_subtitle, 1894 pkt); 1895// if (len1 < 0) 1896// break; 1897 if (got_subtitle && sp->sub.format == 0) { 1898 sp->pts = pts; 1899 1900 for (i = 0; i < sp->sub.num_rects; i++) 1901 { 1902 for (j = 0; j < sp->sub.rects[i]->nb_colors; j++) 1903 { 1904 RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j); 1905 y = RGB_TO_Y_CCIR(r, g, b); 1906 u = RGB_TO_U_CCIR(r, g, b, 0); 1907 v = RGB_TO_V_CCIR(r, g, b, 0); 1908 YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a); 1909 } 1910 } 1911 1912 /* now we can update the picture count */ 1913 if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE) 1914 is->subpq_windex = 0; 1915 SDL_LockMutex(is->subpq_mutex); 1916 is->subpq_size++; 1917 SDL_UnlockMutex(is->subpq_mutex); 1918 } 1919 av_free_packet(pkt); 1920// if (step) 1921// if (cur_stream) 1922// stream_pause(cur_stream); 1923 } 1924 the_end: 1925 return 0; 1926} 1927 1928/* copy samples for viewing in editor window */ 1929static void update_sample_display(VideoState *is, short *samples, int samples_size) 1930{ 1931 int size, len, channels; 1932 1933 channels = is->audio_st->codec->channels; 1934 1935 size = samples_size / sizeof(short); 1936 while (size > 0) { 1937 len = SAMPLE_ARRAY_SIZE - is->sample_array_index; 1938 if (len > size) 1939 len = size; 1940 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short)); 1941 samples += len; 1942 is->sample_array_index += len; 1943 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE) 1944 is->sample_array_index = 0; 1945 size -= len; 1946 } 1947} 1948 1949/* return the new audio buffer size (samples can be added or deleted 1950 to get better sync if video or external master clock) */ 1951static int synchronize_audio(VideoState *is, short *samples, 1952 int samples_size1, double pts) 1953{ 1954 int n, samples_size; 1955 double ref_clock; 1956 1957 n = 2 * is->audio_st->codec->channels; 1958 samples_size = samples_size1; 1959 1960 /* if not master, then we try to remove or add samples to correct the clock */ 1961 if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) || 1962 is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) { 1963 double diff, avg_diff; 1964 int wanted_size, min_size, max_size, nb_samples; 1965 1966 ref_clock = get_master_clock(is); 1967 diff = get_audio_clock(is) - ref_clock; 1968 1969 if (diff < AV_NOSYNC_THRESHOLD) { 1970 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum; 1971 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) { 1972 /* not enough measures to have a correct estimate */ 1973 is->audio_diff_avg_count++; 1974 } else { 1975 /* estimate the A-V difference */ 1976 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef); 1977 1978 if (fabs(avg_diff) >= is->audio_diff_threshold) { 1979 wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n); 1980 nb_samples = samples_size / n; 1981 1982 min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n; 1983 max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n; 1984 if (wanted_size < min_size) 1985 wanted_size = min_size; 1986 else if (wanted_size > max_size) 1987 wanted_size = max_size; 1988 1989 /* add or remove samples to correction the synchro */ 1990 if (wanted_size < samples_size) { 1991 /* remove samples */ 1992 samples_size = wanted_size; 1993 } else if (wanted_size > samples_size) { 1994 uint8_t *samples_end, *q; 1995 int nb; 1996 1997 /* add samples */ 1998 nb = (samples_size - wanted_size); 1999 samples_end = (uint8_t *)samples + samples_size - n; 2000 q = samples_end + n; 2001 while (nb > 0) { 2002 memcpy(q, samples_end, n); 2003 q += n; 2004 nb -= n; 2005 } 2006 samples_size = wanted_size; 2007 } 2008 } 2009#if 0 2010 printf("diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n", 2011 diff, avg_diff, samples_size - samples_size1, 2012 is->audio_clock, is->video_clock, is->audio_diff_threshold); 2013#endif 2014 } 2015 } else { 2016 /* too big difference : may be initial PTS errors, so 2017 reset A-V filter */ 2018 is->audio_diff_avg_count = 0; 2019 is->audio_diff_cum = 0; 2020 } 2021 } 2022 2023 return samples_size; 2024} 2025 2026/* decode one audio frame and returns its uncompressed size */ 2027static int audio_decode_frame(VideoState *is, double *pts_ptr) 2028{ 2029 AVPacket *pkt_temp = &is->audio_pkt_temp; 2030 AVPacket *pkt = &is->audio_pkt; 2031 AVCodecContext *dec= is->audio_st->codec; 2032 int n, len1, data_size; 2033 double pts; 2034 2035 for(;;) { 2036 /* NOTE: the audio packet can contain several frames */ 2037 while (pkt_temp->size > 0) { 2038 data_size = sizeof(is->audio_buf1); 2039 len1 = avcodec_decode_audio3(dec, 2040 (int16_t *)is->audio_buf1, &data_size, 2041 pkt_temp); 2042 if (len1 < 0) { 2043 /* if error, we skip the frame */ 2044 pkt_temp->size = 0; 2045 break; 2046 } 2047 2048 pkt_temp->data += len1; 2049 pkt_temp->size -= len1; 2050 if (data_size <= 0) 2051 continue; 2052 2053 if (dec->sample_fmt != is->audio_src_fmt) { 2054 if (is->reformat_ctx) 2055 av_audio_convert_free(is->reformat_ctx); 2056 is->reformat_ctx= av_audio_convert_alloc(SAMPLE_FMT_S16, 1, 2057 dec->sample_fmt, 1, NULL, 0); 2058 if (!is->reformat_ctx) { 2059 fprintf(stderr, "Cannot convert %s sample format to %s sample format\n", 2060 avcodec_get_sample_fmt_name(dec->sample_fmt), 2061 avcodec_get_sample_fmt_name(SAMPLE_FMT_S16)); 2062 break; 2063 } 2064 is->audio_src_fmt= dec->sample_fmt; 2065 } 2066 2067 if (is->reformat_ctx) { 2068 const void *ibuf[6]= {is->audio_buf1}; 2069 void *obuf[6]= {is->audio_buf2}; 2070 int istride[6]= {av_get_bits_per_sample_format(dec->sample_fmt)/8}; 2071 int ostride[6]= {2}; 2072 int len= data_size/istride[0]; 2073 if (av_audio_convert(is->reformat_ctx, obuf, ostride, ibuf, istride, len)<0) { 2074 printf("av_audio_convert() failed\n"); 2075 break; 2076 } 2077 is->audio_buf= is->audio_buf2; 2078 /* FIXME: existing code assume that data_size equals framesize*channels*2 2079 remove this legacy cruft */ 2080 data_size= len*2; 2081 }else{ 2082 is->audio_buf= is->audio_buf1; 2083 } 2084 2085 /* if no pts, then compute it */ 2086 pts = is->audio_clock; 2087 *pts_ptr = pts; 2088 n = 2 * dec->channels; 2089 is->audio_clock += (double)data_size / 2090 (double)(n * dec->sample_rate); 2091#if defined(DEBUG_SYNC) 2092 { 2093 static double last_clock; 2094 printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n", 2095 is->audio_clock - last_clock, 2096 is->audio_clock, pts); 2097 last_clock = is->audio_clock; 2098 } 2099#endif 2100 return data_size; 2101 } 2102 2103 /* free the current packet */ 2104 if (pkt->data) 2105 av_free_packet(pkt); 2106 2107 if (is->paused || is->audioq.abort_request) { 2108 return -1; 2109 } 2110 2111 /* read next packet */ 2112 if (packet_queue_get(&is->audioq, pkt, 1) < 0) 2113 return -1; 2114 if(pkt->data == flush_pkt.data){ 2115 avcodec_flush_buffers(dec); 2116 continue; 2117 } 2118 2119 pkt_temp->data = pkt->data; 2120 pkt_temp->size = pkt->size; 2121 2122 /* if update the audio clock with the pts */ 2123 if (pkt->pts != AV_NOPTS_VALUE) { 2124 is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts; 2125 } 2126 } 2127} 2128 2129/* get the current audio output buffer size, in samples. With SDL, we 2130 cannot have a precise information */ 2131static int audio_write_get_buf_size(VideoState *is) 2132{ 2133 return is->audio_buf_size - is->audio_buf_index; 2134} 2135 2136 2137/* prepare a new audio buffer */ 2138static void sdl_audio_callback(void *opaque, Uint8 *stream, int len) 2139{ 2140 VideoState *is = opaque; 2141 int audio_size, len1; 2142 double pts; 2143 2144 audio_callback_time = av_gettime(); 2145 2146 while (len > 0) { 2147 if (is->audio_buf_index >= is->audio_buf_size) { 2148 audio_size = audio_decode_frame(is, &pts); 2149 if (audio_size < 0) { 2150 /* if error, just output silence */ 2151 is->audio_buf = is->audio_buf1; 2152 is->audio_buf_size = 1024; 2153 memset(is->audio_buf, 0, is->audio_buf_size); 2154 } else { 2155 if (is->show_audio) 2156 update_sample_display(is, (int16_t *)is->audio_buf, audio_size); 2157 audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size, 2158 pts); 2159 is->audio_buf_size = audio_size; 2160 } 2161 is->audio_buf_index = 0; 2162 } 2163 len1 = is->audio_buf_size - is->audio_buf_index; 2164 if (len1 > len) 2165 len1 = len; 2166 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1); 2167 len -= len1; 2168 stream += len1; 2169 is->audio_buf_index += len1; 2170 } 2171} 2172 2173/* open a given stream. Return 0 if OK */ 2174static int stream_component_open(VideoState *is, int stream_index) 2175{ 2176 AVFormatContext *ic = is->ic; 2177 AVCodecContext *avctx; 2178 AVCodec *codec; 2179 SDL_AudioSpec wanted_spec, spec; 2180 2181 if (stream_index < 0 || stream_index >= ic->nb_streams) 2182 return -1; 2183 avctx = ic->streams[stream_index]->codec; 2184 2185 /* prepare audio output */ 2186 if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) { 2187 if (avctx->channels > 0) { 2188 avctx->request_channels = FFMIN(2, avctx->channels); 2189 } else { 2190 avctx->request_channels = 2; 2191 } 2192 } 2193 2194 codec = avcodec_find_decoder(avctx->codec_id); 2195 avctx->debug_mv = debug_mv; 2196 avctx->debug = debug; 2197 avctx->workaround_bugs = workaround_bugs; 2198 avctx->lowres = lowres; 2199 if(lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE; 2200 avctx->idct_algo= idct; 2201 if(fast) avctx->flags2 |= CODEC_FLAG2_FAST; 2202 avctx->skip_frame= skip_frame; 2203 avctx->skip_idct= skip_idct; 2204 avctx->skip_loop_filter= skip_loop_filter; 2205 avctx->error_recognition= error_recognition; 2206 avctx->error_concealment= error_concealment; 2207 avcodec_thread_init(avctx, thread_count); 2208 2209 set_context_opts(avctx, avcodec_opts[avctx->codec_type], 0); 2210 2211 if (!codec || 2212 avcodec_open(avctx, codec) < 0) 2213 return -1; 2214 2215 /* prepare audio output */ 2216 if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) { 2217 wanted_spec.freq = avctx->sample_rate; 2218 wanted_spec.format = AUDIO_S16SYS; 2219 wanted_spec.channels = avctx->channels; 2220 wanted_spec.silence = 0; 2221 wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE; 2222 wanted_spec.callback = sdl_audio_callback; 2223 wanted_spec.userdata = is; 2224 if (SDL_OpenAudio(&wanted_spec, &spec) < 0) { 2225 fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError()); 2226 return -1; 2227 } 2228 is->audio_hw_buf_size = spec.size; 2229 is->audio_src_fmt= SAMPLE_FMT_S16; 2230 } 2231 2232 ic->streams[stream_index]->discard = AVDISCARD_DEFAULT; 2233 switch(avctx->codec_type) { 2234 case AVMEDIA_TYPE_AUDIO: 2235 is->audio_stream = stream_index; 2236 is->audio_st = ic->streams[stream_index]; 2237 is->audio_buf_size = 0; 2238 is->audio_buf_index = 0; 2239 2240 /* init averaging filter */ 2241 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB); 2242 is->audio_diff_avg_count = 0; 2243 /* since we do not have a precise anough audio fifo fullness, 2244 we correct audio sync only if larger than this threshold */ 2245 is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / avctx->sample_rate; 2246 2247 memset(&is->audio_pkt, 0, sizeof(is->audio_pkt)); 2248 packet_queue_init(&is->audioq); 2249 SDL_PauseAudio(0); 2250 break; 2251 case AVMEDIA_TYPE_VIDEO: 2252 is->video_stream = stream_index; 2253 is->video_st = ic->streams[stream_index]; 2254 2255// is->video_current_pts_time = av_gettime(); 2256 2257 packet_queue_init(&is->videoq); 2258 is->video_tid = SDL_CreateThread(video_thread, is); 2259 break; 2260 case AVMEDIA_TYPE_SUBTITLE: 2261 is->subtitle_stream = stream_index; 2262 is->subtitle_st = ic->streams[stream_index]; 2263 packet_queue_init(&is->subtitleq); 2264 2265 is->subtitle_tid = SDL_CreateThread(subtitle_thread, is); 2266 break; 2267 default: 2268 break; 2269 } 2270 return 0; 2271} 2272 2273static void stream_component_close(VideoState *is, int stream_index) 2274{ 2275 AVFormatContext *ic = is->ic; 2276 AVCodecContext *avctx; 2277 2278 if (stream_index < 0 || stream_index >= ic->nb_streams) 2279 return; 2280 avctx = ic->streams[stream_index]->codec; 2281 2282 switch(avctx->codec_type) { 2283 case AVMEDIA_TYPE_AUDIO: 2284 packet_queue_abort(&is->audioq); 2285 2286 SDL_CloseAudio(); 2287 2288 packet_queue_end(&is->audioq); 2289 if (is->reformat_ctx) 2290 av_audio_convert_free(is->reformat_ctx); 2291 is->reformat_ctx = NULL; 2292 break; 2293 case AVMEDIA_TYPE_VIDEO: 2294 packet_queue_abort(&is->videoq); 2295 2296 /* note: we also signal this mutex to make sure we deblock the 2297 video thread in all cases */ 2298 SDL_LockMutex(is->pictq_mutex); 2299 SDL_CondSignal(is->pictq_cond); 2300 SDL_UnlockMutex(is->pictq_mutex); 2301 2302 SDL_WaitThread(is->video_tid, NULL); 2303 2304 packet_queue_end(&is->videoq); 2305 break; 2306 case AVMEDIA_TYPE_SUBTITLE: 2307 packet_queue_abort(&is->subtitleq); 2308 2309 /* note: we also signal this mutex to make sure we deblock the 2310 video thread in all cases */ 2311 SDL_LockMutex(is->subpq_mutex); 2312 is->subtitle_stream_changed = 1; 2313 2314 SDL_CondSignal(is->subpq_cond); 2315 SDL_UnlockMutex(is->subpq_mutex); 2316 2317 SDL_WaitThread(is->subtitle_tid, NULL); 2318 2319 packet_queue_end(&is->subtitleq); 2320 break; 2321 default: 2322 break; 2323 } 2324 2325 ic->streams[stream_index]->discard = AVDISCARD_ALL; 2326 avcodec_close(avctx); 2327 switch(avctx->codec_type) { 2328 case AVMEDIA_TYPE_AUDIO: 2329 is->audio_st = NULL; 2330 is->audio_stream = -1; 2331 break; 2332 case AVMEDIA_TYPE_VIDEO: 2333 is->video_st = NULL; 2334 is->video_stream = -1; 2335 break; 2336 case AVMEDIA_TYPE_SUBTITLE: 2337 is->subtitle_st = NULL; 2338 is->subtitle_stream = -1; 2339 break; 2340 default: 2341 break; 2342 } 2343} 2344 2345/* since we have only one decoding thread, we can use a global 2346 variable instead of a thread local variable */ 2347static VideoState *global_video_state; 2348 2349static int decode_interrupt_cb(void) 2350{ 2351 return (global_video_state && global_video_state->abort_request); 2352} 2353 2354/* this thread gets the stream from the disk or the network */ 2355static int decode_thread(void *arg) 2356{ 2357 VideoState *is = arg; 2358 AVFormatContext *ic; 2359 int err, i, ret; 2360 int st_index[AVMEDIA_TYPE_NB]; 2361 int st_count[AVMEDIA_TYPE_NB]={0}; 2362 int st_best_packet_count[AVMEDIA_TYPE_NB]; 2363 AVPacket pkt1, *pkt = &pkt1; 2364 AVFormatParameters params, *ap = ¶ms; 2365 int eof=0; 2366 int pkt_in_play_range = 0; 2367 2368 ic = avformat_alloc_context(); 2369 2370 memset(st_index, -1, sizeof(st_index)); 2371 memset(st_best_packet_count, -1, sizeof(st_best_packet_count)); 2372 is->video_stream = -1; 2373 is->audio_stream = -1; 2374 is->subtitle_stream = -1; 2375 2376 global_video_state = is; 2377 url_set_interrupt_cb(decode_interrupt_cb); 2378 2379 memset(ap, 0, sizeof(*ap)); 2380 2381 ap->prealloced_context = 1; 2382 ap->width = frame_width; 2383 ap->height= frame_height; 2384 ap->time_base= (AVRational){1, 25}; 2385 ap->pix_fmt = frame_pix_fmt; 2386 2387 set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM); 2388 2389 err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap); 2390 if (err < 0) { 2391 print_error(is->filename, err); 2392 ret = -1; 2393 goto fail; 2394 } 2395 is->ic = ic; 2396 2397 if(genpts) 2398 ic->flags |= AVFMT_FLAG_GENPTS; 2399 2400 err = av_find_stream_info(ic); 2401 if (err < 0) { 2402 fprintf(stderr, "%s: could not find codec parameters\n", is->filename); 2403 ret = -1; 2404 goto fail; 2405 } 2406 if(ic->pb) 2407 ic->pb->eof_reached= 0; //FIXME hack, ffplay maybe should not use url_feof() to test for the end 2408 2409 if(seek_by_bytes<0) 2410 seek_by_bytes= !!(ic->iformat->flags & AVFMT_TS_DISCONT); 2411 2412 /* if seeking requested, we execute it */ 2413 if (start_time != AV_NOPTS_VALUE) { 2414 int64_t timestamp; 2415 2416 timestamp = start_time; 2417 /* add the stream start time */ 2418 if (ic->start_time != AV_NOPTS_VALUE) 2419 timestamp += ic->start_time; 2420 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0); 2421 if (ret < 0) { 2422 fprintf(stderr, "%s: could not seek to position %0.3f\n", 2423 is->filename, (double)timestamp / AV_TIME_BASE); 2424 } 2425 } 2426 2427 for(i = 0; i < ic->nb_streams; i++) { 2428 AVStream *st= ic->streams[i]; 2429 AVCodecContext *avctx = st->codec; 2430 ic->streams[i]->discard = AVDISCARD_ALL; 2431 if(avctx->codec_type >= (unsigned)AVMEDIA_TYPE_NB) 2432 continue; 2433 if(st_count[avctx->codec_type]++ != wanted_stream[avctx->codec_type] && wanted_stream[avctx->codec_type] >= 0) 2434 continue; 2435 2436 if(st_best_packet_count[avctx->codec_type] >= st->codec_info_nb_frames) 2437 continue; 2438 st_best_packet_count[avctx->codec_type]= st->codec_info_nb_frames; 2439 2440 switch(avctx->codec_type) { 2441 case AVMEDIA_TYPE_AUDIO: 2442 if (!audio_disable) 2443 st_index[AVMEDIA_TYPE_AUDIO] = i; 2444 break; 2445 case AVMEDIA_TYPE_VIDEO: 2446 case AVMEDIA_TYPE_SUBTITLE: 2447 if (!video_disable) 2448 st_index[avctx->codec_type] = i; 2449 break; 2450 default: 2451 break; 2452 } 2453 } 2454 if (show_status) { 2455 dump_format(ic, 0, is->filename, 0); 2456 } 2457 2458 /* open the streams */ 2459 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) { 2460 stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]); 2461 } 2462 2463 ret=-1; 2464 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) { 2465 ret= stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]); 2466 } 2467 is->refresh_tid = SDL_CreateThread(refresh_thread, is); 2468 if(ret<0) { 2469 if (!display_disable) 2470 is->show_audio = 2; 2471 } 2472 2473 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) { 2474 stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]); 2475 } 2476 2477 if (is->video_stream < 0 && is->audio_stream < 0) { 2478 fprintf(stderr, "%s: could not open codecs\n", is->filename); 2479 ret = -1; 2480 goto fail; 2481 } 2482 2483 for(;;) { 2484 if (is->abort_request) 2485 break; 2486 if (is->paused != is->last_paused) { 2487 is->last_paused = is->paused; 2488 if (is->paused) 2489 is->read_pause_return= av_read_pause(ic); 2490 else 2491 av_read_play(ic); 2492 } 2493#if CONFIG_RTSP_DEMUXER 2494 if (is->paused && !strcmp(ic->iformat->name, "rtsp")) { 2495 /* wait 10 ms to avoid trying to get another packet */ 2496 /* XXX: horrible */ 2497 SDL_Delay(10); 2498 continue; 2499 } 2500#endif 2501 if (is->seek_req) { 2502 int64_t seek_target= is->seek_pos; 2503 int64_t seek_min= is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN; 2504 int64_t seek_max= is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX; 2505//FIXME the +-2 is due to rounding being not done in the correct direction in generation 2506// of the seek_pos/seek_rel variables 2507 2508 ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags); 2509 if (ret < 0) { 2510 fprintf(stderr, "%s: error while seeking\n", is->ic->filename); 2511 }else{ 2512 if (is->audio_stream >= 0) { 2513 packet_queue_flush(&is->audioq); 2514 packet_queue_put(&is->audioq, &flush_pkt); 2515 } 2516 if (is->subtitle_stream >= 0) { 2517 packet_queue_flush(&is->subtitleq); 2518 packet_queue_put(&is->subtitleq, &flush_pkt); 2519 } 2520 if (is->video_stream >= 0) { 2521 packet_queue_flush(&is->videoq); 2522 packet_queue_put(&is->videoq, &flush_pkt); 2523 } 2524 } 2525 is->seek_req = 0; 2526 eof= 0; 2527 } 2528 2529 /* if the queue are full, no need to read more */ 2530 if ( is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE 2531 || ( (is->audioq .size > MIN_AUDIOQ_SIZE || is->audio_stream<0) 2532 && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream<0) 2533 && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream<0))) { 2534 /* wait 10 ms */ 2535 SDL_Delay(10); 2536 continue; 2537 } 2538 if(url_feof(ic->pb) || eof) { 2539 if(is->video_stream >= 0){ 2540 av_init_packet(pkt); 2541 pkt->data=NULL; 2542 pkt->size=0; 2543 pkt->stream_index= is->video_stream; 2544 packet_queue_put(&is->videoq, pkt); 2545 } 2546 SDL_Delay(10); 2547 if(is->audioq.size + is->videoq.size + is->subtitleq.size ==0){ 2548 if(loop!=1 && (!loop || --loop)){ 2549 stream_seek(cur_stream, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0); 2550 }else if(autoexit){ 2551 ret=AVERROR_EOF; 2552 goto fail; 2553 } 2554 } 2555 continue; 2556 } 2557 ret = av_read_frame(ic, pkt); 2558 if (ret < 0) { 2559 if (ret == AVERROR_EOF) 2560 eof=1; 2561 if (url_ferror(ic->pb)) 2562 break; 2563 SDL_Delay(100); /* wait for user event */ 2564 continue; 2565 } 2566 /* check if packet is in play range specified by user, then queue, otherwise discard */ 2567 pkt_in_play_range = duration == AV_NOPTS_VALUE || 2568 (pkt->pts - ic->streams[pkt->stream_index]->start_time) * 2569 av_q2d(ic->streams[pkt->stream_index]->time_base) - 2570 (double)(start_time != AV_NOPTS_VALUE ? start_time : 0)/1000000 2571 <= ((double)duration/1000000); 2572 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) { 2573 packet_queue_put(&is->audioq, pkt); 2574 } else if (pkt->stream_index == is->video_stream && pkt_in_play_range) { 2575 packet_queue_put(&is->videoq, pkt); 2576 } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) { 2577 packet_queue_put(&is->subtitleq, pkt); 2578 } else { 2579 av_free_packet(pkt); 2580 } 2581 } 2582 /* wait until the end */ 2583 while (!is->abort_request) { 2584 SDL_Delay(100); 2585 } 2586 2587 ret = 0; 2588 fail: 2589 /* disable interrupting */ 2590 global_video_state = NULL; 2591 2592 /* close each stream */ 2593 if (is->audio_stream >= 0) 2594 stream_component_close(is, is->audio_stream); 2595 if (is->video_stream >= 0) 2596 stream_component_close(is, is->video_stream); 2597 if (is->subtitle_stream >= 0) 2598 stream_component_close(is, is->subtitle_stream); 2599 if (is->ic) { 2600 av_close_input_file(is->ic); 2601 is->ic = NULL; /* safety */ 2602 } 2603 url_set_interrupt_cb(NULL); 2604 2605 if (ret != 0) { 2606 SDL_Event event; 2607 2608 event.type = FF_QUIT_EVENT; 2609 event.user.data1 = is; 2610 SDL_PushEvent(&event); 2611 } 2612 return 0; 2613} 2614 2615static VideoState *stream_open(const char *filename, AVInputFormat *iformat) 2616{ 2617 VideoState *is; 2618 2619 is = av_mallocz(sizeof(VideoState)); 2620 if (!is) 2621 return NULL; 2622 av_strlcpy(is->filename, filename, sizeof(is->filename)); 2623 is->iformat = iformat; 2624 is->ytop = 0; 2625 is->xleft = 0; 2626 2627 /* start video display */ 2628 is->pictq_mutex = SDL_CreateMutex(); 2629 is->pictq_cond = SDL_CreateCond(); 2630 2631 is->subpq_mutex = SDL_CreateMutex(); 2632 is->subpq_cond = SDL_CreateCond(); 2633 2634 is->av_sync_type = av_sync_type; 2635 is->parse_tid = SDL_CreateThread(decode_thread, is); 2636 if (!is->parse_tid) { 2637 av_free(is); 2638 return NULL; 2639 } 2640 return is; 2641} 2642 2643static void stream_close(VideoState *is) 2644{ 2645 VideoPicture *vp; 2646 int i; 2647 /* XXX: use a special url_shutdown call to abort parse cleanly */ 2648 is->abort_request = 1; 2649 SDL_WaitThread(is->parse_tid, NULL); 2650 SDL_WaitThread(is->refresh_tid, NULL); 2651 2652 /* free all pictures */ 2653 for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) { 2654 vp = &is->pictq[i]; 2655#if CONFIG_AVFILTER 2656 if (vp->picref) { 2657 avfilter_unref_pic(vp->picref); 2658 vp->picref = NULL; 2659 } 2660#endif 2661 if (vp->bmp) { 2662 SDL_FreeYUVOverlay(vp->bmp); 2663 vp->bmp = NULL; 2664 } 2665 } 2666 SDL_DestroyMutex(is->pictq_mutex); 2667 SDL_DestroyCond(is->pictq_cond); 2668 SDL_DestroyMutex(is->subpq_mutex); 2669 SDL_DestroyCond(is->subpq_cond); 2670#if !CONFIG_AVFILTER 2671 if (is->img_convert_ctx) 2672 sws_freeContext(is->img_convert_ctx); 2673#endif 2674 av_free(is); 2675} 2676 2677static void stream_cycle_channel(VideoState *is, int codec_type) 2678{ 2679 AVFormatContext *ic = is->ic; 2680 int start_index, stream_index; 2681 AVStream *st; 2682 2683 if (codec_type == AVMEDIA_TYPE_VIDEO) 2684 start_index = is->video_stream; 2685 else if (codec_type == AVMEDIA_TYPE_AUDIO) 2686 start_index = is->audio_stream; 2687 else 2688 start_index = is->subtitle_stream; 2689 if (start_index < (codec_type == AVMEDIA_TYPE_SUBTITLE ? -1 : 0)) 2690 return; 2691 stream_index = start_index; 2692 for(;;) { 2693 if (++stream_index >= is->ic->nb_streams) 2694 { 2695 if (codec_type == AVMEDIA_TYPE_SUBTITLE) 2696 { 2697 stream_index = -1; 2698 goto the_end; 2699 } else 2700 stream_index = 0; 2701 } 2702 if (stream_index == start_index) 2703 return; 2704 st = ic->streams[stream_index]; 2705 if (st->codec->codec_type == codec_type) { 2706 /* check that parameters are OK */ 2707 switch(codec_type) { 2708 case AVMEDIA_TYPE_AUDIO: 2709 if (st->codec->sample_rate != 0 && 2710 st->codec->channels != 0) 2711 goto the_end; 2712 break; 2713 case AVMEDIA_TYPE_VIDEO: 2714 case AVMEDIA_TYPE_SUBTITLE: 2715 goto the_end; 2716 default: 2717 break; 2718 } 2719 } 2720 } 2721 the_end: 2722 stream_component_close(is, start_index); 2723 stream_component_open(is, stream_index); 2724} 2725 2726 2727static void toggle_full_screen(void) 2728{ 2729 is_full_screen = !is_full_screen; 2730 if (!fs_screen_width) { 2731 /* use default SDL method */ 2732// SDL_WM_ToggleFullScreen(screen); 2733 } 2734 video_open(cur_stream); 2735} 2736 2737static void toggle_pause(void) 2738{ 2739 if (cur_stream) 2740 stream_pause(cur_stream); 2741 step = 0; 2742} 2743 2744static void step_to_next_frame(void) 2745{ 2746 if (cur_stream) { 2747 /* if the stream is paused unpause it, then step */ 2748 if (cur_stream->paused) 2749 stream_pause(cur_stream); 2750 } 2751 step = 1; 2752} 2753 2754static void do_exit(void) 2755{ 2756 int i; 2757 if (cur_stream) { 2758 stream_close(cur_stream); 2759 cur_stream = NULL; 2760 } 2761 for (i = 0; i < AVMEDIA_TYPE_NB; i++) 2762 av_free(avcodec_opts[i]); 2763 av_free(avformat_opts); 2764 av_free(sws_opts); 2765#if CONFIG_AVFILTER 2766 avfilter_uninit(); 2767#endif 2768 if (show_status) 2769 printf("\n"); 2770 SDL_Quit(); 2771 exit(0); 2772} 2773 2774static void toggle_audio_display(void) 2775{ 2776 if (cur_stream) { 2777 int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00); 2778 cur_stream->show_audio = (cur_stream->show_audio + 1) % 3; 2779 fill_rectangle(screen, 2780 cur_stream->xleft, cur_stream->ytop, cur_stream->width, cur_stream->height, 2781 bgcolor); 2782 SDL_UpdateRect(screen, cur_stream->xleft, cur_stream->ytop, cur_stream->width, cur_stream->height); 2783 } 2784} 2785 2786/* handle an event sent by the GUI */ 2787static void event_loop(void) 2788{ 2789 SDL_Event event; 2790 double incr, pos, frac; 2791 2792 for(;;) { 2793 double x; 2794 SDL_WaitEvent(&event); 2795 switch(event.type) { 2796 case SDL_KEYDOWN: 2797 switch(event.key.keysym.sym) { 2798 case SDLK_ESCAPE: 2799 case SDLK_q: 2800 do_exit(); 2801 break; 2802 case SDLK_f: 2803 toggle_full_screen(); 2804 break; 2805 case SDLK_p: 2806 case SDLK_SPACE: 2807 toggle_pause(); 2808 break; 2809 case SDLK_s: //S: Step to next frame 2810 step_to_next_frame(); 2811 break; 2812 case SDLK_a: 2813 if (cur_stream) 2814 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO); 2815 break; 2816 case SDLK_v: 2817 if (cur_stream) 2818 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO); 2819 break; 2820 case SDLK_t: 2821 if (cur_stream) 2822 stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE); 2823 break; 2824 case SDLK_w: 2825 toggle_audio_display(); 2826 break; 2827 case SDLK_LEFT: 2828 incr = -10.0; 2829 goto do_seek; 2830 case SDLK_RIGHT: 2831 incr = 10.0; 2832 goto do_seek; 2833 case SDLK_UP: 2834 incr = 60.0; 2835 goto do_seek; 2836 case SDLK_DOWN: 2837 incr = -60.0; 2838 do_seek: 2839 if (cur_stream) { 2840 if (seek_by_bytes) { 2841 if (cur_stream->video_stream >= 0 && cur_stream->video_current_pos>=0){ 2842 pos= cur_stream->video_current_pos; 2843 }else if(cur_stream->audio_stream >= 0 && cur_stream->audio_pkt.pos>=0){ 2844 pos= cur_stream->audio_pkt.pos; 2845 }else 2846 pos = url_ftell(cur_stream->ic->pb); 2847 if (cur_stream->ic->bit_rate) 2848 incr *= cur_stream->ic->bit_rate / 8.0; 2849 else 2850 incr *= 180000.0; 2851 pos += incr; 2852 stream_seek(cur_stream, pos, incr, 1); 2853 } else { 2854 pos = get_master_clock(cur_stream); 2855 pos += incr; 2856 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0); 2857 } 2858 } 2859 break; 2860 default: 2861 break; 2862 } 2863 break; 2864 case SDL_MOUSEBUTTONDOWN: 2865 case SDL_MOUSEMOTION: 2866 if(event.type ==SDL_MOUSEBUTTONDOWN){ 2867 x= event.button.x; 2868 }else{ 2869 if(event.motion.state != SDL_PRESSED) 2870 break; 2871 x= event.motion.x; 2872 } 2873 if (cur_stream) { 2874 if(seek_by_bytes || cur_stream->ic->duration<=0){ 2875 uint64_t size= url_fsize(cur_stream->ic->pb); 2876 stream_seek(cur_stream, size*x/cur_stream->width, 0, 1); 2877 }else{ 2878 int64_t ts; 2879 int ns, hh, mm, ss; 2880 int tns, thh, tmm, tss; 2881 tns = cur_stream->ic->duration/1000000LL; 2882 thh = tns/3600; 2883 tmm = (tns%3600)/60; 2884 tss = (tns%60); 2885 frac = x/cur_stream->width; 2886 ns = frac*tns; 2887 hh = ns/3600; 2888 mm = (ns%3600)/60; 2889 ss = (ns%60); 2890 fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100, 2891 hh, mm, ss, thh, tmm, tss); 2892 ts = frac*cur_stream->ic->duration; 2893 if (cur_stream->ic->start_time != AV_NOPTS_VALUE) 2894 ts += cur_stream->ic->start_time; 2895 stream_seek(cur_stream, ts, 0, 0); 2896 } 2897 } 2898 break; 2899 case SDL_VIDEORESIZE: 2900 if (cur_stream) { 2901 screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0, 2902 SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL); 2903 screen_width = cur_stream->width = event.resize.w; 2904 screen_height= cur_stream->height= event.resize.h; 2905 } 2906 break; 2907 case SDL_QUIT: 2908 case FF_QUIT_EVENT: 2909 do_exit(); 2910 break; 2911 case FF_ALLOC_EVENT: 2912 video_open(event.user.data1); 2913 alloc_picture(event.user.data1); 2914 break; 2915 case FF_REFRESH_EVENT: 2916 video_refresh_timer(event.user.data1); 2917 cur_stream->refresh=0; 2918 break; 2919 default: 2920 break; 2921 } 2922 } 2923} 2924 2925static void opt_frame_size(const char *arg) 2926{ 2927 if (av_parse_video_frame_size(&frame_width, &frame_height, arg) < 0) { 2928 fprintf(stderr, "Incorrect frame size\n"); 2929 exit(1); 2930 } 2931 if ((frame_width % 2) != 0 || (frame_height % 2) != 0) { 2932 fprintf(stderr, "Frame size must be a multiple of 2\n"); 2933 exit(1); 2934 } 2935} 2936 2937static int opt_width(const char *opt, const char *arg) 2938{ 2939 screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX); 2940 return 0; 2941} 2942 2943static int opt_height(const char *opt, const char *arg) 2944{ 2945 screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX); 2946 return 0; 2947} 2948 2949static void opt_format(const char *arg) 2950{ 2951 file_iformat = av_find_input_format(arg); 2952 if (!file_iformat) { 2953 fprintf(stderr, "Unknown input format: %s\n", arg); 2954 exit(1); 2955 } 2956} 2957 2958static void opt_frame_pix_fmt(const char *arg) 2959{ 2960 frame_pix_fmt = av_get_pix_fmt(arg); 2961} 2962 2963static int opt_sync(const char *opt, const char *arg) 2964{ 2965 if (!strcmp(arg, "audio")) 2966 av_sync_type = AV_SYNC_AUDIO_MASTER; 2967 else if (!strcmp(arg, "video")) 2968 av_sync_type = AV_SYNC_VIDEO_MASTER; 2969 else if (!strcmp(arg, "ext")) 2970 av_sync_type = AV_SYNC_EXTERNAL_CLOCK; 2971 else { 2972 fprintf(stderr, "Unknown value for %s: %s\n", opt, arg); 2973 exit(1); 2974 } 2975 return 0; 2976} 2977 2978static int opt_seek(const char *opt, const char *arg) 2979{ 2980 start_time = parse_time_or_die(opt, arg, 1); 2981 return 0; 2982} 2983 2984static int opt_duration(const char *opt, const char *arg) 2985{ 2986 duration = parse_time_or_die(opt, arg, 1); 2987 return 0; 2988} 2989 2990static int opt_debug(const char *opt, const char *arg) 2991{ 2992 av_log_set_level(99); 2993 debug = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX); 2994 return 0; 2995} 2996 2997static int opt_vismv(const char *opt, const char *arg) 2998{ 2999 debug_mv = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX); 3000 return 0; 3001} 3002 3003static int opt_thread_count(const char *opt, const char *arg) 3004{ 3005 thread_count= parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX); 3006#if !HAVE_THREADS 3007 fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n"); 3008#endif 3009 return 0; 3010} 3011 3012static const OptionDef options[] = { 3013#include "cmdutils_common_opts.h" 3014 { "x", HAS_ARG | OPT_FUNC2, {(void*)opt_width}, "force displayed width", "width" }, 3015 { "y", HAS_ARG | OPT_FUNC2, {(void*)opt_height}, "force displayed height", "height" }, 3016 { "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" }, 3017 { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" }, 3018 { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" }, 3019 { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" }, 3020 { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_stream[AVMEDIA_TYPE_AUDIO]}, "select desired audio stream", "stream_number" }, 3021 { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_stream[AVMEDIA_TYPE_VIDEO]}, "select desired video stream", "stream_number" }, 3022 { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_stream[AVMEDIA_TYPE_SUBTITLE]}, "select desired subtitle stream", "stream_number" }, 3023 { "ss", HAS_ARG | OPT_FUNC2, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" }, 3024 { "t", HAS_ARG | OPT_FUNC2, {(void*)&opt_duration}, "play \"duration\" seconds of audio/video", "duration" }, 3025 { "bytes", OPT_INT | HAS_ARG, {(void*)&seek_by_bytes}, "seek by bytes 0=off 1=on -1=auto", "val" }, 3026 { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" }, 3027 { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" }, 3028 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_frame_pix_fmt}, "set pixel format", "format" }, 3029 { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" }, 3030 { "debug", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" }, 3031 { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" }, 3032 { "vismv", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" }, 3033 { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" }, 3034 { "genpts", OPT_BOOL | OPT_EXPERT, {(void*)&genpts}, "generate pts", "" }, 3035 { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&decoder_reorder_pts}, "let decoder reorder pts 0=off 1=on -1=auto", ""}, 3036 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" }, 3037 { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" }, 3038 { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" }, 3039 { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" }, 3040 { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo", "algo" }, 3041 { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_recognition}, "set error detection threshold (0-4)", "threshold" }, 3042 { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options", "bit_mask" }, 3043 { "sync", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" }, 3044 { "threads", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" }, 3045 { "autoexit", OPT_BOOL | OPT_EXPERT, {(void*)&autoexit}, "exit at the end", "" }, 3046 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&loop}, "set number of times the playback shall be looped", "loop count" }, 3047 { "framedrop", OPT_BOOL | OPT_EXPERT, {(void*)&framedrop}, "drop frames when cpu is too slow", "" }, 3048 { "window_title", OPT_STRING | HAS_ARG, {(void*)&window_title}, "set window title", "window title" }, 3049#if CONFIG_AVFILTER 3050 { "vfilters", OPT_STRING | HAS_ARG, {(void*)&vfilters}, "video filters", "filter list" }, 3051#endif 3052 { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, {(void*)&rdftspeed}, "rdft speed", "msecs" }, 3053 { "default", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" }, 3054 { NULL, }, 3055}; 3056 3057static void show_usage(void) 3058{ 3059 printf("Simple media player\n"); 3060 printf("usage: ffplay [options] input_file\n"); 3061 printf("\n"); 3062} 3063 3064static void show_help(void) 3065{ 3066 show_usage(); 3067 show_help_options(options, "Main options:\n", 3068 OPT_EXPERT, 0); 3069 show_help_options(options, "\nAdvanced options:\n", 3070 OPT_EXPERT, OPT_EXPERT); 3071 printf("\nWhile playing:\n" 3072 "q, ESC quit\n" 3073 "f toggle full screen\n" 3074 "p, SPC pause\n" 3075 "a cycle audio channel\n" 3076 "v cycle video channel\n" 3077 "t cycle subtitle channel\n" 3078 "w show audio waves\n" 3079 "s activate frame-step mode\n" 3080 "left/right seek backward/forward 10 seconds\n" 3081 "down/up seek backward/forward 1 minute\n" 3082 "mouse click seek to percentage in file corresponding to fraction of width\n" 3083 ); 3084} 3085 3086static void opt_input_file(const char *filename) 3087{ 3088 if (input_filename) { 3089 fprintf(stderr, "Argument '%s' provided as input filename, but '%s' was already specified.\n", 3090 filename, input_filename); 3091 exit(1); 3092 } 3093 if (!strcmp(filename, "-")) 3094 filename = "pipe:"; 3095 input_filename = filename; 3096} 3097 3098/* Called from the main */ 3099int main(int argc, char **argv) 3100{ 3101 int flags, i; 3102 3103 /* register all codecs, demux and protocols */ 3104 avcodec_register_all(); 3105#if CONFIG_AVDEVICE 3106 avdevice_register_all(); 3107#endif 3108#if CONFIG_AVFILTER 3109 avfilter_register_all(); 3110#endif 3111 av_register_all(); 3112 3113 for(i=0; i<AVMEDIA_TYPE_NB; i++){ 3114 avcodec_opts[i]= avcodec_alloc_context2(i); 3115 } 3116 avformat_opts = avformat_alloc_context(); 3117#if !CONFIG_AVFILTER 3118 sws_opts = sws_getContext(16,16,0, 16,16,0, sws_flags, NULL,NULL,NULL); 3119#endif 3120 3121 show_banner(); 3122 3123 parse_options(argc, argv, options, opt_input_file); 3124 3125 if (!input_filename) { 3126 show_usage(); 3127 fprintf(stderr, "An input file must be specified\n"); 3128 fprintf(stderr, "Use -h to get full help or, even better, run 'man ffplay'\n"); 3129 exit(1); 3130 } 3131 3132 if (display_disable) { 3133 video_disable = 1; 3134 } 3135 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER; 3136#if !defined(__MINGW32__) && !defined(__APPLE__) 3137 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */ 3138#endif 3139 if (SDL_Init (flags)) { 3140 fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError()); 3141 exit(1); 3142 } 3143 3144 if (!display_disable) { 3145#if HAVE_SDL_VIDEO_SIZE 3146 const SDL_VideoInfo *vi = SDL_GetVideoInfo(); 3147 fs_screen_width = vi->current_w; 3148 fs_screen_height = vi->current_h; 3149#endif 3150 } 3151 3152 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE); 3153 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE); 3154 SDL_EventState(SDL_USEREVENT, SDL_IGNORE); 3155 3156 av_init_packet(&flush_pkt); 3157 flush_pkt.data= "FLUSH"; 3158 3159 cur_stream = stream_open(input_filename, file_iformat); 3160 3161 event_loop(); 3162 3163 /* never returns */ 3164 3165 return 0; 3166} 3167