ffplay.c 74 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489
  1. /*
  2. * FFplay : Simple Media Player based on the ffmpeg libraries
  3. * Copyright (c) 2003 Fabrice Bellard
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  18. */
  19. #define HAVE_AV_CONFIG_H
  20. #include "avformat.h"
  21. #include "cmdutils.h"
  22. #include <SDL.h>
  23. #include <SDL_thread.h>
  24. #ifdef CONFIG_WIN32
  25. #undef main /* We don't want SDL to override our main() */
  26. #endif
  27. #ifdef CONFIG_OS2
  28. #define INCL_DOS
  29. #include <os2.h>
  30. #include <stdio.h>
  31. void MorphToPM()
  32. {
  33. PPIB pib;
  34. PTIB tib;
  35. DosGetInfoBlocks(&tib, &pib);
  36. // Change flag from VIO to PM:
  37. if (pib->pib_ultype==2) pib->pib_ultype = 3;
  38. }
  39. #endif
  40. #if defined(__linux__)
  41. #define HAVE_X11
  42. #endif
  43. #ifdef HAVE_X11
  44. #include <X11/Xlib.h>
  45. #endif
  46. //#define DEBUG_SYNC
  47. #define MAX_VIDEOQ_SIZE (5 * 256 * 1024)
  48. #define MAX_AUDIOQ_SIZE (5 * 16 * 1024)
  49. #define MAX_SUBTITLEQ_SIZE (5 * 16 * 1024)
  50. /* SDL audio buffer size, in samples. Should be small to have precise
  51. A/V sync as SDL does not have hardware buffer fullness info. */
  52. #define SDL_AUDIO_BUFFER_SIZE 1024
  53. /* no AV sync correction is done if below the AV sync threshold */
  54. #define AV_SYNC_THRESHOLD 0.01
  55. /* no AV correction is done if too big error */
  56. #define AV_NOSYNC_THRESHOLD 10.0
  57. /* maximum audio speed change to get correct sync */
  58. #define SAMPLE_CORRECTION_PERCENT_MAX 10
  59. /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
  60. #define AUDIO_DIFF_AVG_NB 20
  61. /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
  62. #define SAMPLE_ARRAY_SIZE (2*65536)
  63. typedef struct PacketQueue {
  64. AVPacketList *first_pkt, *last_pkt;
  65. int nb_packets;
  66. int size;
  67. int abort_request;
  68. SDL_mutex *mutex;
  69. SDL_cond *cond;
  70. } PacketQueue;
  71. #define VIDEO_PICTURE_QUEUE_SIZE 1
  72. #define SUBPICTURE_QUEUE_SIZE 4
  73. typedef struct VideoPicture {
  74. double pts; ///<presentation time stamp for this picture
  75. SDL_Overlay *bmp;
  76. int width, height; /* source height & width */
  77. int allocated;
  78. } VideoPicture;
  79. typedef struct SubPicture {
  80. double pts; /* presentation time stamp for this picture */
  81. AVSubtitle sub;
  82. } SubPicture;
  83. enum {
  84. AV_SYNC_AUDIO_MASTER, /* default choice */
  85. AV_SYNC_VIDEO_MASTER,
  86. AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
  87. };
  88. typedef struct VideoState {
  89. SDL_Thread *parse_tid;
  90. SDL_Thread *video_tid;
  91. AVInputFormat *iformat;
  92. int no_background;
  93. int abort_request;
  94. int paused;
  95. int last_paused;
  96. int seek_req;
  97. int seek_flags;
  98. int64_t seek_pos;
  99. AVFormatContext *ic;
  100. int dtg_active_format;
  101. int audio_stream;
  102. int av_sync_type;
  103. double external_clock; /* external clock base */
  104. int64_t external_clock_time;
  105. double audio_clock;
  106. double audio_diff_cum; /* used for AV difference average computation */
  107. double audio_diff_avg_coef;
  108. double audio_diff_threshold;
  109. int audio_diff_avg_count;
  110. AVStream *audio_st;
  111. PacketQueue audioq;
  112. int audio_hw_buf_size;
  113. /* samples output by the codec. we reserve more space for avsync
  114. compensation */
  115. uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
  116. unsigned int audio_buf_size; /* in bytes */
  117. int audio_buf_index; /* in bytes */
  118. AVPacket audio_pkt;
  119. uint8_t *audio_pkt_data;
  120. int audio_pkt_size;
  121. int show_audio; /* if true, display audio samples */
  122. int16_t sample_array[SAMPLE_ARRAY_SIZE];
  123. int sample_array_index;
  124. int last_i_start;
  125. SDL_Thread *subtitle_tid;
  126. int subtitle_stream;
  127. int subtitle_stream_changed;
  128. AVStream *subtitle_st;
  129. PacketQueue subtitleq;
  130. SubPicture subpq[SUBPICTURE_QUEUE_SIZE];
  131. int subpq_size, subpq_rindex, subpq_windex;
  132. SDL_mutex *subpq_mutex;
  133. SDL_cond *subpq_cond;
  134. double frame_timer;
  135. double frame_last_pts;
  136. double frame_last_delay;
  137. double video_clock; ///<pts of last decoded frame / predicted pts of next decoded frame
  138. int video_stream;
  139. AVStream *video_st;
  140. PacketQueue videoq;
  141. double video_current_pts; ///<current displayed pts (different from video_clock if frame fifos are used)
  142. int64_t video_current_pts_time; ///<time (av_gettime) at which we updated video_current_pts - used to have running video pts
  143. VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];
  144. int pictq_size, pictq_rindex, pictq_windex;
  145. SDL_mutex *pictq_mutex;
  146. SDL_cond *pictq_cond;
  147. SDL_mutex *video_decoder_mutex;
  148. SDL_mutex *audio_decoder_mutex;
  149. SDL_mutex *subtitle_decoder_mutex;
  150. // QETimer *video_timer;
  151. char filename[1024];
  152. int width, height, xleft, ytop;
  153. } VideoState;
  154. void show_help(void);
  155. static int audio_write_get_buf_size(VideoState *is);
  156. /* options specified by the user */
  157. static AVInputFormat *file_iformat;
  158. static AVImageFormat *image_format;
  159. static const char *input_filename;
  160. static int fs_screen_width;
  161. static int fs_screen_height;
  162. static int screen_width = 640;
  163. static int screen_height = 480;
  164. static int audio_disable;
  165. static int video_disable;
  166. static int display_disable;
  167. static int show_status;
  168. static int av_sync_type = AV_SYNC_AUDIO_MASTER;
  169. static int64_t start_time = AV_NOPTS_VALUE;
  170. static int debug = 0;
  171. static int debug_mv = 0;
  172. static int step = 0;
  173. static int thread_count = 1;
  174. static int workaround_bugs = 1;
  175. static int fast = 0;
  176. static int genpts = 0;
  177. static int lowres = 0;
  178. static int idct = FF_IDCT_AUTO;
  179. static enum AVDiscard skip_frame= AVDISCARD_DEFAULT;
  180. static enum AVDiscard skip_idct= AVDISCARD_DEFAULT;
  181. static enum AVDiscard skip_loop_filter= AVDISCARD_DEFAULT;
  182. static int error_resilience = FF_ER_CAREFUL;
  183. static int error_concealment = 3;
  184. /* current context */
  185. static int is_full_screen;
  186. static VideoState *cur_stream;
  187. static int64_t audio_callback_time;
  188. #define FF_ALLOC_EVENT (SDL_USEREVENT)
  189. #define FF_REFRESH_EVENT (SDL_USEREVENT + 1)
  190. #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
  191. SDL_Surface *screen;
  192. /* packet queue handling */
  193. static void packet_queue_init(PacketQueue *q)
  194. {
  195. memset(q, 0, sizeof(PacketQueue));
  196. q->mutex = SDL_CreateMutex();
  197. q->cond = SDL_CreateCond();
  198. }
  199. static void packet_queue_flush(PacketQueue *q)
  200. {
  201. AVPacketList *pkt, *pkt1;
  202. SDL_LockMutex(q->mutex);
  203. for(pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
  204. pkt1 = pkt->next;
  205. av_free_packet(&pkt->pkt);
  206. av_freep(&pkt);
  207. }
  208. q->last_pkt = NULL;
  209. q->first_pkt = NULL;
  210. q->nb_packets = 0;
  211. q->size = 0;
  212. SDL_UnlockMutex(q->mutex);
  213. }
  214. static void packet_queue_end(PacketQueue *q)
  215. {
  216. packet_queue_flush(q);
  217. SDL_DestroyMutex(q->mutex);
  218. SDL_DestroyCond(q->cond);
  219. }
  220. static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
  221. {
  222. AVPacketList *pkt1;
  223. /* duplicate the packet */
  224. if (av_dup_packet(pkt) < 0)
  225. return -1;
  226. pkt1 = av_malloc(sizeof(AVPacketList));
  227. if (!pkt1)
  228. return -1;
  229. pkt1->pkt = *pkt;
  230. pkt1->next = NULL;
  231. SDL_LockMutex(q->mutex);
  232. if (!q->last_pkt)
  233. q->first_pkt = pkt1;
  234. else
  235. q->last_pkt->next = pkt1;
  236. q->last_pkt = pkt1;
  237. q->nb_packets++;
  238. q->size += pkt1->pkt.size;
  239. /* XXX: should duplicate packet data in DV case */
  240. SDL_CondSignal(q->cond);
  241. SDL_UnlockMutex(q->mutex);
  242. return 0;
  243. }
  244. static void packet_queue_abort(PacketQueue *q)
  245. {
  246. SDL_LockMutex(q->mutex);
  247. q->abort_request = 1;
  248. SDL_CondSignal(q->cond);
  249. SDL_UnlockMutex(q->mutex);
  250. }
  251. /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
  252. static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
  253. {
  254. AVPacketList *pkt1;
  255. int ret;
  256. SDL_LockMutex(q->mutex);
  257. for(;;) {
  258. if (q->abort_request) {
  259. ret = -1;
  260. break;
  261. }
  262. pkt1 = q->first_pkt;
  263. if (pkt1) {
  264. q->first_pkt = pkt1->next;
  265. if (!q->first_pkt)
  266. q->last_pkt = NULL;
  267. q->nb_packets--;
  268. q->size -= pkt1->pkt.size;
  269. *pkt = pkt1->pkt;
  270. av_free(pkt1);
  271. ret = 1;
  272. break;
  273. } else if (!block) {
  274. ret = 0;
  275. break;
  276. } else {
  277. SDL_CondWait(q->cond, q->mutex);
  278. }
  279. }
  280. SDL_UnlockMutex(q->mutex);
  281. return ret;
  282. }
  283. static inline void fill_rectangle(SDL_Surface *screen,
  284. int x, int y, int w, int h, int color)
  285. {
  286. SDL_Rect rect;
  287. rect.x = x;
  288. rect.y = y;
  289. rect.w = w;
  290. rect.h = h;
  291. SDL_FillRect(screen, &rect, color);
  292. }
  293. #if 0
  294. /* draw only the border of a rectangle */
  295. void fill_border(VideoState *s, int x, int y, int w, int h, int color)
  296. {
  297. int w1, w2, h1, h2;
  298. /* fill the background */
  299. w1 = x;
  300. if (w1 < 0)
  301. w1 = 0;
  302. w2 = s->width - (x + w);
  303. if (w2 < 0)
  304. w2 = 0;
  305. h1 = y;
  306. if (h1 < 0)
  307. h1 = 0;
  308. h2 = s->height - (y + h);
  309. if (h2 < 0)
  310. h2 = 0;
  311. fill_rectangle(screen,
  312. s->xleft, s->ytop,
  313. w1, s->height,
  314. color);
  315. fill_rectangle(screen,
  316. s->xleft + s->width - w2, s->ytop,
  317. w2, s->height,
  318. color);
  319. fill_rectangle(screen,
  320. s->xleft + w1, s->ytop,
  321. s->width - w1 - w2, h1,
  322. color);
  323. fill_rectangle(screen,
  324. s->xleft + w1, s->ytop + s->height - h2,
  325. s->width - w1 - w2, h2,
  326. color);
  327. }
  328. #endif
  329. #define SCALEBITS 10
  330. #define ONE_HALF (1 << (SCALEBITS - 1))
  331. #define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5))
  332. #define RGB_TO_Y_CCIR(r, g, b) \
  333. ((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \
  334. FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
  335. #define RGB_TO_U_CCIR(r1, g1, b1, shift)\
  336. (((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 + \
  337. FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
  338. #define RGB_TO_V_CCIR(r1, g1, b1, shift)\
  339. (((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 - \
  340. FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
  341. #define ALPHA_BLEND(a, oldp, newp, s)\
  342. ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
  343. #define RGBA_IN(r, g, b, a, s)\
  344. {\
  345. unsigned int v = ((const uint32_t *)(s))[0];\
  346. a = (v >> 24) & 0xff;\
  347. r = (v >> 16) & 0xff;\
  348. g = (v >> 8) & 0xff;\
  349. b = v & 0xff;\
  350. }
  351. #define YUVA_IN(y, u, v, a, s, pal)\
  352. {\
  353. unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)s];\
  354. a = (val >> 24) & 0xff;\
  355. y = (val >> 16) & 0xff;\
  356. u = (val >> 8) & 0xff;\
  357. v = val & 0xff;\
  358. }
  359. #define YUVA_OUT(d, y, u, v, a)\
  360. {\
  361. ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
  362. }
  363. #define BPP 1
  364. static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect)
  365. {
  366. int wrap, wrap3, width2, skip2;
  367. int y, u, v, a, u1, v1, a1, w, h;
  368. uint8_t *lum, *cb, *cr;
  369. const uint8_t *p;
  370. const uint32_t *pal;
  371. lum = dst->data[0] + rect->y * dst->linesize[0];
  372. cb = dst->data[1] + (rect->y >> 1) * dst->linesize[1];
  373. cr = dst->data[2] + (rect->y >> 1) * dst->linesize[2];
  374. width2 = (rect->w + 1) >> 1;
  375. skip2 = rect->x >> 1;
  376. wrap = dst->linesize[0];
  377. wrap3 = rect->linesize;
  378. p = rect->bitmap;
  379. pal = rect->rgba_palette; /* Now in YCrCb! */
  380. if (rect->y & 1) {
  381. lum += rect->x;
  382. cb += skip2;
  383. cr += skip2;
  384. if (rect->x & 1) {
  385. YUVA_IN(y, u, v, a, p, pal);
  386. lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
  387. cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
  388. cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
  389. cb++;
  390. cr++;
  391. lum++;
  392. p += BPP;
  393. }
  394. for(w = rect->w - (rect->x & 1); w >= 2; w -= 2) {
  395. YUVA_IN(y, u, v, a, p, pal);
  396. u1 = u;
  397. v1 = v;
  398. a1 = a;
  399. lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
  400. YUVA_IN(y, u, v, a, p + BPP, pal);
  401. u1 += u;
  402. v1 += v;
  403. a1 += a;
  404. lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
  405. cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
  406. cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
  407. cb++;
  408. cr++;
  409. p += 2 * BPP;
  410. lum += 2;
  411. }
  412. if (w) {
  413. YUVA_IN(y, u, v, a, p, pal);
  414. lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
  415. cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
  416. cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
  417. }
  418. p += wrap3 + (wrap3 - rect->w * BPP);
  419. lum += wrap + (wrap - rect->w - rect->x);
  420. cb += dst->linesize[1] - width2 - skip2;
  421. cr += dst->linesize[2] - width2 - skip2;
  422. }
  423. for(h = rect->h - (rect->y & 1); h >= 2; h -= 2) {
  424. lum += rect->x;
  425. cb += skip2;
  426. cr += skip2;
  427. if (rect->x & 1) {
  428. YUVA_IN(y, u, v, a, p, pal);
  429. u1 = u;
  430. v1 = v;
  431. a1 = a;
  432. lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
  433. p += wrap3;
  434. lum += wrap;
  435. YUVA_IN(y, u, v, a, p, pal);
  436. u1 += u;
  437. v1 += v;
  438. a1 += a;
  439. lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
  440. cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
  441. cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
  442. cb++;
  443. cr++;
  444. p += -wrap3 + BPP;
  445. lum += -wrap + 1;
  446. }
  447. for(w = rect->w - (rect->x & 1); w >= 2; w -= 2) {
  448. YUVA_IN(y, u, v, a, p, pal);
  449. u1 = u;
  450. v1 = v;
  451. a1 = a;
  452. lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
  453. YUVA_IN(y, u, v, a, p, pal);
  454. u1 += u;
  455. v1 += v;
  456. a1 += a;
  457. lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
  458. p += wrap3;
  459. lum += wrap;
  460. YUVA_IN(y, u, v, a, p, pal);
  461. u1 += u;
  462. v1 += v;
  463. a1 += a;
  464. lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
  465. YUVA_IN(y, u, v, a, p, pal);
  466. u1 += u;
  467. v1 += v;
  468. a1 += a;
  469. lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
  470. cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
  471. cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
  472. cb++;
  473. cr++;
  474. p += -wrap3 + 2 * BPP;
  475. lum += -wrap + 2;
  476. }
  477. if (w) {
  478. YUVA_IN(y, u, v, a, p, pal);
  479. u1 = u;
  480. v1 = v;
  481. a1 = a;
  482. lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
  483. p += wrap3;
  484. lum += wrap;
  485. YUVA_IN(y, u, v, a, p, pal);
  486. u1 += u;
  487. v1 += v;
  488. a1 += a;
  489. lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
  490. cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
  491. cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
  492. cb++;
  493. cr++;
  494. p += -wrap3 + BPP;
  495. lum += -wrap + 1;
  496. }
  497. p += wrap3 + (wrap3 - rect->w * BPP);
  498. lum += wrap + (wrap - rect->w - rect->x);
  499. cb += dst->linesize[1] - width2 - skip2;
  500. cr += dst->linesize[2] - width2 - skip2;
  501. }
  502. /* handle odd height */
  503. if (h) {
  504. lum += rect->x;
  505. cb += skip2;
  506. cr += skip2;
  507. if (rect->x & 1) {
  508. YUVA_IN(y, u, v, a, p, pal);
  509. lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
  510. cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
  511. cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
  512. cb++;
  513. cr++;
  514. lum++;
  515. p += BPP;
  516. }
  517. for(w = rect->w - (rect->x & 1); w >= 2; w -= 2) {
  518. YUVA_IN(y, u, v, a, p, pal);
  519. u1 = u;
  520. v1 = v;
  521. a1 = a;
  522. lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
  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], u, 1);
  529. cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 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. }
  541. }
  542. }
  543. static void free_subpicture(SubPicture *sp)
  544. {
  545. int i;
  546. for (i = 0; i < sp->sub.num_rects; i++)
  547. {
  548. av_free(sp->sub.rects[i].bitmap);
  549. av_free(sp->sub.rects[i].rgba_palette);
  550. }
  551. av_free(sp->sub.rects);
  552. memset(&sp->sub, 0, sizeof(AVSubtitle));
  553. }
  554. static void video_image_display(VideoState *is)
  555. {
  556. VideoPicture *vp;
  557. SubPicture *sp;
  558. AVPicture pict;
  559. float aspect_ratio;
  560. int width, height, x, y;
  561. SDL_Rect rect;
  562. int i;
  563. vp = &is->pictq[is->pictq_rindex];
  564. if (vp->bmp) {
  565. /* XXX: use variable in the frame */
  566. if (is->video_st->codec->sample_aspect_ratio.num == 0)
  567. aspect_ratio = 0;
  568. else
  569. aspect_ratio = av_q2d(is->video_st->codec->sample_aspect_ratio)
  570. * is->video_st->codec->width / is->video_st->codec->height;;
  571. if (aspect_ratio <= 0.0)
  572. aspect_ratio = (float)is->video_st->codec->width /
  573. (float)is->video_st->codec->height;
  574. /* if an active format is indicated, then it overrides the
  575. mpeg format */
  576. #if 0
  577. if (is->video_st->codec->dtg_active_format != is->dtg_active_format) {
  578. is->dtg_active_format = is->video_st->codec->dtg_active_format;
  579. printf("dtg_active_format=%d\n", is->dtg_active_format);
  580. }
  581. #endif
  582. #if 0
  583. switch(is->video_st->codec->dtg_active_format) {
  584. case FF_DTG_AFD_SAME:
  585. default:
  586. /* nothing to do */
  587. break;
  588. case FF_DTG_AFD_4_3:
  589. aspect_ratio = 4.0 / 3.0;
  590. break;
  591. case FF_DTG_AFD_16_9:
  592. aspect_ratio = 16.0 / 9.0;
  593. break;
  594. case FF_DTG_AFD_14_9:
  595. aspect_ratio = 14.0 / 9.0;
  596. break;
  597. case FF_DTG_AFD_4_3_SP_14_9:
  598. aspect_ratio = 14.0 / 9.0;
  599. break;
  600. case FF_DTG_AFD_16_9_SP_14_9:
  601. aspect_ratio = 14.0 / 9.0;
  602. break;
  603. case FF_DTG_AFD_SP_4_3:
  604. aspect_ratio = 4.0 / 3.0;
  605. break;
  606. }
  607. #endif
  608. if (is->subtitle_st)
  609. {
  610. if (is->subpq_size > 0)
  611. {
  612. sp = &is->subpq[is->subpq_rindex];
  613. if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000))
  614. {
  615. SDL_LockYUVOverlay (vp->bmp);
  616. pict.data[0] = vp->bmp->pixels[0];
  617. pict.data[1] = vp->bmp->pixels[2];
  618. pict.data[2] = vp->bmp->pixels[1];
  619. pict.linesize[0] = vp->bmp->pitches[0];
  620. pict.linesize[1] = vp->bmp->pitches[2];
  621. pict.linesize[2] = vp->bmp->pitches[1];
  622. for (i = 0; i < sp->sub.num_rects; i++)
  623. blend_subrect(&pict, &sp->sub.rects[i]);
  624. SDL_UnlockYUVOverlay (vp->bmp);
  625. }
  626. }
  627. }
  628. /* XXX: we suppose the screen has a 1.0 pixel ratio */
  629. height = is->height;
  630. width = ((int)rint(height * aspect_ratio)) & -3;
  631. if (width > is->width) {
  632. width = is->width;
  633. height = ((int)rint(width / aspect_ratio)) & -3;
  634. }
  635. x = (is->width - width) / 2;
  636. y = (is->height - height) / 2;
  637. if (!is->no_background) {
  638. /* fill the background */
  639. // fill_border(is, x, y, width, height, QERGB(0x00, 0x00, 0x00));
  640. } else {
  641. is->no_background = 0;
  642. }
  643. rect.x = is->xleft + x;
  644. rect.y = is->xleft + y;
  645. rect.w = width;
  646. rect.h = height;
  647. SDL_DisplayYUVOverlay(vp->bmp, &rect);
  648. } else {
  649. #if 0
  650. fill_rectangle(screen,
  651. is->xleft, is->ytop, is->width, is->height,
  652. QERGB(0x00, 0x00, 0x00));
  653. #endif
  654. }
  655. }
  656. static inline int compute_mod(int a, int b)
  657. {
  658. a = a % b;
  659. if (a >= 0)
  660. return a;
  661. else
  662. return a + b;
  663. }
  664. static void video_audio_display(VideoState *s)
  665. {
  666. int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
  667. int ch, channels, h, h2, bgcolor, fgcolor;
  668. int16_t time_diff;
  669. /* compute display index : center on currently output samples */
  670. channels = s->audio_st->codec->channels;
  671. nb_display_channels = channels;
  672. if (!s->paused) {
  673. n = 2 * channels;
  674. delay = audio_write_get_buf_size(s);
  675. delay /= n;
  676. /* to be more precise, we take into account the time spent since
  677. the last buffer computation */
  678. if (audio_callback_time) {
  679. time_diff = av_gettime() - audio_callback_time;
  680. delay += (time_diff * s->audio_st->codec->sample_rate) / 1000000;
  681. }
  682. delay -= s->width / 2;
  683. if (delay < s->width)
  684. delay = s->width;
  685. i_start = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
  686. s->last_i_start = i_start;
  687. } else {
  688. i_start = s->last_i_start;
  689. }
  690. bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
  691. fill_rectangle(screen,
  692. s->xleft, s->ytop, s->width, s->height,
  693. bgcolor);
  694. fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
  695. /* total height for one channel */
  696. h = s->height / nb_display_channels;
  697. /* graph height / 2 */
  698. h2 = (h * 9) / 20;
  699. for(ch = 0;ch < nb_display_channels; ch++) {
  700. i = i_start + ch;
  701. y1 = s->ytop + ch * h + (h / 2); /* position of center line */
  702. for(x = 0; x < s->width; x++) {
  703. y = (s->sample_array[i] * h2) >> 15;
  704. if (y < 0) {
  705. y = -y;
  706. ys = y1 - y;
  707. } else {
  708. ys = y1;
  709. }
  710. fill_rectangle(screen,
  711. s->xleft + x, ys, 1, y,
  712. fgcolor);
  713. i += channels;
  714. if (i >= SAMPLE_ARRAY_SIZE)
  715. i -= SAMPLE_ARRAY_SIZE;
  716. }
  717. }
  718. fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
  719. for(ch = 1;ch < nb_display_channels; ch++) {
  720. y = s->ytop + ch * h;
  721. fill_rectangle(screen,
  722. s->xleft, y, s->width, 1,
  723. fgcolor);
  724. }
  725. SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
  726. }
  727. /* display the current picture, if any */
  728. static void video_display(VideoState *is)
  729. {
  730. if (is->audio_st && is->show_audio)
  731. video_audio_display(is);
  732. else if (is->video_st)
  733. video_image_display(is);
  734. }
  735. static Uint32 sdl_refresh_timer_cb(Uint32 interval, void *opaque)
  736. {
  737. SDL_Event event;
  738. event.type = FF_REFRESH_EVENT;
  739. event.user.data1 = opaque;
  740. SDL_PushEvent(&event);
  741. return 0; /* 0 means stop timer */
  742. }
  743. /* schedule a video refresh in 'delay' ms */
  744. static void schedule_refresh(VideoState *is, int delay)
  745. {
  746. SDL_AddTimer(delay, sdl_refresh_timer_cb, is);
  747. }
  748. /* get the current audio clock value */
  749. static double get_audio_clock(VideoState *is)
  750. {
  751. double pts;
  752. int hw_buf_size, bytes_per_sec;
  753. pts = is->audio_clock;
  754. hw_buf_size = audio_write_get_buf_size(is);
  755. bytes_per_sec = 0;
  756. if (is->audio_st) {
  757. bytes_per_sec = is->audio_st->codec->sample_rate *
  758. 2 * is->audio_st->codec->channels;
  759. }
  760. if (bytes_per_sec)
  761. pts -= (double)hw_buf_size / bytes_per_sec;
  762. return pts;
  763. }
  764. /* get the current video clock value */
  765. static double get_video_clock(VideoState *is)
  766. {
  767. double delta;
  768. if (is->paused) {
  769. delta = 0;
  770. } else {
  771. delta = (av_gettime() - is->video_current_pts_time) / 1000000.0;
  772. }
  773. return is->video_current_pts + delta;
  774. }
  775. /* get the current external clock value */
  776. static double get_external_clock(VideoState *is)
  777. {
  778. int64_t ti;
  779. ti = av_gettime();
  780. return is->external_clock + ((ti - is->external_clock_time) * 1e-6);
  781. }
  782. /* get the current master clock value */
  783. static double get_master_clock(VideoState *is)
  784. {
  785. double val;
  786. if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
  787. if (is->video_st)
  788. val = get_video_clock(is);
  789. else
  790. val = get_audio_clock(is);
  791. } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
  792. if (is->audio_st)
  793. val = get_audio_clock(is);
  794. else
  795. val = get_video_clock(is);
  796. } else {
  797. val = get_external_clock(is);
  798. }
  799. return val;
  800. }
  801. /* seek in the stream */
  802. static void stream_seek(VideoState *is, int64_t pos, int rel)
  803. {
  804. if (!is->seek_req) {
  805. is->seek_pos = pos;
  806. is->seek_flags = rel < 0 ? AVSEEK_FLAG_BACKWARD : 0;
  807. is->seek_req = 1;
  808. }
  809. }
  810. /* pause or resume the video */
  811. static void stream_pause(VideoState *is)
  812. {
  813. is->paused = !is->paused;
  814. if (is->paused) {
  815. is->video_current_pts = get_video_clock(is);
  816. }
  817. }
  818. /* called to display each frame */
  819. static void video_refresh_timer(void *opaque)
  820. {
  821. VideoState *is = opaque;
  822. VideoPicture *vp;
  823. double actual_delay, delay, sync_threshold, ref_clock, diff;
  824. SubPicture *sp, *sp2;
  825. if (is->video_st) {
  826. if (is->pictq_size == 0) {
  827. /* if no picture, need to wait */
  828. schedule_refresh(is, 1);
  829. } else {
  830. /* dequeue the picture */
  831. vp = &is->pictq[is->pictq_rindex];
  832. /* update current video pts */
  833. is->video_current_pts = vp->pts;
  834. is->video_current_pts_time = av_gettime();
  835. /* compute nominal delay */
  836. delay = vp->pts - is->frame_last_pts;
  837. if (delay <= 0 || delay >= 1.0) {
  838. /* if incorrect delay, use previous one */
  839. delay = is->frame_last_delay;
  840. }
  841. is->frame_last_delay = delay;
  842. is->frame_last_pts = vp->pts;
  843. /* update delay to follow master synchronisation source */
  844. if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) ||
  845. is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
  846. /* if video is slave, we try to correct big delays by
  847. duplicating or deleting a frame */
  848. ref_clock = get_master_clock(is);
  849. diff = vp->pts - ref_clock;
  850. /* skip or repeat frame. We take into account the
  851. delay to compute the threshold. I still don't know
  852. if it is the best guess */
  853. sync_threshold = AV_SYNC_THRESHOLD;
  854. if (delay > sync_threshold)
  855. sync_threshold = delay;
  856. if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
  857. if (diff <= -sync_threshold)
  858. delay = 0;
  859. else if (diff >= sync_threshold)
  860. delay = 2 * delay;
  861. }
  862. }
  863. is->frame_timer += delay;
  864. /* compute the REAL delay (we need to do that to avoid
  865. long term errors */
  866. actual_delay = is->frame_timer - (av_gettime() / 1000000.0);
  867. if (actual_delay < 0.010) {
  868. /* XXX: should skip picture */
  869. actual_delay = 0.010;
  870. }
  871. /* launch timer for next picture */
  872. schedule_refresh(is, (int)(actual_delay * 1000 + 0.5));
  873. #if defined(DEBUG_SYNC)
  874. printf("video: delay=%0.3f actual_delay=%0.3f pts=%0.3f A-V=%f\n",
  875. delay, actual_delay, vp->pts, -diff);
  876. #endif
  877. if(is->subtitle_st) {
  878. if (is->subtitle_stream_changed) {
  879. SDL_LockMutex(is->subpq_mutex);
  880. while (is->subpq_size) {
  881. free_subpicture(&is->subpq[is->subpq_rindex]);
  882. /* update queue size and signal for next picture */
  883. if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
  884. is->subpq_rindex = 0;
  885. is->subpq_size--;
  886. }
  887. is->subtitle_stream_changed = 0;
  888. SDL_CondSignal(is->subpq_cond);
  889. SDL_UnlockMutex(is->subpq_mutex);
  890. } else {
  891. if (is->subpq_size > 0) {
  892. sp = &is->subpq[is->subpq_rindex];
  893. if (is->subpq_size > 1)
  894. sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
  895. else
  896. sp2 = NULL;
  897. if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
  898. || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
  899. {
  900. free_subpicture(sp);
  901. /* update queue size and signal for next picture */
  902. if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
  903. is->subpq_rindex = 0;
  904. SDL_LockMutex(is->subpq_mutex);
  905. is->subpq_size--;
  906. SDL_CondSignal(is->subpq_cond);
  907. SDL_UnlockMutex(is->subpq_mutex);
  908. }
  909. }
  910. }
  911. }
  912. /* display picture */
  913. video_display(is);
  914. /* update queue size and signal for next picture */
  915. if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
  916. is->pictq_rindex = 0;
  917. SDL_LockMutex(is->pictq_mutex);
  918. is->pictq_size--;
  919. SDL_CondSignal(is->pictq_cond);
  920. SDL_UnlockMutex(is->pictq_mutex);
  921. }
  922. } else if (is->audio_st) {
  923. /* draw the next audio frame */
  924. schedule_refresh(is, 40);
  925. /* if only audio stream, then display the audio bars (better
  926. than nothing, just to test the implementation */
  927. /* display picture */
  928. video_display(is);
  929. } else {
  930. schedule_refresh(is, 100);
  931. }
  932. if (show_status) {
  933. static int64_t last_time;
  934. int64_t cur_time;
  935. int aqsize, vqsize, sqsize;
  936. double av_diff;
  937. cur_time = av_gettime();
  938. if (!last_time || (cur_time - last_time) >= 500 * 1000) {
  939. aqsize = 0;
  940. vqsize = 0;
  941. sqsize = 0;
  942. if (is->audio_st)
  943. aqsize = is->audioq.size;
  944. if (is->video_st)
  945. vqsize = is->videoq.size;
  946. if (is->subtitle_st)
  947. sqsize = is->subtitleq.size;
  948. av_diff = 0;
  949. if (is->audio_st && is->video_st)
  950. av_diff = get_audio_clock(is) - get_video_clock(is);
  951. printf("%7.2f A-V:%7.3f aq=%5dKB vq=%5dKB sq=%5dB \r",
  952. get_master_clock(is), av_diff, aqsize / 1024, vqsize / 1024, sqsize);
  953. fflush(stdout);
  954. last_time = cur_time;
  955. }
  956. }
  957. }
  958. /* allocate a picture (needs to do that in main thread to avoid
  959. potential locking problems */
  960. static void alloc_picture(void *opaque)
  961. {
  962. VideoState *is = opaque;
  963. VideoPicture *vp;
  964. vp = &is->pictq[is->pictq_windex];
  965. if (vp->bmp)
  966. SDL_FreeYUVOverlay(vp->bmp);
  967. #if 0
  968. /* XXX: use generic function */
  969. /* XXX: disable overlay if no hardware acceleration or if RGB format */
  970. switch(is->video_st->codec->pix_fmt) {
  971. case PIX_FMT_YUV420P:
  972. case PIX_FMT_YUV422P:
  973. case PIX_FMT_YUV444P:
  974. case PIX_FMT_YUV422:
  975. case PIX_FMT_YUV410P:
  976. case PIX_FMT_YUV411P:
  977. is_yuv = 1;
  978. break;
  979. default:
  980. is_yuv = 0;
  981. break;
  982. }
  983. #endif
  984. vp->bmp = SDL_CreateYUVOverlay(is->video_st->codec->width,
  985. is->video_st->codec->height,
  986. SDL_YV12_OVERLAY,
  987. screen);
  988. vp->width = is->video_st->codec->width;
  989. vp->height = is->video_st->codec->height;
  990. SDL_LockMutex(is->pictq_mutex);
  991. vp->allocated = 1;
  992. SDL_CondSignal(is->pictq_cond);
  993. SDL_UnlockMutex(is->pictq_mutex);
  994. }
  995. /**
  996. *
  997. * @param pts the dts of the pkt / pts of the frame and guessed if not known
  998. */
  999. static int queue_picture(VideoState *is, AVFrame *src_frame, double pts)
  1000. {
  1001. VideoPicture *vp;
  1002. int dst_pix_fmt;
  1003. AVPicture pict;
  1004. /* wait until we have space to put a new picture */
  1005. SDL_LockMutex(is->pictq_mutex);
  1006. while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
  1007. !is->videoq.abort_request) {
  1008. SDL_CondWait(is->pictq_cond, is->pictq_mutex);
  1009. }
  1010. SDL_UnlockMutex(is->pictq_mutex);
  1011. if (is->videoq.abort_request)
  1012. return -1;
  1013. vp = &is->pictq[is->pictq_windex];
  1014. /* alloc or resize hardware picture buffer */
  1015. if (!vp->bmp ||
  1016. vp->width != is->video_st->codec->width ||
  1017. vp->height != is->video_st->codec->height) {
  1018. SDL_Event event;
  1019. vp->allocated = 0;
  1020. /* the allocation must be done in the main thread to avoid
  1021. locking problems */
  1022. event.type = FF_ALLOC_EVENT;
  1023. event.user.data1 = is;
  1024. SDL_PushEvent(&event);
  1025. /* wait until the picture is allocated */
  1026. SDL_LockMutex(is->pictq_mutex);
  1027. while (!vp->allocated && !is->videoq.abort_request) {
  1028. SDL_CondWait(is->pictq_cond, is->pictq_mutex);
  1029. }
  1030. SDL_UnlockMutex(is->pictq_mutex);
  1031. if (is->videoq.abort_request)
  1032. return -1;
  1033. }
  1034. /* if the frame is not skipped, then display it */
  1035. if (vp->bmp) {
  1036. /* get a pointer on the bitmap */
  1037. SDL_LockYUVOverlay (vp->bmp);
  1038. dst_pix_fmt = PIX_FMT_YUV420P;
  1039. pict.data[0] = vp->bmp->pixels[0];
  1040. pict.data[1] = vp->bmp->pixels[2];
  1041. pict.data[2] = vp->bmp->pixels[1];
  1042. pict.linesize[0] = vp->bmp->pitches[0];
  1043. pict.linesize[1] = vp->bmp->pitches[2];
  1044. pict.linesize[2] = vp->bmp->pitches[1];
  1045. img_convert(&pict, dst_pix_fmt,
  1046. (AVPicture *)src_frame, is->video_st->codec->pix_fmt,
  1047. is->video_st->codec->width, is->video_st->codec->height);
  1048. /* update the bitmap content */
  1049. SDL_UnlockYUVOverlay(vp->bmp);
  1050. vp->pts = pts;
  1051. /* now we can update the picture count */
  1052. if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
  1053. is->pictq_windex = 0;
  1054. SDL_LockMutex(is->pictq_mutex);
  1055. is->pictq_size++;
  1056. SDL_UnlockMutex(is->pictq_mutex);
  1057. }
  1058. return 0;
  1059. }
  1060. /**
  1061. * compute the exact PTS for the picture if it is omitted in the stream
  1062. * @param pts1 the dts of the pkt / pts of the frame
  1063. */
  1064. static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1)
  1065. {
  1066. double frame_delay, pts;
  1067. pts = pts1;
  1068. if (pts != 0) {
  1069. /* update video clock with pts, if present */
  1070. is->video_clock = pts;
  1071. } else {
  1072. pts = is->video_clock;
  1073. }
  1074. /* update video clock for next frame */
  1075. frame_delay = av_q2d(is->video_st->codec->time_base);
  1076. /* for MPEG2, the frame can be repeated, so we update the
  1077. clock accordingly */
  1078. frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
  1079. is->video_clock += frame_delay;
  1080. #if defined(DEBUG_SYNC) && 0
  1081. {
  1082. int ftype;
  1083. if (src_frame->pict_type == FF_B_TYPE)
  1084. ftype = 'B';
  1085. else if (src_frame->pict_type == FF_I_TYPE)
  1086. ftype = 'I';
  1087. else
  1088. ftype = 'P';
  1089. printf("frame_type=%c clock=%0.3f pts=%0.3f\n",
  1090. ftype, pts, pts1);
  1091. }
  1092. #endif
  1093. return queue_picture(is, src_frame, pts);
  1094. }
  1095. static int video_thread(void *arg)
  1096. {
  1097. VideoState *is = arg;
  1098. AVPacket pkt1, *pkt = &pkt1;
  1099. int len1, got_picture;
  1100. AVFrame *frame= avcodec_alloc_frame();
  1101. double pts;
  1102. for(;;) {
  1103. while (is->paused && !is->videoq.abort_request) {
  1104. SDL_Delay(10);
  1105. }
  1106. if (packet_queue_get(&is->videoq, pkt, 1) < 0)
  1107. break;
  1108. /* NOTE: ipts is the PTS of the _first_ picture beginning in
  1109. this packet, if any */
  1110. pts = 0;
  1111. if (pkt->dts != AV_NOPTS_VALUE)
  1112. pts = av_q2d(is->video_st->time_base)*pkt->dts;
  1113. SDL_LockMutex(is->video_decoder_mutex);
  1114. len1 = avcodec_decode_video(is->video_st->codec,
  1115. frame, &got_picture,
  1116. pkt->data, pkt->size);
  1117. SDL_UnlockMutex(is->video_decoder_mutex);
  1118. // if (len1 < 0)
  1119. // break;
  1120. if (got_picture) {
  1121. if (output_picture2(is, frame, pts) < 0)
  1122. goto the_end;
  1123. }
  1124. av_free_packet(pkt);
  1125. if (step)
  1126. if (cur_stream)
  1127. stream_pause(cur_stream);
  1128. }
  1129. the_end:
  1130. av_free(frame);
  1131. return 0;
  1132. }
  1133. static int subtitle_thread(void *arg)
  1134. {
  1135. VideoState *is = arg;
  1136. SubPicture *sp;
  1137. AVPacket pkt1, *pkt = &pkt1;
  1138. int len1, got_subtitle;
  1139. double pts;
  1140. int i, j;
  1141. int r, g, b, y, u, v, a;
  1142. for(;;) {
  1143. while (is->paused && !is->subtitleq.abort_request) {
  1144. SDL_Delay(10);
  1145. }
  1146. if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
  1147. break;
  1148. SDL_LockMutex(is->subpq_mutex);
  1149. while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
  1150. !is->subtitleq.abort_request) {
  1151. SDL_CondWait(is->subpq_cond, is->subpq_mutex);
  1152. }
  1153. SDL_UnlockMutex(is->subpq_mutex);
  1154. if (is->subtitleq.abort_request)
  1155. goto the_end;
  1156. sp = &is->subpq[is->subpq_windex];
  1157. /* NOTE: ipts is the PTS of the _first_ picture beginning in
  1158. this packet, if any */
  1159. pts = 0;
  1160. if (pkt->pts != AV_NOPTS_VALUE)
  1161. pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;
  1162. SDL_LockMutex(is->subtitle_decoder_mutex);
  1163. len1 = avcodec_decode_subtitle(is->subtitle_st->codec,
  1164. &sp->sub, &got_subtitle,
  1165. pkt->data, pkt->size);
  1166. SDL_UnlockMutex(is->subtitle_decoder_mutex);
  1167. // if (len1 < 0)
  1168. // break;
  1169. if (got_subtitle && sp->sub.format == 0) {
  1170. sp->pts = pts;
  1171. for (i = 0; i < sp->sub.num_rects; i++)
  1172. {
  1173. for (j = 0; j < sp->sub.rects[i].nb_colors; j++)
  1174. {
  1175. RGBA_IN(r, g, b, a, sp->sub.rects[i].rgba_palette + j);
  1176. y = RGB_TO_Y_CCIR(r, g, b);
  1177. u = RGB_TO_U_CCIR(r, g, b, 0);
  1178. v = RGB_TO_V_CCIR(r, g, b, 0);
  1179. YUVA_OUT(sp->sub.rects[i].rgba_palette + j, y, u, v, a);
  1180. }
  1181. }
  1182. /* now we can update the picture count */
  1183. if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
  1184. is->subpq_windex = 0;
  1185. SDL_LockMutex(is->subpq_mutex);
  1186. is->subpq_size++;
  1187. SDL_UnlockMutex(is->subpq_mutex);
  1188. }
  1189. av_free_packet(pkt);
  1190. // if (step)
  1191. // if (cur_stream)
  1192. // stream_pause(cur_stream);
  1193. }
  1194. the_end:
  1195. return 0;
  1196. }
  1197. /* copy samples for viewing in editor window */
  1198. static void update_sample_display(VideoState *is, short *samples, int samples_size)
  1199. {
  1200. int size, len, channels;
  1201. channels = is->audio_st->codec->channels;
  1202. size = samples_size / sizeof(short);
  1203. while (size > 0) {
  1204. len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
  1205. if (len > size)
  1206. len = size;
  1207. memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
  1208. samples += len;
  1209. is->sample_array_index += len;
  1210. if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
  1211. is->sample_array_index = 0;
  1212. size -= len;
  1213. }
  1214. }
  1215. /* return the new audio buffer size (samples can be added or deleted
  1216. to get better sync if video or external master clock) */
  1217. static int synchronize_audio(VideoState *is, short *samples,
  1218. int samples_size1, double pts)
  1219. {
  1220. int n, samples_size;
  1221. double ref_clock;
  1222. n = 2 * is->audio_st->codec->channels;
  1223. samples_size = samples_size1;
  1224. /* if not master, then we try to remove or add samples to correct the clock */
  1225. if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
  1226. is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
  1227. double diff, avg_diff;
  1228. int wanted_size, min_size, max_size, nb_samples;
  1229. ref_clock = get_master_clock(is);
  1230. diff = get_audio_clock(is) - ref_clock;
  1231. if (diff < AV_NOSYNC_THRESHOLD) {
  1232. is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
  1233. if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
  1234. /* not enough measures to have a correct estimate */
  1235. is->audio_diff_avg_count++;
  1236. } else {
  1237. /* estimate the A-V difference */
  1238. avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
  1239. if (fabs(avg_diff) >= is->audio_diff_threshold) {
  1240. wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
  1241. nb_samples = samples_size / n;
  1242. min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
  1243. max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
  1244. if (wanted_size < min_size)
  1245. wanted_size = min_size;
  1246. else if (wanted_size > max_size)
  1247. wanted_size = max_size;
  1248. /* add or remove samples to correction the synchro */
  1249. if (wanted_size < samples_size) {
  1250. /* remove samples */
  1251. samples_size = wanted_size;
  1252. } else if (wanted_size > samples_size) {
  1253. uint8_t *samples_end, *q;
  1254. int nb;
  1255. /* add samples */
  1256. nb = (samples_size - wanted_size);
  1257. samples_end = (uint8_t *)samples + samples_size - n;
  1258. q = samples_end + n;
  1259. while (nb > 0) {
  1260. memcpy(q, samples_end, n);
  1261. q += n;
  1262. nb -= n;
  1263. }
  1264. samples_size = wanted_size;
  1265. }
  1266. }
  1267. #if 0
  1268. printf("diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
  1269. diff, avg_diff, samples_size - samples_size1,
  1270. is->audio_clock, is->video_clock, is->audio_diff_threshold);
  1271. #endif
  1272. }
  1273. } else {
  1274. /* too big difference : may be initial PTS errors, so
  1275. reset A-V filter */
  1276. is->audio_diff_avg_count = 0;
  1277. is->audio_diff_cum = 0;
  1278. }
  1279. }
  1280. return samples_size;
  1281. }
  1282. /* decode one audio frame and returns its uncompressed size */
  1283. static int audio_decode_frame(VideoState *is, uint8_t *audio_buf, double *pts_ptr)
  1284. {
  1285. AVPacket *pkt = &is->audio_pkt;
  1286. int n, len1, data_size;
  1287. double pts;
  1288. for(;;) {
  1289. /* NOTE: the audio packet can contain several frames */
  1290. while (is->audio_pkt_size > 0) {
  1291. SDL_LockMutex(is->audio_decoder_mutex);
  1292. len1 = avcodec_decode_audio(is->audio_st->codec,
  1293. (int16_t *)audio_buf, &data_size,
  1294. is->audio_pkt_data, is->audio_pkt_size);
  1295. SDL_UnlockMutex(is->audio_decoder_mutex);
  1296. if (len1 < 0) {
  1297. /* if error, we skip the frame */
  1298. is->audio_pkt_size = 0;
  1299. break;
  1300. }
  1301. is->audio_pkt_data += len1;
  1302. is->audio_pkt_size -= len1;
  1303. if (data_size <= 0)
  1304. continue;
  1305. /* if no pts, then compute it */
  1306. pts = is->audio_clock;
  1307. *pts_ptr = pts;
  1308. n = 2 * is->audio_st->codec->channels;
  1309. is->audio_clock += (double)data_size /
  1310. (double)(n * is->audio_st->codec->sample_rate);
  1311. #if defined(DEBUG_SYNC)
  1312. {
  1313. static double last_clock;
  1314. printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
  1315. is->audio_clock - last_clock,
  1316. is->audio_clock, pts);
  1317. last_clock = is->audio_clock;
  1318. }
  1319. #endif
  1320. return data_size;
  1321. }
  1322. /* free the current packet */
  1323. if (pkt->data)
  1324. av_free_packet(pkt);
  1325. if (is->paused || is->audioq.abort_request) {
  1326. return -1;
  1327. }
  1328. /* read next packet */
  1329. if (packet_queue_get(&is->audioq, pkt, 1) < 0)
  1330. return -1;
  1331. is->audio_pkt_data = pkt->data;
  1332. is->audio_pkt_size = pkt->size;
  1333. /* if update the audio clock with the pts */
  1334. if (pkt->pts != AV_NOPTS_VALUE) {
  1335. is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
  1336. }
  1337. }
  1338. }
  1339. /* get the current audio output buffer size, in samples. With SDL, we
  1340. cannot have a precise information */
  1341. static int audio_write_get_buf_size(VideoState *is)
  1342. {
  1343. return is->audio_hw_buf_size - is->audio_buf_index;
  1344. }
  1345. /* prepare a new audio buffer */
  1346. void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
  1347. {
  1348. VideoState *is = opaque;
  1349. int audio_size, len1;
  1350. double pts;
  1351. audio_callback_time = av_gettime();
  1352. while (len > 0) {
  1353. if (is->audio_buf_index >= is->audio_buf_size) {
  1354. audio_size = audio_decode_frame(is, is->audio_buf, &pts);
  1355. if (audio_size < 0) {
  1356. /* if error, just output silence */
  1357. is->audio_buf_size = 1024;
  1358. memset(is->audio_buf, 0, is->audio_buf_size);
  1359. } else {
  1360. if (is->show_audio)
  1361. update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
  1362. audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size,
  1363. pts);
  1364. is->audio_buf_size = audio_size;
  1365. }
  1366. is->audio_buf_index = 0;
  1367. }
  1368. len1 = is->audio_buf_size - is->audio_buf_index;
  1369. if (len1 > len)
  1370. len1 = len;
  1371. memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
  1372. len -= len1;
  1373. stream += len1;
  1374. is->audio_buf_index += len1;
  1375. }
  1376. }
  1377. /* open a given stream. Return 0 if OK */
  1378. static int stream_component_open(VideoState *is, int stream_index)
  1379. {
  1380. AVFormatContext *ic = is->ic;
  1381. AVCodecContext *enc;
  1382. AVCodec *codec;
  1383. SDL_AudioSpec wanted_spec, spec;
  1384. if (stream_index < 0 || stream_index >= ic->nb_streams)
  1385. return -1;
  1386. enc = ic->streams[stream_index]->codec;
  1387. /* prepare audio output */
  1388. if (enc->codec_type == CODEC_TYPE_AUDIO) {
  1389. wanted_spec.freq = enc->sample_rate;
  1390. wanted_spec.format = AUDIO_S16SYS;
  1391. /* hack for AC3. XXX: suppress that */
  1392. if (enc->channels > 2)
  1393. enc->channels = 2;
  1394. wanted_spec.channels = enc->channels;
  1395. wanted_spec.silence = 0;
  1396. wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
  1397. wanted_spec.callback = sdl_audio_callback;
  1398. wanted_spec.userdata = is;
  1399. if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
  1400. fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
  1401. return -1;
  1402. }
  1403. is->audio_hw_buf_size = spec.size;
  1404. }
  1405. codec = avcodec_find_decoder(enc->codec_id);
  1406. enc->debug_mv = debug_mv;
  1407. enc->debug = debug;
  1408. if(debug)
  1409. av_log_set_level(AV_LOG_DEBUG);
  1410. enc->workaround_bugs = workaround_bugs;
  1411. enc->lowres = lowres;
  1412. if(lowres) enc->flags |= CODEC_FLAG_EMU_EDGE;
  1413. enc->idct_algo= idct;
  1414. if(fast) enc->flags2 |= CODEC_FLAG2_FAST;
  1415. enc->skip_frame= skip_frame;
  1416. enc->skip_idct= skip_idct;
  1417. enc->skip_loop_filter= skip_loop_filter;
  1418. enc->error_resilience= error_resilience;
  1419. enc->error_concealment= error_concealment;
  1420. if (!codec ||
  1421. avcodec_open(enc, codec) < 0)
  1422. return -1;
  1423. #if defined(HAVE_THREADS)
  1424. if(thread_count>1)
  1425. avcodec_thread_init(enc, thread_count);
  1426. #endif
  1427. enc->thread_count= thread_count;
  1428. switch(enc->codec_type) {
  1429. case CODEC_TYPE_AUDIO:
  1430. is->audio_stream = stream_index;
  1431. is->audio_st = ic->streams[stream_index];
  1432. is->audio_buf_size = 0;
  1433. is->audio_buf_index = 0;
  1434. /* init averaging filter */
  1435. is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
  1436. is->audio_diff_avg_count = 0;
  1437. /* since we do not have a precise anough audio fifo fullness,
  1438. we correct audio sync only if larger than this threshold */
  1439. is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / enc->sample_rate;
  1440. memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
  1441. packet_queue_init(&is->audioq);
  1442. SDL_PauseAudio(0);
  1443. break;
  1444. case CODEC_TYPE_VIDEO:
  1445. is->video_stream = stream_index;
  1446. is->video_st = ic->streams[stream_index];
  1447. is->frame_last_delay = 40e-3;
  1448. is->frame_timer = (double)av_gettime() / 1000000.0;
  1449. is->video_current_pts_time = av_gettime();
  1450. packet_queue_init(&is->videoq);
  1451. is->video_tid = SDL_CreateThread(video_thread, is);
  1452. break;
  1453. case CODEC_TYPE_SUBTITLE:
  1454. is->subtitle_stream = stream_index;
  1455. is->subtitle_st = ic->streams[stream_index];
  1456. packet_queue_init(&is->subtitleq);
  1457. is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
  1458. break;
  1459. default:
  1460. break;
  1461. }
  1462. return 0;
  1463. }
  1464. static void stream_component_close(VideoState *is, int stream_index)
  1465. {
  1466. AVFormatContext *ic = is->ic;
  1467. AVCodecContext *enc;
  1468. if (stream_index < 0 || stream_index >= ic->nb_streams)
  1469. return;
  1470. enc = ic->streams[stream_index]->codec;
  1471. switch(enc->codec_type) {
  1472. case CODEC_TYPE_AUDIO:
  1473. packet_queue_abort(&is->audioq);
  1474. SDL_CloseAudio();
  1475. packet_queue_end(&is->audioq);
  1476. break;
  1477. case CODEC_TYPE_VIDEO:
  1478. packet_queue_abort(&is->videoq);
  1479. /* note: we also signal this mutex to make sure we deblock the
  1480. video thread in all cases */
  1481. SDL_LockMutex(is->pictq_mutex);
  1482. SDL_CondSignal(is->pictq_cond);
  1483. SDL_UnlockMutex(is->pictq_mutex);
  1484. SDL_WaitThread(is->video_tid, NULL);
  1485. packet_queue_end(&is->videoq);
  1486. break;
  1487. case CODEC_TYPE_SUBTITLE:
  1488. packet_queue_abort(&is->subtitleq);
  1489. /* note: we also signal this mutex to make sure we deblock the
  1490. video thread in all cases */
  1491. SDL_LockMutex(is->subpq_mutex);
  1492. is->subtitle_stream_changed = 1;
  1493. SDL_CondSignal(is->subpq_cond);
  1494. SDL_UnlockMutex(is->subpq_mutex);
  1495. SDL_WaitThread(is->subtitle_tid, NULL);
  1496. packet_queue_end(&is->subtitleq);
  1497. break;
  1498. default:
  1499. break;
  1500. }
  1501. avcodec_close(enc);
  1502. switch(enc->codec_type) {
  1503. case CODEC_TYPE_AUDIO:
  1504. is->audio_st = NULL;
  1505. is->audio_stream = -1;
  1506. break;
  1507. case CODEC_TYPE_VIDEO:
  1508. is->video_st = NULL;
  1509. is->video_stream = -1;
  1510. break;
  1511. case CODEC_TYPE_SUBTITLE:
  1512. is->subtitle_st = NULL;
  1513. is->subtitle_stream = -1;
  1514. break;
  1515. default:
  1516. break;
  1517. }
  1518. }
  1519. void dump_stream_info(AVFormatContext *s)
  1520. {
  1521. if (s->track != 0)
  1522. fprintf(stderr, "Track: %d\n", s->track);
  1523. if (s->title[0] != '\0')
  1524. fprintf(stderr, "Title: %s\n", s->title);
  1525. if (s->author[0] != '\0')
  1526. fprintf(stderr, "Author: %s\n", s->author);
  1527. if (s->album[0] != '\0')
  1528. fprintf(stderr, "Album: %s\n", s->album);
  1529. if (s->year != 0)
  1530. fprintf(stderr, "Year: %d\n", s->year);
  1531. if (s->genre[0] != '\0')
  1532. fprintf(stderr, "Genre: %s\n", s->genre);
  1533. }
  1534. /* since we have only one decoding thread, we can use a global
  1535. variable instead of a thread local variable */
  1536. static VideoState *global_video_state;
  1537. static int decode_interrupt_cb(void)
  1538. {
  1539. return (global_video_state && global_video_state->abort_request);
  1540. }
  1541. /* this thread gets the stream from the disk or the network */
  1542. static int decode_thread(void *arg)
  1543. {
  1544. VideoState *is = arg;
  1545. AVFormatContext *ic;
  1546. int err, i, ret, video_index, audio_index, use_play;
  1547. AVPacket pkt1, *pkt = &pkt1;
  1548. AVFormatParameters params, *ap = &params;
  1549. video_index = -1;
  1550. audio_index = -1;
  1551. is->video_stream = -1;
  1552. is->audio_stream = -1;
  1553. is->subtitle_stream = -1;
  1554. global_video_state = is;
  1555. url_set_interrupt_cb(decode_interrupt_cb);
  1556. memset(ap, 0, sizeof(*ap));
  1557. ap->image_format = image_format;
  1558. ap->initial_pause = 1; /* we force a pause when starting an RTSP
  1559. stream */
  1560. err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap);
  1561. if (err < 0) {
  1562. print_error(is->filename, err);
  1563. ret = -1;
  1564. goto fail;
  1565. }
  1566. is->ic = ic;
  1567. #ifdef CONFIG_NETWORK
  1568. use_play = (ic->iformat == &rtsp_demux);
  1569. #else
  1570. use_play = 0;
  1571. #endif
  1572. if(genpts)
  1573. ic->flags |= AVFMT_FLAG_GENPTS;
  1574. if (!use_play) {
  1575. err = av_find_stream_info(ic);
  1576. if (err < 0) {
  1577. fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
  1578. ret = -1;
  1579. goto fail;
  1580. }
  1581. ic->pb.eof_reached= 0; //FIXME hack, ffplay maybe shouldnt use url_feof() to test for the end
  1582. }
  1583. /* if seeking requested, we execute it */
  1584. if (start_time != AV_NOPTS_VALUE) {
  1585. int64_t timestamp;
  1586. timestamp = start_time;
  1587. /* add the stream start time */
  1588. if (ic->start_time != AV_NOPTS_VALUE)
  1589. timestamp += ic->start_time;
  1590. ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
  1591. if (ret < 0) {
  1592. fprintf(stderr, "%s: could not seek to position %0.3f\n",
  1593. is->filename, (double)timestamp / AV_TIME_BASE);
  1594. }
  1595. }
  1596. /* now we can begin to play (RTSP stream only) */
  1597. av_read_play(ic);
  1598. if (use_play) {
  1599. err = av_find_stream_info(ic);
  1600. if (err < 0) {
  1601. fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
  1602. ret = -1;
  1603. goto fail;
  1604. }
  1605. }
  1606. for(i = 0; i < ic->nb_streams; i++) {
  1607. AVCodecContext *enc = ic->streams[i]->codec;
  1608. switch(enc->codec_type) {
  1609. case CODEC_TYPE_AUDIO:
  1610. if (audio_index < 0 && !audio_disable)
  1611. audio_index = i;
  1612. break;
  1613. case CODEC_TYPE_VIDEO:
  1614. if (video_index < 0 && !video_disable)
  1615. video_index = i;
  1616. break;
  1617. default:
  1618. break;
  1619. }
  1620. }
  1621. if (show_status) {
  1622. dump_format(ic, 0, is->filename, 0);
  1623. dump_stream_info(ic);
  1624. }
  1625. /* open the streams */
  1626. if (audio_index >= 0) {
  1627. stream_component_open(is, audio_index);
  1628. }
  1629. if (video_index >= 0) {
  1630. stream_component_open(is, video_index);
  1631. } else {
  1632. if (!display_disable)
  1633. is->show_audio = 1;
  1634. }
  1635. if (is->video_stream < 0 && is->audio_stream < 0) {
  1636. fprintf(stderr, "%s: could not open codecs\n", is->filename);
  1637. ret = -1;
  1638. goto fail;
  1639. }
  1640. for(;;) {
  1641. if (is->abort_request)
  1642. break;
  1643. #ifdef CONFIG_NETWORK
  1644. if (is->paused != is->last_paused) {
  1645. is->last_paused = is->paused;
  1646. if (is->paused)
  1647. av_read_pause(ic);
  1648. else
  1649. av_read_play(ic);
  1650. }
  1651. if (is->paused && ic->iformat == &rtsp_demux) {
  1652. /* wait 10 ms to avoid trying to get another packet */
  1653. /* XXX: horrible */
  1654. SDL_Delay(10);
  1655. continue;
  1656. }
  1657. #endif
  1658. if (is->seek_req) {
  1659. /* XXX: must lock decoder threads */
  1660. SDL_LockMutex(is->video_decoder_mutex);
  1661. SDL_LockMutex(is->audio_decoder_mutex);
  1662. SDL_LockMutex(is->subtitle_decoder_mutex);
  1663. ret = av_seek_frame(is->ic, -1, is->seek_pos, is->seek_flags);
  1664. if (ret < 0) {
  1665. fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
  1666. }else{
  1667. if (is->audio_stream >= 0) {
  1668. packet_queue_flush(&is->audioq);
  1669. }
  1670. if (is->subtitle_stream >= 0) {
  1671. packet_queue_flush(&is->subtitleq);
  1672. }
  1673. if (is->video_stream >= 0) {
  1674. packet_queue_flush(&is->videoq);
  1675. avcodec_flush_buffers(ic->streams[video_index]->codec);
  1676. }
  1677. }
  1678. SDL_UnlockMutex(is->subtitle_decoder_mutex);
  1679. SDL_UnlockMutex(is->audio_decoder_mutex);
  1680. SDL_UnlockMutex(is->video_decoder_mutex);
  1681. is->seek_req = 0;
  1682. }
  1683. /* if the queue are full, no need to read more */
  1684. if (is->audioq.size > MAX_AUDIOQ_SIZE ||
  1685. is->videoq.size > MAX_VIDEOQ_SIZE ||
  1686. is->subtitleq.size > MAX_SUBTITLEQ_SIZE ||
  1687. url_feof(&ic->pb)) {
  1688. /* wait 10 ms */
  1689. SDL_Delay(10);
  1690. continue;
  1691. }
  1692. ret = av_read_frame(ic, pkt);
  1693. if (ret < 0) {
  1694. if (url_ferror(&ic->pb) == 0) {
  1695. SDL_Delay(100); /* wait for user event */
  1696. continue;
  1697. } else
  1698. break;
  1699. }
  1700. if (pkt->stream_index == is->audio_stream) {
  1701. packet_queue_put(&is->audioq, pkt);
  1702. } else if (pkt->stream_index == is->video_stream) {
  1703. packet_queue_put(&is->videoq, pkt);
  1704. } else if (pkt->stream_index == is->subtitle_stream) {
  1705. packet_queue_put(&is->subtitleq, pkt);
  1706. } else {
  1707. av_free_packet(pkt);
  1708. }
  1709. }
  1710. /* wait until the end */
  1711. while (!is->abort_request) {
  1712. SDL_Delay(100);
  1713. }
  1714. ret = 0;
  1715. fail:
  1716. /* disable interrupting */
  1717. global_video_state = NULL;
  1718. /* close each stream */
  1719. if (is->audio_stream >= 0)
  1720. stream_component_close(is, is->audio_stream);
  1721. if (is->video_stream >= 0)
  1722. stream_component_close(is, is->video_stream);
  1723. if (is->subtitle_stream >= 0)
  1724. stream_component_close(is, is->subtitle_stream);
  1725. if (is->ic) {
  1726. av_close_input_file(is->ic);
  1727. is->ic = NULL; /* safety */
  1728. }
  1729. url_set_interrupt_cb(NULL);
  1730. if (ret != 0) {
  1731. SDL_Event event;
  1732. event.type = FF_QUIT_EVENT;
  1733. event.user.data1 = is;
  1734. SDL_PushEvent(&event);
  1735. }
  1736. return 0;
  1737. }
  1738. static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
  1739. {
  1740. VideoState *is;
  1741. is = av_mallocz(sizeof(VideoState));
  1742. if (!is)
  1743. return NULL;
  1744. pstrcpy(is->filename, sizeof(is->filename), filename);
  1745. is->iformat = iformat;
  1746. if (screen) {
  1747. is->width = screen->w;
  1748. is->height = screen->h;
  1749. }
  1750. is->ytop = 0;
  1751. is->xleft = 0;
  1752. /* start video display */
  1753. is->pictq_mutex = SDL_CreateMutex();
  1754. is->pictq_cond = SDL_CreateCond();
  1755. is->subpq_mutex = SDL_CreateMutex();
  1756. is->subpq_cond = SDL_CreateCond();
  1757. is->subtitle_decoder_mutex = SDL_CreateMutex();
  1758. is->audio_decoder_mutex = SDL_CreateMutex();
  1759. is->video_decoder_mutex = SDL_CreateMutex();
  1760. /* add the refresh timer to draw the picture */
  1761. schedule_refresh(is, 40);
  1762. is->av_sync_type = av_sync_type;
  1763. is->parse_tid = SDL_CreateThread(decode_thread, is);
  1764. if (!is->parse_tid) {
  1765. av_free(is);
  1766. return NULL;
  1767. }
  1768. return is;
  1769. }
  1770. static void stream_close(VideoState *is)
  1771. {
  1772. VideoPicture *vp;
  1773. int i;
  1774. /* XXX: use a special url_shutdown call to abort parse cleanly */
  1775. is->abort_request = 1;
  1776. SDL_WaitThread(is->parse_tid, NULL);
  1777. /* free all pictures */
  1778. for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
  1779. vp = &is->pictq[i];
  1780. if (vp->bmp) {
  1781. SDL_FreeYUVOverlay(vp->bmp);
  1782. vp->bmp = NULL;
  1783. }
  1784. }
  1785. SDL_DestroyMutex(is->pictq_mutex);
  1786. SDL_DestroyCond(is->pictq_cond);
  1787. SDL_DestroyMutex(is->subpq_mutex);
  1788. SDL_DestroyCond(is->subpq_cond);
  1789. SDL_DestroyMutex(is->subtitle_decoder_mutex);
  1790. SDL_DestroyMutex(is->audio_decoder_mutex);
  1791. SDL_DestroyMutex(is->video_decoder_mutex);
  1792. }
  1793. void stream_cycle_channel(VideoState *is, int codec_type)
  1794. {
  1795. AVFormatContext *ic = is->ic;
  1796. int start_index, stream_index;
  1797. AVStream *st;
  1798. if (codec_type == CODEC_TYPE_VIDEO)
  1799. start_index = is->video_stream;
  1800. else if (codec_type == CODEC_TYPE_AUDIO)
  1801. start_index = is->audio_stream;
  1802. else
  1803. start_index = is->subtitle_stream;
  1804. if (start_index < (codec_type == CODEC_TYPE_SUBTITLE ? -1 : 0))
  1805. return;
  1806. stream_index = start_index;
  1807. for(;;) {
  1808. if (++stream_index >= is->ic->nb_streams)
  1809. {
  1810. if (codec_type == CODEC_TYPE_SUBTITLE)
  1811. {
  1812. stream_index = -1;
  1813. goto the_end;
  1814. } else
  1815. stream_index = 0;
  1816. }
  1817. if (stream_index == start_index)
  1818. return;
  1819. st = ic->streams[stream_index];
  1820. if (st->codec->codec_type == codec_type) {
  1821. /* check that parameters are OK */
  1822. switch(codec_type) {
  1823. case CODEC_TYPE_AUDIO:
  1824. if (st->codec->sample_rate != 0 &&
  1825. st->codec->channels != 0)
  1826. goto the_end;
  1827. break;
  1828. case CODEC_TYPE_VIDEO:
  1829. case CODEC_TYPE_SUBTITLE:
  1830. goto the_end;
  1831. default:
  1832. break;
  1833. }
  1834. }
  1835. }
  1836. the_end:
  1837. stream_component_close(is, start_index);
  1838. stream_component_open(is, stream_index);
  1839. }
  1840. void toggle_full_screen(void)
  1841. {
  1842. int w, h, flags;
  1843. is_full_screen = !is_full_screen;
  1844. if (!fs_screen_width) {
  1845. /* use default SDL method */
  1846. SDL_WM_ToggleFullScreen(screen);
  1847. } else {
  1848. /* use the recorded resolution */
  1849. flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
  1850. if (is_full_screen) {
  1851. w = fs_screen_width;
  1852. h = fs_screen_height;
  1853. flags |= SDL_FULLSCREEN;
  1854. } else {
  1855. w = screen_width;
  1856. h = screen_height;
  1857. flags |= SDL_RESIZABLE;
  1858. }
  1859. screen = SDL_SetVideoMode(w, h, 0, flags);
  1860. cur_stream->width = w;
  1861. cur_stream->height = h;
  1862. }
  1863. }
  1864. void toggle_pause(void)
  1865. {
  1866. if (cur_stream)
  1867. stream_pause(cur_stream);
  1868. step = 0;
  1869. }
  1870. void step_to_next_frame(void)
  1871. {
  1872. if (cur_stream) {
  1873. if (cur_stream->paused)
  1874. cur_stream->paused=0;
  1875. cur_stream->video_current_pts = get_video_clock(cur_stream);
  1876. }
  1877. step = 1;
  1878. }
  1879. void do_exit(void)
  1880. {
  1881. if (cur_stream) {
  1882. stream_close(cur_stream);
  1883. cur_stream = NULL;
  1884. }
  1885. if (show_status)
  1886. printf("\n");
  1887. SDL_Quit();
  1888. exit(0);
  1889. }
  1890. void toggle_audio_display(void)
  1891. {
  1892. if (cur_stream) {
  1893. cur_stream->show_audio = !cur_stream->show_audio;
  1894. }
  1895. }
  1896. /* handle an event sent by the GUI */
  1897. void event_loop(void)
  1898. {
  1899. SDL_Event event;
  1900. double incr, pos, frac;
  1901. for(;;) {
  1902. SDL_WaitEvent(&event);
  1903. switch(event.type) {
  1904. case SDL_KEYDOWN:
  1905. switch(event.key.keysym.sym) {
  1906. case SDLK_ESCAPE:
  1907. case SDLK_q:
  1908. do_exit();
  1909. break;
  1910. case SDLK_f:
  1911. toggle_full_screen();
  1912. break;
  1913. case SDLK_p:
  1914. case SDLK_SPACE:
  1915. toggle_pause();
  1916. break;
  1917. case SDLK_s: //S: Step to next frame
  1918. step_to_next_frame();
  1919. break;
  1920. case SDLK_a:
  1921. if (cur_stream)
  1922. stream_cycle_channel(cur_stream, CODEC_TYPE_AUDIO);
  1923. break;
  1924. case SDLK_v:
  1925. if (cur_stream)
  1926. stream_cycle_channel(cur_stream, CODEC_TYPE_VIDEO);
  1927. break;
  1928. case SDLK_t:
  1929. if (cur_stream)
  1930. stream_cycle_channel(cur_stream, CODEC_TYPE_SUBTITLE);
  1931. break;
  1932. case SDLK_w:
  1933. toggle_audio_display();
  1934. break;
  1935. case SDLK_LEFT:
  1936. incr = -10.0;
  1937. goto do_seek;
  1938. case SDLK_RIGHT:
  1939. incr = 10.0;
  1940. goto do_seek;
  1941. case SDLK_UP:
  1942. incr = 60.0;
  1943. goto do_seek;
  1944. case SDLK_DOWN:
  1945. incr = -60.0;
  1946. do_seek:
  1947. if (cur_stream) {
  1948. pos = get_master_clock(cur_stream);
  1949. pos += incr;
  1950. stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), incr);
  1951. }
  1952. break;
  1953. default:
  1954. break;
  1955. }
  1956. break;
  1957. case SDL_MOUSEBUTTONDOWN:
  1958. if (cur_stream) {
  1959. int ns, hh, mm, ss;
  1960. int tns, thh, tmm, tss;
  1961. tns = cur_stream->ic->duration/1000000LL;
  1962. thh = tns/3600;
  1963. tmm = (tns%3600)/60;
  1964. tss = (tns%60);
  1965. frac = (double)event.button.x/(double)cur_stream->width;
  1966. ns = frac*tns;
  1967. hh = ns/3600;
  1968. mm = (ns%3600)/60;
  1969. ss = (ns%60);
  1970. fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
  1971. hh, mm, ss, thh, tmm, tss);
  1972. stream_seek(cur_stream, (int64_t)(cur_stream->ic->start_time+frac*cur_stream->ic->duration), 0);
  1973. }
  1974. break;
  1975. case SDL_VIDEORESIZE:
  1976. if (cur_stream) {
  1977. screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
  1978. SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
  1979. cur_stream->width = event.resize.w;
  1980. cur_stream->height = event.resize.h;
  1981. }
  1982. break;
  1983. case SDL_QUIT:
  1984. case FF_QUIT_EVENT:
  1985. do_exit();
  1986. break;
  1987. case FF_ALLOC_EVENT:
  1988. alloc_picture(event.user.data1);
  1989. break;
  1990. case FF_REFRESH_EVENT:
  1991. video_refresh_timer(event.user.data1);
  1992. break;
  1993. default:
  1994. break;
  1995. }
  1996. }
  1997. }
  1998. void opt_width(const char *arg)
  1999. {
  2000. screen_width = atoi(arg);
  2001. }
  2002. void opt_height(const char *arg)
  2003. {
  2004. screen_height = atoi(arg);
  2005. }
  2006. static void opt_format(const char *arg)
  2007. {
  2008. file_iformat = av_find_input_format(arg);
  2009. if (!file_iformat) {
  2010. fprintf(stderr, "Unknown input format: %s\n", arg);
  2011. exit(1);
  2012. }
  2013. }
  2014. static void opt_image_format(const char *arg)
  2015. {
  2016. AVImageFormat *f;
  2017. for(f = first_image_format; f != NULL; f = f->next) {
  2018. if (!strcmp(arg, f->name))
  2019. break;
  2020. }
  2021. if (!f) {
  2022. fprintf(stderr, "Unknown image format: '%s'\n", arg);
  2023. exit(1);
  2024. }
  2025. image_format = f;
  2026. }
  2027. #ifdef CONFIG_NETWORK
  2028. void opt_rtp_tcp(void)
  2029. {
  2030. /* only tcp protocol */
  2031. rtsp_default_protocols = (1 << RTSP_PROTOCOL_RTP_TCP);
  2032. }
  2033. #endif
  2034. void opt_sync(const char *arg)
  2035. {
  2036. if (!strcmp(arg, "audio"))
  2037. av_sync_type = AV_SYNC_AUDIO_MASTER;
  2038. else if (!strcmp(arg, "video"))
  2039. av_sync_type = AV_SYNC_VIDEO_MASTER;
  2040. else if (!strcmp(arg, "ext"))
  2041. av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
  2042. else
  2043. show_help();
  2044. }
  2045. void opt_seek(const char *arg)
  2046. {
  2047. start_time = parse_date(arg, 1);
  2048. }
  2049. static void opt_debug(const char *arg)
  2050. {
  2051. debug = atoi(arg);
  2052. }
  2053. static void opt_vismv(const char *arg)
  2054. {
  2055. debug_mv = atoi(arg);
  2056. }
  2057. static void opt_thread_count(const char *arg)
  2058. {
  2059. thread_count= atoi(arg);
  2060. #if !defined(HAVE_THREADS)
  2061. fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
  2062. #endif
  2063. }
  2064. const OptionDef options[] = {
  2065. { "h", 0, {(void*)show_help}, "show help" },
  2066. { "x", HAS_ARG, {(void*)opt_width}, "force displayed width", "width" },
  2067. { "y", HAS_ARG, {(void*)opt_height}, "force displayed height", "height" },
  2068. #if 0
  2069. /* disabled as SDL/X11 does not support it correctly on application launch */
  2070. { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" },
  2071. #endif
  2072. { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },
  2073. { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
  2074. { "ss", HAS_ARG, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" },
  2075. { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" },
  2076. { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
  2077. { "img", HAS_ARG, {(void*)opt_image_format}, "force image format", "img_fmt" },
  2078. { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" },
  2079. { "debug", HAS_ARG | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
  2080. { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" },
  2081. { "vismv", HAS_ARG | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },
  2082. { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" },
  2083. { "genpts", OPT_BOOL | OPT_EXPERT, {(void*)&genpts}, "generate pts", "" },
  2084. { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" },
  2085. { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" },
  2086. { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" },
  2087. { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" },
  2088. { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo", "algo" },
  2089. { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_resilience}, "set error detection threshold (0-4)", "threshold" },
  2090. { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options", "bit_mask" },
  2091. #ifdef CONFIG_NETWORK
  2092. { "rtp_tcp", OPT_EXPERT, {(void*)&opt_rtp_tcp}, "force RTP/TCP protocol usage", "" },
  2093. #endif
  2094. { "sync", HAS_ARG | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
  2095. { "threads", HAS_ARG | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
  2096. { NULL, },
  2097. };
  2098. void show_help(void)
  2099. {
  2100. printf("ffplay version " FFMPEG_VERSION ", Copyright (c) 2003 Fabrice Bellard\n"
  2101. "usage: ffplay [options] input_file\n"
  2102. "Simple media player\n");
  2103. printf("\n");
  2104. show_help_options(options, "Main options:\n",
  2105. OPT_EXPERT, 0);
  2106. show_help_options(options, "\nAdvanced options:\n",
  2107. OPT_EXPERT, OPT_EXPERT);
  2108. printf("\nWhile playing:\n"
  2109. "q, ESC quit\n"
  2110. "f toggle full screen\n"
  2111. "p, SPC pause\n"
  2112. "a cycle audio channel\n"
  2113. "v cycle video channel\n"
  2114. "t cycle subtitle channel\n"
  2115. "w show audio waves\n"
  2116. "left/right seek backward/forward 10 seconds\n"
  2117. "down/up seek backward/forward 1 minute\n"
  2118. "mouse click seek to percentage in file corresponding to fraction of width\n"
  2119. );
  2120. exit(1);
  2121. }
  2122. void parse_arg_file(const char *filename)
  2123. {
  2124. if (!strcmp(filename, "-"))
  2125. filename = "pipe:";
  2126. input_filename = filename;
  2127. }
  2128. /* Called from the main */
  2129. int main(int argc, char **argv)
  2130. {
  2131. int flags, w, h;
  2132. /* register all codecs, demux and protocols */
  2133. av_register_all();
  2134. #ifdef CONFIG_OS2
  2135. MorphToPM(); // Morph the VIO application to a PM one to be able to use Win* functions
  2136. // Make stdout and stderr unbuffered
  2137. setbuf( stdout, NULL );
  2138. setbuf( stderr, NULL );
  2139. #endif
  2140. parse_options(argc, argv, options);
  2141. if (!input_filename)
  2142. show_help();
  2143. if (display_disable) {
  2144. video_disable = 1;
  2145. }
  2146. flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
  2147. #ifndef CONFIG_WIN32
  2148. flags |= SDL_INIT_EVENTTHREAD; /* Not supported on win32 */
  2149. #endif
  2150. if (SDL_Init (flags)) {
  2151. fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
  2152. exit(1);
  2153. }
  2154. if (!display_disable) {
  2155. #ifdef HAVE_X11
  2156. /* save the screen resolution... SDL should allow full screen
  2157. by resizing the window */
  2158. {
  2159. Display *dpy;
  2160. dpy = XOpenDisplay(NULL);
  2161. if (dpy) {
  2162. fs_screen_width = DisplayWidth(dpy, DefaultScreen(dpy));
  2163. fs_screen_height = DisplayHeight(dpy, DefaultScreen(dpy));
  2164. XCloseDisplay(dpy);
  2165. }
  2166. }
  2167. #endif
  2168. flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
  2169. if (is_full_screen && fs_screen_width) {
  2170. w = fs_screen_width;
  2171. h = fs_screen_height;
  2172. flags |= SDL_FULLSCREEN;
  2173. } else {
  2174. w = screen_width;
  2175. h = screen_height;
  2176. flags |= SDL_RESIZABLE;
  2177. }
  2178. screen = SDL_SetVideoMode(w, h, 0, flags);
  2179. if (!screen) {
  2180. fprintf(stderr, "SDL: could not set video mode - exiting\n");
  2181. exit(1);
  2182. }
  2183. SDL_WM_SetCaption("FFplay", "FFplay");
  2184. }
  2185. SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
  2186. SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
  2187. SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
  2188. SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
  2189. cur_stream = stream_open(input_filename, file_iformat);
  2190. event_loop();
  2191. /* never returns */
  2192. return 0;
  2193. }