diff options
-rw-r--r-- | DOCS/man/fr/mplayer.1 | 11 | ||||
-rw-r--r-- | DOCS/xml/pl/encoding-guide.xml | 156 | ||||
-rwxr-xr-x | configure | 32 | ||||
-rw-r--r-- | cpudetect.c | 15 | ||||
-rw-r--r-- | etc/codecs.conf | 9 | ||||
-rw-r--r-- | libmpcodecs/ad_libvorbis.c | 4 | ||||
-rw-r--r-- | libmpcodecs/vf_screenshot.c | 168 | ||||
-rw-r--r-- | libmpeg2/idct.c | 2 | ||||
-rw-r--r-- | libmpeg2/libmpeg2_changes.diff | 2 | ||||
-rw-r--r-- | libvo/video_out.h | 4 | ||||
-rw-r--r-- | libvo/vo_direct3d.c | 162 | ||||
-rw-r--r-- | libvo/vo_fbdev.c | 1813 | ||||
-rw-r--r-- | libvo/vo_gl.c | 42 | ||||
-rw-r--r-- | libvo/vo_macosx.m | 12 | ||||
-rw-r--r-- | libvo/vo_quartz.c | 2512 | ||||
-rw-r--r-- | libvo/vo_wii.c | 275 | ||||
-rw-r--r-- | libvo/vo_x11.c | 37 | ||||
-rw-r--r-- | libvo/vo_xvmc.c | 9 | ||||
-rw-r--r-- | mplayer.c | 11 | ||||
-rw-r--r-- | subdir.mak | 2 |
20 files changed, 2624 insertions, 2654 deletions
diff --git a/DOCS/man/fr/mplayer.1 b/DOCS/man/fr/mplayer.1 index 58bedeb1f2..2d3a595ba6 100644 --- a/DOCS/man/fr/mplayer.1 +++ b/DOCS/man/fr/mplayer.1 @@ -1,4 +1,4 @@ -.\" synced with r27906 +.\" synced with r27979 .\" Encoding: iso-8859-1 .\" MPlayer (C) 2000-2008 MPlayer Team .\" The English man page was/is done by Gabucino, Diego Biurrun, Jonas Jermann @@ -3435,8 +3435,9 @@ La position initiale dfinie par l'option \-geometry est relative l'cran dfini. Fontionnera gnralement uniquement avec "\-fstype \-fullscreen" ou "\-fstype none". -Cette option ne convient pour dfinir l'cran de dmarrage (de mme pour -l'cran en mode plein cran), \-geometry est plus appropri. +Cette option ne convient pas pour dfinir l'cran de dmarrage (car l'affichage +se fera toujours en plein cran sur le moniteur donn), \-geometry est plus +appropri. Gr par les pilotes de sortie vido gl, gl2, x11, et xv. . .TP @@ -3684,6 +3685,10 @@ Comme pour vidix VIDIX tournant sous Windows. . .TP +.B direct3d (Windows uniquement) (CODE BTA!) +Pilote de sortie vido utilisant l'interface Direct3D (utilse sous Vista). +. +.TP .B directx (Windows uniquement) Pilote de sortie vido utilisant l'interface DirectX. .PD 0 diff --git a/DOCS/xml/pl/encoding-guide.xml b/DOCS/xml/pl/encoding-guide.xml index cbb7c07f4f..8f83921cda 100644 --- a/DOCS/xml/pl/encoding-guide.xml +++ b/DOCS/xml/pl/encoding-guide.xml @@ -1096,137 +1096,141 @@ rozdzielczości DVD) żeby dobrze wyglądać. </sect2> <!-- ********** --> -<!-- synced 'till here --> <sect2 id="menc-feat-dvd-mpeg4-filtering"> -<title>Filtering</title> +<title>Filtrowanie</title> <para> -Learning how to use <application>MEncoder</application>'s video filters -is essential to producing good encodes. -All video processing is performed through the filters -- cropping, -scaling, color adjustment, noise removal, sharpening, deinterlacing, -telecine, inverse telecine, and deblocking, just to name a few. -Along with the vast number of supported input formats, the variety of -filters available in <application>MEncoder</application> is one of its -main advantages over other similar programs. +Bardzo ważne do robienia dobrych kodowań jest nauczenie się posługiwania +systemem filtrów <application>MEncodera</application>. +Całe przetwarzanie video jest wykonywane przez filtry – kadrowanie, skalowanie, +dopasowywanie kolorów, usuwanie szumu, telecine, odwrócone telecine, usuwanie +bloków żeby wymienić choć część. +Poza dużą ilością obsługiwanych formatów wejściowych to właśnie zakres +dostępnych filtrów jest jedną z głównych przewag +<application>MEncodera</application> nad podobnymi programami. </para> <para> -Filters are loaded in a chain using the -vf option: +Filtry są ładowane do łańcucha przy pomocy opcji -vf: -<screen>-vf filter1=options,filter2=options,...</screen> +<screen>-vf filtr1=opcje,filtr2=opcje,...</screen> -Most filters take several numeric options separated by colons, but -the syntax for options varies from filter to filter, so read the man -page for details on the filters you wish to use. +Większość filtrów przyjmuje kilka parametrów numerycznych oddzielanych +dwukropkami, ale dokładna składnia zależy od filtru więc szczegóły odnośnie +filtrów, które chcesz zastosować, znajdziesz na stronie man. </para> <para> -Filters operate on the video in the order they are loaded. -For example, the following chain: +Filtry działają na filmie w kolejnoścy w jakiej zostały załadowane. +Na przykład następujący łańcuch: <screen>-vf crop=688:464:12:4,scale=640:464</screen> -will first crop the 688x464 region of the picture with upper-left -corner at (12,4), and then scale the result down to 640x464. +najpierw skadruje fragment 688x464 filmu z lewym górnym rogiem na pozycji +(12,4) a potem zmniejszy rozdzielczość wyniku do 640x464. </para> <para> -Certain filters need to be loaded at or near the beginning of the -filter chain, in order to take advantage of information from the -video decoder that will be lost or invalidated by other filters. -The principal examples are <option>pp</option> (postprocessing, only -when it is performing deblock or dering operations), -<option>spp</option> (another postprocessor to remove MPEG artifacts), -<option>pullup</option> (inverse telecine), and -<option>softpulldown</option> (for converting soft telecine to hard telecine). +Niektóre filtry trzeba ładować na początku lub blisko początku łańcucha, +ponieważ korzystają one z informacji którą następne filtry mogą zgubić lub +unieważnić. +Sztandarowym przykłądem jest <option>pp</option> (postprocessing, tylko gdy +wykonuje operacje usuwania bloków lub pierścieni), +<option>spp</option> (inny postprocessor do usuwania artefaktów MPEG), +<option>pullup</option> (odwrócone telecine) i +<option>softpulldown</option> (konwertuje miękkie telecine na twarde). </para> <para> -In general, you want to do as little filtering as possible to the movie -in order to remain close to the original DVD source. Cropping is often -necessary (as described above), but avoid to scale the video. Although -scaling down is sometimes preferred to using higher quantizers, we want -to avoid both these things: remember that we decided from the start to -trade bits for quality. +W ogólności chcesz przeprowadzać jak najmniej filtrowania żeby film pozostał +możliwie bliski oryginałowi. +Kadrowanie często jest niezbęne (jak opisano powyżej) ale staraj się uniknąć +skalowania. +Chociaż czasami zmniejszenie rozdzielczości jest lepszym wyjściem niż użycie +wyższego kwantyzatora, chcemy uniknąć obu: pamiętajmy, że od początku +zdecydowaliśmy się wybrać jakość kosztem wielkości. </para> <para> -Also, do not adjust gamma, contrast, brightness, etc. What looks good -on your display may not look good on others. These adjustments should -be done on playback only. +Nie należy też dostosowywać gammy, kontrastu, jasności itp. +Co wygląda dobrze na Twoim ekranie może nie być tak dobre na innych. +Takie dostrojenia powinny być wykonywane tylko przy odtwarzaniu. </para> <para> -One thing you might want to do, however, is pass the video through a -very light denoise filter, such as <option>-vf hqdn3d=2:1:2</option>. -Again, it is a matter of putting those bits to better use: why waste them -encoding noise when you can just add that noise back in during playback? -Increasing the parameters for <option>hqdn3d</option> will further -improve compressibility, but if you increase the values too much, you -risk degrading the image visibly. The suggested values above -(<option>2:1:2</option>) are quite conservative; you should feel free to -experiment with higher values and observe the results for yourself. +Jedną rzeczą którą możesz chcieć zrobić, jest przepuszczenie filmu przez bardzo +lekkie usuwanie szumów, takie jak <option>-vf hqdn3d=2:1:2</option>. +Znów, to kwestia lepszego zastosowania bitów: po co marnować je na zakodowanie +szumu skoro można dodać ten szum przy odtwarzaniu? +Zwiększenie parametrów dla <option>hqdn3d</option> jeszcze bardziej poprawi +kompresowalność, ale jeśli przesadzisz to zauważalnie zniekształcisz obraz. +Wartości sugerowane powyżej (<option>2:1:2</option>) są dość konserwatywne; nie +bój się eksperymentować z wyższymi wartościami i samemu oceniać wyniki. </para> </sect2> <!-- ********** --> <sect2 id="menc-feat-dvd-mpeg4-interlacing"> -<title>Interlacing and Telecine</title> +<title>Przeplot i telecine</title> <para> -Almost all movies are shot at 24 fps. Because NTSC is 30000/1001 fps, some -processing must be done to this 24 fps video to make it run at the correct -NTSC framerate. The process is called 3:2 pulldown, commonly referred to -as telecine (because pulldown is often applied during the telecine -process), and, naively described, it works by slowing the film down to -24000/1001 fps, and repeating every fourth frame. +Prawie wszystkie filmy są kręcone przy 24 fps. +Ponieważ NTSC ma 30000/1001 fps potrzebna jest pewna przeróbka żeby film 24 fps +mógł być wyświetlany z prawidłową szybkością NTSC. +Ten proces nazywa się 3:2 pulldown, często zwany też telecine (ponieważ jest +używany przy konwersji z kina do telewizji) i, w uproszczeniu, jest to +spowolnienie filmu do 24000/1001 fps i powtórzenie co czwartej klatki. </para> <para> -No special processing, however, is done to the video for PAL DVDs, which -run at 25 fps. (Technically, PAL can be telecined, called 2:2 pulldown, -but this does not become an issue in practice.) The 24 fps film is simply -played back at 25 fps. The result is that the movie runs slightly faster, -but unless you are an alien, you probably will not notice the difference. -Most PAL DVDs have pitch-corrected audio, so when they are played back at -25 fps things will sound right, even though the audio track (and hence the -whole movie) has a running time that is 4% less than NTSC DVDs. +Filmy DVD PAL, odtwarzanie przy 25 fps, nie wymagają żadnego specjalnego +traktowania. +(Technicznie rzecz ujmując, PAL może być poddany telecine, nazywanemu 2:2 +pulldown, ale w praktyce nie jest to problemem.) +Po prostu film 24 fps jest odtwarzany przy 25 fps. +W wyniku tego film jest odtwarzany odrobinkę szybciej, ale jeśli nie masz +nieziemskich zmysłów to tego nie zauważysz. +Większość DVD PAL ma skorygowaną wysokość dźwięku, więc kiedy są odtwarzane +przy 25 fps dźwięk będzie brzmiał poprawnie, mimo tego że ścieżka dźwiekowa +(jak i cały film) jest o 4% krótsza niż DVD NTSC. </para> <para> -Because the video in a PAL DVD has not been altered, you need not worry -much about framerate. The source is 25 fps, and your rip will be 25 -fps. However, if you are ripping an NTSC DVD movie, you may need to -apply inverse telecine. +Ponieważ film na DVD PAL nie został zmieniony, nie ma powodu za bardzo +przejmować się framerate. +Oryginał ma 25 fps i Twój rip też będzie miał 25 fps. +Jednak jeśli ripujesz film z DVD NTSC możesz być zmuszony do zastosowania +odwrotnego telecine. </para> <para> -For movies shot at 24 fps, the video on the NTSC DVD is either telecined -30000/1001, or else it is progressive 24000/1001 fps and intended to be -telecined on-the-fly by a DVD player. On the other hand, TV series are usually -only interlaced, not telecined. This is not a hard rule: some TV series -are interlaced (such as Buffy the Vampire Slayer) whereas some are a -mixture of progressive and interlaced (such as Angel, or 24). +Dla filmów nagrywanych przy 24 fps obraz na DVD NTSC jest albo poddany telecine +na 30000/1001 albo jest progresywny przy 24000/1001 i przeznaczony do poddania +telecine w locie przez odtwarzacz DVD. +Z drugiej strony seriale telewizyjne zazwyczaj mają tylko przeplot, nie są poddane telecine. +Nie jest to reguła: Niektóre seriale (na przykład Buffy Łowca Wampirów) mają +przeplot, a inne są mieszanką progresywnego i przeplotu (Angel, 24). </para> <para> -It is highly recommended that you read the section on +Jest wysoce zalecane żebyś przeczytał sekcję +<!-- TODO przetłumaczyć tytuł --> <link linkend="menc-feat-telecine">How to deal with telecine and interlacing in NTSC DVDs</link> -to learn how to handle the different possibilities. +żeby dowiedzieć się jak sobie radzić z różnymi możliwościami. </para> <para> -However, if you are mostly just ripping movies, likely you are either -dealing with 24 fps progressive or telecined video, in which case you can -use the <option>pullup</option> filter <option>-vf -pullup,softskip</option>. +Jednak jeśli zazwyczaj tylko ripujesz filmy, prawdopodobnie masz doczynienia +z filmem 24 fps progresywnym lub poddanym telecine, a w takim przypadku możesz +użyć filtra <option>pullup</option> podając parametr +<option>-vf pullup,softskip</option>. </para> </sect2> <!-- ********** --> +<!-- synced 'till here --> <sect2 id="menc-feat-dvd-mpeg4-encoding-interlaced"> <title>Encoding interlaced video</title> @@ -1488,7 +1488,7 @@ if test "`basename $_cc`" = "icc" || test "`basename $_cc`" = "ecc"; then cc_version="v. ?.??, bad" cc_fail=yes ;; - 10.1) + 10.1|11.0) cc_version="$cc_version, ok" ;; *) @@ -3582,9 +3582,23 @@ if test "$_macosx" = auto ; then fi if test "$_macosx" = yes ; then cat > $TMPC <<EOF +#include <CoreAudio/CoreAudio.h> +int main(void) { return 0; } +EOF + if cc_check -framework CoreAudio; then + _ld_extra="$_ld_extra -framework CoreAudio -framework AudioUnit -framework AudioToolbox" + _coreaudio=yes + _def_coreaudio='#define CONFIG_COREAUDIO 1' + _aosrc="$_aosrc ao_macosx.c" + _aomodules="macosx $_aomodules" + else + _coreaudio=no + _def_coreaudio='#undef CONFIG_COREAUDIO' + _noaomodules="macosx $_noaomodules" + fi + cat > $TMPC <<EOF #include <Carbon/Carbon.h> #include <QuickTime/QuickTime.h> -#include <CoreAudio/CoreAudio.h> int main(void) { EnterMovies(); ExitMovies(); @@ -3592,21 +3606,15 @@ int main(void) { return 0; } EOF - if cc_check -framework Carbon -framework QuickTime -framework CoreAudio; then - _ld_extra="$_ld_extra -framework Carbon -framework QuickTime -framework CoreAudio -framework AudioUnit -framework AudioToolbox" - _coreaudio=yes - _def_coreaudio='#define CONFIG_COREAUDIO 1' - _aosrc="$_aosrc ao_macosx.c" - _aomodules="macosx $_aomodules" + if cc_check -framework Carbon -framework QuickTime; then + _ld_extra="$_ld_extra -framework Carbon -framework QuickTime" + _quartz=yes _def_quartz='#define CONFIG_QUARTZ 1' _vosrc="$_vosrc vo_quartz.c" _vomodules="quartz $_vomodules" _def_quicktime='#define CONFIG_QUICKTIME 1' else - _macosx=no - _coreaudio=no - _def_coreaudio='#undef CONFIG_COREAUDIO' - _noaomodules="macosx $_noaomodules" + _quartz=yes _def_quartz='#undef CONFIG_QUARTZ' _novomodules="quartz $_novomodules" _def_quicktime='#undef CONFIG_QUICKTIME' diff --git a/cpudetect.c b/cpudetect.c index 22edd58795..ffd0705e0e 100644 --- a/cpudetect.c +++ b/cpudetect.c @@ -57,10 +57,17 @@ static int has_cpuid(void) long a, c; // code from libavcodec: +#ifdef ARCH_X86_64 +#define PUSHF "pushfq\n\t" +#define POPF "popfq\n\t" +#else +#define PUSHF "pushfl\n\t" +#define POPF "popfl\n\t" +#endif __asm__ volatile ( /* See if CPUID instruction is supported ... */ /* ... Get copies of EFLAGS into eax and ecx */ - "pushf\n\t" + PUSHF "pop %0\n\t" "mov %0, %1\n\t" @@ -68,15 +75,17 @@ static int has_cpuid(void) /* to the EFLAGS reg */ "xor $0x200000, %0\n\t" "push %0\n\t" - "popf\n\t" + POPF /* ... Get the (hopefully modified) EFLAGS */ - "pushf\n\t" + PUSHF "pop %0\n\t" : "=a" (a), "=c" (c) : : "cc" ); +#undef PUSHF +#undef POPF return a != c; } diff --git a/etc/codecs.conf b/etc/codecs.conf index a4989bc057..79184f2c22 100644 --- a/etc/codecs.conf +++ b/etc/codecs.conf @@ -3491,6 +3491,15 @@ audiocodec vorbis driver libvorbis dll "libvorbis" +audiocodec tremor + info "OggVorbis audio decoder" + status working + comment "OggVorbis fixed-point decoder useful for ARM based systems" + fourcc vrbs + format 0x566F + driver tremor + dll "tremor" + audiocodec vorbisacm info "OggVorbis ACM" status working diff --git a/libmpcodecs/ad_libvorbis.c b/libmpcodecs/ad_libvorbis.c index 6f37e27710..520b07f50a 100644 --- a/libmpcodecs/ad_libvorbis.c +++ b/libmpcodecs/ad_libvorbis.c @@ -12,7 +12,11 @@ static const ad_info_t info = { "Ogg/Vorbis audio decoder", +#ifdef CONFIG_TREMOR + "tremor", +#else "libvorbis", +#endif "Felix Buenemann, A'rpi", "libvorbis", "" diff --git a/libmpcodecs/vf_screenshot.c b/libmpcodecs/vf_screenshot.c index 7770dd4de0..8471285345 100644 --- a/libmpcodecs/vf_screenshot.c +++ b/libmpcodecs/vf_screenshot.c @@ -41,11 +41,11 @@ struct vf_priv_s { //===========================================================================// static int config(struct vf_instance* vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt) + int width, int height, int d_width, int d_height, + unsigned int flags, unsigned int outfmt) { vf->priv->ctx=sws_getContextFromCmdLine(width, height, outfmt, - d_width, d_height, IMGFMT_RGB24); + d_width, d_height, IMGFMT_RGB24); vf->priv->outbuffer_size = d_width * d_height * 3 * 2; vf->priv->outbuffer = realloc(vf->priv->outbuffer, vf->priv->outbuffer_size); @@ -72,10 +72,10 @@ static void write_png(struct vf_priv_s *priv) fp = fopen (fname, "wb"); if (fp == NULL) { - mp_msg(MSGT_VFILTER,MSGL_ERR,"\nPNG Error opening %s for writing!\n", fname); - return; + mp_msg(MSGT_VFILTER,MSGL_ERR,"\nPNG Error opening %s for writing!\n", fname); + return; } - + pic.data[0] = priv->buffer; pic.linesize[0] = priv->stride; size = avcodec_encode_video(priv->avctx, priv->outbuffer, priv->outbuffer_size, &pic); @@ -95,11 +95,11 @@ static int fexists(char *fname) static void gen_fname(struct vf_priv_s* priv) { do { - snprintf (priv->fname, 100, "shot%04d.png", ++priv->frameno); + snprintf (priv->fname, 100, "shot%04d.png", ++priv->frameno); } while (fexists(priv->fname) && priv->frameno < 100000); if (fexists(priv->fname)) { - priv->fname[0] = '\0'; - return; + priv->fname[0] = '\0'; + return; } mp_msg(MSGT_VFILTER,MSGL_INFO,"*** screenshot '%s' ***\n",priv->fname); @@ -110,96 +110,99 @@ static void scale_image(struct vf_priv_s* priv, mp_image_t *mpi) { uint8_t *dst[3]; int dst_stride[3]; - + dst_stride[0] = priv->stride; dst_stride[1] = dst_stride[2] = 0; if (!priv->buffer) - priv->buffer = memalign(16, dst_stride[0]*priv->dh); + priv->buffer = memalign(16, dst_stride[0]*priv->dh); dst[0] = priv->buffer; dst[1] = dst[2] = 0; sws_scale_ordered(priv->ctx, mpi->planes, mpi->stride, 0, priv->dh, dst, dst_stride); } -static void start_slice(struct vf_instance* vf, mp_image_t *mpi){ +static void start_slice(struct vf_instance* vf, mp_image_t *mpi) +{ vf->dmpi=vf_get_image(vf->next,mpi->imgfmt, - mpi->type, mpi->flags, mpi->width, mpi->height); + mpi->type, mpi->flags, mpi->width, mpi->height); if (vf->priv->shot) { - vf->priv->store_slices = 1; - if (!vf->priv->buffer) - vf->priv->buffer = memalign(16, vf->priv->stride*vf->priv->dh); + vf->priv->store_slices = 1; + if (!vf->priv->buffer) + vf->priv->buffer = memalign(16, vf->priv->stride*vf->priv->dh); } - + } -static void draw_slice(struct vf_instance* vf, - unsigned char** src, int* stride, int w,int h, int x, int y){ +static void draw_slice(struct vf_instance* vf, unsigned char** src, + int* stride, int w,int h, int x, int y) +{ if (vf->priv->store_slices) { - uint8_t *dst[3]; - int dst_stride[3]; - dst_stride[0] = vf->priv->stride; - dst_stride[1] = dst_stride[2] = 0; - dst[0] = vf->priv->buffer; - dst[1] = dst[2] = 0; - sws_scale_ordered(vf->priv->ctx, src, stride, y, h, dst, dst_stride); + uint8_t *dst[3]; + int dst_stride[3]; + dst_stride[0] = vf->priv->stride; + dst_stride[1] = dst_stride[2] = 0; + dst[0] = vf->priv->buffer; + dst[1] = dst[2] = 0; + sws_scale_ordered(vf->priv->ctx, src, stride, y, h, dst, dst_stride); } vf_next_draw_slice(vf,src,stride,w,h,x,y); } -static void get_image(struct vf_instance* vf, mp_image_t *mpi){ +static void get_image(struct vf_instance* vf, mp_image_t *mpi) +{ // FIXME: should vf.c really call get_image when using slices?? if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK) return; - vf->dmpi= vf_get_image(vf->next, mpi->imgfmt, - mpi->type, mpi->flags/* | MP_IMGFLAG_READABLE*/, mpi->width, mpi->height); + vf->dmpi= vf_get_image(vf->next, mpi->imgfmt, + mpi->type, mpi->flags/* | MP_IMGFLAG_READABLE*/, mpi->width, mpi->height); mpi->planes[0]=vf->dmpi->planes[0]; mpi->stride[0]=vf->dmpi->stride[0]; if(mpi->flags&MP_IMGFLAG_PLANAR){ - mpi->planes[1]=vf->dmpi->planes[1]; - mpi->planes[2]=vf->dmpi->planes[2]; - mpi->stride[1]=vf->dmpi->stride[1]; - mpi->stride[2]=vf->dmpi->stride[2]; + mpi->planes[1]=vf->dmpi->planes[1]; + mpi->planes[2]=vf->dmpi->planes[2]; + mpi->stride[1]=vf->dmpi->stride[1]; + mpi->stride[2]=vf->dmpi->stride[2]; } mpi->width=vf->dmpi->width; mpi->flags|=MP_IMGFLAG_DIRECT; - + mpi->priv=(void*)vf->dmpi; } static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts) { mp_image_t *dmpi = (mp_image_t *)mpi->priv; - + if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK) dmpi = vf->dmpi; else if(!(mpi->flags&MP_IMGFLAG_DIRECT)){ - dmpi=vf_get_image(vf->next,mpi->imgfmt, - MP_IMGTYPE_EXPORT, 0, - mpi->width, mpi->height); - vf_clone_mpi_attributes(dmpi, mpi); - dmpi->planes[0]=mpi->planes[0]; - dmpi->planes[1]=mpi->planes[1]; - dmpi->planes[2]=mpi->planes[2]; - dmpi->stride[0]=mpi->stride[0]; - dmpi->stride[1]=mpi->stride[1]; - dmpi->stride[2]=mpi->stride[2]; - dmpi->width=mpi->width; - dmpi->height=mpi->height; + dmpi=vf_get_image(vf->next,mpi->imgfmt, + MP_IMGTYPE_EXPORT, 0, + mpi->width, mpi->height); + vf_clone_mpi_attributes(dmpi, mpi); + dmpi->planes[0]=mpi->planes[0]; + dmpi->planes[1]=mpi->planes[1]; + dmpi->planes[2]=mpi->planes[2]; + dmpi->stride[0]=mpi->stride[0]; + dmpi->stride[1]=mpi->stride[1]; + dmpi->stride[2]=mpi->stride[2]; + dmpi->width=mpi->width; + dmpi->height=mpi->height; } if(vf->priv->shot) { - if (vf->priv->shot==1) - vf->priv->shot=0; - gen_fname(vf->priv); - if (vf->priv->fname[0]) { - if (!vf->priv->store_slices) - scale_image(vf->priv, dmpi); - write_png(vf->priv); - } - vf->priv->store_slices = 0; + if (vf->priv->shot==1) + vf->priv->shot=0; + gen_fname(vf->priv); + if (vf->priv->fname[0]) { + if (!vf->priv->store_slices) + scale_image(vf->priv, dmpi); + write_png(vf->priv); + } + vf->priv->store_slices = 0; } return vf_next_put_image(vf, dmpi, pts); @@ -212,15 +215,15 @@ static int control (vf_instance_t *vf, int request, void *data) * 1: take screenshots with each frame until the same command is given once again **/ if(request==VFCTRL_SCREENSHOT) { - if (data && *(int*)data) { // repeated screenshot mode - if (vf->priv->shot==2) - vf->priv->shot=0; - else - vf->priv->shot=2; - } else { // single screenshot - if (!vf->priv->shot) - vf->priv->shot=1; - } + if (data && *(int*)data) { // repeated screenshot mode + if (vf->priv->shot==2) + vf->priv->shot=0; + else + vf->priv->shot=2; + } else { // single screenshot + if (!vf->priv->shot) + vf->priv->shot=1; + } return CONTROL_TRUE; } return vf_next_control (vf, request, data); @@ -243,19 +246,27 @@ static int query_format(struct vf_instance* vf, unsigned int fmt) case IMGFMT_BGR15: case IMGFMT_RGB32: case IMGFMT_RGB24: - case IMGFMT_Y800: - case IMGFMT_Y8: - case IMGFMT_YVU9: - case IMGFMT_IF09: - case IMGFMT_444P: - case IMGFMT_422P: - case IMGFMT_411P: - return vf_next_query_format(vf, fmt); + case IMGFMT_Y800: + case IMGFMT_Y8: + case IMGFMT_YVU9: + case IMGFMT_IF09: + case IMGFMT_444P: + case IMGFMT_422P: + case IMGFMT_411P: + return vf_next_query_format(vf, fmt); } return 0; } -static void uninit(vf_instance_t *vf); +static void uninit(vf_instance_t *vf) +{ + av_freep(&vf->priv->avctx); + if(vf->priv->ctx) sws_freeContext(vf->priv->ctx); + if (vf->priv->buffer) free(vf->priv->buffer); + free(vf->priv->outbuffer); + free(vf->priv); +} + // open conflicts with stdio.h at least under MinGW static int screenshot_open(vf_instance_t *vf, char* args) { @@ -283,15 +294,6 @@ static int screenshot_open(vf_instance_t *vf, char* args) return 1; } -static void uninit(vf_instance_t *vf) -{ - av_freep(&vf->priv->avctx); - if(vf->priv->ctx) sws_freeContext(vf->priv->ctx); - if (vf->priv->buffer) free(vf->priv->buffer); - free(vf->priv->outbuffer); - free(vf->priv); -} - const vf_info_t vf_info_screenshot = { "screenshot to file", diff --git a/libmpeg2/idct.c b/libmpeg2/idct.c index 82049df4bc..e753053354 100644 --- a/libmpeg2/idct.c +++ b/libmpeg2/idct.c @@ -265,7 +265,7 @@ void mpeg2_idct_init (uint32_t accel) mpeg2_idct_altivec_init (); } else #endif -#ifdef HAVE_VIS +#ifdef HAVE_MVI if (accel & MPEG2_ACCEL_ALPHA_MVI) { mpeg2_idct_copy = mpeg2_idct_copy_mvi; mpeg2_idct_add = mpeg2_idct_add_mvi; diff --git a/libmpeg2/libmpeg2_changes.diff b/libmpeg2/libmpeg2_changes.diff index ec95f96997..6220b61f03 100644 --- a/libmpeg2/libmpeg2_changes.diff +++ b/libmpeg2/libmpeg2_changes.diff @@ -111,7 +111,7 @@ } else #endif -#ifdef ARCH_ALPHA -+#ifdef HAVE_VIS ++#ifdef HAVE_MVI if (accel & MPEG2_ACCEL_ALPHA_MVI) { mpeg2_idct_copy = mpeg2_idct_copy_mvi; mpeg2_idct_add = mpeg2_idct_add_mvi; diff --git a/libvo/video_out.h b/libvo/video_out.h index e392b55f2b..7ad09a74a8 100644 --- a/libvo/video_out.h +++ b/libvo/video_out.h @@ -286,8 +286,6 @@ extern int vo_colorkey; extern int WinID; -#if defined(CONFIG_FBDEV) || defined(CONFIG_VESA) - typedef struct { float min; float max; @@ -300,6 +298,4 @@ extern char *monitor_hfreq_str; extern char *monitor_vfreq_str; extern char *monitor_dotclock_str; -#endif /* defined(CONFIG_FBDEV) || defined(CONFIG_VESA) */ - #endif /* MPLAYER_VIDEO_OUT_H */ diff --git a/libvo/vo_direct3d.c b/libvo/vo_direct3d.c index 43f594777c..78b8dbc159 100644 --- a/libvo/vo_direct3d.c +++ b/libvo/vo_direct3d.c @@ -52,9 +52,9 @@ const LIBVO_EXTERN(direct3d) static struct global_priv { int is_paused; /**< 1 = Movie is paused, 0 = Movie is not paused */ - int is_cfg_finished; /**< Synchronization "semaphore". 1 when - instance of reconfigure_d3d is finished */ - + int is_clear_needed; /**< 1 = Clear the backbuffer before StretchRect + 0 = (default) Don't clear it */ + D3DLOCKED_RECT locked_rect; /**< The locked Offscreen surface */ RECT fs_movie_rect; /**< Rect (upscaled) of the movie when displayed in fullscreen */ RECT fs_panscan_rect; /**< PanScan source surface cropping in @@ -155,6 +155,12 @@ static void calc_fs_rect(void) "<vo_direct3d>Fullscreen Movie Rect: t: %ld, l: %ld, r: %ld, b:%ld\r\n", priv->fs_movie_rect.top, priv->fs_movie_rect.left, priv->fs_movie_rect.right, priv->fs_movie_rect.bottom); + + /* The backbuffer should be cleared before next StretchRect. This is + * necessary because our new draw area could be smaller than the + * previous one used by StretchRect and without it, leftovers from the + * previous frame will be left. */ + priv->is_clear_needed = 1; } /** @brief Destroy D3D Context related to the current window. @@ -164,6 +170,11 @@ static void destroy_d3d_context(void) mp_msg(MSGT_VO,MSGL_V,"<vo_direct3d>destroy_d3d_context called\r\n"); /* Let's destroy the old (if any) D3D Content */ + if (priv->locked_rect.pBits) { + IDirect3DSurface9_UnlockRect(priv->d3d_surface); + priv->locked_rect.pBits = NULL; + } + if (priv->d3d_surface != NULL) { IDirect3DSurface9_Release (priv->d3d_surface); priv->d3d_surface = NULL; @@ -254,10 +265,6 @@ static int reconfigure_d3d(void) return 0; } - /* Fill the Surface with black color. */ - IDirect3DDevice9_ColorFill(priv->d3d_device, priv->d3d_surface, NULL, - D3DCOLOR_ARGB(0xFF, 0, 0, 0) ); - calc_fs_rect(); return 1; @@ -269,9 +276,6 @@ static void uninit_d3d(void) { mp_msg(MSGT_VO,MSGL_V,"<vo_direct3d>uninit_d3d called\r\n"); - /* Block further calls to reconfigure_d3d(). */ - priv->is_cfg_finished = 0; - /* Destroy D3D Context inside the window. */ destroy_d3d_context(); @@ -288,40 +292,48 @@ static void uninit_d3d(void) */ static uint32_t render_d3d_frame(mp_image_t *mpi) { - D3DLOCKED_RECT locked_rect; /**< Offscreen surface we lock in order - to copy MPlayer's frame inside it.*/ - /* Uncomment when direct rendering is implemented. * if (mpi->flags & MP_IMGFLAG_DIRECT) ... */ if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK) - return VO_TRUE; + goto skip_upload; if (mpi->flags & MP_IMGFLAG_PLANAR) { /* Copy a planar frame. */ draw_slice(mpi->planes,mpi->stride,mpi->w,mpi->h,0,0); - return VO_TRUE; + goto skip_upload; } - /* If the previous if failed, we should draw a packed frame */ - if (FAILED(IDirect3DDevice9_BeginScene(priv->d3d_device))) { - mp_msg(MSGT_VO,MSGL_ERR,"<vo_direct3d>BeginScene failed\n"); - return VO_ERROR; - } - - if (FAILED(IDirect3DSurface9_LockRect(priv->d3d_surface, - &locked_rect, NULL, 0))) { - mp_msg(MSGT_VO,MSGL_ERR,"<vo_direct3d>Surface lock failure\n"); - return VO_ERROR; + /* If we're here, then we should lock the rect and copy a packed frame */ + if (!priv->locked_rect.pBits) { + if (FAILED(IDirect3DSurface9_LockRect(priv->d3d_surface, + &priv->locked_rect, NULL, 0))) { + mp_msg(MSGT_VO,MSGL_ERR,"<vo_direct3d>Surface lock failure\n"); + return VO_ERROR; + } } - memcpy_pic(locked_rect.pBits, mpi->planes[0], mpi->stride[0], - mpi->height, locked_rect.Pitch, mpi->stride[0]); + memcpy_pic(priv->locked_rect.pBits, mpi->planes[0], mpi->stride[0], + mpi->height, priv->locked_rect.Pitch, mpi->stride[0]); +skip_upload: + /* This unlock is used for both slice_draw path and render_d3d_frame path. */ if (FAILED(IDirect3DSurface9_UnlockRect(priv->d3d_surface))) { mp_msg(MSGT_VO,MSGL_V,"<vo_direct3d>Surface unlock failure\n"); return VO_ERROR; } + priv->locked_rect.pBits = NULL; + + if (FAILED(IDirect3DDevice9_BeginScene(priv->d3d_device))) { + mp_msg(MSGT_VO,MSGL_ERR,"<vo_direct3d>BeginScene failed\n"); + return VO_ERROR; + } + + if (priv->is_clear_needed) { + IDirect3DDevice9_Clear (priv->d3d_device, 0, NULL, + D3DCLEAR_TARGET, 0, 0, 0); + priv->is_clear_needed = 0; + } if (FAILED(IDirect3DDevice9_StretchRect(priv->d3d_device, priv->d3d_surface, @@ -441,9 +453,6 @@ static int preinit(const char *arg) return -1; } - /* Allow the first call to reconfigure_d3d. */ - priv->is_cfg_finished = 1; - return 0; } @@ -527,14 +536,9 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, return VO_ERROR; } - if (priv->is_cfg_finished) { - priv->is_cfg_finished = 0; - if (!reconfigure_d3d()) { - priv->is_cfg_finished = 1; - return VO_ERROR; - } - priv->is_cfg_finished = 1; - } + if (!reconfigure_d3d()) + return VO_ERROR; + return 0; /* Success */ } @@ -560,7 +564,6 @@ static void flip_page(void) mp_msg(MSGT_VO,MSGL_V,"<vo_direct3d>Video adapter reinitialized.\n"); } - /*IDirect3DDevice9_Clear (priv->d3d_device, 0, NULL, D3DCLEAR_TARGET, 0, 0, 0);*/ } /** @brief libvo Callback: Draw OSD/Subtitles, @@ -607,75 +610,50 @@ static void check_events(void) */ static int draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y ) { - D3DLOCKED_RECT locked_rect; /**< Offscreen surface we lock in order - to copy MPlayer's frame inside it.*/ - char *Src; /**< Pointer to the source image */ - char *Dst; /**< Pointer to the destination image */ - int UVstride; /**< Stride of the U/V planes */ - - if (FAILED(IDirect3DDevice9_BeginScene(priv->d3d_device))) { - mp_msg(MSGT_VO,MSGL_ERR,"<vo_direct3d>BeginScene failed\n"); - return VO_ERROR; - } - - if (FAILED(IDirect3DSurface9_LockRect(priv->d3d_surface, - &locked_rect, NULL, 0))) { - mp_msg(MSGT_VO,MSGL_V,"<vo_direct3d>Surface lock failure\n"); - return VO_FALSE; + char *my_src; /**< Pointer to the source image */ + char *dst; /**< Pointer to the destination image */ + int uv_stride; /**< Stride of the U/V planes */ + + /* Lock the offscreen surface if it's not already locked. */ + if (!priv->locked_rect.pBits) { + if (FAILED(IDirect3DSurface9_LockRect(priv->d3d_surface, + &priv->locked_rect, NULL, 0))) { + mp_msg(MSGT_VO,MSGL_V,"<vo_direct3d>Surface lock failure\n"); + return VO_FALSE; + } } - UVstride = locked_rect.Pitch / 2; + uv_stride = priv->locked_rect.Pitch / 2; /* Copy Y */ - Dst = locked_rect.pBits; - Dst = Dst + locked_rect.Pitch * y + x; - Src=src[0]; - memcpy_pic(Dst, Src, w, h, locked_rect.Pitch, stride[0]); + dst = priv->locked_rect.pBits; + dst = dst + priv->locked_rect.Pitch * y + x; + my_src=src[0]; + memcpy_pic(dst, my_src, w, h, priv->locked_rect.Pitch, stride[0]); w/=2;h/=2;x/=2;y/=2; /* Copy U */ - Dst = locked_rect.pBits; - Dst = Dst + locked_rect.Pitch * priv->src_height - + UVstride * y + x; + dst = priv->locked_rect.pBits; + dst = dst + priv->locked_rect.Pitch * priv->src_height + + uv_stride * y + x; if (priv->movie_src_fmt == MAKEFOURCC('Y','V','1','2')) - Src=src[2]; + my_src=src[2]; else - Src=src[1]; + my_src=src[1]; - memcpy_pic(Dst, Src, w, h, UVstride, stride[1]); + memcpy_pic(dst, my_src, w, h, uv_stride, stride[1]); /* Copy V */ - Dst = locked_rect.pBits; - Dst = Dst + locked_rect.Pitch * priv->src_height - + UVstride * (priv->src_height / 2) + UVstride * y + x; + dst = priv->locked_rect.pBits; + dst = dst + priv->locked_rect.Pitch * priv->src_height + + uv_stride * (priv->src_height / 2) + uv_stride * y + x; if (priv->movie_src_fmt == MAKEFOURCC('Y','V','1','2')) - Src=src[1]; + my_src=src[1]; else - Src=src[2]; - - memcpy_pic(Dst, Src, w, h, UVstride, stride[2]); + my_src=src[2]; - if (FAILED(IDirect3DSurface9_UnlockRect(priv->d3d_surface))) { - mp_msg(MSGT_VO,MSGL_V,"<vo_direct3d>Surface unlock failure\n"); - return VO_ERROR; - } - - if (FAILED(IDirect3DDevice9_StretchRect(priv->d3d_device, - priv->d3d_surface, - &priv->fs_panscan_rect, - priv->d3d_backbuf, - &priv->fs_movie_rect, - D3DTEXF_LINEAR))) { - mp_msg(MSGT_VO,MSGL_V, - "<vo_direct3d>Unable to copy the frame to the back buffer\n"); - return VO_ERROR; - } - - if (FAILED(IDirect3DDevice9_EndScene(priv->d3d_device))) { - mp_msg(MSGT_VO,MSGL_ERR,"<vo_direct3d>EndScene failed\n"); - return VO_ERROR; - } + memcpy_pic(dst, my_src, w, h, uv_stride, stride[2]); return 0; /* Success */ } diff --git a/libvo/vo_fbdev.c b/libvo/vo_fbdev.c index e8f5e86ba7..310e3e0400 100644 --- a/libvo/vo_fbdev.c +++ b/libvo/vo_fbdev.c @@ -2,7 +2,7 @@ * Video driver for Framebuffer device * by Szabolcs Berecz <szabi@inf.elte.hu> * (C) 2001 - * + * * Some idea and code borrowed from Chris Lawrence's ppmtofb-0.27 * Some fixes and small improvements by Joey Parrish <joey@nicewarrior.org> */ @@ -33,10 +33,10 @@ #include "mp_msg.h" static const vo_info_t info = { - "Framebuffer Device", - "fbdev", - "Szabolcs Berecz <szabi@inf.elte.hu>", - "" + "Framebuffer Device", + "fbdev", + "Szabolcs Berecz <szabi@inf.elte.hu>", + "" }; LIBVO_EXTERN(fbdev) @@ -48,39 +48,39 @@ static vidix_grkey_t gr_key; #endif static signed int pre_init_err = -2; /****************************** -* fb.modes support * -******************************/ + * fb.modes support * + ******************************/ static range_t *monitor_hfreq = NULL; static range_t *monitor_vfreq = NULL; static range_t *monitor_dotclock = NULL; typedef struct { - char *name; - uint32_t xres, yres, vxres, vyres, depth; - uint32_t pixclock, left, right, upper, lower, hslen, vslen; - uint32_t sync; - uint32_t vmode; + char *name; + uint32_t xres, yres, vxres, vyres, depth; + uint32_t pixclock, left, right, upper, lower, hslen, vslen; + uint32_t sync; + uint32_t vmode; } fb_mode_t; -#define MAX_NR_TOKEN 16 +#define MAX_NR_TOKEN 16 -#define MAX_LINE_LEN 1000 +#define MAX_LINE_LEN 1000 -#define RET_EOF -1 -#define RET_EOL -2 +#define RET_EOF -1 +#define RET_EOL -2 static int validate_mode(fb_mode_t *m) { - if (!m->xres) { - mp_msg(MSGT_VO, MSGL_V, "needs geometry "); - return 0; - } - if (!m->pixclock) { - mp_msg(MSGT_VO, MSGL_V, "needs timings "); - return 0; - } - return 1; + if (!m->xres) { + mp_msg(MSGT_VO, MSGL_V, "needs geometry "); + return 0; + } + if (!m->pixclock) { + mp_msg(MSGT_VO, MSGL_V, "needs timings "); + return 0; + } + return 1; } static FILE *fp; @@ -90,58 +90,58 @@ static char *token[MAX_NR_TOKEN]; static int get_token(int num) { - static int read_nextline = 1; - static int line_pos; - int i; - char c; - - if (num >= MAX_NR_TOKEN) { - mp_msg(MSGT_VO, MSGL_V, "get_token(): max >= MAX_NR_TOKEN!\n"); - goto out_eof; - } - - if (read_nextline) { - if (!fgets(line, MAX_LINE_LEN, fp)) - goto out_eof; - line_pos = 0; - ++line_num; - read_nextline = 0; - } - for (i = 0; i < num; i++) { - while (isspace(line[line_pos])) - ++line_pos; - if (line[line_pos] == '\0' || line[line_pos] == '#') { - read_nextline = 1; - goto out_eol; - } - token[i] = line + line_pos; - c = line[line_pos]; - if (c == '"' || c == '\'') { - token[i]++; - while (line[++line_pos] != c && line[line_pos]) - /* NOTHING */; - if (!line[line_pos]) - goto out_eol; - line[line_pos] = ' '; - } else { - for (/* NOTHING */; !isspace(line[line_pos]) && - line[line_pos]; line_pos++) - /* NOTHING */; - } - if (!line[line_pos]) { - read_nextline = 1; - if (i == num - 1) - goto out_ok; - goto out_eol; - } - line[line_pos++] = '\0'; - } + static int read_nextline = 1; + static int line_pos; + int i; + char c; + + if (num >= MAX_NR_TOKEN) { + mp_msg(MSGT_VO, MSGL_V, "get_token(): max >= MAX_NR_TOKEN!\n"); + goto out_eof; + } + + if (read_nextline) { + if (!fgets(line, MAX_LINE_LEN, fp)) + goto out_eof; + line_pos = 0; + ++line_num; + read_nextline = 0; + } + for (i = 0; i < num; i++) { + while (isspace(line[line_pos])) + ++line_pos; + if (line[line_pos] == '\0' || line[line_pos] == '#') { + read_nextline = 1; + goto out_eol; + } + token[i] = line + line_pos; + c = line[line_pos]; + if (c == '"' || c == '\'') { + token[i]++; + while (line[++line_pos] != c && line[line_pos]) + /* NOTHING */; + if (!line[line_pos]) + goto out_eol; + line[line_pos] = ' '; + } else { + for (/* NOTHING */; !isspace(line[line_pos]) && + line[line_pos]; line_pos++) + /* NOTHING */; + } + if (!line[line_pos]) { + read_nextline = 1; + if (i == num - 1) + goto out_ok; + goto out_eol; + } + line[line_pos++] = '\0'; + } out_ok: - return i; + return i; out_eof: - return RET_EOF; + return RET_EOF; out_eol: - return RET_EOL; + return RET_EOL; } static fb_mode_t *fb_modes = NULL; @@ -150,388 +150,389 @@ static int nr_modes = 0; static int parse_fbmode_cfg(char *cfgfile) { #define CHECK_IN_MODE_DEF\ - if (!in_mode_def) {\ - mp_msg(MSGT_VO, MSGL_V, "'needs 'mode' first");\ - goto err_out_print_linenum;\ - } - fb_mode_t *mode = NULL; - char *endptr; // strtoul()... - int in_mode_def = 0; - int tmp, i; - - /* If called more than once, reuse parsed data */ - if (nr_modes) - return nr_modes; - - mp_msg(MSGT_VO, MSGL_V, "Reading %s: ", cfgfile); - - if ((fp = fopen(cfgfile, "r")) == NULL) { - mp_msg(MSGT_VO, MSGL_V, "can't open '%s': %s\n", cfgfile, strerror(errno)); - return -1; - } - - if ((line = (char *) malloc(MAX_LINE_LEN + 1)) == NULL) { - mp_msg(MSGT_VO, MSGL_V, "can't get memory for 'line': %s\n", strerror(errno)); - return -2; - } - - /* - * check if the cfgfile starts with 'mode' - */ - while ((tmp = get_token(1)) == RET_EOL) - /* NOTHING */; - if (tmp == RET_EOF) - goto out; - if (!strcmp(token[0], "mode")) - goto loop_enter; - goto err_out_parse_error; - - while ((tmp = get_token(1)) != RET_EOF) { - if (tmp == RET_EOL) - continue; - if (!strcmp(token[0], "mode")) { - if (in_mode_def) { - mp_msg(MSGT_VO, MSGL_V, "'endmode' required"); - goto err_out_print_linenum; - } - if (!validate_mode(mode)) - goto err_out_not_valid; - loop_enter: - if (!(fb_modes = (fb_mode_t *) realloc(fb_modes, - sizeof(fb_mode_t) * (nr_modes + 1)))) { - mp_msg(MSGT_VO, MSGL_V, "can't realloc 'fb_modes' (nr_modes = %d):" - " %s\n", nr_modes, strerror(errno)); - goto err_out; - } - mode=fb_modes + nr_modes; - ++nr_modes; - memset(mode,0,sizeof(fb_mode_t)); - - if (get_token(1) < 0) - goto err_out_parse_error; - for (i = 0; i < nr_modes - 1; i++) { - if (!strcmp(token[0], fb_modes[i].name)) { - mp_msg(MSGT_VO, MSGL_V, "mode name '%s' isn't unique", token[0]); - goto err_out_print_linenum; - } - } - if (!(mode->name = strdup(token[0]))) { - mp_msg(MSGT_VO, MSGL_V, "can't strdup -> 'name': %s\n", strerror(errno)); - goto err_out; - } - in_mode_def = 1; - } else if (!strcmp(token[0], "geometry")) { - CHECK_IN_MODE_DEF; - if (get_token(5) < 0) - goto err_out_parse_error; - mode->xres = strtoul(token[0], &endptr, 0); - if (*endptr) - goto err_out_parse_error; - mode->yres = strtoul(token[1], &endptr, 0); - if (*endptr) - goto err_out_parse_error; - mode->vxres = strtoul(token[2], &endptr, 0); - if (*endptr) - goto err_out_parse_error; - mode->vyres = strtoul(token[3], &endptr, 0); - if (*endptr) - goto err_out_parse_error; - mode->depth = strtoul(token[4], &endptr, 0); - if (*endptr) - goto err_out_parse_error; - } else if (!strcmp(token[0], "timings")) { - CHECK_IN_MODE_DEF; - if (get_token(7) < 0) - goto err_out_parse_error; - mode->pixclock = strtoul(token[0], &endptr, 0); - if (*endptr) - goto err_out_parse_error; - mode->left = strtoul(token[1], &endptr, 0); - if (*endptr) - goto err_out_parse_error; - mode->right = strtoul(token[2], &endptr, 0); - if (*endptr) - goto err_out_parse_error; - mode->upper = strtoul(token[3], &endptr, 0); - if (*endptr) - goto err_out_parse_error; - mode->lower = strtoul(token[4], &endptr, 0); - if (*endptr) - goto err_out_parse_error; - mode->hslen = strtoul(token[5], &endptr, 0); - if (*endptr) - goto err_out_parse_error; - mode->vslen = strtoul(token[6], &endptr, 0); - if (*endptr) - goto err_out_parse_error; - } else if (!strcmp(token[0], "endmode")) { - CHECK_IN_MODE_DEF; - in_mode_def = 0; - } else if (!strcmp(token[0], "accel")) { - CHECK_IN_MODE_DEF; - if (get_token(1) < 0) - goto err_out_parse_error; - /* - * it's only used for text acceleration - * so we just ignore it. - */ - } else if (!strcmp(token[0], "hsync")) { - CHECK_IN_MODE_DEF; - if (get_token(1) < 0) - goto err_out_parse_error; - if (!strcmp(token[0], "low")) - mode->sync &= ~FB_SYNC_HOR_HIGH_ACT; - else if(!strcmp(token[0], "high")) - mode->sync |= FB_SYNC_HOR_HIGH_ACT; - else - goto err_out_parse_error; - } else if (!strcmp(token[0], "vsync")) { - CHECK_IN_MODE_DEF; - if (get_token(1) < 0) - goto err_out_parse_error; - if (!strcmp(token[0], "low")) - mode->sync &= ~FB_SYNC_VERT_HIGH_ACT; - else if(!strcmp(token[0], "high")) - mode->sync |= FB_SYNC_VERT_HIGH_ACT; - else - goto err_out_parse_error; - } else if (!strcmp(token[0], "csync")) { - CHECK_IN_MODE_DEF; - if (get_token(1) < 0) - goto err_out_parse_error; - if (!strcmp(token[0], "low")) - mode->sync &= ~FB_SYNC_COMP_HIGH_ACT; - else if(!strcmp(token[0], "high")) - mode->sync |= FB_SYNC_COMP_HIGH_ACT; - else - goto err_out_parse_error; - } else if (!strcmp(token[0], "extsync")) { - CHECK_IN_MODE_DEF; - if (get_token(1) < 0) - goto err_out_parse_error; - if (!strcmp(token[0], "false")) - mode->sync &= ~FB_SYNC_EXT; - else if(!strcmp(token[0], "true")) - mode->sync |= FB_SYNC_EXT; - else - goto err_out_parse_error; - } else if (!strcmp(token[0], "laced")) { - CHECK_IN_MODE_DEF; - if (get_token(1) < 0) - goto err_out_parse_error; - if (!strcmp(token[0], "false")) - mode->vmode = FB_VMODE_NONINTERLACED; - else if (!strcmp(token[0], "true")) - mode->vmode = FB_VMODE_INTERLACED; - else - goto err_out_parse_error; - } else if (!strcmp(token[0], "double")) { - CHECK_IN_MODE_DEF; - if (get_token(1) < 0) - goto err_out_parse_error; - if (!strcmp(token[0], "false")) - ; - else if (!strcmp(token[0], "true")) - mode->vmode = FB_VMODE_DOUBLE; - else - goto err_out_parse_error; - } else - goto err_out_parse_error; - } - if (!validate_mode(mode)) - goto err_out_not_valid; + if (!in_mode_def) {\ + mp_msg(MSGT_VO, MSGL_V, "'needs 'mode' first");\ + goto err_out_print_linenum;\ + } + fb_mode_t *mode = NULL; + char *endptr; // strtoul()... + int in_mode_def = 0; + int tmp, i; + + /* If called more than once, reuse parsed data */ + if (nr_modes) + return nr_modes; + + mp_msg(MSGT_VO, MSGL_V, "Reading %s: ", cfgfile); + + if ((fp = fopen(cfgfile, "r")) == NULL) { + mp_msg(MSGT_VO, MSGL_V, "can't open '%s': %s\n", cfgfile, strerror(errno)); + return -1; + } + + if ((line = (char *) malloc(MAX_LINE_LEN + 1)) == NULL) { + mp_msg(MSGT_VO, MSGL_V, "can't get memory for 'line': %s\n", strerror(errno)); + return -2; + } + + /* + * check if the cfgfile starts with 'mode' + */ + while ((tmp = get_token(1)) == RET_EOL) + /* NOTHING */; + if (tmp == RET_EOF) + goto out; + if (!strcmp(token[0], "mode")) + goto loop_enter; + goto err_out_parse_error; + + while ((tmp = get_token(1)) != RET_EOF) { + if (tmp == RET_EOL) + continue; + if (!strcmp(token[0], "mode")) { + if (in_mode_def) { + mp_msg(MSGT_VO, MSGL_V, "'endmode' required"); + goto err_out_print_linenum; + } + if (!validate_mode(mode)) + goto err_out_not_valid; + loop_enter: + if (!(fb_modes = (fb_mode_t *) + realloc(fb_modes, sizeof(fb_mode_t) * (nr_modes + 1)))) { + mp_msg(MSGT_VO, MSGL_V, "can't realloc 'fb_modes' (nr_modes = %d):" + " %s\n", nr_modes, strerror(errno)); + goto err_out; + } + mode = fb_modes + nr_modes; + ++nr_modes; + memset(mode, 0, sizeof(fb_mode_t)); + + if (get_token(1) < 0) + goto err_out_parse_error; + for (i = 0; i < nr_modes - 1; i++) { + if (!strcmp(token[0], fb_modes[i].name)) { + mp_msg(MSGT_VO, MSGL_V, "mode name '%s' isn't unique", token[0]); + goto err_out_print_linenum; + } + } + if (!(mode->name = strdup(token[0]))) { + mp_msg(MSGT_VO, MSGL_V, "can't strdup -> 'name': %s\n", strerror(errno)); + goto err_out; + } + in_mode_def = 1; + } else if (!strcmp(token[0], "geometry")) { + CHECK_IN_MODE_DEF; + if (get_token(5) < 0) + goto err_out_parse_error; + mode->xres = strtoul(token[0], &endptr, 0); + if (*endptr) + goto err_out_parse_error; + mode->yres = strtoul(token[1], &endptr, 0); + if (*endptr) + goto err_out_parse_error; + mode->vxres = strtoul(token[2], &endptr, 0); + if (*endptr) + goto err_out_parse_error; + mode->vyres = strtoul(token[3], &endptr, 0); + if (*endptr) + goto err_out_parse_error; + mode->depth = strtoul(token[4], &endptr, 0); + if (*endptr) + goto err_out_parse_error; + } else if (!strcmp(token[0], "timings")) { + CHECK_IN_MODE_DEF; + if (get_token(7) < 0) + goto err_out_parse_error; + mode->pixclock = strtoul(token[0], &endptr, 0); + if (*endptr) + goto err_out_parse_error; + mode->left = strtoul(token[1], &endptr, 0); + if (*endptr) + goto err_out_parse_error; + mode->right = strtoul(token[2], &endptr, 0); + if (*endptr) + goto err_out_parse_error; + mode->upper = strtoul(token[3], &endptr, 0); + if (*endptr) + goto err_out_parse_error; + mode->lower = strtoul(token[4], &endptr, 0); + if (*endptr) + goto err_out_parse_error; + mode->hslen = strtoul(token[5], &endptr, 0); + if (*endptr) + goto err_out_parse_error; + mode->vslen = strtoul(token[6], &endptr, 0); + if (*endptr) + goto err_out_parse_error; + } else if (!strcmp(token[0], "endmode")) { + CHECK_IN_MODE_DEF; + in_mode_def = 0; + } else if (!strcmp(token[0], "accel")) { + CHECK_IN_MODE_DEF; + if (get_token(1) < 0) + goto err_out_parse_error; + /* + * it's only used for text acceleration + * so we just ignore it. + */ + } else if (!strcmp(token[0], "hsync")) { + CHECK_IN_MODE_DEF; + if (get_token(1) < 0) + goto err_out_parse_error; + if (!strcmp(token[0], "low")) + mode->sync &= ~FB_SYNC_HOR_HIGH_ACT; + else if (!strcmp(token[0], "high")) + mode->sync |= FB_SYNC_HOR_HIGH_ACT; + else + goto err_out_parse_error; + } else if (!strcmp(token[0], "vsync")) { + CHECK_IN_MODE_DEF; + if (get_token(1) < 0) + goto err_out_parse_error; + if (!strcmp(token[0], "low")) + mode->sync &= ~FB_SYNC_VERT_HIGH_ACT; + else if (!strcmp(token[0], "high")) + mode->sync |= FB_SYNC_VERT_HIGH_ACT; + else + goto err_out_parse_error; + } else if (!strcmp(token[0], "csync")) { + CHECK_IN_MODE_DEF; + if (get_token(1) < 0) + goto err_out_parse_error; + if (!strcmp(token[0], "low")) + mode->sync &= ~FB_SYNC_COMP_HIGH_ACT; + else if (!strcmp(token[0], "high")) + mode->sync |= FB_SYNC_COMP_HIGH_ACT; + else + goto err_out_parse_error; + } else if (!strcmp(token[0], "extsync")) { + CHECK_IN_MODE_DEF; + if (get_token(1) < 0) + goto err_out_parse_error; + if (!strcmp(token[0], "false")) + mode->sync &= ~FB_SYNC_EXT; + else if (!strcmp(token[0], "true")) + mode->sync |= FB_SYNC_EXT; + else + goto err_out_parse_error; + } else if (!strcmp(token[0], "laced")) { + CHECK_IN_MODE_DEF; + if (get_token(1) < 0) + goto err_out_parse_error; + if (!strcmp(token[0], "false")) + mode->vmode = FB_VMODE_NONINTERLACED; + else if (!strcmp(token[0], "true")) + mode->vmode = FB_VMODE_INTERLACED; + else + goto err_out_parse_error; + } else if (!strcmp(token[0], "double")) { + CHECK_IN_MODE_DEF; + if (get_token(1) < 0) + goto err_out_parse_error; + if (!strcmp(token[0], "false")) + ; + else if (!strcmp(token[0], "true")) + mode->vmode = FB_VMODE_DOUBLE; + else + goto err_out_parse_error; + } else + goto err_out_parse_error; + } + if (!validate_mode(mode)) + goto err_out_not_valid; out: - mp_msg(MSGT_VO, MSGL_V, "%d modes\n", nr_modes); - free(line); - fclose(fp); - return nr_modes; + mp_msg(MSGT_VO, MSGL_V, "%d modes\n", nr_modes); + free(line); + fclose(fp); + return nr_modes; err_out_parse_error: - mp_msg(MSGT_VO, MSGL_V, "parse error"); + mp_msg(MSGT_VO, MSGL_V, "parse error"); err_out_print_linenum: - mp_msg(MSGT_VO, MSGL_V, " at line %d\n", line_num); + mp_msg(MSGT_VO, MSGL_V, " at line %d\n", line_num); err_out: - if (fb_modes) { - free(fb_modes); - fb_modes = NULL; - } - nr_modes = 0; - free(line); - free(fp); - return -2; + if (fb_modes) { + free(fb_modes); + fb_modes = NULL; + } + nr_modes = 0; + free(line); + free(fp); + return -2; err_out_not_valid: - mp_msg(MSGT_VO, MSGL_V, "previous mode is not correct"); - goto err_out_print_linenum; + mp_msg(MSGT_VO, MSGL_V, "previous mode is not correct"); + goto err_out_print_linenum; } static fb_mode_t *find_mode_by_name(char *name) { - int i; + int i; - for (i = 0; i < nr_modes; i++) - if (!strcmp(name, fb_modes[i].name)) - return fb_modes + i; - return NULL; + for (i = 0; i < nr_modes; i++) + if (!strcmp(name, fb_modes[i].name)) + return fb_modes + i; + return NULL; } -static float dcf(fb_mode_t *m) //driving clock frequency +static float dcf(fb_mode_t *m) //driving clock frequency { - return 1e12f / m->pixclock; + return 1e12f / m->pixclock; } -static float hsf(fb_mode_t *m) //horizontal scan frequency +static float hsf(fb_mode_t *m) //horizontal scan frequency { - int htotal = m->left + m->xres + m->right + m->hslen; - return dcf(m) / htotal; + int htotal = m->left + m->xres + m->right + m->hslen; + return dcf(m) / htotal; } -static float vsf(fb_mode_t *m) //vertical scan frequency +static float vsf(fb_mode_t *m) //vertical scan frequency { - int vtotal = m->upper + m->yres + m->lower + m->vslen; - return hsf(m) / vtotal; + int vtotal = m->upper + m->yres + m->lower + m->vslen; + return hsf(m) / vtotal; } static int mode_works(fb_mode_t *m, range_t *hfreq, range_t *vfreq, - range_t *dotclock) + range_t *dotclock) { - float h = hsf(m); - float v = vsf(m); - float d = dcf(m); - int ret = 1; - - mp_msg(MSGT_VO, MSGL_DBG2, "mode %dx%d:", m->xres, m->yres); - if (!in_range(hfreq, h)) { - ret = 0; - mp_msg(MSGT_VO, MSGL_DBG2, " hsync out of range."); - } - if (!in_range(vfreq, v)) { - ret = 0; - mp_msg(MSGT_VO, MSGL_DBG2, " vsync out of range."); - } - if (!in_range(dotclock, d)) { - ret = 0; - mp_msg(MSGT_VO, MSGL_DBG2, " dotclock out of range."); - } - if (ret) - mp_msg(MSGT_VO, MSGL_DBG2, " hsync, vsync, dotclock ok.\n"); - else - mp_msg(MSGT_VO, MSGL_DBG2, "\n"); - - return ret; + float h = hsf(m); + float v = vsf(m); + float d = dcf(m); + int ret = 1; + + mp_msg(MSGT_VO, MSGL_DBG2, "mode %dx%d:", m->xres, m->yres); + if (!in_range(hfreq, h)) { + ret = 0; + mp_msg(MSGT_VO, MSGL_DBG2, " hsync out of range."); + } + if (!in_range(vfreq, v)) { + ret = 0; + mp_msg(MSGT_VO, MSGL_DBG2, " vsync out of range."); + } + if (!in_range(dotclock, d)) { + ret = 0; + mp_msg(MSGT_VO, MSGL_DBG2, " dotclock out of range."); + } + if (ret) + mp_msg(MSGT_VO, MSGL_DBG2, " hsync, vsync, dotclock ok.\n"); + else + mp_msg(MSGT_VO, MSGL_DBG2, "\n"); + + return ret; } static fb_mode_t *find_best_mode(int xres, int yres, range_t *hfreq, - range_t *vfreq, range_t *dotclock) + range_t *vfreq, range_t *dotclock) { - int i; - fb_mode_t *best = fb_modes; - fb_mode_t *curr; - - mp_msg(MSGT_VO, MSGL_DBG2, "Searching for first working mode\n"); - - for (i = 0; i < nr_modes; i++, best++) - if (mode_works(best, hfreq, vfreq, dotclock)) - break; - - if (i == nr_modes) - return NULL; - if (i == nr_modes - 1) - return best; - - mp_msg(MSGT_VO, MSGL_DBG2, "First working mode: %dx%d\n", best->xres, best->yres); - mp_msg(MSGT_VO, MSGL_DBG2, "Searching for better modes\n"); - - for (curr = best + 1; i < nr_modes - 1; i++, curr++) { - if (!mode_works(curr, hfreq, vfreq, dotclock)) - continue; - - if (best->xres < xres || best->yres < yres) { - if (curr->xres > best->xres || curr->yres > best->yres) { - mp_msg(MSGT_VO, MSGL_DBG2, "better than %dx%d, which is too small.\n", - best->xres, best->yres); - best = curr; - } else - mp_msg(MSGT_VO, MSGL_DBG2, "too small.\n"); - } else if (curr->xres == best->xres && curr->yres == best->yres && - vsf(curr) > vsf(best)) { - mp_msg(MSGT_VO, MSGL_DBG2, "faster screen refresh.\n"); - best = curr; - } else if ((curr->xres <= best->xres && curr->yres <= best->yres) && - (curr->xres >= xres && curr->yres >= yres)) { - mp_msg(MSGT_VO, MSGL_DBG2, "better than %dx%d, which is too large.\n", - best->xres, best->yres); - best = curr; - } else { - if (curr->xres < xres || curr->yres < yres) - mp_msg(MSGT_VO, MSGL_DBG2, "too small.\n"); - else if (curr->xres > best->xres || curr->yres > best->yres) - mp_msg(MSGT_VO, MSGL_DBG2, "too large.\n"); - else mp_msg(MSGT_VO, MSGL_DBG2, "it's worse, don't know why.\n"); - } - } - - return best; + int i; + fb_mode_t *best = fb_modes; + fb_mode_t *curr; + + mp_msg(MSGT_VO, MSGL_DBG2, "Searching for first working mode\n"); + + for (i = 0; i < nr_modes; i++, best++) + if (mode_works(best, hfreq, vfreq, dotclock)) + break; + + if (i == nr_modes) + return NULL; + if (i == nr_modes - 1) + return best; + + mp_msg(MSGT_VO, MSGL_DBG2, "First working mode: %dx%d\n", best->xres, best->yres); + mp_msg(MSGT_VO, MSGL_DBG2, "Searching for better modes\n"); + + for (curr = best + 1; i < nr_modes - 1; i++, curr++) { + if (!mode_works(curr, hfreq, vfreq, dotclock)) + continue; + + if (best->xres < xres || best->yres < yres) { + if (curr->xres > best->xres || curr->yres > best->yres) { + mp_msg(MSGT_VO, MSGL_DBG2, "better than %dx%d, which is too small.\n", + best->xres, best->yres); + best = curr; + } else + mp_msg(MSGT_VO, MSGL_DBG2, "too small.\n"); + } else if (curr->xres == best->xres && curr->yres == best->yres && + vsf(curr) > vsf(best)) { + mp_msg(MSGT_VO, MSGL_DBG2, "faster screen refresh.\n"); + best = curr; + } else if ((curr->xres <= best->xres && curr->yres <= best->yres) && + (curr->xres >= xres && curr->yres >= yres)) { + mp_msg(MSGT_VO, MSGL_DBG2, "better than %dx%d, which is too large.\n", + best->xres, best->yres); + best = curr; + } else { + if (curr->xres < xres || curr->yres < yres) + mp_msg(MSGT_VO, MSGL_DBG2, "too small.\n"); + else if (curr->xres > best->xres || curr->yres > best->yres) + mp_msg(MSGT_VO, MSGL_DBG2, "too large.\n"); + else + mp_msg(MSGT_VO, MSGL_DBG2, "it's worse, don't know why.\n"); + } + } + + return best; } static void set_bpp(struct fb_var_screeninfo *p, int bpp) { - p->bits_per_pixel = (bpp + 1) & ~1; - p->red.msb_right = p->green.msb_right = p->blue.msb_right = p->transp.msb_right = 0; - p->transp.offset = p->transp.length = 0; - p->blue.offset = 0; - switch (bpp) { - case 32: - p->transp.offset = 24; - p->transp.length = 8; - case 24: - p->red.offset = 16; - p->red.length = 8; - p->green.offset = 8; - p->green.length = 8; - p->blue.length = 8; - break; - case 16: - p->red.offset = 11; - p->green.length = 6; - p->red.length = 5; - p->green.offset = 5; - p->blue.length = 5; - break; - case 15: - p->red.offset = 10; - p->green.length = 5; - p->red.length = 5; - p->green.offset = 5; - p->blue.length = 5; - break; - } + p->bits_per_pixel = (bpp + 1) & ~1; + p->red.msb_right = p->green.msb_right = p->blue.msb_right = p->transp.msb_right = 0; + p->transp.offset = p->transp.length = 0; + p->blue.offset = 0; + switch (bpp) { + case 32: + p->transp.offset = 24; + p->transp.length = 8; + case 24: + p->red.offset = 16; + p->red.length = 8; + p->green.offset = 8; + p->green.length = 8; + p->blue.length = 8; + break; + case 16: + p->red.offset = 11; + p->green.length = 6; + p->red.length = 5; + p->green.offset = 5; + p->blue.length = 5; + break; + case 15: + p->red.offset = 10; + p->green.length = 5; + p->red.length = 5; + p->green.offset = 5; + p->blue.length = 5; + break; + } } static void fb_mode2fb_vinfo(fb_mode_t *m, struct fb_var_screeninfo *v) { - v->xres = m->xres; - v->yres = m->yres; - v->xres_virtual = m->vxres; - v->yres_virtual = m->vyres; - set_bpp(v, m->depth); - v->pixclock = m->pixclock; - v->left_margin = m->left; - v->right_margin = m->right; - v->upper_margin = m->upper; - v->lower_margin = m->lower; - v->hsync_len = m->hslen; - v->vsync_len = m->vslen; - v->sync = m->sync; - v->vmode = m->vmode; + v->xres = m->xres; + v->yres = m->yres; + v->xres_virtual = m->vxres; + v->yres_virtual = m->vyres; + set_bpp(v, m->depth); + v->pixclock = m->pixclock; + v->left_margin = m->left; + v->right_margin = m->right; + v->upper_margin = m->upper; + v->lower_margin = m->lower; + v->hsync_len = m->hslen; + v->vsync_len = m->vslen; + v->sync = m->sync; + v->vmode = m->vmode; } /****************************** -* vo_fbdev * +* vo_fbdev * ******************************/ /* command line/config file options */ -char *fb_dev_name = NULL; +static char *fb_dev_name = NULL; char *fb_mode_cfgfile = NULL; char *fb_mode_name = NULL; @@ -546,22 +547,22 @@ static int fb_dev_fd; static int fb_tty_fd = -1; static size_t fb_size; static uint8_t *frame_buffer; -static uint8_t *center; /* thx .so :) */ +static uint8_t *center; static struct fb_fix_screeninfo fb_finfo; static struct fb_var_screeninfo fb_orig_vinfo; static struct fb_var_screeninfo fb_vinfo; static unsigned short fb_ored[256], fb_ogreen[256], fb_oblue[256]; static struct fb_cmap fb_oldcmap = { 0, 256, fb_ored, fb_ogreen, fb_oblue }; static int fb_cmap_changed = 0; -static int fb_pixel_size; // 32: 4 24: 3 16: 2 15: 2 -static int fb_bpp; // 32: 32 24: 24 16: 16 15: 15 -static int fb_bpp_we_want; // 32: 32 24: 24 16: 16 15: 15 +static int fb_pixel_size; // 32: 4 24: 3 16: 2 15: 2 +static int fb_bpp; // 32: 32 24: 24 16: 16 15: 15 +static int fb_bpp_we_want; // 32: 32 24: 24 16: 16 15: 15 static int fb_line_len; static int fb_xres; static int fb_yres; static void (*draw_alpha_p)(int w, int h, unsigned char *src, - unsigned char *srca, int stride, unsigned char *dst, - int dstride); + unsigned char *srca, int stride, + unsigned char *dst, int dstride); static int in_width; static int in_height; @@ -579,507 +580,441 @@ static int fs; */ static struct fb_cmap *make_directcolor_cmap(struct fb_var_screeninfo *var) { - /* Hopefully any DIRECTCOLOR device will have a big enough palette - * to handle mapping the full color depth. - * e.g. 8 bpp -> 256 entry palette - * - * We could handle some sort of gamma here - */ - int i, cols, rcols, gcols, bcols; - uint16_t *red, *green, *blue; - struct fb_cmap *cmap; - - rcols = 1 << var->red.length; - gcols = 1 << var->green.length; - bcols = 1 << var->blue.length; - - /* Make our palette the length of the deepest color */ - cols = (rcols > gcols ? rcols : gcols); - cols = (cols > bcols ? cols : bcols); - - red = malloc(cols * sizeof(red[0])); - if(!red) { - mp_msg(MSGT_VO, MSGL_V, "Can't allocate red palette with %d entries.\n", cols); - return NULL; - } - for(i=0; i< rcols; i++) - red[i] = (65535/(rcols-1)) * i; - - green = malloc(cols * sizeof(green[0])); - if(!green) { - mp_msg(MSGT_VO, MSGL_V, "Can't allocate green palette with %d entries.\n", cols); - free(red); - return NULL; - } - for(i=0; i< gcols; i++) - green[i] = (65535/(gcols-1)) * i; - - blue = malloc(cols * sizeof(blue[0])); - if(!blue) { - mp_msg(MSGT_VO, MSGL_V, "Can't allocate blue palette with %d entries.\n", cols); - free(red); - free(green); - return NULL; - } - for(i=0; i< bcols; i++) - blue[i] = (65535/(bcols-1)) * i; - - cmap = malloc(sizeof(struct fb_cmap)); - if(!cmap) { - mp_msg(MSGT_VO, MSGL_V, "Can't allocate color map\n"); - free(red); - free(green); - free(blue); - return NULL; - } - cmap->start = 0; - cmap->transp = 0; - cmap->len = cols; - cmap->red = red; - cmap->blue = blue; - cmap->green = green; - cmap->transp = NULL; - - return cmap; + /* Hopefully any DIRECTCOLOR device will have a big enough palette + * to handle mapping the full color depth. + * e.g. 8 bpp -> 256 entry palette + * + * We could handle some sort of gamma here + */ + int i, cols, rcols, gcols, bcols; + uint16_t *red, *green, *blue; + struct fb_cmap *cmap; + + rcols = 1 << var->red.length; + gcols = 1 << var->green.length; + bcols = 1 << var->blue.length; + + /* Make our palette the length of the deepest color */ + cols = (rcols > gcols ? rcols : gcols); + cols = (cols > bcols ? cols : bcols); + + red = malloc(cols * sizeof(red[0])); + if (!red) { + mp_msg(MSGT_VO, MSGL_V, "Can't allocate red palette with %d entries.\n", cols); + return NULL; + } + for (i = 0; i < rcols; i++) + red[i] = (65535 / (rcols - 1)) * i; + + green = malloc(cols * sizeof(green[0])); + if (!green) { + mp_msg(MSGT_VO, MSGL_V, "Can't allocate green palette with %d entries.\n", cols); + free(red); + return NULL; + } + for (i = 0; i < gcols; i++) + green[i] = (65535 / (gcols - 1)) * i; + + blue = malloc(cols * sizeof(blue[0])); + if (!blue) { + mp_msg(MSGT_VO, MSGL_V, "Can't allocate blue palette with %d entries.\n", cols); + free(red); + free(green); + return NULL; + } + for (i = 0; i < bcols; i++) + blue[i] = (65535 / (bcols - 1)) * i; + + cmap = malloc(sizeof(struct fb_cmap)); + if (!cmap) { + mp_msg(MSGT_VO, MSGL_V, "Can't allocate color map\n"); + free(red); + free(green); + free(blue); + return NULL; + } + cmap->start = 0; + cmap->transp = 0; + cmap->len = cols; + cmap->red = red; + cmap->blue = blue; + cmap->green = green; + cmap->transp = NULL; + + return cmap; } static int fb_preinit(int reset) { - static int fb_preinit_done = 0; - static int fb_works = 0; - - if (reset) - { - fb_preinit_done = 0; - return 0; - } - - if (fb_preinit_done) - return fb_works; - - if (!fb_dev_name && !(fb_dev_name = getenv("FRAMEBUFFER"))) - fb_dev_name = strdup("/dev/fb0"); - mp_msg(MSGT_VO, MSGL_V, "using %s\n", fb_dev_name); - - if ((fb_dev_fd = open(fb_dev_name, O_RDWR)) == -1) { - mp_msg(MSGT_VO, MSGL_ERR, "Can't open %s: %s\n", fb_dev_name, strerror(errno)); - goto err_out; - } - if (ioctl(fb_dev_fd, FBIOGET_VSCREENINFO, &fb_vinfo)) { - mp_msg(MSGT_VO, MSGL_ERR, "Can't get VSCREENINFO: %s\n", strerror(errno)); - goto err_out_fd; - } - fb_orig_vinfo = fb_vinfo; - - if ((fb_tty_fd = open("/dev/tty", O_RDWR)) < 0) { - mp_msg(MSGT_VO, MSGL_ERR, "notice: Can't open /dev/tty: %s\n", strerror(errno)); + static int fb_preinit_done = 0; + static int fb_works = 0; + + if (reset) { + fb_preinit_done = 0; + return 0; + } + + if (fb_preinit_done) + return fb_works; + + if (!fb_dev_name && !(fb_dev_name = getenv("FRAMEBUFFER"))) + fb_dev_name = strdup("/dev/fb0"); + mp_msg(MSGT_VO, MSGL_V, "using %s\n", fb_dev_name); + + if ((fb_dev_fd = open(fb_dev_name, O_RDWR)) == -1) { + mp_msg(MSGT_VO, MSGL_ERR, "Can't open %s: %s\n", fb_dev_name, strerror(errno)); + goto err_out; + } + if (ioctl(fb_dev_fd, FBIOGET_VSCREENINFO, &fb_vinfo)) { + mp_msg(MSGT_VO, MSGL_ERR, "Can't get VSCREENINFO: %s\n", strerror(errno)); + goto err_out_fd; + } + fb_orig_vinfo = fb_vinfo; + + if ((fb_tty_fd = open("/dev/tty", O_RDWR)) < 0) { + mp_msg(MSGT_VO, MSGL_ERR, "notice: Can't open /dev/tty: %s\n", strerror(errno)); + } + + fb_bpp = fb_vinfo.red.length + fb_vinfo.green.length + + fb_vinfo.blue.length + fb_vinfo.transp.length; + + if (fb_bpp == 8 && !vo_dbpp) { + mp_msg(MSGT_VO, MSGL_ERR, "8 bpp output is not supported.\n"); + goto err_out_tty_fd; + } + + if (vo_dbpp) { + if (vo_dbpp != 15 && vo_dbpp != 16 && vo_dbpp != 24 && vo_dbpp != 32) { + mp_msg(MSGT_VO, MSGL_ERR, "can't switch to %d bpp\n", vo_dbpp); + goto err_out_fd; } + fb_bpp = vo_dbpp; + } - fb_bpp = fb_vinfo.red.length + fb_vinfo.green.length + - fb_vinfo.blue.length + fb_vinfo.transp.length; - - if (fb_bpp == 8 && !vo_dbpp) { - mp_msg(MSGT_VO, MSGL_ERR, "8 bpp output is not supported.\n"); - goto err_out_tty_fd; - } - - if (vo_dbpp) { - if (vo_dbpp != 15 && vo_dbpp != 16 && vo_dbpp != 24 && - vo_dbpp != 32) { - mp_msg(MSGT_VO, MSGL_ERR, "can't switch to %d bpp\n", vo_dbpp); - goto err_out_fd; - } - fb_bpp = vo_dbpp; - } - - if (!fb_mode_cfgfile) - fb_mode_cfgfile = strdup("/etc/fb.modes"); - - fb_preinit_done = 1; - fb_works = 1; - return 1; + if (!fb_mode_cfgfile) + fb_mode_cfgfile = strdup("/etc/fb.modes"); + + fb_preinit_done = 1; + fb_works = 1; + return 1; err_out_tty_fd: - close(fb_tty_fd); - fb_tty_fd = -1; + close(fb_tty_fd); + fb_tty_fd = -1; err_out_fd: - close(fb_dev_fd); - fb_dev_fd = -1; + close(fb_dev_fd); + fb_dev_fd = -1; err_out: - fb_preinit_done = 1; - fb_works = 0; - return 0; -} - -static void lots_of_printf(void) -{ - mp_msg(MSGT_VO, MSGL_V, "var info:\n"); - mp_msg(MSGT_VO, MSGL_V, "xres: %u\n", fb_vinfo.xres); - mp_msg(MSGT_VO, MSGL_V, "yres: %u\n", fb_vinfo.yres); - mp_msg(MSGT_VO, MSGL_V, "xres_virtual: %u\n", fb_vinfo.xres_virtual); - mp_msg(MSGT_VO, MSGL_V, "yres_virtual: %u\n", fb_vinfo.yres_virtual); - mp_msg(MSGT_VO, MSGL_V, "xoffset: %u\n", fb_vinfo.xoffset); - mp_msg(MSGT_VO, MSGL_V, "yoffset: %u\n", fb_vinfo.yoffset); - mp_msg(MSGT_VO, MSGL_V, "bits_per_pixel: %u\n", fb_vinfo.bits_per_pixel); - mp_msg(MSGT_VO, MSGL_V, "grayscale: %u\n", fb_vinfo.grayscale); - mp_msg(MSGT_VO, MSGL_V, "red: %lu %lu %lu\n", - (unsigned long) fb_vinfo.red.offset, - (unsigned long) fb_vinfo.red.length, - (unsigned long) fb_vinfo.red.msb_right); - mp_msg(MSGT_VO, MSGL_V, "green: %lu %lu %lu\n", - (unsigned long) fb_vinfo.green.offset, - (unsigned long) fb_vinfo.green.length, - (unsigned long) fb_vinfo.green.msb_right); - mp_msg(MSGT_VO, MSGL_V, "blue: %lu %lu %lu\n", - (unsigned long) fb_vinfo.blue.offset, - (unsigned long) fb_vinfo.blue.length, - (unsigned long) fb_vinfo.blue.msb_right); - mp_msg(MSGT_VO, MSGL_V, "transp: %lu %lu %lu\n", - (unsigned long) fb_vinfo.transp.offset, - (unsigned long) fb_vinfo.transp.length, - (unsigned long) fb_vinfo.transp.msb_right); - mp_msg(MSGT_VO, MSGL_V, "nonstd: %u\n", fb_vinfo.nonstd); - mp_msg(MSGT_VO, MSGL_DBG2, "activate: %u\n", fb_vinfo.activate); - mp_msg(MSGT_VO, MSGL_DBG2, "height: %u\n", fb_vinfo.height); - mp_msg(MSGT_VO, MSGL_DBG2, "width: %u\n", fb_vinfo.width); - mp_msg(MSGT_VO, MSGL_DBG2, "accel_flags: %u\n", fb_vinfo.accel_flags); - mp_msg(MSGT_VO, MSGL_DBG2, "timing:\n"); - mp_msg(MSGT_VO, MSGL_DBG2, "pixclock: %u\n", fb_vinfo.pixclock); - mp_msg(MSGT_VO, MSGL_DBG2, "left_margin: %u\n", fb_vinfo.left_margin); - mp_msg(MSGT_VO, MSGL_DBG2, "right_margin: %u\n", fb_vinfo.right_margin); - mp_msg(MSGT_VO, MSGL_DBG2, "upper_margin: %u\n", fb_vinfo.upper_margin); - mp_msg(MSGT_VO, MSGL_DBG2, "lower_margin: %u\n", fb_vinfo.lower_margin); - mp_msg(MSGT_VO, MSGL_DBG2, "hsync_len: %u\n", fb_vinfo.hsync_len); - mp_msg(MSGT_VO, MSGL_DBG2, "vsync_len: %u\n", fb_vinfo.vsync_len); - mp_msg(MSGT_VO, MSGL_DBG2, "sync: %u\n", fb_vinfo.sync); - mp_msg(MSGT_VO, MSGL_DBG2, "vmode: %u\n", fb_vinfo.vmode); - mp_msg(MSGT_VO, MSGL_V, "fix info:\n"); - mp_msg(MSGT_VO, MSGL_V, "framebuffer size: %d bytes\n", fb_finfo.smem_len); - mp_msg(MSGT_VO, MSGL_V, "type: %lu\n", (unsigned long) fb_finfo.type); - mp_msg(MSGT_VO, MSGL_V, "type_aux: %lu\n", (unsigned long) fb_finfo.type_aux); - mp_msg(MSGT_VO, MSGL_V, "visual: %lu\n", (unsigned long) fb_finfo.visual); - mp_msg(MSGT_VO, MSGL_V, "line_length: %lu bytes\n", (unsigned long) fb_finfo.line_length); - mp_msg(MSGT_VO, MSGL_DBG2, "id: %.16s\n", fb_finfo.id); - mp_msg(MSGT_VO, MSGL_DBG2, "smem_start: %p\n", (void *) fb_finfo.smem_start); - mp_msg(MSGT_VO, MSGL_DBG2, "xpanstep: %u\n", fb_finfo.xpanstep); - mp_msg(MSGT_VO, MSGL_DBG2, "ypanstep: %u\n", fb_finfo.ypanstep); - mp_msg(MSGT_VO, MSGL_DBG2, "ywrapstep: %u\n", fb_finfo.ywrapstep); - mp_msg(MSGT_VO, MSGL_DBG2, "mmio_start: %p\n", (void *) fb_finfo.mmio_start); - mp_msg(MSGT_VO, MSGL_DBG2, "mmio_len: %u bytes\n", fb_finfo.mmio_len); - mp_msg(MSGT_VO, MSGL_DBG2, "accel: %u\n", fb_finfo.accel); - mp_msg(MSGT_VO, MSGL_V, "fb_bpp: %d\n", fb_bpp); - mp_msg(MSGT_VO, MSGL_V, "fb_pixel_size: %d bytes\n", fb_pixel_size); - mp_msg(MSGT_VO, MSGL_V, "other:\n"); - mp_msg(MSGT_VO, MSGL_V, "in_width: %d\n", in_width); - mp_msg(MSGT_VO, MSGL_V, "in_height: %d\n", in_height); - mp_msg(MSGT_VO, MSGL_V, "out_width: %d\n", out_width); - mp_msg(MSGT_VO, MSGL_V, "out_height: %d\n", out_height); - mp_msg(MSGT_VO, MSGL_V, "first_row: %d\n", first_row); - mp_msg(MSGT_VO, MSGL_V, "last_row: %d\n", last_row); - mp_msg(MSGT_VO, MSGL_DBG2, "draw_alpha_p:%dbpp = %p\n", fb_bpp, draw_alpha_p); + fb_preinit_done = 1; + fb_works = 0; + return 0; } static void vt_set_textarea(int u, int l) { - /* how can I determine the font height? - * just use 16 for now - */ - int urow = ((u + 15) / 16) + 1; - int lrow = l / 16; - - mp_msg(MSGT_VO, MSGL_DBG2, "vt_set_textarea(%d,%d): %d,%d\n", u, l, urow, lrow); - if(vt_fp) { - fprintf(vt_fp, "\33[%d;%dr\33[%d;%dH", urow, lrow, lrow, 0); - fflush(vt_fp); - } + /* how can I determine the font height? + * just use 16 for now + */ + int urow = ((u + 15) / 16) + 1; + int lrow = l / 16; + + mp_msg(MSGT_VO, MSGL_DBG2, "vt_set_textarea(%d,%d): %d,%d\n", u, l, urow, lrow); + if (vt_fp) { + fprintf(vt_fp, "\33[%d;%dr\33[%d;%dH", urow, lrow, lrow, 0); + fflush(vt_fp); + } } static int config(uint32_t width, uint32_t height, uint32_t d_width, - uint32_t d_height, uint32_t flags, char *title, - uint32_t format) + uint32_t d_height, uint32_t flags, char *title, + uint32_t format) { - struct fb_cmap *cmap; - int vm = flags & VOFLAG_MODESWITCHING; - int zoom = flags & VOFLAG_SWSCALE; - int vt_fd; - - fs = flags & VOFLAG_FULLSCREEN; - - if(pre_init_err == -2) - { - mp_msg(MSGT_VO, MSGL_ERR, "Internal fatal error: config() was called before preinit()\n"); - return -1; - } - - if (pre_init_err) return 1; - - if (fb_mode_name && !vm) { - mp_msg(MSGT_VO, MSGL_ERR, "-fbmode can only be used with -vm\n"); - return 1; - } - if (vm && (parse_fbmode_cfg(fb_mode_cfgfile) < 0)) - return 1; - if (d_width && (fs || vm)) { - out_width = d_width; - out_height = d_height; - } else { - out_width = width; - out_height = height; - } - in_width = width; - in_height = height; - pixel_format = format; - - if (fb_mode_name) { - if (!(fb_mode = find_mode_by_name(fb_mode_name))) { - mp_msg(MSGT_VO, MSGL_ERR, "can't find requested video mode\n"); - return 1; - } - fb_mode2fb_vinfo(fb_mode, &fb_vinfo); - } else if (vm) { - monitor_hfreq = str2range(monitor_hfreq_str); - monitor_vfreq = str2range(monitor_vfreq_str); - monitor_dotclock = str2range(monitor_dotclock_str); - if (!monitor_hfreq || !monitor_vfreq || !monitor_dotclock) { - mp_msg(MSGT_VO, MSGL_ERR, "you have to specify the capabilities of" - " the monitor.\n"); - return 1; - } - if (!(fb_mode = find_best_mode(out_width, out_height, - monitor_hfreq, monitor_vfreq, - monitor_dotclock))) { - mp_msg(MSGT_VO, MSGL_ERR, "can't find best video mode\n"); - return 1; - } - mp_msg(MSGT_VO, MSGL_V, "using mode %dx%d @ %.1fHz\n", fb_mode->xres, - fb_mode->yres, vsf(fb_mode)); - fb_mode2fb_vinfo(fb_mode, &fb_vinfo); - } - fb_bpp_we_want = fb_bpp; - set_bpp(&fb_vinfo, fb_bpp); - fb_vinfo.xres_virtual = fb_vinfo.xres; - fb_vinfo.yres_virtual = fb_vinfo.yres; - - if (fb_tty_fd >= 0 && ioctl(fb_tty_fd, KDSETMODE, KD_GRAPHICS) < 0) { - mp_msg(MSGT_VO, MSGL_V, "Can't set graphics mode: %s\n", strerror(errno)); - close(fb_tty_fd); - fb_tty_fd = -1; + struct fb_cmap *cmap; + int vm = flags & VOFLAG_MODESWITCHING; + int zoom = flags & VOFLAG_SWSCALE; + int vt_fd; + + fs = flags & VOFLAG_FULLSCREEN; + + if (pre_init_err == -2) { + mp_msg(MSGT_VO, MSGL_ERR, "Internal fatal error: config() was called before preinit()\n"); + return -1; + } + + if (pre_init_err) + return 1; + + if (fb_mode_name && !vm) { + mp_msg(MSGT_VO, MSGL_ERR, "-fbmode can only be used with -vm\n"); + return 1; + } + if (vm && (parse_fbmode_cfg(fb_mode_cfgfile) < 0)) + return 1; + if (d_width && (fs || vm)) { + out_width = d_width; + out_height = d_height; + } else { + out_width = width; + out_height = height; + } + in_width = width; + in_height = height; + pixel_format = format; + + if (fb_mode_name) { + if (!(fb_mode = find_mode_by_name(fb_mode_name))) { + mp_msg(MSGT_VO, MSGL_ERR, "can't find requested video mode\n"); + return 1; } + fb_mode2fb_vinfo(fb_mode, &fb_vinfo); + } else if (vm) { + monitor_hfreq = str2range(monitor_hfreq_str); + monitor_vfreq = str2range(monitor_vfreq_str); + monitor_dotclock = str2range(monitor_dotclock_str); + if (!monitor_hfreq || !monitor_vfreq || !monitor_dotclock) { + mp_msg(MSGT_VO, MSGL_ERR, "you have to specify the capabilities of" + " the monitor.\n"); + return 1; + } + if (!(fb_mode = find_best_mode(out_width, out_height, monitor_hfreq, + monitor_vfreq, monitor_dotclock))) { + mp_msg(MSGT_VO, MSGL_ERR, "can't find best video mode\n"); + return 1; + } + mp_msg(MSGT_VO, MSGL_V, "using mode %dx%d @ %.1fHz\n", fb_mode->xres, + fb_mode->yres, vsf(fb_mode)); + fb_mode2fb_vinfo(fb_mode, &fb_vinfo); + } + fb_bpp_we_want = fb_bpp; + set_bpp(&fb_vinfo, fb_bpp); + fb_vinfo.xres_virtual = fb_vinfo.xres; + fb_vinfo.yres_virtual = fb_vinfo.yres; + + if (fb_tty_fd >= 0 && ioctl(fb_tty_fd, KDSETMODE, KD_GRAPHICS) < 0) { + mp_msg(MSGT_VO, MSGL_V, "Can't set graphics mode: %s\n", strerror(errno)); + close(fb_tty_fd); + fb_tty_fd = -1; + } + + if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_vinfo)) { + mp_msg(MSGT_VO, MSGL_ERR, "Can't put VSCREENINFO: %s\n", strerror(errno)); + if (fb_tty_fd >= 0 && ioctl(fb_tty_fd, KDSETMODE, KD_TEXT) < 0) { + mp_msg(MSGT_VO, MSGL_ERR, "Can't restore text mode: %s\n", strerror(errno)); + } + return 1; + } + + fb_pixel_size = fb_vinfo.bits_per_pixel / 8; + fb_bpp = fb_vinfo.red.length + fb_vinfo.green.length + + fb_vinfo.blue.length + fb_vinfo.transp.length; + if (fb_bpp_we_want != fb_bpp) + mp_msg(MSGT_VO, MSGL_WARN, "requested %d bpp, got %d bpp!!!\n", + fb_bpp_we_want, fb_bpp); + + switch (fb_bpp) { + case 32: + draw_alpha_p = vo_draw_alpha_rgb32; + break; + case 24: + draw_alpha_p = vo_draw_alpha_rgb24; + break; + case 16: + draw_alpha_p = vo_draw_alpha_rgb16; + break; + case 15: + draw_alpha_p = vo_draw_alpha_rgb15; + break; + default: + return 1; + } + + fb_xres = fb_vinfo.xres; + fb_yres = fb_vinfo.yres; + + if (vm || fs) { + out_width = fb_xres; + out_height = fb_yres; + } + if (out_width < in_width || out_height < in_height) { + mp_msg(MSGT_VO, MSGL_ERR, "screensize is smaller than video size\n"); + return 1; + } + + first_row = (out_height - in_height) / 2; + last_row = (out_height + in_height) / 2; + + if (ioctl(fb_dev_fd, FBIOGET_FSCREENINFO, &fb_finfo)) { + mp_msg(MSGT_VO, MSGL_ERR, "Can't get FSCREENINFO: %s\n", strerror(errno)); + return 1; + } + + if (fb_finfo.type != FB_TYPE_PACKED_PIXELS) { + mp_msg(MSGT_VO, MSGL_ERR, "type %d not supported\n", fb_finfo.type); + return 1; + } + + switch (fb_finfo.visual) { + case FB_VISUAL_TRUECOLOR: + break; + case FB_VISUAL_DIRECTCOLOR: + mp_msg(MSGT_VO, MSGL_V, "creating cmap for directcolor\n"); + if (ioctl(fb_dev_fd, FBIOGETCMAP, &fb_oldcmap)) { + mp_msg(MSGT_VO, MSGL_ERR, "can't get cmap: %s\n", + strerror(errno)); + return 1; + } + if (!(cmap = make_directcolor_cmap(&fb_vinfo))) + return 1; + if (ioctl(fb_dev_fd, FBIOPUTCMAP, cmap)) { + mp_msg(MSGT_VO, MSGL_ERR, "can't put cmap: %s\n", + strerror(errno)); + return 1; + } + fb_cmap_changed = 1; + free(cmap->red); + free(cmap->green); + free(cmap->blue); + free(cmap); + break; + default: + mp_msg(MSGT_VO, MSGL_ERR, "visual: %d not yet supported\n", + fb_finfo.visual); + return 1; + } + + fb_line_len = fb_finfo.line_length; + fb_size = fb_finfo.smem_len; - if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_vinfo)) { - mp_msg(MSGT_VO, MSGL_ERR, "Can't put VSCREENINFO: %s\n", strerror(errno)); - if (fb_tty_fd >= 0 && ioctl(fb_tty_fd, KDSETMODE, KD_TEXT) < 0) { - mp_msg(MSGT_VO, MSGL_ERR, "Can't restore text mode: %s\n", strerror(errno)); - } - return 1; - } - - fb_pixel_size = fb_vinfo.bits_per_pixel / 8; - fb_bpp = fb_vinfo.red.length + fb_vinfo.green.length + - fb_vinfo.blue.length + fb_vinfo.transp.length; - if (fb_bpp_we_want != fb_bpp) - mp_msg(MSGT_VO, MSGL_WARN, "requested %d bpp, got %d bpp!!!\n", - fb_bpp_we_want, fb_bpp); - - switch (fb_bpp) { - case 32: draw_alpha_p = vo_draw_alpha_rgb32; break; - case 24: draw_alpha_p = vo_draw_alpha_rgb24; break; - case 16: draw_alpha_p = vo_draw_alpha_rgb16; break; - case 15: draw_alpha_p = vo_draw_alpha_rgb15; break; - default: return 1; - } - - fb_xres = fb_vinfo.xres; - fb_yres = fb_vinfo.yres; - - if (vm || fs) { - out_width = fb_xres; - out_height = fb_yres; - } - if (out_width < in_width || out_height < in_height) { - mp_msg(MSGT_VO, MSGL_ERR, "screensize is smaller than video size\n"); - return 1; - } - - first_row = (out_height - in_height) / 2; - last_row = (out_height + in_height) / 2; - - if (ioctl(fb_dev_fd, FBIOGET_FSCREENINFO, &fb_finfo)) { - mp_msg(MSGT_VO, MSGL_ERR, "Can't get FSCREENINFO: %s\n", strerror(errno)); - return 1; - } - - lots_of_printf(); - - if (fb_finfo.type != FB_TYPE_PACKED_PIXELS) { - mp_msg(MSGT_VO, MSGL_ERR, "type %d not supported\n", fb_finfo.type); - return 1; - } - - switch (fb_finfo.visual) { - case FB_VISUAL_TRUECOLOR: - break; - case FB_VISUAL_DIRECTCOLOR: - mp_msg(MSGT_VO, MSGL_V, "creating cmap for directcolor\n"); - if (ioctl(fb_dev_fd, FBIOGETCMAP, &fb_oldcmap)) { - mp_msg(MSGT_VO, MSGL_ERR, "can't get cmap: %s\n", - strerror(errno)); - return 1; - } - if (!(cmap = make_directcolor_cmap(&fb_vinfo))) - return 1; - if (ioctl(fb_dev_fd, FBIOPUTCMAP, cmap)) { - mp_msg(MSGT_VO, MSGL_ERR, "can't put cmap: %s\n", - strerror(errno)); - return 1; - } - fb_cmap_changed = 1; - free(cmap->red); - free(cmap->green); - free(cmap->blue); - free(cmap); - break; - default: - mp_msg(MSGT_VO, MSGL_ERR, "visual: %d not yet supported\n", - fb_finfo.visual); - return 1; - } - - fb_line_len = fb_finfo.line_length; - fb_size = fb_finfo.smem_len; - frame_buffer = NULL; #ifdef CONFIG_VIDIX - if(vidix_name) - { - unsigned image_width,image_height,x_offset,y_offset; - if(zoom || fs){ - aspect_save_orig(width,height); - aspect_save_prescale(d_width,d_height); - aspect_save_screenres(fb_xres,fb_yres); - aspect(&image_width,&image_height,fs ? A_ZOOM : A_NOZOOM); - } else { - image_width=width; - image_height=height; - } - - if(fb_xres > image_width) - x_offset = (fb_xres - image_width) / 2; - else x_offset = 0; - if(fb_yres > image_height) - y_offset = (fb_yres - image_height) / 2; - else y_offset = 0; - - if(vidix_init(width,height,x_offset,y_offset,image_width, - image_height,format,fb_bpp, - fb_xres,fb_yres) != 0) - { - mp_msg(MSGT_VO, MSGL_ERR, "Can't initialize VIDIX driver\n"); - vidix_name = NULL; - vidix_term(); - return -1; - } - else mp_msg(MSGT_VO, MSGL_V, "Using VIDIX\n"); - vidix_start(); - if (vidix_grkey_support()) - { - vidix_grkey_get(&gr_key); - gr_key.key_op = KEYS_PUT; - if (!(vo_colorkey & 0xff000000)) - { - gr_key.ckey.op = CKEY_TRUE; - gr_key.ckey.red = (vo_colorkey & 0x00ff0000) >> 16; - gr_key.ckey.green = (vo_colorkey & 0x0000ff00) >> 8; - gr_key.ckey.blue = vo_colorkey & 0x000000ff; - } - else - gr_key.ckey.op = CKEY_FALSE; - vidix_grkey_set(&gr_key); - } - } - else + if (vidix_name) { + unsigned image_width, image_height, x_offset, y_offset; + if (zoom || fs) { + aspect_save_orig(width, height); + aspect_save_prescale(d_width, d_height); + aspect_save_screenres(fb_xres, fb_yres); + aspect(&image_width, &image_height, fs ? A_ZOOM : A_NOZOOM); + } else { + image_width = width; + image_height = height; + } + + if (fb_xres > image_width) + x_offset = (fb_xres - image_width) / 2; + else + x_offset = 0; + if (fb_yres > image_height) + y_offset = (fb_yres - image_height) / 2; + else + y_offset = 0; + + if (vidix_init(width, height, x_offset, y_offset, image_width, + image_height, format, fb_bpp, fb_xres, fb_yres) != 0) { + mp_msg(MSGT_VO, MSGL_ERR, "Can't initialize VIDIX driver\n"); + vidix_name = NULL; + vidix_term(); + return -1; + } else + mp_msg(MSGT_VO, MSGL_V, "Using VIDIX\n"); + vidix_start(); + if (vidix_grkey_support()) { + vidix_grkey_get(&gr_key); + gr_key.key_op = KEYS_PUT; + if (!(vo_colorkey & 0xff000000)) { + gr_key.ckey.op = CKEY_TRUE; + gr_key.ckey.red = (vo_colorkey & 0x00ff0000) >> 16; + gr_key.ckey.green = (vo_colorkey & 0x0000ff00) >> 8; + gr_key.ckey.blue = vo_colorkey & 0x000000ff; + } else + gr_key.ckey.op = CKEY_FALSE; + vidix_grkey_set(&gr_key); + } + } else #endif - { - int x_offset=0,y_offset=0; - geometry(&x_offset, &y_offset, &out_width, &out_height, fb_xres, fb_yres); - if ((frame_buffer = (uint8_t *) mmap(0, fb_size, PROT_READ | PROT_WRITE, - MAP_SHARED, fb_dev_fd, 0)) == (uint8_t *) -1) { - mp_msg(MSGT_VO, MSGL_ERR, "Can't mmap %s: %s\n", fb_dev_name, strerror(errno)); - return 1; - } - - center = frame_buffer + - ( (out_width - in_width) / 2 ) * fb_pixel_size + - ( (out_height - in_height) / 2 ) * fb_line_len + - x_offset * fb_pixel_size + y_offset * fb_line_len; - - mp_msg(MSGT_VO, MSGL_DBG2, "frame_buffer @ %p\n", frame_buffer); - mp_msg(MSGT_VO, MSGL_DBG2, "center @ %p\n", center); - mp_msg(MSGT_VO, MSGL_V, "pixel per line: %d\n", fb_line_len / fb_pixel_size); - - if (fs || vm) - memset(frame_buffer, '\0', fb_line_len * fb_yres); - } - if (vt_doit && (vt_fd = open("/dev/tty", O_WRONLY)) == -1) { - mp_msg(MSGT_VO, MSGL_ERR, "can't open /dev/tty: %s\n", strerror(errno)); - vt_doit = 0; - } - if (vt_doit && !(vt_fp = fdopen(vt_fd, "w"))) { - mp_msg(MSGT_VO, MSGL_ERR, "can't fdopen /dev/tty: %s\n", strerror(errno)); - vt_doit = 0; - } - - if (vt_doit) - vt_set_textarea(last_row, fb_yres); - - return 0; + { + int x_offset = 0, y_offset = 0; + geometry(&x_offset, &y_offset, &out_width, &out_height, fb_xres, fb_yres); + + frame_buffer = (uint8_t *) mmap(0, fb_size, PROT_READ | PROT_WRITE, + MAP_SHARED, fb_dev_fd, 0); + if (frame_buffer == (uint8_t *) -1) { + mp_msg(MSGT_VO, MSGL_ERR, "Can't mmap %s: %s\n", fb_dev_name, strerror(errno)); + return 1; + } + + center = frame_buffer + + ( (out_width - in_width) / 2 ) * fb_pixel_size + + ( (out_height - in_height) / 2 ) * fb_line_len + + x_offset * fb_pixel_size + y_offset * fb_line_len; + + mp_msg(MSGT_VO, MSGL_DBG2, "frame_buffer @ %p\n", frame_buffer); + mp_msg(MSGT_VO, MSGL_DBG2, "center @ %p\n", center); + mp_msg(MSGT_VO, MSGL_V, "pixel per line: %d\n", fb_line_len / fb_pixel_size); + + if (fs || vm) + memset(frame_buffer, '\0', fb_line_len * fb_yres); + } + if (vt_doit && (vt_fd = open("/dev/tty", O_WRONLY)) == -1) { + mp_msg(MSGT_VO, MSGL_ERR, "can't open /dev/tty: %s\n", strerror(errno)); + vt_doit = 0; + } + if (vt_doit && !(vt_fp = fdopen(vt_fd, "w"))) { + mp_msg(MSGT_VO, MSGL_ERR, "can't fdopen /dev/tty: %s\n", strerror(errno)); + vt_doit = 0; + } + + if (vt_doit) + vt_set_textarea(last_row, fb_yres); + + return 0; } static int query_format(uint32_t format) { - if (!fb_preinit(0)) - return 0; + if (!fb_preinit(0)) + return 0; #ifdef CONFIG_VIDIX - if(vidix_name) - return vidix_query_fourcc(format); + if (vidix_name) + return vidix_query_fourcc(format); #endif - if ((format & IMGFMT_BGR_MASK) == IMGFMT_BGR) { - int bpp = format & 0xff; + if ((format & IMGFMT_BGR_MASK) == IMGFMT_BGR) { + int bpp = format & 0xff; - if (bpp == fb_bpp) - return VFCAP_ACCEPT_STRIDE | VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW; - } - return 0; + if (bpp == fb_bpp) + return VFCAP_ACCEPT_STRIDE | VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW; + } + return 0; } static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src, - unsigned char *srca, int stride) + unsigned char *srca, int stride) { - unsigned char *dst; + unsigned char *dst; - dst = center + fb_line_len * y0 + fb_pixel_size * x0; + dst = center + fb_line_len * y0 + fb_pixel_size * x0; - (*draw_alpha_p)(w, h, src, srca, stride, dst, fb_line_len); + (*draw_alpha_p)(w, h, src, srca, stride, dst, fb_line_len); } -static int draw_frame(uint8_t *src[]) { return 1; } +static int draw_frame(uint8_t *src[]) +{ + return 1; +} -static int draw_slice(uint8_t *src[], int stride[], int w, int h, int x, - int y) +static int draw_slice(uint8_t *src[], int stride[], int w, int h, int x, int y) { - uint8_t *d; - uint8_t *s; + uint8_t *d, *s; - d = center + fb_line_len * y + fb_pixel_size * x; + d = center + fb_line_len * y + fb_pixel_size * x; - s = src[0]; - while (h) { - fast_memcpy(d, s, w * fb_pixel_size); - d += fb_line_len; - s += stride[0]; - h--; - } + s = src[0]; + while (h) { + fast_memcpy(d, s, w * fb_pixel_size); + d += fb_line_len; + s += stride[0]; + h--; + } - return 0; + return 0; } static void check_events(void) @@ -1092,98 +1027,100 @@ static void flip_page(void) static void draw_osd(void) { - vo_draw_text(in_width, in_height, draw_alpha); + vo_draw_text(in_width, in_height, draw_alpha); } static void uninit(void) { - if (fb_cmap_changed) { - if (ioctl(fb_dev_fd, FBIOPUTCMAP, &fb_oldcmap)) - mp_msg(MSGT_VO, MSGL_WARN, "Can't restore original cmap\n"); - fb_cmap_changed = 0; - } - if (ioctl(fb_dev_fd, FBIOGET_VSCREENINFO, &fb_vinfo)) - mp_msg(MSGT_VO, MSGL_WARN, "ioctl FBIOGET_VSCREENINFO: %s\n", strerror(errno)); - fb_orig_vinfo.xoffset = fb_vinfo.xoffset; - fb_orig_vinfo.yoffset = fb_vinfo.yoffset; - if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_orig_vinfo)) - mp_msg(MSGT_VO, MSGL_WARN, "Can't reset original fb_var_screeninfo: %s\n", strerror(errno)); - if (fb_tty_fd >= 0) { - if (ioctl(fb_tty_fd, KDSETMODE, KD_TEXT) < 0) - mp_msg(MSGT_VO, MSGL_WARN, "Can't restore text mode: %s\n", strerror(errno)); - } - if (vt_doit) - vt_set_textarea(0, fb_orig_vinfo.yres); - close(fb_tty_fd); - close(fb_dev_fd); - if(frame_buffer) munmap(frame_buffer, fb_size); - frame_buffer = NULL; + if (fb_cmap_changed) { + if (ioctl(fb_dev_fd, FBIOPUTCMAP, &fb_oldcmap)) + mp_msg(MSGT_VO, MSGL_WARN, "Can't restore original cmap\n"); + fb_cmap_changed = 0; + } + if (ioctl(fb_dev_fd, FBIOGET_VSCREENINFO, &fb_vinfo)) + mp_msg(MSGT_VO, MSGL_WARN, "ioctl FBIOGET_VSCREENINFO: %s\n", strerror(errno)); + fb_orig_vinfo.xoffset = fb_vinfo.xoffset; + fb_orig_vinfo.yoffset = fb_vinfo.yoffset; + if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_orig_vinfo)) + mp_msg(MSGT_VO, MSGL_WARN, "Can't reset original fb_var_screeninfo: %s\n", strerror(errno)); + if (fb_tty_fd >= 0) { + if (ioctl(fb_tty_fd, KDSETMODE, KD_TEXT) < 0) + mp_msg(MSGT_VO, MSGL_WARN, "Can't restore text mode: %s\n", strerror(errno)); + } + if (vt_doit) + vt_set_textarea(0, fb_orig_vinfo.yres); + close(fb_tty_fd); + close(fb_dev_fd); + if (frame_buffer) + munmap(frame_buffer, fb_size); + frame_buffer = NULL; #ifdef CONFIG_VIDIX - if(vidix_name) vidix_term(); + if (vidix_name) + vidix_term(); #endif - fb_preinit(1); + fb_preinit(1); } static int preinit(const char *vo_subdevice) { pre_init_err = 0; - if(vo_subdevice) - { + if (vo_subdevice) { #ifdef CONFIG_VIDIX - if (memcmp(vo_subdevice, "vidix", 5) == 0) - vidix_name = &vo_subdevice[5]; - if(vidix_name) - pre_init_err = vidix_preinit(vidix_name, + if (memcmp(vo_subdevice, "vidix", 5) == 0) + vidix_name = &vo_subdevice[5]; + if (vidix_name) + pre_init_err = vidix_preinit(vidix_name, video_out_fbdev.old_functions); - else + else #endif - { - if (fb_dev_name) free(fb_dev_name); - fb_dev_name = strdup(vo_subdevice); - } + { + if (fb_dev_name) + free(fb_dev_name); + fb_dev_name = strdup(vo_subdevice); + } } - if(!pre_init_err) return pre_init_err = (fb_preinit(0) ? 0 : -1); + if (!pre_init_err) + return pre_init_err = (fb_preinit(0) ? 0 : -1); return -1; } static uint32_t get_image(mp_image_t *mpi) { - if ( - !IMGFMT_IS_BGR(mpi->imgfmt) || - (IMGFMT_BGR_DEPTH(mpi->imgfmt) != fb_bpp) || - ((mpi->type != MP_IMGTYPE_STATIC) && (mpi->type != MP_IMGTYPE_TEMP)) || - (mpi->flags & MP_IMGFLAG_PLANAR) || - (mpi->flags & MP_IMGFLAG_YUV) || - (mpi->width != in_width) || - (mpi->height != in_height) + if (!IMGFMT_IS_BGR(mpi->imgfmt) || + (IMGFMT_BGR_DEPTH(mpi->imgfmt) != fb_bpp) || + ((mpi->type != MP_IMGTYPE_STATIC) && (mpi->type != MP_IMGTYPE_TEMP)) || + (mpi->flags & MP_IMGFLAG_PLANAR) || + (mpi->flags & MP_IMGFLAG_YUV) || + (mpi->width != in_width) || + (mpi->height != in_height) ) - return VO_FALSE; + return VO_FALSE; mpi->planes[0] = center; mpi->stride[0] = fb_line_len; - mpi->flags |= MP_IMGFLAG_DIRECT; + mpi->flags |= MP_IMGFLAG_DIRECT; return VO_TRUE; } static int control(uint32_t request, void *data) { - switch (request) { - case VOCTRL_GET_IMAGE: - return get_image(data); - case VOCTRL_QUERY_FORMAT: - return query_format(*((uint32_t*)data)); - } + switch (request) { + case VOCTRL_GET_IMAGE: + return get_image(data); + case VOCTRL_QUERY_FORMAT: + return query_format(*((uint32_t*)data)); + } #ifdef CONFIG_VIDIX - if (vidix_name) { - switch (request) { - case VOCTRL_SET_EQUALIZER: - case VOCTRL_GET_EQUALIZER: - return vidix_control(request, data); - } - } + if (vidix_name) { + switch (request) { + case VOCTRL_SET_EQUALIZER: + case VOCTRL_GET_EQUALIZER: + return vidix_control(request, data); + } + } #endif - return VO_NOTIMPL; + return VO_NOTIMPL; } diff --git a/libvo/vo_gl.c b/libvo/vo_gl.c index 781d455115..b478a803ad 100644 --- a/libvo/vo_gl.c +++ b/libvo/vo_gl.c @@ -91,8 +91,11 @@ static GLint gl_texfmt; static GLenum gl_format; static GLenum gl_type; static GLuint gl_buffer; +static GLuint gl_buffer_uv[2]; static int gl_buffersize; +static int gl_buffersize_uv; static void *gl_bufferptr; +static void *gl_bufferptr_uv[2]; static GLuint fragprog; static GLuint default_texs[22]; static char *custom_prog; @@ -381,6 +384,10 @@ static void uninitGl(void) { DeleteBuffers(1, &gl_buffer); gl_buffer = 0; gl_buffersize = 0; gl_bufferptr = NULL; + if (DeleteBuffers && gl_buffer_uv[0]) + DeleteBuffers(2, gl_buffer_uv); + gl_buffer_uv[0] = gl_buffer_uv[1] = 0; gl_buffersize_uv = 0; + gl_bufferptr_uv[0] = gl_bufferptr_uv[1] = 0; err_shown = 0; } @@ -537,7 +544,7 @@ static void create_osd_texture(int x0, int y0, int w, int h, #ifndef FAST_OSD glGenTextures(1, &osdatex[osdtexCnt]); BindTexture(gl_target, osdatex[osdtexCnt]); - glCreateClearTex(gl_target, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, scale_type, sx, sy, 255); + glCreateClearTex(gl_target, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, scale_type, sx, sy, 0); { int i; char *tmp = malloc(stride * h); @@ -713,6 +720,27 @@ static uint32_t get_image(mp_image_t *mpi) { mpi->stride[1] = mpi->width >> 1; mpi->planes[2] = mpi->planes[1] + mpi->stride[1] * (mpi->height >> 1); mpi->stride[2] = mpi->width >> 1; + if (ati_hack) { + mpi->flags &= ~MP_IMGFLAG_COMMON_PLANE; + if (!gl_buffer_uv[0]) GenBuffers(2, gl_buffer_uv); + if (mpi->stride[1] * mpi->height > gl_buffersize_uv) { + BindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_buffer_uv[0]); + BufferData(GL_PIXEL_UNPACK_BUFFER, mpi->stride[1] * mpi->height, + NULL, GL_DYNAMIC_DRAW); + BindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_buffer_uv[1]); + BufferData(GL_PIXEL_UNPACK_BUFFER, mpi->stride[1] * mpi->height, + NULL, GL_DYNAMIC_DRAW); + gl_buffersize_uv = mpi->stride[1] * mpi->height; + } + if (!gl_bufferptr_uv[0]) { + BindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_buffer_uv[0]); + gl_bufferptr_uv[0] = MapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); + BindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_buffer_uv[1]); + gl_bufferptr_uv[1] = MapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); + } + mpi->planes[1] = gl_bufferptr_uv[0]; + mpi->planes[2] = gl_bufferptr_uv[1]; + } } mpi->flags |= MP_IMGFLAG_DIRECT; return VO_TRUE; @@ -752,13 +780,25 @@ static uint32_t draw_image(mp_image_t *mpi) { UnmapBuffer(GL_PIXEL_UNPACK_BUFFER); gl_bufferptr = NULL; slice = 0; // always "upload" full texture + if (!(mpi->flags & MP_IMGFLAG_COMMON_PLANE)) + planes[0] = planes[1] = planes[2] = NULL; } glUploadTex(gl_target, gl_format, gl_type, planes[0], stride[0], mpi->x, mpi->y, w, h, slice); if (mpi->imgfmt == IMGFMT_YV12) { + if ((mpi->flags & MP_IMGFLAG_DIRECT) && !(mpi->flags & MP_IMGFLAG_COMMON_PLANE)) { + BindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_buffer_uv[0]); + UnmapBuffer(GL_PIXEL_UNPACK_BUFFER); + gl_bufferptr_uv[0] = NULL; + } ActiveTexture(GL_TEXTURE1); glUploadTex(gl_target, gl_format, gl_type, planes[1], stride[1], mpi->x / 2, mpi->y / 2, w / 2, h / 2, slice); + if ((mpi->flags & MP_IMGFLAG_DIRECT) && !(mpi->flags & MP_IMGFLAG_COMMON_PLANE)) { + BindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_buffer_uv[1]); + UnmapBuffer(GL_PIXEL_UNPACK_BUFFER); + gl_bufferptr_uv[1] = NULL; + } ActiveTexture(GL_TEXTURE2); glUploadTex(gl_target, gl_format, gl_type, planes[2], stride[2], mpi->x / 2, mpi->y / 2, w / 2, h / 2, slice); diff --git a/libvo/vo_macosx.m b/libvo/vo_macosx.m index 9cd0a1a008..50f1553c60 100644 --- a/libvo/vo_macosx.m +++ b/libvo/vo_macosx.m @@ -10,6 +10,12 @@ #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> +#include <CoreServices/CoreServices.h> +//special workaround for Apple bug #6267445 +//(OSServices Power API disabled in OSServices.h for 64bit systems) +#ifndef __POWER__ +#include <CoreServices/../Frameworks/OSServices.framework/Headers/Power.h> +#endif //MPLAYER #include "config.h" @@ -324,8 +330,6 @@ static int preinit(const char *arg) { #if !defined (CONFIG_MACOSX_FINDER) || !defined (CONFIG_SDL) //this chunk of code is heavily based off SDL_macosx.m from SDL - //it uses an Apple private function to request foreground operation - void CPSEnableForegroundOperation(ProcessSerialNumber* psn); ProcessSerialNumber myProc, frProc; Boolean sameProc; @@ -335,7 +339,7 @@ static int preinit(const char *arg) { if (SameProcess(&frProc, &myProc, &sameProc) == noErr && !sameProc) { - CPSEnableForegroundOperation(&myProc); + TransformProcessType(&myProc, kProcessTransformToForegroundApplication); } SetFrontProcess(&myProc); } @@ -751,7 +755,7 @@ static int control(uint32_t request, void *data) glFlush(); - //auto hide mouse cursor and futur on-screen control? + //auto hide mouse cursor (and future on-screen control?) if(isFullscreen && !mouseHide && !isRootwin) { int curTime = TickCount()/60; diff --git a/libvo/vo_quartz.c b/libvo/vo_quartz.c index 164d00b79d..cc7cdb922b 100644 --- a/libvo/vo_quartz.c +++ b/libvo/vo_quartz.c @@ -1,19 +1,17 @@ -/* - vo_quartz.c - - by Nicolas Plourde <nicolasplourde@gmail.com> - - Copyright (c) Nicolas Plourde - April 2004 - - YUV support Copyright (C) 2004 Romain Dolbeau <romain@dolbeau.org> - - MPlayer Mac OSX Quartz video out module. - - todo: -screen overlay output - -fit osd in black bar when available - -fix RGB32 - -(add sugestion here) - */ +/** + \author Nicolas Plourde <nicolasplourde@gmail.com> + + Copyright (c) Nicolas Plourde - April 2004 + + YUV support Copyright (C) 2004 Romain Dolbeau <romain@dolbeau.org> + + \brief MPlayer Mac OSX Quartz video out module. + + \todo: -screen overlay output + -fit osd in black bar when available + -fix RGB32 + -(add sugestion here) +*/ //SYS #include <stdio.h> @@ -38,12 +36,12 @@ #include "vo_quartz.h" -static const vo_info_t info = +static const vo_info_t info = { - "Mac OSX (Quartz)", - "quartz", - "Nicolas Plourde <nicolasplourde@hotmail.com>, Romain Dolbeau <romain@dolbeau.org>", - "" + "Mac OSX (Quartz)", + "quartz", + "Nicolas Plourde <nicolasplourde@hotmail.com>, Romain Dolbeau <romain@dolbeau.org>", + "" }; const LIBVO_EXTERN(quartz) @@ -59,11 +57,11 @@ static CodecType image_qtcodec; static PlanarPixmapInfoYUV420 *P = NULL; static struct { - ImageDescriptionHandle desc; - Handle extension_colr; - Handle extension_fiel; - Handle extension_clap; - Handle extension_pasp; + ImageDescriptionHandle desc; + Handle extension_colr; + Handle extension_fiel; + Handle extension_clap; + Handle extension_pasp; } yuv_qt_stuff; static MatrixRecord matrix; static int EnterMoviesDone = 0; @@ -84,45 +82,46 @@ static int int_pause = 0; static float winAlpha = 1; static int mouseHide = FALSE; -static int device_width; -static int device_height; -static int device_id; +static int device_id = 0; -static short fs_res_x=0; -static short fs_res_y=0; +static short fs_res_x = 0; +static short fs_res_y = 0; static WindowRef theWindow = NULL; static WindowGroupRef winGroup = NULL; -static CGContextRef context; static CGRect bounds; -static GDHandle deviceHdl; +static CGDirectDisplayID displayId = 0; +static CFDictionaryRef originalMode = NULL; -static CGDataProviderRef dataProviderRef; -static CGImageRef image; +static CGDataProviderRef dataProviderRef = NULL; +static CGImageRef image = NULL; -static Rect imgRect; // size of the original image (unscaled) -static Rect dstRect; // size of the displayed image (after scaling) -static Rect winRect; // size of the window containg the displayed image (include padding) -static Rect oldWinRect; // size of the window containg the displayed image (include padding) when NOT in FS mode -static Rect deviceRect; // size of the display device +static Rect imgRect; // size of the original image (unscaled) +static Rect dstRect; // size of the displayed image (after scaling) +static Rect winRect; // size of the window containg the displayed image (include padding) +static Rect oldWinRect; // size of the window containg the displayed image (include padding) when NOT in FS mode +static CGRect displayRect; // size of the display device static Rect oldWinBounds; static MenuRef windMenu; static MenuRef movMenu; static MenuRef aspectMenu; +static int lastScreensaverUpdate = 0; +static int lastMouseHide = 0; + enum { - kQuitCmd = 1, - kHalfScreenCmd = 2, - kNormalScreenCmd = 3, - kDoubleScreenCmd = 4, - kFullScreenCmd = 5, - kKeepAspectCmd = 6, - kAspectOrgCmd = 7, - kAspectFullCmd = 8, - kAspectWideCmd = 9, - kPanScanCmd = 10 + kQuitCmd = 1, + kHalfScreenCmd = 2, + kNormalScreenCmd = 3, + kDoubleScreenCmd = 4, + kFullScreenCmd = 5, + kKeepAspectCmd = 6, + kAspectOrgCmd = 7, + kAspectFullCmd = 8, + kAspectWideCmd = 9, + kPanScanCmd = 10 }; #include "osdep/keycodes.h" @@ -138,119 +137,120 @@ void window_panscan(); static inline int convert_key(UInt32 key, UInt32 charcode) { - switch(key) + switch (key) { - case QZ_IBOOK_ENTER: - case QZ_RETURN: return KEY_ENTER; - case QZ_ESCAPE: return KEY_ESC; - case QZ_BACKSPACE: return KEY_BACKSPACE; - case QZ_LALT: return KEY_BACKSPACE; - case QZ_LCTRL: return KEY_BACKSPACE; - case QZ_LSHIFT: return KEY_BACKSPACE; - case QZ_F1: return KEY_F+1; - case QZ_F2: return KEY_F+2; - case QZ_F3: return KEY_F+3; - case QZ_F4: return KEY_F+4; - case QZ_F5: return KEY_F+5; - case QZ_F6: return KEY_F+6; - case QZ_F7: return KEY_F+7; - case QZ_F8: return KEY_F+8; - case QZ_F9: return KEY_F+9; - case QZ_F10: return KEY_F+10; - case QZ_F11: return KEY_F+11; - case QZ_F12: return KEY_F+12; - case QZ_INSERT: return KEY_INSERT; - case QZ_DELETE: return KEY_DELETE; - case QZ_HOME: return KEY_HOME; - case QZ_END: return KEY_END; - case QZ_KP_PLUS: return '+'; - case QZ_KP_MINUS: return '-'; - case QZ_TAB: return KEY_TAB; - case QZ_PAGEUP: return KEY_PAGE_UP; - case QZ_PAGEDOWN: return KEY_PAGE_DOWN; - case QZ_UP: return KEY_UP; - case QZ_DOWN: return KEY_DOWN; - case QZ_LEFT: return KEY_LEFT; - case QZ_RIGHT: return KEY_RIGHT; - case QZ_KP_MULTIPLY: return '*'; - case QZ_KP_DIVIDE: return '/'; - case QZ_KP_ENTER: return KEY_KPENTER; - case QZ_KP_PERIOD: return KEY_KPDEC; - case QZ_KP0: return KEY_KP0; - case QZ_KP1: return KEY_KP1; - case QZ_KP2: return KEY_KP2; - case QZ_KP3: return KEY_KP3; - case QZ_KP4: return KEY_KP4; - case QZ_KP5: return KEY_KP5; - case QZ_KP6: return KEY_KP6; - case QZ_KP7: return KEY_KP7; - case QZ_KP8: return KEY_KP8; - case QZ_KP9: return KEY_KP9; - default: return charcode; + case QZ_IBOOK_ENTER: + case QZ_RETURN: return KEY_ENTER; + case QZ_ESCAPE: return KEY_ESC; + case QZ_BACKSPACE: return KEY_BACKSPACE; + case QZ_LALT: return KEY_BACKSPACE; + case QZ_LCTRL: return KEY_BACKSPACE; + case QZ_LSHIFT: return KEY_BACKSPACE; + case QZ_F1: return KEY_F + 1; + case QZ_F2: return KEY_F + 2; + case QZ_F3: return KEY_F + 3; + case QZ_F4: return KEY_F + 4; + case QZ_F5: return KEY_F + 5; + case QZ_F6: return KEY_F + 6; + case QZ_F7: return KEY_F + 7; + case QZ_F8: return KEY_F + 8; + case QZ_F9: return KEY_F + 9; + case QZ_F10: return KEY_F + 10; + case QZ_F11: return KEY_F + 11; + case QZ_F12: return KEY_F + 12; + case QZ_INSERT: return KEY_INSERT; + case QZ_DELETE: return KEY_DELETE; + case QZ_HOME: return KEY_HOME; + case QZ_END: return KEY_END; + case QZ_KP_PLUS: return '+'; + case QZ_KP_MINUS: return '-'; + case QZ_TAB: return KEY_TAB; + case QZ_PAGEUP: return KEY_PAGE_UP; + case QZ_PAGEDOWN: return KEY_PAGE_DOWN; + case QZ_UP: return KEY_UP; + case QZ_DOWN: return KEY_DOWN; + case QZ_LEFT: return KEY_LEFT; + case QZ_RIGHT: return KEY_RIGHT; + case QZ_KP_MULTIPLY: return '*'; + case QZ_KP_DIVIDE: return '/'; + case QZ_KP_ENTER: return KEY_KPENTER; + case QZ_KP_PERIOD: return KEY_KPDEC; + case QZ_KP0: return KEY_KP0; + case QZ_KP1: return KEY_KP1; + case QZ_KP2: return KEY_KP2; + case QZ_KP3: return KEY_KP3; + case QZ_KP4: return KEY_KP4; + case QZ_KP5: return KEY_KP5; + case QZ_KP6: return KEY_KP6; + case QZ_KP7: return KEY_KP7; + case QZ_KP8: return KEY_KP8; + case QZ_KP9: return KEY_KP9; + default: return charcode; } } static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src, unsigned char *srca, int stride) { - switch (image_format) - { - case IMGFMT_RGB32: - vo_draw_alpha_rgb32(w,h,src,srca,stride,image_data+4*(y0*imgRect.right+x0),4*imgRect.right); - break; - case IMGFMT_YV12: - case IMGFMT_IYUV: - case IMGFMT_I420: - vo_draw_alpha_yv12(w,h,src,srca,stride, ((char*)P) + be2me_32(P->componentInfoY.offset) + x0 + y0 * imgRect.right, imgRect.right); - break; - case IMGFMT_UYVY: - vo_draw_alpha_uyvy(w,h,src,srca,stride,((char*)P) + (x0 + y0 * imgRect.right) * 2,imgRect.right*2); - break; - case IMGFMT_YUY2: - vo_draw_alpha_yuy2(w,h,src,srca,stride,((char*)P) + (x0 + y0 * imgRect.right) * 2,imgRect.right*2); - break; - } + switch (image_format) + { + case IMGFMT_RGB32: + vo_draw_alpha_rgb32(w, h, src, srca, stride, image_data + 4 * (y0 * imgRect.right + x0), 4 * imgRect.right); + break; + case IMGFMT_YV12: + case IMGFMT_IYUV: + case IMGFMT_I420: + vo_draw_alpha_yv12(w, h, src, srca, stride, ((char *)P) + be2me_32(P->componentInfoY.offset) + x0 + y0 * imgRect.right, imgRect.right); + break; + case IMGFMT_UYVY: + vo_draw_alpha_uyvy(w, h, src, srca, stride, ((char *)P) + (x0 + y0 * imgRect.right) * 2, imgRect.right * 2); + break; + case IMGFMT_YUY2: + vo_draw_alpha_yuy2(w, h, src, srca, stride, ((char *)P) + (x0 + y0 * imgRect.right) * 2, imgRect.right * 2); + break; + } } //default keyboard event handler static OSStatus KeyEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData) { OSStatus result = noErr; - UInt32 class = GetEventClass (event); - UInt32 kind = GetEventKind (event); - - result = CallNextEventHandler(nextHandler, event); - - if(class == kEventClassKeyboard) - { - char macCharCodes; - UInt32 macKeyCode; - UInt32 macKeyModifiers; - - GetEventParameter(event, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(macCharCodes), NULL, &macCharCodes); - GetEventParameter(event, kEventParamKeyCode, typeUInt32, NULL, sizeof(macKeyCode), NULL, &macKeyCode); - GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(macKeyModifiers), NULL, &macKeyModifiers); - - if(macKeyModifiers != 256) - { - if (kind == kEventRawKeyRepeat || kind == kEventRawKeyDown) - { - int key = convert_key(macKeyCode, macCharCodes); - if(key != -1) - mplayer_put_key(key); - } - } - else if(macKeyModifiers == 256) - { - switch(macCharCodes) - { - case '[': SetWindowAlpha(theWindow, winAlpha-=0.05); break; - case ']': SetWindowAlpha(theWindow, winAlpha+=0.05); break; - } - } - else - result = eventNotHandledErr; - } - + UInt32 class = GetEventClass(event); + UInt32 kind = GetEventKind(event); + + result = CallNextEventHandler(nextHandler, event); + + if (class == kEventClassKeyboard) + { + char macCharCodes; + UInt32 macKeyCode; + UInt32 macKeyModifiers; + + GetEventParameter(event, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(macCharCodes), NULL, &macCharCodes); + GetEventParameter(event, kEventParamKeyCode, typeUInt32, NULL, sizeof(macKeyCode), NULL, &macKeyCode); + GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(macKeyModifiers), NULL, &macKeyModifiers); + + if (macKeyModifiers != 256) + { + if (kind == kEventRawKeyRepeat || kind == kEventRawKeyDown) + { + int key = convert_key(macKeyCode, macCharCodes); + + if (key != -1) + mplayer_put_key(key); + } + } + else if (macKeyModifiers == 256) + { + switch (macCharCodes) + { + case '[': SetWindowAlpha(theWindow, winAlpha -= 0.05); break; + case ']': SetWindowAlpha(theWindow, winAlpha += 0.05); break; + } + } + else + result = eventNotHandledErr; + } + return result; } @@ -258,120 +258,128 @@ static OSStatus KeyEventHandler(EventHandlerCallRef nextHandler, EventRef event, static OSStatus MouseEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData) { OSStatus result = noErr; - UInt32 class = GetEventClass (event); - UInt32 kind = GetEventKind (event); - - result = CallNextEventHandler(nextHandler, event); - - if(class == kEventClassMouse) - { - WindowPtr tmpWin; - Point mousePos; - Point winMousePos; - - GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, 0, sizeof(Point), 0, &mousePos); - GetEventParameter(event, kEventParamWindowMouseLocation, typeQDPoint, 0, sizeof(Point), 0, &winMousePos); - - switch (kind) - { - case kEventMouseMoved: - { - if(vo_quartz_fs) - { - CGDisplayShowCursor(kCGDirectMainDisplay); - mouseHide = FALSE; - } - } - break; - - case kEventMouseWheelMoved: - { - int wheel; - short part; - - GetEventParameter(event, kEventParamMouseWheelDelta, typeSInt32, 0, sizeof(int), 0, &wheel); - - part = FindWindow(mousePos,&tmpWin); - - if(part == inContent) - { - if(wheel > 0) - mplayer_put_key(MOUSE_BTN3); - else - mplayer_put_key(MOUSE_BTN4); - } - } - break; - - case kEventMouseDown: - case kEventMouseUp: - { - EventMouseButton button; - short part; - Rect bounds; - - GetWindowPortBounds(theWindow, &bounds); - GetEventParameter(event, kEventParamMouseButton, typeMouseButton, 0, sizeof(EventMouseButton), 0, &button); - - part = FindWindow(mousePos,&tmpWin); - if(kind == kEventMouseUp) - { - if (part != inContent) - break; - switch(button) - { - case kEventMouseButtonPrimary: - mplayer_put_key(MOUSE_BTN0); - break; - case kEventMouseButtonSecondary: - mplayer_put_key(MOUSE_BTN2); - break; - case kEventMouseButtonTertiary: - mplayer_put_key(MOUSE_BTN1); - break; - - default:result = eventNotHandledErr;break; - } - break; - } - if( (winMousePos.h > (bounds.right - 15)) && (winMousePos.v > (bounds.bottom)) ) - { - if(!vo_quartz_fs) - { - GrowWindow(theWindow, mousePos, NULL); - } - } - else if(part == inMenuBar) - { - MenuSelect(mousePos); - HiliteMenu(0); - } - else if(part == inContent) - { - switch(button) - { - case kEventMouseButtonPrimary: - mplayer_put_key(MOUSE_BTN0 | MP_KEY_DOWN); - break; - case kEventMouseButtonSecondary: - mplayer_put_key(MOUSE_BTN2 | MP_KEY_DOWN); - break; - case kEventMouseButtonTertiary: - mplayer_put_key(MOUSE_BTN1 | MP_KEY_DOWN); - break; - - default:result = eventNotHandledErr;break; - } - } - } - break; - - case kEventMouseDragged: - break; - - default:result = eventNotHandledErr;break; - } - } + UInt32 class = GetEventClass(event); + UInt32 kind = GetEventKind(event); + + result = CallNextEventHandler(nextHandler, event); + + if (class == kEventClassMouse) + { + WindowPtr tmpWin; + Point mousePos; + Point winMousePos; + + GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, 0, sizeof(Point), 0, &mousePos); + GetEventParameter(event, kEventParamWindowMouseLocation, typeQDPoint, 0, sizeof(Point), 0, &winMousePos); + + switch (kind) + { + case kEventMouseMoved: + { + if (vo_quartz_fs) + { + CGDisplayShowCursor(displayId); + mouseHide = FALSE; + } + } + break; + + case kEventMouseWheelMoved: + { + int wheel; + short part; + + GetEventParameter(event, kEventParamMouseWheelDelta, typeSInt32, 0, sizeof(int), 0, &wheel); + + part = FindWindow(mousePos, &tmpWin); + + if (part == inContent) + { + if (wheel > 0) + mplayer_put_key(MOUSE_BTN3); + else + mplayer_put_key(MOUSE_BTN4); + } + } + break; + + case kEventMouseDown: + case kEventMouseUp: + { + EventMouseButton button; + short part; + Rect bounds; + + GetWindowPortBounds(theWindow, &bounds); + GetEventParameter(event, kEventParamMouseButton, typeMouseButton, 0, sizeof(EventMouseButton), 0, &button); + + part = FindWindow(mousePos, &tmpWin); + if (kind == kEventMouseUp) + { + if (part != inContent) + break; + switch (button) + { + case kEventMouseButtonPrimary: + mplayer_put_key(MOUSE_BTN0); + break; + case kEventMouseButtonSecondary: + mplayer_put_key(MOUSE_BTN2); + break; + case kEventMouseButtonTertiary: + mplayer_put_key(MOUSE_BTN1); + break; + + default: + result = eventNotHandledErr; + break; + } + break; + } + if ((winMousePos.h > (bounds.right - 15)) && (winMousePos.v > (bounds.bottom))) + { + if (!vo_quartz_fs) + { + Rect newSize; + + ResizeWindow(theWindow, mousePos, NULL, &newSize); + } + } + else if (part == inMenuBar) + { + MenuSelect(mousePos); + HiliteMenu(0); + } + else if (part == inContent) + { + switch (button) + { + case kEventMouseButtonPrimary: + mplayer_put_key(MOUSE_BTN0 | MP_KEY_DOWN); + break; + case kEventMouseButtonSecondary: + mplayer_put_key(MOUSE_BTN2 | MP_KEY_DOWN); + break; + case kEventMouseButtonTertiary: + mplayer_put_key(MOUSE_BTN1 | MP_KEY_DOWN); + break; + + default: + result = eventNotHandledErr; + break; + } + } + } + break; + + case kEventMouseDragged: + break; + + default: + result = eventNotHandledErr; + break; + } + } return result; } @@ -380,1070 +388,1102 @@ static OSStatus MouseEventHandler(EventHandlerCallRef nextHandler, EventRef even static OSStatus WindowEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData) { OSStatus result = noErr; - uint32_t d_width; - uint32_t d_height; - UInt32 class = GetEventClass (event); - UInt32 kind = GetEventKind (event); - - result = CallNextEventHandler(nextHandler, event); - - aspect(&d_width,&d_height,A_NOZOOM); - - if(class == kEventClassCommand) - { - HICommand theHICommand; - GetEventParameter( event, kEventParamDirectObject, typeHICommand, NULL, sizeof( HICommand ), NULL, &theHICommand ); - - switch ( theHICommand.commandID ) - { - case kHICommandQuit: - mplayer_put_key(KEY_CLOSE_WIN); - break; - - case kHalfScreenCmd: - if(vo_quartz_fs) - { - vo_fs = (!(vo_fs)); window_fullscreen(); - } - - SizeWindow(theWindow, (d_width/2), ((d_width/movie_aspect)/2), 1); - window_resized(); - break; - - case kNormalScreenCmd: - if(vo_quartz_fs) - { - vo_fs = (!(vo_fs)); window_fullscreen(); - } - - SizeWindow(theWindow, d_width, (d_width/movie_aspect), 1); - window_resized(); - break; - - case kDoubleScreenCmd: - if(vo_quartz_fs) - { - vo_fs = (!(vo_fs)); window_fullscreen(); - } - - SizeWindow(theWindow, (d_width*2), ((d_width/movie_aspect)*2), 1); - window_resized(); - break; - - case kFullScreenCmd: - vo_fs = (!(vo_fs)); window_fullscreen(); - break; - - case kKeepAspectCmd: - vo_keepaspect = (!(vo_keepaspect)); - CheckMenuItem (aspectMenu, 1, vo_keepaspect); - window_resized(); - break; - - case kAspectOrgCmd: - movie_aspect = old_movie_aspect; - if(!vo_quartz_fs) - { - SizeWindow(theWindow, dstRect.right, (dstRect.right/movie_aspect),1); - } - window_resized(); - break; - - case kAspectFullCmd: - movie_aspect = 4.0f/3.0f; - if(!vo_quartz_fs) - { - SizeWindow(theWindow, dstRect.right, (dstRect.right/movie_aspect),1); - } - window_resized(); - break; - - case kAspectWideCmd: - movie_aspect = 16.0f/9.0f; - if(!vo_quartz_fs) - { - SizeWindow(theWindow, dstRect.right, (dstRect.right/movie_aspect),1); - } - window_resized(); - break; - - case kPanScanCmd: - vo_panscan = (!(vo_panscan)); - CheckMenuItem (aspectMenu, 2, vo_panscan); - window_panscan(); - window_resized(); - break; - - default: - result = eventNotHandledErr; - break; - } - } - else if(class == kEventClassWindow) - { - WindowRef window; - Rect rectPort = {0,0,0,0}; - - GetEventParameter(event, kEventParamDirectObject, typeWindowRef, NULL, sizeof(WindowRef), NULL, &window); - - if(window) - { - GetPortBounds(GetWindowPort(window), &rectPort); - } - - switch (kind) - { - case kEventWindowClosed: - theWindow = NULL; - mplayer_put_key(KEY_CLOSE_WIN); - break; - - //resize window - case kEventWindowZoomed: - case kEventWindowBoundsChanged: - window_resized(); - flip_page(); - window_resized(); - break; - - default: - result = eventNotHandledErr; - break; - } - } - + uint32_t d_width; + uint32_t d_height; + UInt32 class = GetEventClass(event); + UInt32 kind = GetEventKind(event); + + result = CallNextEventHandler(nextHandler, event); + + aspect(&d_width, &d_height, A_NOZOOM); + + if (class == kEventClassCommand) + { + HICommand theHICommand; + + GetEventParameter(event, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &theHICommand); + + switch (theHICommand.commandID) + { + case kHICommandQuit: + mplayer_put_key(KEY_CLOSE_WIN); + break; + + case kHalfScreenCmd: + if (vo_quartz_fs) + { + vo_fs = (!(vo_fs)); + window_fullscreen(); + } + + SizeWindow(theWindow, (d_width / 2), ((d_width / movie_aspect) / 2), 1); + window_resized(); + break; + + case kNormalScreenCmd: + if (vo_quartz_fs) + { + vo_fs = (!(vo_fs)); + window_fullscreen(); + } + + SizeWindow(theWindow, d_width, (d_width / movie_aspect), 1); + window_resized(); + break; + + case kDoubleScreenCmd: + if (vo_quartz_fs) + { + vo_fs = (!(vo_fs)); + window_fullscreen(); + } + + SizeWindow(theWindow, (d_width * 2), ((d_width / movie_aspect) * 2), 1); + window_resized(); + break; + + case kFullScreenCmd: + vo_fs = (!(vo_fs)); + window_fullscreen(); + break; + + case kKeepAspectCmd: + vo_keepaspect = (!(vo_keepaspect)); + CheckMenuItem(aspectMenu, 1, vo_keepaspect); + window_resized(); + break; + + case kAspectOrgCmd: + movie_aspect = old_movie_aspect; + if (!vo_quartz_fs) + { + SizeWindow(theWindow, dstRect.right, (dstRect.right / movie_aspect), 1); + } + window_resized(); + break; + + case kAspectFullCmd: + movie_aspect = 4.0f / 3.0f; + if (!vo_quartz_fs) + { + SizeWindow(theWindow, dstRect.right, (dstRect.right / movie_aspect), 1); + } + window_resized(); + break; + + case kAspectWideCmd: + movie_aspect = 16.0f / 9.0f; + if (!vo_quartz_fs) + { + SizeWindow(theWindow, dstRect.right, (dstRect.right / movie_aspect), 1); + } + window_resized(); + break; + + case kPanScanCmd: + vo_panscan = (!(vo_panscan)); + CheckMenuItem(aspectMenu, 2, vo_panscan); + window_panscan(); + window_resized(); + break; + + default: + result = eventNotHandledErr; + break; + } + } + else if (class == kEventClassWindow) + { + WindowRef window; + Rect rectWindow = { 0, 0, 0, 0 }; + + GetEventParameter(event, kEventParamDirectObject, typeWindowRef, NULL, sizeof(WindowRef), NULL, &window); + + if (window) + { + GetWindowBounds(window, kWindowGlobalPortRgn, &rectWindow); + } + + switch (kind) + { + case kEventWindowClosed: + theWindow = NULL; + mplayer_put_key(KEY_CLOSE_WIN); + break; + + // resize window + case kEventWindowZoomed: + case kEventWindowBoundsChanged: + window_resized(); + flip_page(); + window_resized(); + break; + + default: + result = eventNotHandledErr; + break; + } + } + return result; } -static void quartz_CreateWindow(uint32_t d_width, uint32_t d_height, WindowAttributes windowAttrs) +static void quartz_CreateWindow(uint32_t d_width, uint32_t d_height, WindowAttributes windowAttrs) { - CFStringRef titleKey; - CFStringRef windowTitle; - OSStatus result; - - MenuItemIndex index; - CFStringRef movMenuTitle; - CFStringRef aspMenuTitle; - + CFStringRef titleKey; + CFStringRef windowTitle; + OSStatus result; + + MenuItemIndex index; + CFStringRef movMenuTitle; + CFStringRef aspMenuTitle; + const EventTypeSpec win_events[] = { - { kEventClassWindow, kEventWindowClosed }, - { kEventClassWindow, kEventWindowBoundsChanged }, - { kEventClassCommand, kEventCommandProcess } + {kEventClassWindow, kEventWindowClosed}, + {kEventClassWindow, kEventWindowBoundsChanged}, + {kEventClassCommand, kEventCommandProcess} }; const EventTypeSpec key_events[] = { - { kEventClassKeyboard, kEventRawKeyDown }, - { kEventClassKeyboard, kEventRawKeyRepeat } + {kEventClassKeyboard, kEventRawKeyDown}, + {kEventClassKeyboard, kEventRawKeyRepeat} + }; + + const EventTypeSpec mouse_events[] = { + {kEventClassMouse, kEventMouseMoved}, + {kEventClassMouse, kEventMouseWheelMoved}, + {kEventClassMouse, kEventMouseDown}, + {kEventClassMouse, kEventMouseUp}, + {kEventClassMouse, kEventMouseDragged} }; - const EventTypeSpec mouse_events[] = { - { kEventClassMouse, kEventMouseMoved }, - { kEventClassMouse, kEventMouseWheelMoved }, - { kEventClassMouse, kEventMouseDown }, - { kEventClassMouse, kEventMouseUp }, - { kEventClassMouse, kEventMouseDragged } - }; - - SetRect(&winRect, 0, 0, d_width, d_height); - SetRect(&oldWinRect, 0, 0, d_width, d_height); - SetRect(&dstRect, 0, 0, d_width, d_height); - - //Clear Menu Bar - ClearMenuBar(); - - //Create Window Menu - CreateStandardWindowMenu(0, &windMenu); - InsertMenu(windMenu, 0); - - //Create Movie Menu - CreateNewMenu (1004, 0, &movMenu); - movMenuTitle = CFSTR("Movie"); - SetMenuTitleWithCFString(movMenu, movMenuTitle); - - AppendMenuItemTextWithCFString(movMenu, CFSTR("Half Size"), 0, kHalfScreenCmd, &index); - SetMenuItemCommandKey(movMenu, index, 0, '0'); - - AppendMenuItemTextWithCFString(movMenu, CFSTR("Normal Size"), 0, kNormalScreenCmd, &index); - SetMenuItemCommandKey(movMenu, index, 0, '1'); - - AppendMenuItemTextWithCFString(movMenu, CFSTR("Double Size"), 0, kDoubleScreenCmd, &index); - SetMenuItemCommandKey(movMenu, index, 0, '2'); - - AppendMenuItemTextWithCFString(movMenu, CFSTR("Full Size"), 0, kFullScreenCmd, &index); - SetMenuItemCommandKey(movMenu, index, 0, 'F'); - - AppendMenuItemTextWithCFString(movMenu, NULL, kMenuItemAttrSeparator, 0, &index); - - AppendMenuItemTextWithCFString(movMenu, CFSTR("Aspect Ratio"), 0, 0, &index); - - ////Create Aspect Ratio Sub Menu - CreateNewMenu (0, 0, &aspectMenu); - aspMenuTitle = CFSTR("Aspect Ratio"); - SetMenuTitleWithCFString(aspectMenu, aspMenuTitle); - SetMenuItemHierarchicalMenu(movMenu, 6, aspectMenu); - - AppendMenuItemTextWithCFString(aspectMenu, CFSTR("Keep"), 0, kKeepAspectCmd, &index); - CheckMenuItem (aspectMenu, 1, vo_keepaspect); - AppendMenuItemTextWithCFString(aspectMenu, CFSTR("Pan-Scan"), 0, kPanScanCmd, &index); - CheckMenuItem (aspectMenu, 2, vo_panscan); - AppendMenuItemTextWithCFString(aspectMenu, NULL, kMenuItemAttrSeparator, 0, &index); - AppendMenuItemTextWithCFString(aspectMenu, CFSTR("Original"), 0, kAspectOrgCmd, &index); - AppendMenuItemTextWithCFString(aspectMenu, CFSTR("4:3"), 0, kAspectFullCmd, &index); - AppendMenuItemTextWithCFString(aspectMenu, CFSTR("16:9"), 0, kAspectWideCmd, &index); - - InsertMenu(movMenu, GetMenuID(windMenu)); //insert before Window menu - - DrawMenuBar(); - - //create window - CreateNewWindow(kDocumentWindowClass, windowAttrs, &winRect, &theWindow); - - CreateWindowGroup(0, &winGroup); - SetWindowGroup(theWindow, winGroup); - - //Set window title - titleKey = CFSTR("MPlayer - The Movie Player"); - windowTitle = CFCopyLocalizedString(titleKey, NULL); - result = SetWindowTitleWithCFString(theWindow, windowTitle); - CFRelease(titleKey); - CFRelease(windowTitle); - - //Install event handler - InstallApplicationEventHandler (NewEventHandlerUPP (KeyEventHandler), GetEventTypeCount(key_events), key_events, NULL, NULL); - InstallApplicationEventHandler (NewEventHandlerUPP (MouseEventHandler), GetEventTypeCount(mouse_events), mouse_events, NULL, NULL); - InstallWindowEventHandler (theWindow, NewEventHandlerUPP (WindowEventHandler), GetEventTypeCount(win_events), win_events, theWindow, NULL); + SetRect(&winRect, 0, 0, d_width, d_height); + SetRect(&oldWinRect, 0, 0, d_width, d_height); + SetRect(&dstRect, 0, 0, d_width, d_height); + + // Clear Menu Bar + ClearMenuBar(); + + // Create Window Menu + CreateStandardWindowMenu(0, &windMenu); + InsertMenu(windMenu, 0); + + // Create Movie Menu + CreateNewMenu(1004, 0, &movMenu); + movMenuTitle = CFSTR("Movie"); + SetMenuTitleWithCFString(movMenu, movMenuTitle); + + AppendMenuItemTextWithCFString(movMenu, CFSTR("Half Size"), 0, kHalfScreenCmd, &index); + SetMenuItemCommandKey(movMenu, index, 0, '0'); + + AppendMenuItemTextWithCFString(movMenu, CFSTR("Normal Size"), 0, kNormalScreenCmd, &index); + SetMenuItemCommandKey(movMenu, index, 0, '1'); + + AppendMenuItemTextWithCFString(movMenu, CFSTR("Double Size"), 0, kDoubleScreenCmd, &index); + SetMenuItemCommandKey(movMenu, index, 0, '2'); + + AppendMenuItemTextWithCFString(movMenu, CFSTR("Full Size"), 0, kFullScreenCmd, &index); + SetMenuItemCommandKey(movMenu, index, 0, 'F'); + + AppendMenuItemTextWithCFString(movMenu, NULL, kMenuItemAttrSeparator, 0, &index); + + AppendMenuItemTextWithCFString(movMenu, CFSTR("Aspect Ratio"), 0, 0, &index); + + //// Create Aspect Ratio Sub Menu + CreateNewMenu(0, 0, &aspectMenu); + aspMenuTitle = CFSTR("Aspect Ratio"); + SetMenuTitleWithCFString(aspectMenu, aspMenuTitle); + SetMenuItemHierarchicalMenu(movMenu, 6, aspectMenu); + + AppendMenuItemTextWithCFString(aspectMenu, CFSTR("Keep"), 0, kKeepAspectCmd, &index); + CheckMenuItem(aspectMenu, 1, vo_keepaspect); + AppendMenuItemTextWithCFString(aspectMenu, CFSTR("Pan-Scan"), 0, kPanScanCmd, &index); + CheckMenuItem(aspectMenu, 2, vo_panscan); + AppendMenuItemTextWithCFString(aspectMenu, NULL, kMenuItemAttrSeparator, 0, &index); + AppendMenuItemTextWithCFString(aspectMenu, CFSTR("Original"), 0, kAspectOrgCmd, &index); + AppendMenuItemTextWithCFString(aspectMenu, CFSTR("4:3"), 0, kAspectFullCmd, &index); + AppendMenuItemTextWithCFString(aspectMenu, CFSTR("16:9"), 0, kAspectWideCmd, &index); + + InsertMenu(movMenu, GetMenuID(windMenu)); //insert before Window menu + + DrawMenuBar(); + + // create window + CreateNewWindow(kDocumentWindowClass, windowAttrs, &winRect, &theWindow); + + CreateWindowGroup(0, &winGroup); + SetWindowGroup(theWindow, winGroup); + + // Set window title + titleKey = CFSTR("MPlayer - The Movie Player"); + windowTitle = CFCopyLocalizedString(titleKey, NULL); + result = SetWindowTitleWithCFString(theWindow, windowTitle); + CFRelease(titleKey); + CFRelease(windowTitle); + + // Install event handler + InstallApplicationEventHandler(NewEventHandlerUPP(KeyEventHandler), GetEventTypeCount(key_events), key_events, NULL, NULL); + InstallApplicationEventHandler(NewEventHandlerUPP(MouseEventHandler), GetEventTypeCount(mouse_events), mouse_events, NULL, NULL); + InstallWindowEventHandler(theWindow, NewEventHandlerUPP(WindowEventHandler), GetEventTypeCount(win_events), win_events, theWindow, NULL); } static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format) { - WindowAttributes windowAttrs; - OSErr qterr; - int i; - CGRect tmpBounds; - - //Get Main device info/////////////////////////////////////////////////// - - - deviceHdl = GetMainDevice(); - - for(i=0; i<device_id; i++) - { - deviceHdl = GetNextDevice(deviceHdl); - - if(deviceHdl == NULL) - { - mp_msg(MSGT_VO, MSGL_FATAL, "Quartz error: Device ID %d do not exist, falling back to main device.\n", device_id); - deviceHdl = GetMainDevice(); - device_id = 0; - break; - } - } - - deviceRect = (*deviceHdl)->gdRect; - device_width = deviceRect.right-deviceRect.left; - device_height = deviceRect.bottom-deviceRect.top; - - monitor_aspect = (float)device_width/(float)device_height; - - //misc mplayer setup///////////////////////////////////////////////////// - SetRect(&imgRect, 0, 0, width, height); - switch (image_format) - { - case IMGFMT_RGB32: - image_depth = 32; - break; - case IMGFMT_YV12: - case IMGFMT_IYUV: + WindowAttributes windowAttrs; + OSErr qterr; + CGRect tmpBounds; + CGDisplayCount displayCount; + CGDirectDisplayID *displays; + + // Get Main device info/////////////////////////////////////////////////// + + // Display IDs might not be consecutive, get the list of all devices up to # device_id + displayCount = device_id + 1; + displays = malloc(sizeof(CGDirectDisplayID) * displayCount); + if (kCGErrorSuccess != CGGetActiveDisplayList(displayCount, displays, &displayCount) || displayCount < device_id + 1) { + mp_msg(MSGT_VO, MSGL_FATAL, "Quartz error: Device ID %d do not exist, falling back to main device.\n", device_id); + displayId = kCGDirectMainDisplay; + device_id = 0; + } + else + { + displayId = displays[device_id]; + } + free(displays); + + displayRect = CGDisplayBounds(displayId); + + monitor_aspect = (float)displayRect.size.width / (float)displayRect.size.height; + + // misc mplayer setup///////////////////////////////////////////////////// + SetRect(&imgRect, 0, 0, width, height); + switch (image_format) + { + case IMGFMT_RGB32: + image_depth = 32; + break; + case IMGFMT_YV12: + case IMGFMT_IYUV: + case IMGFMT_I420: + case IMGFMT_UYVY: + case IMGFMT_YUY2: + image_depth = 16; + break; + } + image_size = ((imgRect.right * imgRect.bottom * image_depth) + 7) / 8; + + vo_fs = flags & VOFLAG_FULLSCREEN; + + // get movie aspect + panscan_init(); + aspect_save_orig(width, height); + aspect_save_prescale(d_width, d_height); + aspect_save_screenres(displayRect.size.width, displayRect.size.height); + + aspect(&d_width, &d_height, A_NOZOOM); + + movie_aspect = (float)d_width / (float)d_height; + old_movie_aspect = movie_aspect; + + if (image_data) + free(image_data); + + image_data = malloc(image_size); + + // Create player window////////////////////////////////////////////////// + windowAttrs = kWindowStandardDocumentAttributes + | kWindowStandardHandlerAttribute + | kWindowLiveResizeAttribute; + + windowAttrs &= (~kWindowResizableAttribute); + + if (theWindow == NULL) + { + CGContextRef context; + + quartz_CreateWindow(d_width, d_height, windowAttrs); + + if (theWindow == NULL) + { + mp_msg(MSGT_VO, MSGL_FATAL, "Quartz error: Couldn't create window !!!!!\n"); + return -1; + } + tmpBounds = CGRectMake(0, 0, winRect.right, winRect.bottom); + QDBeginCGContext(GetWindowPort(theWindow), &context); + CGContextFillRect(context, tmpBounds); + QDEndCGContext(GetWindowPort(theWindow), &context); + } + else + { + HideWindow(theWindow); + ChangeWindowAttributes(theWindow, ~windowAttrs, windowAttrs); + SetRect(&winRect, 0, 0, d_width, d_height); + SetRect(&oldWinRect, 0, 0, d_width, d_height); + SizeWindow(theWindow, d_width, d_height, 1); + } + + switch (image_format) + { + case IMGFMT_RGB32: + { + CGContextRef context; + + QDBeginCGContext(GetWindowPort(theWindow), &context); + + dataProviderRef = CGDataProviderCreateWithData(0, image_data, imgRect.right * imgRect.bottom * 4, 0); + + image = CGImageCreate(imgRect.right, + imgRect.bottom, + 8, + image_depth, + ((imgRect.right * 32) + 7) / 8, + CGColorSpaceCreateDeviceRGB(), + kCGImageAlphaNoneSkipFirst, + dataProviderRef, 0, 1, kCGRenderingIntentDefault); + + QDEndCGContext(GetWindowPort(theWindow), &context); + break; + } + + case IMGFMT_YV12: + case IMGFMT_IYUV: + case IMGFMT_I420: + case IMGFMT_UYVY: + case IMGFMT_YUY2: + { + get_image_done = 0; + + if (!EnterMoviesDone) + { + qterr = EnterMovies(); + EnterMoviesDone = 1; + } + else + qterr = 0; + + if (qterr) + { + mp_msg(MSGT_VO, MSGL_FATAL, "Quartz error: EnterMovies (%d)\n", qterr); + return -1; + } + + + SetIdentityMatrix(&matrix); + + if ((d_width != width) || (d_height != height)) + { + ScaleMatrix(&matrix, FixDiv(Long2Fix(d_width), Long2Fix(width)), FixDiv(Long2Fix(d_height), Long2Fix(height)), 0, 0); + } + + yuv_qt_stuff.desc = (ImageDescriptionHandle) NewHandleClear(sizeof(ImageDescription)); + + yuv_qt_stuff.extension_colr = NewHandleClear(sizeof(NCLCColorInfoImageDescriptionExtension)); + ((NCLCColorInfoImageDescriptionExtension *) (*yuv_qt_stuff.extension_colr))->colorParamType = kVideoColorInfoImageDescriptionExtensionType; + ((NCLCColorInfoImageDescriptionExtension *) (*yuv_qt_stuff.extension_colr))->primaries = 2; + ((NCLCColorInfoImageDescriptionExtension *) (*yuv_qt_stuff.extension_colr))->transferFunction = 2; + ((NCLCColorInfoImageDescriptionExtension *) (*yuv_qt_stuff.extension_colr))->matrix = 2; + + yuv_qt_stuff.extension_fiel = NewHandleClear(sizeof(FieldInfoImageDescriptionExtension)); + ((FieldInfoImageDescriptionExtension *) (*yuv_qt_stuff.extension_fiel))->fieldCount = 1; + ((FieldInfoImageDescriptionExtension *) (*yuv_qt_stuff.extension_fiel))->fieldOrderings = 0; + + yuv_qt_stuff.extension_clap = NewHandleClear(sizeof(CleanApertureImageDescriptionExtension)); + ((CleanApertureImageDescriptionExtension *) (*yuv_qt_stuff.extension_clap))->cleanApertureWidthN = imgRect.right; + ((CleanApertureImageDescriptionExtension *) (*yuv_qt_stuff.extension_clap))->cleanApertureWidthD = 1; + ((CleanApertureImageDescriptionExtension *) (*yuv_qt_stuff.extension_clap))->cleanApertureHeightN = imgRect.bottom; + ((CleanApertureImageDescriptionExtension *) (*yuv_qt_stuff.extension_clap))->cleanApertureHeightD = 1; + ((CleanApertureImageDescriptionExtension *) (*yuv_qt_stuff.extension_clap))->horizOffN = 0; + ((CleanApertureImageDescriptionExtension *) (*yuv_qt_stuff.extension_clap))->horizOffD = 1; + ((CleanApertureImageDescriptionExtension *) (*yuv_qt_stuff.extension_clap))->vertOffN = 0; + ((CleanApertureImageDescriptionExtension *) (*yuv_qt_stuff.extension_clap))->vertOffD = 1; + + yuv_qt_stuff.extension_pasp = NewHandleClear(sizeof(PixelAspectRatioImageDescriptionExtension)); + ((PixelAspectRatioImageDescriptionExtension *) (*yuv_qt_stuff.extension_pasp))->hSpacing = 1; + ((PixelAspectRatioImageDescriptionExtension *) (*yuv_qt_stuff.extension_pasp))->vSpacing = 1; + + (*yuv_qt_stuff.desc)->idSize = sizeof(ImageDescription); + (*yuv_qt_stuff.desc)->cType = image_qtcodec; + (*yuv_qt_stuff.desc)->version = 2; + (*yuv_qt_stuff.desc)->revisionLevel = 0; + (*yuv_qt_stuff.desc)->vendor = 'mpla'; + (*yuv_qt_stuff.desc)->width = imgRect.right; + (*yuv_qt_stuff.desc)->height = imgRect.bottom; + (*yuv_qt_stuff.desc)->hRes = Long2Fix(72); + (*yuv_qt_stuff.desc)->vRes = Long2Fix(72); + (*yuv_qt_stuff.desc)->temporalQuality = 0; + (*yuv_qt_stuff.desc)->spatialQuality = codecLosslessQuality; + (*yuv_qt_stuff.desc)->frameCount = 1; + (*yuv_qt_stuff.desc)->dataSize = 0; + (*yuv_qt_stuff.desc)->depth = 24; + (*yuv_qt_stuff.desc)->clutID = -1; + + qterr = AddImageDescriptionExtension(yuv_qt_stuff.desc, yuv_qt_stuff.extension_colr, kColorInfoImageDescriptionExtension); + if (qterr) + { + mp_msg(MSGT_VO, MSGL_ERR, "Quartz error: AddImageDescriptionExtension [colr] (%d)\n", qterr); + } + + qterr = AddImageDescriptionExtension(yuv_qt_stuff.desc, yuv_qt_stuff.extension_fiel, kFieldInfoImageDescriptionExtension); + if (qterr) + { + mp_msg(MSGT_VO, MSGL_ERR, "Quartz error: AddImageDescriptionExtension [fiel] (%d)\n", qterr); + } + + qterr = AddImageDescriptionExtension(yuv_qt_stuff.desc, yuv_qt_stuff.extension_clap, kCleanApertureImageDescriptionExtension); + if (qterr) + { + mp_msg(MSGT_VO, MSGL_ERR, "Quartz error: AddImageDescriptionExtension [clap] (%d)\n", qterr); + } + + qterr = AddImageDescriptionExtension(yuv_qt_stuff.desc, yuv_qt_stuff.extension_pasp, kCleanApertureImageDescriptionExtension); + if (qterr) + { + mp_msg(MSGT_VO, MSGL_ERR, "Quartz error: AddImageDescriptionExtension [pasp] (%d)\n", qterr); + } + if (P != NULL) { // second or subsequent movie + free(P); + } + P = calloc(sizeof(PlanarPixmapInfoYUV420) + image_size, 1); + switch (image_format) + { + case IMGFMT_YV12: + case IMGFMT_IYUV: case IMGFMT_I420: + P->componentInfoY.offset = be2me_32(sizeof(PlanarPixmapInfoYUV420)); + P->componentInfoCb.offset = be2me_32(be2me_32(P->componentInfoY.offset) + image_size / 2); + P->componentInfoCr.offset = be2me_32(be2me_32(P->componentInfoCb.offset) + image_size / 4); + P->componentInfoY.rowBytes = be2me_32(imgRect.right); + P->componentInfoCb.rowBytes = be2me_32(imgRect.right / 2); + P->componentInfoCr.rowBytes = be2me_32(imgRect.right / 2); + image_buffer_size = image_size + sizeof(PlanarPixmapInfoYUV420); + break; case IMGFMT_UYVY: case IMGFMT_YUY2: - image_depth = 16; - break; - } - image_size = ((imgRect.right*imgRect.bottom*image_depth)+7)/8; - - vo_fs = flags & VOFLAG_FULLSCREEN; - - //get movie aspect - panscan_init(); - aspect_save_orig(width,height); - aspect_save_prescale(d_width,d_height); - aspect_save_screenres(device_width, device_height); - - aspect(&d_width,&d_height,A_NOZOOM); - - movie_aspect = (float)d_width/(float)d_height; - old_movie_aspect = movie_aspect; - - if(image_data) - free(image_data); - - image_data = malloc(image_size); - - //Create player window////////////////////////////////////////////////// - windowAttrs = kWindowStandardDocumentAttributes - | kWindowStandardHandlerAttribute - | kWindowLiveResizeAttribute; - - windowAttrs &= (~kWindowResizableAttribute); - - if (theWindow == NULL) - { - quartz_CreateWindow(d_width, d_height, windowAttrs); - - if (theWindow == NULL) - { - mp_msg(MSGT_VO, MSGL_FATAL, "Quartz error: Couldn't create window !!!!!\n"); - return -1; - } - tmpBounds = CGRectMake( 0, 0, winRect.right, winRect.bottom); - CreateCGContextForPort(GetWindowPort(theWindow),&context); - CGContextFillRect(context, tmpBounds); - } - else - { - HideWindow(theWindow); - ChangeWindowAttributes(theWindow, ~windowAttrs, windowAttrs); - SetRect(&winRect, 0, 0, d_width, d_height); - SetRect(&oldWinRect, 0, 0, d_width, d_height); - SizeWindow (theWindow, d_width, d_height, 1); - } - - switch (image_format) - { - case IMGFMT_RGB32: - { - CreateCGContextForPort (GetWindowPort (theWindow), &context); - - dataProviderRef = CGDataProviderCreateWithData (0, image_data, imgRect.right * imgRect.bottom * 4, 0); - - image = CGImageCreate (imgRect.right, - imgRect.bottom, - 8, - image_depth, - ((imgRect.right*32)+7)/8, - CGColorSpaceCreateDeviceRGB(), - kCGImageAlphaNoneSkipFirst, - dataProviderRef, 0, 1, kCGRenderingIntentDefault); - break; - } - - case IMGFMT_YV12: - case IMGFMT_IYUV: - case IMGFMT_I420: - case IMGFMT_UYVY: - case IMGFMT_YUY2: - { - get_image_done = 0; - - if (!EnterMoviesDone) - { - qterr = EnterMovies(); - EnterMoviesDone = 1; - } - else - qterr = 0; - - if (qterr) - { - mp_msg(MSGT_VO, MSGL_FATAL, "Quartz error: EnterMovies (%d)\n", qterr); - return -1; - } - - - SetIdentityMatrix(&matrix); - - if ((d_width != width) || (d_height != height)) - { - ScaleMatrix(&matrix, FixDiv(Long2Fix(d_width),Long2Fix(width)), FixDiv(Long2Fix(d_height),Long2Fix(height)), 0, 0); - } - - yuv_qt_stuff.desc = (ImageDescriptionHandle)NewHandleClear( sizeof(ImageDescription) ); - - yuv_qt_stuff.extension_colr = NewHandleClear(sizeof(NCLCColorInfoImageDescriptionExtension)); - ((NCLCColorInfoImageDescriptionExtension*)(*yuv_qt_stuff.extension_colr))->colorParamType = kVideoColorInfoImageDescriptionExtensionType; - ((NCLCColorInfoImageDescriptionExtension*)(*yuv_qt_stuff.extension_colr))->primaries = 2; - ((NCLCColorInfoImageDescriptionExtension*)(*yuv_qt_stuff.extension_colr))->transferFunction = 2; - ((NCLCColorInfoImageDescriptionExtension*)(*yuv_qt_stuff.extension_colr))->matrix = 2; - - yuv_qt_stuff.extension_fiel = NewHandleClear(sizeof(FieldInfoImageDescriptionExtension)); - ((FieldInfoImageDescriptionExtension*)(*yuv_qt_stuff.extension_fiel))->fieldCount = 1; - ((FieldInfoImageDescriptionExtension*)(*yuv_qt_stuff.extension_fiel))->fieldOrderings = 0; - - yuv_qt_stuff.extension_clap = NewHandleClear(sizeof(CleanApertureImageDescriptionExtension)); - ((CleanApertureImageDescriptionExtension*)(*yuv_qt_stuff.extension_clap))->cleanApertureWidthN = imgRect.right; - ((CleanApertureImageDescriptionExtension*)(*yuv_qt_stuff.extension_clap))->cleanApertureWidthD = 1; - ((CleanApertureImageDescriptionExtension*)(*yuv_qt_stuff.extension_clap))->cleanApertureHeightN = imgRect.bottom; - ((CleanApertureImageDescriptionExtension*)(*yuv_qt_stuff.extension_clap))->cleanApertureHeightD = 1; - ((CleanApertureImageDescriptionExtension*)(*yuv_qt_stuff.extension_clap))->horizOffN = 0; - ((CleanApertureImageDescriptionExtension*)(*yuv_qt_stuff.extension_clap))->horizOffD = 1; - ((CleanApertureImageDescriptionExtension*)(*yuv_qt_stuff.extension_clap))->vertOffN = 0; - ((CleanApertureImageDescriptionExtension*)(*yuv_qt_stuff.extension_clap))->vertOffD = 1; - - yuv_qt_stuff.extension_pasp = NewHandleClear(sizeof(PixelAspectRatioImageDescriptionExtension)); - ((PixelAspectRatioImageDescriptionExtension*)(*yuv_qt_stuff.extension_pasp))->hSpacing = 1; - ((PixelAspectRatioImageDescriptionExtension*)(*yuv_qt_stuff.extension_pasp))->vSpacing = 1; - - (*yuv_qt_stuff.desc)->idSize = sizeof(ImageDescription); - (*yuv_qt_stuff.desc)->cType = image_qtcodec; - (*yuv_qt_stuff.desc)->version = 2; - (*yuv_qt_stuff.desc)->revisionLevel = 0; - (*yuv_qt_stuff.desc)->vendor = 'mpla'; - (*yuv_qt_stuff.desc)->width = imgRect.right; - (*yuv_qt_stuff.desc)->height = imgRect.bottom; - (*yuv_qt_stuff.desc)->hRes = Long2Fix(72); - (*yuv_qt_stuff.desc)->vRes = Long2Fix(72); - (*yuv_qt_stuff.desc)->temporalQuality = 0; - (*yuv_qt_stuff.desc)->spatialQuality = codecLosslessQuality; - (*yuv_qt_stuff.desc)->frameCount = 1; - (*yuv_qt_stuff.desc)->dataSize = 0; - (*yuv_qt_stuff.desc)->depth = 24; - (*yuv_qt_stuff.desc)->clutID = -1; - - qterr = AddImageDescriptionExtension(yuv_qt_stuff.desc, yuv_qt_stuff.extension_colr, kColorInfoImageDescriptionExtension); - if (qterr) - { - mp_msg(MSGT_VO, MSGL_ERR, "Quartz error: AddImageDescriptionExtension [colr] (%d)\n", qterr); - } - - qterr = AddImageDescriptionExtension(yuv_qt_stuff.desc, yuv_qt_stuff.extension_fiel, kFieldInfoImageDescriptionExtension); - if (qterr) - { - mp_msg(MSGT_VO, MSGL_ERR, "Quartz error: AddImageDescriptionExtension [fiel] (%d)\n", qterr); - } - - qterr = AddImageDescriptionExtension(yuv_qt_stuff.desc, yuv_qt_stuff.extension_clap, kCleanApertureImageDescriptionExtension); - if (qterr) - { - mp_msg(MSGT_VO, MSGL_ERR, "Quartz error: AddImageDescriptionExtension [clap] (%d)\n", qterr); - } - - qterr = AddImageDescriptionExtension(yuv_qt_stuff.desc, yuv_qt_stuff.extension_pasp, kCleanApertureImageDescriptionExtension); - if (qterr) - { - mp_msg(MSGT_VO, MSGL_ERR, "Quartz error: AddImageDescriptionExtension [pasp] (%d)\n", qterr); - } - if (P != NULL) { // second or subsequent movie - free(P); - } - P = calloc(sizeof(PlanarPixmapInfoYUV420) + image_size, 1); - switch (image_format) - { - case IMGFMT_YV12: - case IMGFMT_IYUV: - case IMGFMT_I420: - P->componentInfoY.offset = be2me_32(sizeof(PlanarPixmapInfoYUV420)); - P->componentInfoCb.offset = be2me_32(be2me_32(P->componentInfoY.offset) + image_size / 2); - P->componentInfoCr.offset = be2me_32(be2me_32(P->componentInfoCb.offset) + image_size / 4); - P->componentInfoY.rowBytes = be2me_32(imgRect.right); - P->componentInfoCb.rowBytes = be2me_32(imgRect.right / 2); - P->componentInfoCr.rowBytes = be2me_32(imgRect.right / 2); - image_buffer_size = image_size + sizeof(PlanarPixmapInfoYUV420); - break; - case IMGFMT_UYVY: - case IMGFMT_YUY2: - image_buffer_size = image_size; - break; - } - - qterr = DecompressSequenceBeginS(&seqId, - yuv_qt_stuff.desc, - (char *)P, - image_buffer_size, - GetWindowPort(theWindow), - NULL, - NULL, - ((d_width != width) || (d_height != height)) ? - &matrix : NULL, - srcCopy, - NULL, - 0, - codecLosslessQuality, - bestSpeedCodec); - - if (qterr) - { - mp_msg(MSGT_VO, MSGL_FATAL, "Quartz error: DecompressSequenceBeginS (%d)\n", qterr); - return -1; - } - } - break; - } - - //Show window - RepositionWindow(theWindow, NULL, kWindowCenterOnMainScreen); - ShowWindow (theWindow); - - if(vo_fs) - window_fullscreen(); - - if(vo_ontop) - window_ontop(); - - if(vo_rootwin) - { - vo_fs = TRUE; - winLevel = 0; - SetWindowGroupLevel(winGroup, CGWindowLevelForKey(levelList[winLevel])); - window_fullscreen(); - } - - window_resized(); - - return 0; + image_buffer_size = image_size; + break; + } + + qterr = DecompressSequenceBeginS(&seqId, + yuv_qt_stuff.desc, + (char *)P, + image_buffer_size, + GetWindowPort(theWindow), + NULL, + NULL, + ((d_width != width) || (d_height != height)) ? + &matrix : NULL, + srcCopy, + NULL, + 0, + codecLosslessQuality, + bestSpeedCodec); + + if (qterr) + { + mp_msg(MSGT_VO, MSGL_FATAL, "Quartz error: DecompressSequenceBeginS (%d)\n", qterr); + return -1; + } + } + break; + } + + // Show window + RepositionWindow(theWindow, NULL, kWindowCenterOnMainScreen); + ShowWindow(theWindow); + + if (vo_fs) + window_fullscreen(); + + if (vo_ontop) + window_ontop(); + + if (vo_rootwin) + { + vo_fs = TRUE; + winLevel = 0; + SetWindowGroupLevel(winGroup, CGWindowLevelForKey(levelList[winLevel])); + window_fullscreen(); + } + + window_resized(); + + return 0; } static void check_events(void) { - EventRef theEvent; - EventTargetRef theTarget; - OSStatus theErr; - - //Get event - theTarget = GetEventDispatcherTarget(); - theErr = ReceiveNextEvent(0, 0, kEventDurationNoWait,true, &theEvent); - if(theErr == noErr && theEvent != NULL) - { - SendEventToEventTarget (theEvent, theTarget); - ReleaseEvent(theEvent); - } + EventRef theEvent; + EventTargetRef theTarget; + OSStatus theErr; + + // Get event + theTarget = GetEventDispatcherTarget(); + theErr = ReceiveNextEvent(0, 0, kEventDurationNoWait, true, &theEvent); + if (theErr == noErr && theEvent != NULL) + { + SendEventToEventTarget(theEvent, theTarget); + ReleaseEvent(theEvent); + } } static void draw_osd(void) { - vo_draw_text(imgRect.right,imgRect.bottom,draw_alpha); + vo_draw_text(imgRect.right, imgRect.bottom, draw_alpha); } static void flip_page(void) { - int curTime; - static int lastTime = 0; - - if(theWindow == NULL) - return; - - switch (image_format) - { - case IMGFMT_RGB32: - { - CGContextDrawImage (context, bounds, image); - } - break; - - case IMGFMT_YV12: - case IMGFMT_IYUV: - case IMGFMT_I420: - case IMGFMT_UYVY: - case IMGFMT_YUY2: - if (EnterMoviesDone) - { - OSErr qterr; - CodecFlags flags = 0; - qterr = DecompressSequenceFrameWhen(seqId, - (char *)P, - image_buffer_size, - 0, //codecFlagUseImageBuffer, - &flags, - NULL, - NULL); - if (qterr) - { - mp_msg(MSGT_VO, MSGL_ERR, "Quartz error: DecompressSequenceFrameWhen in flip_page (%d) flags:0x%08x\n", qterr, flags); - } - } - break; - } - - if(!vo_quartz_fs) - { - //render resize box - CGContextBeginPath(context); - CGContextSetAllowsAntialiasing(context, false); - //CGContextSaveGState(context); - - //line white - CGContextSetRGBStrokeColor (context, 0.2, 0.2, 0.2, 0.5); - CGContextMoveToPoint( context, winRect.right-1, 1); CGContextAddLineToPoint( context, winRect.right-1, 1); - CGContextMoveToPoint( context, winRect.right-1, 5); CGContextAddLineToPoint( context, winRect.right-5, 1); - CGContextMoveToPoint( context, winRect.right-1, 9); CGContextAddLineToPoint( context, winRect.right-9, 1); - CGContextStrokePath( context ); - - //line gray - CGContextSetRGBStrokeColor (context, 0.4, 0.4, 0.4, 0.5); - CGContextMoveToPoint( context, winRect.right-1, 2); CGContextAddLineToPoint( context, winRect.right-2, 1); - CGContextMoveToPoint( context, winRect.right-1, 6); CGContextAddLineToPoint( context, winRect.right-6, 1); - CGContextMoveToPoint( context, winRect.right-1, 10); CGContextAddLineToPoint( context, winRect.right-10, 1); - CGContextStrokePath( context ); - - //line black - CGContextSetRGBStrokeColor (context, 0.6, 0.6, 0.6, 0.5); - CGContextMoveToPoint( context, winRect.right-1, 3); CGContextAddLineToPoint( context, winRect.right-3, 1); - CGContextMoveToPoint( context, winRect.right-1, 7); CGContextAddLineToPoint( context, winRect.right-7, 1); - CGContextMoveToPoint( context, winRect.right-1, 11); CGContextAddLineToPoint( context, winRect.right-11, 1); - CGContextStrokePath( context ); - - //CGContextRestoreGState( context ); - CGContextFlush (context); - } - - //auto hide mouse cursor and futur on-screen control? - if(vo_quartz_fs && !mouseHide) - { - int curTime = TickCount()/60; - static int lastTime = 0; - - if( ((curTime - lastTime) >= 5) || (lastTime == 0) ) - { - CGDisplayHideCursor(kCGDirectMainDisplay); - mouseHide = TRUE; - lastTime = curTime; - } - } - - //update activity every 30 seconds to prevent - //screensaver from starting up. - curTime = TickCount()/60; - - if( ((curTime - lastTime) >= 30) || (lastTime == 0) ) - { - UpdateSystemActivity(UsrActivity); - lastTime = curTime; - } + int curTime; + + if (theWindow == NULL) + return; + + switch (image_format) + { + case IMGFMT_RGB32: + { + CGContextRef context; + + QDBeginCGContext(GetWindowPort(theWindow), &context); + CGContextDrawImage(context, bounds, image); + QDEndCGContext(GetWindowPort(theWindow), &context); + } + break; + + case IMGFMT_YV12: + case IMGFMT_IYUV: + case IMGFMT_I420: + case IMGFMT_UYVY: + case IMGFMT_YUY2: + if (EnterMoviesDone) + { + OSErr qterr; + CodecFlags flags = 0; + + qterr = DecompressSequenceFrameWhen(seqId, + (char *)P, + image_buffer_size, + 0, //codecFlagUseImageBuffer, + &flags, + NULL, + NULL); + if (qterr) + { + mp_msg(MSGT_VO, MSGL_ERR, "Quartz error: DecompressSequenceFrameWhen in flip_page (%d) flags:0x%08x\n", qterr, flags); + } + } + break; + } + + if (!vo_quartz_fs) + { + CGContextRef context; + + QDBeginCGContext(GetWindowPort(theWindow), &context); + // render resize box + CGContextBeginPath(context); + CGContextSetAllowsAntialiasing(context, false); + //CGContextSaveGState(context); + + // line white + CGContextSetRGBStrokeColor(context, 0.2, 0.2, 0.2, 0.5); + CGContextMoveToPoint(context, winRect.right - 1, 1); CGContextAddLineToPoint(context, winRect.right - 1, 1); + CGContextMoveToPoint(context, winRect.right - 1, 5); CGContextAddLineToPoint(context, winRect.right - 5, 1); + CGContextMoveToPoint(context, winRect.right - 1, 9); CGContextAddLineToPoint(context, winRect.right - 9, 1); + CGContextStrokePath(context); + + // line gray + CGContextSetRGBStrokeColor(context, 0.4, 0.4, 0.4, 0.5); + CGContextMoveToPoint(context, winRect.right - 1, 2); CGContextAddLineToPoint(context, winRect.right - 2, 1); + CGContextMoveToPoint(context, winRect.right - 1, 6); CGContextAddLineToPoint(context, winRect.right - 6, 1); + CGContextMoveToPoint(context, winRect.right - 1, 10); CGContextAddLineToPoint(context, winRect.right - 10, 1); + CGContextStrokePath(context); + + // line black + CGContextSetRGBStrokeColor(context, 0.6, 0.6, 0.6, 0.5); + CGContextMoveToPoint(context, winRect.right - 1, 3); CGContextAddLineToPoint(context, winRect.right - 3, 1); + CGContextMoveToPoint(context, winRect.right - 1, 7); CGContextAddLineToPoint(context, winRect.right - 7, 1); + CGContextMoveToPoint(context, winRect.right - 1, 11); CGContextAddLineToPoint(context, winRect.right - 11, 1); + CGContextStrokePath(context); + + // CGContextRestoreGState( context ); + CGContextFlush(context); + QDEndCGContext(GetWindowPort(theWindow), &context); + } + + curTime = TickCount() / 60; + + // auto hide mouse cursor (and future on-screen control?) + if (vo_quartz_fs && !mouseHide) + { + if (((curTime - lastMouseHide) >= 5) || (lastMouseHide == 0)) + { + CGDisplayHideCursor(displayId); + mouseHide = TRUE; + lastMouseHide = curTime; + } + } + // update activity every 30 seconds to prevent + // screensaver from starting up. + if (((curTime - lastScreensaverUpdate) >= 30) || (lastScreensaverUpdate == 0)) + { + UpdateSystemActivity(UsrActivity); + lastScreensaverUpdate = curTime; + } } -static int draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y) +static int draw_slice(uint8_t * src[], int stride[], int w, int h, int x, int y) { - switch (image_format) - { - case IMGFMT_YV12: - case IMGFMT_I420: - memcpy_pic(((char*)P) + be2me_32(P->componentInfoY.offset) + x + imgRect.right * y, src[0], w, h, imgRect.right, stride[0]); - x=x/2;y=y/2;w=w/2;h=h/2; - - memcpy_pic(((char*)P) + be2me_32(P->componentInfoCb.offset) + x + imgRect.right / 2 * y, src[1], w, h, imgRect.right / 2, stride[1]); - memcpy_pic(((char*)P) + be2me_32(P->componentInfoCr.offset) + x + imgRect.right / 2 * y, src[2], w, h, imgRect.right / 2, stride[2]); - return 0; - - case IMGFMT_IYUV: - memcpy_pic(((char*)P) + be2me_32(P->componentInfoY.offset) + x + imgRect.right * y, src[0], w, h, imgRect.right, stride[0]); - x=x/2;y=y/2;w=w/2;h=h/2; - - memcpy_pic(((char*)P) + be2me_32(P->componentInfoCr.offset) + x + imgRect.right / 2 * y, src[1], w, h, imgRect.right / 2, stride[1]); - memcpy_pic(((char*)P) + be2me_32(P->componentInfoCb.offset) + x + imgRect.right / 2 * y, src[2], w, h, imgRect.right / 2, stride[2]); - return 0; - } - return -1; + switch (image_format) + { + case IMGFMT_YV12: + case IMGFMT_I420: + memcpy_pic(((char *)P) + be2me_32(P->componentInfoY.offset) + x + imgRect.right * y, src[0], w, h, imgRect.right, stride[0]); + x=x/2;y=y/2;w=w/2;h=h/2; + + memcpy_pic(((char *)P) + be2me_32(P->componentInfoCb.offset) + x + imgRect.right / 2 * y, src[1], w, h, imgRect.right / 2, stride[1]); + memcpy_pic(((char *)P) + be2me_32(P->componentInfoCr.offset) + x + imgRect.right / 2 * y, src[2], w, h, imgRect.right / 2, stride[2]); + return 0; + + case IMGFMT_IYUV: + memcpy_pic(((char *)P) + be2me_32(P->componentInfoY.offset) + x + imgRect.right * y, src[0], w, h, imgRect.right, stride[0]); + x=x/2;y=y/2;w=w/2;h=h/2; + + memcpy_pic(((char *)P) + be2me_32(P->componentInfoCr.offset) + x + imgRect.right / 2 * y, src[1], w, h, imgRect.right / 2, stride[1]); + memcpy_pic(((char *)P) + be2me_32(P->componentInfoCb.offset) + x + imgRect.right / 2 * y, src[2], w, h, imgRect.right / 2, stride[2]); + return 0; + } + return -1; } -static int draw_frame(uint8_t *src[]) +static int draw_frame(uint8_t * src[]) { - switch (image_format) - { - case IMGFMT_RGB32: - fast_memcpy(image_data,src[0],image_size); - return 0; - - case IMGFMT_UYVY: - case IMGFMT_YUY2: - memcpy_pic(((char*)P), src[0], imgRect.right * 2, imgRect.bottom, imgRect.right * 2, imgRect.right * 2); - return 0; - } - return -1; + switch (image_format) + { + case IMGFMT_RGB32: + fast_memcpy(image_data, src[0], image_size); + return 0; + + case IMGFMT_UYVY: + case IMGFMT_YUY2: + memcpy_pic(((char *)P), src[0], imgRect.right * 2, imgRect.bottom, imgRect.right * 2, imgRect.right * 2); + return 0; + } + return -1; } static int query_format(uint32_t format) { - image_format = format; - image_qtcodec = 0; + image_format = format; + image_qtcodec = 0; - if (format == IMGFMT_RGB32) - { - return VFCAP_CSP_SUPPORTED | VFCAP_OSD | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN; + if (format == IMGFMT_RGB32) + { + return VFCAP_CSP_SUPPORTED | VFCAP_OSD | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN; } - + if ((format == IMGFMT_YV12) || (format == IMGFMT_IYUV) || (format == IMGFMT_I420)) - { - image_qtcodec = kMpegYUV420CodecType; //kYUV420CodecType ?; - return VFCAP_CSP_SUPPORTED | VFCAP_OSD | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_ACCEPT_STRIDE; + { + image_qtcodec = kMpegYUV420CodecType; //kYUV420CodecType ?; + return VFCAP_CSP_SUPPORTED | VFCAP_OSD | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_ACCEPT_STRIDE; } if (format == IMGFMT_YUY2) - { - image_qtcodec = kComponentVideoUnsigned; - return VFCAP_CSP_SUPPORTED | VFCAP_OSD | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN; + { + image_qtcodec = kComponentVideoUnsigned; + return VFCAP_CSP_SUPPORTED | VFCAP_OSD | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN; } - + if (format == IMGFMT_UYVY) - { - image_qtcodec = k422YpCbCr8CodecType; - return VFCAP_CSP_SUPPORTED | VFCAP_OSD | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN; - } + { + image_qtcodec = k422YpCbCr8CodecType; + return VFCAP_CSP_SUPPORTED | VFCAP_OSD | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN; + } return 0; } static void uninit(void) { - OSErr qterr; - - switch (image_format) - { - case IMGFMT_YV12: - case IMGFMT_IYUV: - case IMGFMT_I420: - case IMGFMT_UYVY: - case IMGFMT_YUY2: - { - if (EnterMoviesDone) - { - qterr = CDSequenceEnd(seqId); - if (qterr) - { - mp_msg(MSGT_VO, MSGL_ERR, "Quartz error: CDSequenceEnd (%d)\n", qterr); - } - } - break; - } - default: - break; - } - - ShowMenuBar(); + OSErr qterr; + + switch (image_format) + { + case IMGFMT_YV12: + case IMGFMT_IYUV: + case IMGFMT_I420: + case IMGFMT_UYVY: + case IMGFMT_YUY2: + { + if (EnterMoviesDone) + { + qterr = CDSequenceEnd(seqId); + if (qterr) + { + mp_msg(MSGT_VO, MSGL_ERR, "Quartz error: CDSequenceEnd (%d)\n", qterr); + } + } + break; + } + default: + break; + } + + ShowMenuBar(); } static int preinit(const char *arg) { - int parse_err = 0; - - if(arg) + int parse_err = 0; + + if(arg) { char *parse_pos = (char *)&arg[0]; - while (parse_pos[0] && !parse_err) - { - if (strncmp (parse_pos, "device_id=", 10) == 0) - { - parse_pos = &parse_pos[10]; + + while (parse_pos[0] && !parse_err) + { + if (strncmp(parse_pos, "device_id=", 10) == 0) + { + parse_pos = &parse_pos[10]; device_id = strtol(parse_pos, &parse_pos, 0); } - if (strncmp (parse_pos, "fs_res=", 7) == 0) + if (strncmp(parse_pos, "fs_res=", 7) == 0) { - parse_pos = &parse_pos[7]; - fs_res_x = strtol(parse_pos, &parse_pos, 0); - parse_pos = &parse_pos[1]; - fs_res_y = strtol(parse_pos, &parse_pos, 0); + parse_pos = &parse_pos[7]; + fs_res_x = strtol(parse_pos, &parse_pos, 0); + parse_pos = &parse_pos[1]; + fs_res_y = strtol(parse_pos, &parse_pos, 0); } - if (parse_pos[0] == ':') parse_pos = &parse_pos[1]; - else if (parse_pos[0]) parse_err = 1; + if (parse_pos[0] == ':') + parse_pos = &parse_pos[1]; + else if (parse_pos[0]) + parse_err = 1; } } - + #if !defined (CONFIG_MACOSX_FINDER) || !defined (CONFIG_SDL) - //this chunk of code is heavily based off SDL_macosx.m from SDL - //it uses an Apple private function to request foreground operation -{ - void CPSEnableForegroundOperation(ProcessSerialNumber* psn); - ProcessSerialNumber myProc, frProc; - Boolean sameProc; - - if (GetFrontProcess(&frProc) == noErr) - { - if (GetCurrentProcess(&myProc) == noErr) - { - if (SameProcess(&frProc, &myProc, &sameProc) == noErr && !sameProc) - { - CPSEnableForegroundOperation(&myProc); - } - SetFrontProcess(&myProc); - } - } -} + // this chunk of code is heavily based off SDL_macosx.m from SDL + // the CPSEnableForegroundOperation that was here before is private and shouldn't be used + // replaced by a call to the 10.3+ TransformProcessType + { + ProcessSerialNumber myProc, frProc; + Boolean sameProc; + + if (GetFrontProcess(&frProc) == noErr) + { + if (GetCurrentProcess(&myProc) == noErr) + { + if (SameProcess(&frProc, &myProc, &sameProc) == noErr && !sameProc) + { + TransformProcessType(&myProc, kProcessTransformToForegroundApplication); + } + SetFrontProcess(&myProc); + } + } + } #endif return 0; } -static uint32_t draw_yuv_image(mp_image_t *mpi) +static uint32_t draw_yuv_image(mp_image_t * mpi) { - // ATM we're only called for planar IMGFMT - // drawing is done directly in P - // and displaying is in flip_page. - return get_image_done ? VO_TRUE : VO_FALSE; + // ATM we're only called for planar IMGFMT + // drawing is done directly in P + // and displaying is in flip_page. + return get_image_done ? VO_TRUE : VO_FALSE; } -static uint32_t get_yuv_image(mp_image_t *mpi) +static uint32_t get_yuv_image(mp_image_t * mpi) { - if(mpi->type!=MP_IMGTYPE_EXPORT) return VO_FALSE; - - if(mpi->imgfmt!=image_format) return VO_FALSE; - - if(mpi->flags&MP_IMGFLAG_PLANAR) - { - if (mpi->num_planes != 3) - { - mp_msg(MSGT_VO, MSGL_ERR, "Quartz error: only 3 planes allowed in get_yuv_image for planar (%d) \n", mpi->num_planes); - return VO_FALSE; - } - - mpi->planes[0]=((char*)P) + be2me_32(P->componentInfoY.offset); - mpi->stride[0]=imgRect.right; - mpi->width=imgRect.right; - - if(mpi->flags&MP_IMGFLAG_SWAPPED) - { - // I420 - mpi->planes[1]=((char*)P) + be2me_32(P->componentInfoCb.offset); - mpi->planes[2]=((char*)P) + be2me_32(P->componentInfoCr.offset); - mpi->stride[1]=imgRect.right/2; - mpi->stride[2]=imgRect.right/2; - } - else - { - // YV12 - mpi->planes[1]=((char*)P) + be2me_32(P->componentInfoCr.offset); - mpi->planes[2]=((char*)P) + be2me_32(P->componentInfoCb.offset); - mpi->stride[1]=imgRect.right/2; - mpi->stride[2]=imgRect.right/2; - } - - mpi->flags|=MP_IMGFLAG_DIRECT; - get_image_done = 1; - return VO_TRUE; - } - else - { - // doesn't work yet - if (mpi->num_planes != 1) - { - mp_msg(MSGT_VO, MSGL_ERR, "Quartz error: only 1 plane allowed in get_yuv_image for packed (%d) \n", mpi->num_planes); - return VO_FALSE; - } - - mpi->planes[0] = (char*)P; - mpi->stride[0] = imgRect.right * 2; - mpi->width=imgRect.right; - mpi->flags|=MP_IMGFLAG_DIRECT; - get_image_done = 1; - return VO_TRUE; - } - return VO_FALSE; + if (mpi->type != MP_IMGTYPE_EXPORT) return VO_FALSE; + + if (mpi->imgfmt != image_format) return VO_FALSE; + + if (mpi->flags & MP_IMGFLAG_PLANAR) + { + if (mpi->num_planes != 3) + { + mp_msg(MSGT_VO, MSGL_ERR, "Quartz error: only 3 planes allowed in get_yuv_image for planar (%d) \n", mpi->num_planes); + return VO_FALSE; + } + + mpi->planes[0] = ((char *)P) + be2me_32(P->componentInfoY.offset); + mpi->stride[0] = imgRect.right; + mpi->width = imgRect.right; + + if (mpi->flags & MP_IMGFLAG_SWAPPED) + { + // I420 + mpi->planes[1] = ((char *)P) + be2me_32(P->componentInfoCb.offset); + mpi->planes[2] = ((char *)P) + be2me_32(P->componentInfoCr.offset); + mpi->stride[1] = imgRect.right / 2; + mpi->stride[2] = imgRect.right / 2; + } + else + { + // YV12 + mpi->planes[1] = ((char *)P) + be2me_32(P->componentInfoCr.offset); + mpi->planes[2] = ((char *)P) + be2me_32(P->componentInfoCb.offset); + mpi->stride[1] = imgRect.right / 2; + mpi->stride[2] = imgRect.right / 2; + } + + mpi->flags |= MP_IMGFLAG_DIRECT; + get_image_done = 1; + return VO_TRUE; + } + else + { + // doesn't work yet + if (mpi->num_planes != 1) + { + mp_msg(MSGT_VO, MSGL_ERR, "Quartz error: only 1 plane allowed in get_yuv_image for packed (%d) \n", mpi->num_planes); + return VO_FALSE; + } + + mpi->planes[0] = (char *)P; + mpi->stride[0] = imgRect.right * 2; + mpi->width = imgRect.right; + mpi->flags |= MP_IMGFLAG_DIRECT; + get_image_done = 1; + return VO_TRUE; + } + return VO_FALSE; } static int control(uint32_t request, void *data) { - switch (request) - { - case VOCTRL_PAUSE: return int_pause = 1; - case VOCTRL_RESUME: return int_pause = 0; - case VOCTRL_FULLSCREEN: vo_fs = (!(vo_fs)); window_fullscreen(); return VO_TRUE; - case VOCTRL_ONTOP: vo_ontop = (!(vo_ontop)); window_ontop(); return VO_TRUE; - case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data)); - case VOCTRL_GET_PANSCAN: return VO_TRUE; - case VOCTRL_SET_PANSCAN: window_panscan(); return VO_TRUE; - - case VOCTRL_GET_IMAGE: - switch (image_format) - { - case IMGFMT_YV12: - case IMGFMT_IYUV: - case IMGFMT_I420: - case IMGFMT_UYVY: - case IMGFMT_YUY2: - return get_yuv_image(data); - break; - default: - break; - } - case VOCTRL_DRAW_IMAGE: - switch (image_format) - { - case IMGFMT_YV12: - case IMGFMT_IYUV: - case IMGFMT_I420: - case IMGFMT_UYVY: - case IMGFMT_YUY2: - return draw_yuv_image(data); - break; - default: - break; - } - } - return VO_NOTIMPL; + switch (request) + { + case VOCTRL_PAUSE: return int_pause = 1; + case VOCTRL_RESUME: return int_pause = 0; + case VOCTRL_FULLSCREEN: vo_fs = (!(vo_fs)); window_fullscreen(); return VO_TRUE; + case VOCTRL_ONTOP: vo_ontop = (!(vo_ontop)); window_ontop(); return VO_TRUE; + case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t *) data)); + case VOCTRL_GET_PANSCAN: return VO_TRUE; + case VOCTRL_SET_PANSCAN: window_panscan(); return VO_TRUE; + + case VOCTRL_GET_IMAGE: + switch (image_format) + { + case IMGFMT_YV12: + case IMGFMT_IYUV: + case IMGFMT_I420: + case IMGFMT_UYVY: + case IMGFMT_YUY2: + return get_yuv_image(data); + break; + default: + break; + } + case VOCTRL_DRAW_IMAGE: + switch (image_format) + { + case IMGFMT_YV12: + case IMGFMT_IYUV: + case IMGFMT_I420: + case IMGFMT_UYVY: + case IMGFMT_YUY2: + return draw_yuv_image(data); + break; + default: + break; + } + } + return VO_NOTIMPL; } void window_resized() { - float aspectX; - float aspectY; - - int padding = 0; - - uint32_t d_width; - uint32_t d_height; - - CGRect tmpBounds; - - GetPortBounds( GetWindowPort(theWindow), &winRect ); - - if(vo_keepaspect) - { - aspect( &d_width, &d_height, A_NOZOOM); - d_height = ((float)d_width/movie_aspect); - - aspectX = (float)((float)winRect.right/(float)d_width); - aspectY = (float)((float)(winRect.bottom)/(float)d_height); - - if((d_height*aspectX)>(winRect.bottom)) - { - padding = (winRect.right - d_width*aspectY)/2; - SetRect(&dstRect, padding, 0, d_width*aspectY+padding, d_height*aspectY); - } - else - { - padding = ((winRect.bottom) - d_height*aspectX)/2; - SetRect(&dstRect, 0, padding, (d_width*aspectX), d_height*aspectX+padding); - } - } - else - { - SetRect(&dstRect, 0, 0, winRect.right, winRect.bottom); - } - - switch (image_format) - { - case IMGFMT_RGB32: - { - bounds = CGRectMake(dstRect.left, dstRect.top, dstRect.right-dstRect.left, dstRect.bottom-dstRect.top); - CreateCGContextForPort (GetWindowPort (theWindow), &context); - break; - } - case IMGFMT_YV12: - case IMGFMT_IYUV: - case IMGFMT_I420: - case IMGFMT_UYVY: - case IMGFMT_YUY2: - { - long scale_X = FixDiv(Long2Fix(dstRect.right - dstRect.left),Long2Fix(imgRect.right)); - long scale_Y = FixDiv(Long2Fix(dstRect.bottom - dstRect.top),Long2Fix(imgRect.bottom)); - - SetIdentityMatrix(&matrix); - if (((dstRect.right - dstRect.left) != imgRect.right) || ((dstRect.bottom - dstRect.right) != imgRect.bottom)) - { - ScaleMatrix(&matrix, scale_X, scale_Y, 0, 0); - - if (padding > 0) - { - TranslateMatrix(&matrix, Long2Fix(dstRect.left), Long2Fix(dstRect.top)); - } - } - - SetDSequenceMatrix(seqId, &matrix); - break; - } - default: - break; - } - - //Clear Background - tmpBounds = CGRectMake( 0, 0, winRect.right, winRect.bottom); - CreateCGContextForPort(GetWindowPort(theWindow),&context); - CGContextFillRect(context, tmpBounds); + float aspectX; + float aspectY; + + int padding = 0; + + uint32_t d_width; + uint32_t d_height; + + CGRect tmpBounds; + + CGContextRef context; + + GetWindowPortBounds(theWindow, &winRect); + + if (vo_keepaspect) + { + aspect(&d_width, &d_height, A_NOZOOM); + d_height = ((float)d_width / movie_aspect); + + aspectX = (float)((float)winRect.right / (float)d_width); + aspectY = (float)((float)(winRect.bottom) / (float)d_height); + + if ((d_height * aspectX) > (winRect.bottom)) + { + padding = (winRect.right - d_width * aspectY) / 2; + SetRect(&dstRect, padding, 0, d_width * aspectY + padding, d_height * aspectY); + } + else + { + padding = ((winRect.bottom) - d_height * aspectX) / 2; + SetRect(&dstRect, 0, padding, (d_width * aspectX), d_height * aspectX + padding); + } + } + else + { + SetRect(&dstRect, 0, 0, winRect.right, winRect.bottom); + } + + switch (image_format) + { + case IMGFMT_RGB32: + { + bounds = CGRectMake(dstRect.left, dstRect.top, dstRect.right - dstRect.left, dstRect.bottom - dstRect.top); + break; + } + case IMGFMT_YV12: + case IMGFMT_IYUV: + case IMGFMT_I420: + case IMGFMT_UYVY: + case IMGFMT_YUY2: + { + long scale_X = FixDiv(Long2Fix(dstRect.right - dstRect.left), Long2Fix(imgRect.right)); + long scale_Y = FixDiv(Long2Fix(dstRect.bottom - dstRect.top), Long2Fix(imgRect.bottom)); + + SetIdentityMatrix(&matrix); + if (((dstRect.right - dstRect.left) != imgRect.right) || ((dstRect.bottom - dstRect.right) != imgRect.bottom)) + { + ScaleMatrix(&matrix, scale_X, scale_Y, 0, 0); + + if (padding > 0) + { + TranslateMatrix(&matrix, Long2Fix(dstRect.left), Long2Fix(dstRect.top)); + } + } + + SetDSequenceMatrix(seqId, &matrix); + break; + } + default: + break; + } + + // Clear Background + tmpBounds = CGRectMake(0, 0, winRect.right, winRect.bottom); + QDBeginCGContext(GetWindowPort(theWindow), &context); + CGContextFillRect(context, tmpBounds); + QDEndCGContext(GetWindowPort(theWindow), &context); } void window_ontop() { - if(!vo_quartz_fs) - { - //Cycle between level - winLevel++; - if(winLevel>2) - winLevel = 1; - } - SetWindowGroupLevel(winGroup, CGWindowLevelForKey(levelList[winLevel])); + if (!vo_quartz_fs) + { + // Cycle between level + winLevel++; + if (winLevel > 2) + winLevel = 1; + } + SetWindowGroupLevel(winGroup, CGWindowLevelForKey(levelList[winLevel])); } void window_fullscreen() { - static Ptr restoreState = NULL; - - //go fullscreen - if(vo_fs) - { - if(winLevel != 0) - { - if(device_id == 0) - { - SetSystemUIMode( kUIModeAllHidden, kUIOptionAutoShowMenuBar); - CGDisplayHideCursor(kCGDirectMainDisplay); - mouseHide = TRUE; - } - - if(fs_res_x != 0 || fs_res_y != 0) - { - BeginFullScreen( &restoreState, deviceHdl, &fs_res_x, &fs_res_y, NULL, NULL, 0); - - //Get Main device info/////////////////////////////////////////////////// - deviceRect = (*deviceHdl)->gdRect; - - device_width = deviceRect.right; - device_height = deviceRect.bottom; - } - } - - //save old window size - if (!vo_quartz_fs) - { - GetWindowPortBounds(theWindow, &oldWinRect); - GetWindowBounds(theWindow, kWindowContentRgn, &oldWinBounds); - } - - //go fullscreen - panscan_calc(); - ChangeWindowAttributes(theWindow, kWindowNoShadowAttribute, 0); - MoveWindow(theWindow, deviceRect.left-(vo_panscan_x >> 1), deviceRect.top-(vo_panscan_y >> 1), 1); - SizeWindow(theWindow, device_width+vo_panscan_x, device_height+vo_panscan_y,1); - - vo_quartz_fs = 1; - } - else //go back to windowed mode - { - vo_quartz_fs = 0; - if(restoreState != NULL) - { - EndFullScreen(restoreState, 0); - - //Get Main device info/////////////////////////////////////////////////// - deviceRect = (*deviceHdl)->gdRect; - - device_width = deviceRect.right; - device_height = deviceRect.bottom; - restoreState = NULL; - } - SetSystemUIMode( kUIModeNormal, 0); - - //show mouse cursor - CGDisplayShowCursor(kCGDirectMainDisplay); - mouseHide = FALSE; - - //revert window to previous setting - ChangeWindowAttributes(theWindow, 0, kWindowNoShadowAttribute); - SizeWindow(theWindow, oldWinRect.right, oldWinRect.bottom,1); - MoveWindow(theWindow, oldWinBounds.left, oldWinBounds.top, 1); - } - window_resized(); + // go fullscreen + if (vo_fs) + { + if (winLevel != 0) + { + if (displayId == kCGDirectMainDisplay) + { + SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar); + CGDisplayHideCursor(displayId); + mouseHide = TRUE; + } + + if (fs_res_x != 0 || fs_res_y != 0) + { + CFDictionaryRef mode; + size_t desiredBitDepth = 32; + boolean_t exactMatch; + + originalMode = CGDisplayCurrentMode(displayId); + + mode = CGDisplayBestModeForParameters(displayId, desiredBitDepth, fs_res_x, fs_res_y, &exactMatch); + + if (mode != NULL) + { + if (!exactMatch) + { + // Warn if the mode doesn't match exactly + mp_msg(MSGT_VO, MSGL_WARN, "Quartz warning: did not get exact mode match (got %dx%d) \n", (int)CFDictionaryGetValue(mode, kCGDisplayWidth), (int)CFDictionaryGetValue(mode, kCGDisplayHeight)); + } + + CGDisplayCapture(displayId); + CGDisplaySwitchToMode(displayId, mode); + } + else + { + mp_msg(MSGT_VO, MSGL_ERR, "Quartz error: can't switch to fullscreen \n"); + } + + // Get Main device info/////////////////////////////////////////////////// + displayRect = CGDisplayBounds(displayId); + } + } + // save old window size + if (!vo_quartz_fs) + { + GetWindowPortBounds(theWindow, &oldWinRect); + GetWindowBounds(theWindow, kWindowContentRgn, &oldWinBounds); + } + // go fullscreen + panscan_calc(); + ChangeWindowAttributes(theWindow, kWindowNoShadowAttribute, 0); + MoveWindow(theWindow, displayRect.origin.x - (vo_panscan_x >> 1), displayRect.origin.y - (vo_panscan_y >> 1), 1); + SizeWindow(theWindow, displayRect.size.width + vo_panscan_x, displayRect.size.height + vo_panscan_y, 1); + + vo_quartz_fs = 1; + } + else //go back to windowed mode + { + vo_quartz_fs = 0; + if (originalMode != NULL) + { + CGDisplaySwitchToMode(displayId, originalMode); + CGDisplayRelease(displayId); + + // Get Main device info/////////////////////////////////////////////////// + displayRect = CGDisplayBounds(displayId); + + originalMode = NULL; + } + SetSystemUIMode(kUIModeNormal, 0); + + // show mouse cursor + CGDisplayShowCursor(displayId); + mouseHide = FALSE; + + // revert window to previous setting + ChangeWindowAttributes(theWindow, 0, kWindowNoShadowAttribute); + SizeWindow(theWindow, oldWinRect.right, oldWinRect.bottom, 1); + MoveWindow(theWindow, oldWinBounds.left, oldWinBounds.top, 1); + } + window_resized(); } void window_panscan() { - panscan_calc(); - - if(vo_panscan > 0) - CheckMenuItem (aspectMenu, 2, 1); - else - CheckMenuItem (aspectMenu, 2, 0); - - if(vo_quartz_fs) - { - MoveWindow(theWindow, deviceRect.left-(vo_panscan_x >> 1), deviceRect.top-(vo_panscan_y >> 1), 1); - SizeWindow(theWindow, device_width+vo_panscan_x, device_height+vo_panscan_y,1); - } + panscan_calc(); + + if (vo_panscan > 0) + CheckMenuItem(aspectMenu, 2, 1); + else + CheckMenuItem(aspectMenu, 2, 0); + + if (vo_quartz_fs) + { + MoveWindow(theWindow, displayRect.origin.x - (vo_panscan_x >> 1), displayRect.origin.y - (vo_panscan_y >> 1), 1); + SizeWindow(theWindow, displayRect.size.width + vo_panscan_x, displayRect.size.height + vo_panscan_y, 1); + } } diff --git a/libvo/vo_wii.c b/libvo/vo_wii.c index bccf6f02ef..8999852d80 100644 --- a/libvo/vo_wii.c +++ b/libvo/vo_wii.c @@ -54,10 +54,6 @@ #include "sub.h" #include "mp_msg.h" -#define WII_DEV_NAME "/dev/fb0" -#define TTY_DEV_NAME "/dev/tty" -#define FB_PIXEL_SIZE 2 - static const vo_info_t info = { "Nintendo Wii/GameCube Framebuffer Device", "wii", @@ -69,31 +65,32 @@ LIBVO_EXTERN(wii) static signed int pre_init_err = -2; +static char *fb_dev_name = NULL; + static FILE *vt_fp = NULL; static int vt_doit = 1; -static int fb_dev_fd = -1; -static int fb_tty_fd = -1; +static int fb_dev_fd; +static int fb_tty_fd = -1; +static size_t fb_size; static uint8_t *frame_buffer; static uint8_t *center; - static struct fb_var_screeninfo fb_orig_vinfo; static struct fb_var_screeninfo fb_vinfo; +static int fb_pixel_size; // 32: 4 24: 3 16: 2 15: 2 static int fb_line_len; -static size_t fb_size; - -static int in_width, out_width; -static int in_height, out_height; +static int in_width; +static int in_height; +static int out_width; +static int out_height; static int fs; -static int -fb_preinit (int reset) +static int fb_preinit(int reset) { static int fb_preinit_done = 0; static int fb_works = 0; - if (reset) - { + if (reset) { fb_preinit_done = 0; return 0; } @@ -101,26 +98,22 @@ fb_preinit (int reset) if (fb_preinit_done) return fb_works; - if ((fb_dev_fd = open (WII_DEV_NAME, O_RDWR)) == -1) - { - mp_msg (MSGT_VO, MSGL_ERR, - "Can't open %s: %s\n", WII_DEV_NAME, strerror (errno)); + if (!fb_dev_name && !(fb_dev_name = getenv("FRAMEBUFFER"))) + fb_dev_name = strdup("/dev/fb0"); + mp_msg(MSGT_VO, MSGL_V, "using %s\n", fb_dev_name); + + if ((fb_dev_fd = open(fb_dev_name, O_RDWR)) == -1) { + mp_msg(MSGT_VO, MSGL_ERR, "Can't open %s: %s\n", fb_dev_name, strerror(errno)); goto err_out; } - - if (ioctl (fb_dev_fd, FBIOGET_VSCREENINFO, &fb_vinfo)) - { - mp_msg (MSGT_VO, MSGL_ERR, - "Can't get VSCREENINFO: %s\n", strerror (errno)); + if (ioctl(fb_dev_fd, FBIOGET_VSCREENINFO, &fb_vinfo)) { + mp_msg(MSGT_VO, MSGL_ERR, "Can't get VSCREENINFO: %s\n", strerror(errno)); goto err_out_fd; } - fb_orig_vinfo = fb_vinfo; - if ((fb_tty_fd = open (TTY_DEV_NAME, O_RDWR)) < 0) - { - mp_msg (MSGT_VO, MSGL_ERR, - "Notice: Can't open %s: %s\n", TTY_DEV_NAME, strerror (errno)); + if ((fb_tty_fd = open("/dev/tty", O_RDWR)) < 0) { + mp_msg(MSGT_VO, MSGL_ERR, "notice: Can't open /dev/tty: %s\n", strerror(errno)); goto err_out_fd; } @@ -129,17 +122,16 @@ fb_preinit (int reset) return 1; err_out_fd: - close (fb_dev_fd); + close(fb_dev_fd); fb_dev_fd = -1; err_out: fb_preinit_done = 1; fb_works = 0; - + return 0; } -static void -vt_set_textarea (int u, int l) +static void vt_set_textarea(int u, int l) { /* how can I determine the font height? * just use 16 for now @@ -147,178 +139,149 @@ vt_set_textarea (int u, int l) int urow = ((u + 15) / 16) + 1; int lrow = l / 16; - mp_msg (MSGT_VO, MSGL_DBG2, - "vt_set_textarea (%d, %d): %d,%d\n", u, l, urow, lrow); + mp_msg(MSGT_VO, MSGL_DBG2, "vt_set_textarea(%d, %d): %d,%d\n", u, l, urow, lrow); - if (vt_fp) - { - fprintf (vt_fp, "\33[%d;%dr\33[%d;%dH", urow, lrow, lrow, 0); - fflush (vt_fp); + if (vt_fp) { + fprintf(vt_fp, "\33[%d;%dr\33[%d;%dH", urow, lrow, lrow, 0); + fflush(vt_fp); } } -static int -config (uint32_t width, uint32_t height, uint32_t d_width, - uint32_t d_height, uint32_t flags, char *title, uint32_t format) +static int config(uint32_t width, uint32_t height, uint32_t d_width, + uint32_t d_height, uint32_t flags, char *title, + uint32_t format) { struct fb_fix_screeninfo fb_finfo; uint32_t black = 0x00800080; long temp; int vt_fd; - + fs = flags & VOFLAG_FULLSCREEN; - if (pre_init_err == -2) - { - mp_msg (MSGT_VO, MSGL_ERR, - "Internal fatal error: config() was called before preinit()\n"); + if (pre_init_err == -2) { + mp_msg(MSGT_VO, MSGL_ERR, "Internal fatal error: config() was called before preinit()\n"); return -1; } if (pre_init_err) return 1; - in_width = width; + in_width = width; in_height = height; - out_width = (d_width && fs) ? d_width : width; + out_width = (d_width && fs) ? d_width : width; out_height = (d_width && fs) ? d_height : height; fb_vinfo.xres_virtual = fb_vinfo.xres; fb_vinfo.yres_virtual = fb_vinfo.yres; - if (fb_tty_fd >= 0 && ioctl (fb_tty_fd, KDSETMODE, KD_GRAPHICS) < 0) - { - mp_msg (MSGT_VO, MSGL_V, - "Can't set graphics mode: %s\n", strerror (errno)); - close (fb_tty_fd); + if (fb_tty_fd >= 0 && ioctl(fb_tty_fd, KDSETMODE, KD_GRAPHICS) < 0) { + mp_msg(MSGT_VO, MSGL_V, "Can't set graphics mode: %s\n", strerror(errno)); + close(fb_tty_fd); fb_tty_fd = -1; } - if (ioctl (fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_vinfo)) - { - mp_msg (MSGT_VO, MSGL_ERR, - "Can't put VSCREENINFO: %s\n", strerror (errno)); - if (fb_tty_fd >= 0 && ioctl (fb_tty_fd, KDSETMODE, KD_TEXT) < 0) - { - mp_msg (MSGT_VO, MSGL_ERR, - "Can't restore text mode: %s\n", strerror (errno)); + if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_vinfo)) { + mp_msg(MSGT_VO, MSGL_ERR, "Can't put VSCREENINFO: %s\n", strerror(errno)); + if (fb_tty_fd >= 0 && ioctl(fb_tty_fd, KDSETMODE, KD_TEXT) < 0) { + mp_msg(MSGT_VO, MSGL_ERR, "Can't restore text mode: %s\n", strerror(errno)); } return 1; } - if (fs) - { - out_width = fb_vinfo.xres; + fb_pixel_size = 2; + + if (fs) { + out_width = fb_vinfo.xres; out_height = fb_vinfo.yres; } - - if (out_width < in_width || out_height < in_height) - { - mp_msg (MSGT_VO, MSGL_ERR, "Screensize is smaller than video size\n"); + if (out_width < in_width || out_height < in_height) { + mp_msg(MSGT_VO, MSGL_ERR, "screensize is smaller than video size\n"); return 1; } - if (ioctl (fb_dev_fd, FBIOGET_FSCREENINFO, &fb_finfo)) - { - mp_msg (MSGT_VO, MSGL_ERR, - "Can't get FSCREENINFO: %s\n", strerror (errno)); + if (ioctl(fb_dev_fd, FBIOGET_FSCREENINFO, &fb_finfo)) { + mp_msg(MSGT_VO, MSGL_ERR, "Can't get FSCREENINFO: %s\n", strerror(errno)); return 1; } - if (fb_finfo.type != FB_TYPE_PACKED_PIXELS) - { - mp_msg (MSGT_VO, MSGL_ERR, "Type %d not supported\n", fb_finfo.type); + if (fb_finfo.type != FB_TYPE_PACKED_PIXELS) { + mp_msg(MSGT_VO, MSGL_ERR, "type %d not supported\n", fb_finfo.type); return 1; } fb_line_len = fb_finfo.line_length; - fb_size = fb_finfo.smem_len; - frame_buffer = NULL; + fb_size = fb_finfo.smem_len; - frame_buffer = (uint8_t *) mmap (0, fb_size, PROT_READ | PROT_WRITE, - MAP_SHARED, fb_dev_fd, 0); - if (frame_buffer == (uint8_t *) -1) - { - mp_msg (MSGT_VO, MSGL_ERR, - "Can't mmap %s: %s\n", WII_DEV_NAME, strerror (errno)); + frame_buffer = (uint8_t *) mmap(0, fb_size, PROT_READ | PROT_WRITE, + MAP_SHARED, fb_dev_fd, 0); + if (frame_buffer == (uint8_t *) -1) { + mp_msg(MSGT_VO, MSGL_ERR, "Can't mmap %s: %s\n", fb_dev_name, strerror(errno)); return 1; } center = frame_buffer + - ((out_width - in_width) / 2) * FB_PIXEL_SIZE + + ((out_width - in_width) / 2) * fb_pixel_size + ((out_height - in_height) / 2) * fb_line_len; - mp_msg (MSGT_VO, MSGL_DBG2, "Frame_buffer @ %p\n", frame_buffer); - mp_msg (MSGT_VO, MSGL_DBG2, "Center @ %p\n", center); - mp_msg (MSGT_VO, MSGL_V, - "Pixel per line: %d\n", fb_line_len / FB_PIXEL_SIZE); + mp_msg(MSGT_VO, MSGL_DBG2, "frame_buffer @ %p\n", frame_buffer); + mp_msg(MSGT_VO, MSGL_DBG2, "center @ %p\n", center); + mp_msg(MSGT_VO, MSGL_V, "pixel per line: %d\n", fb_line_len / fb_pixel_size); /* blanking screen */ for (temp = 0; temp < fb_size; temp += 4) - memcpy (frame_buffer + temp, (void *) &black, 4); + memcpy(frame_buffer + temp, (void *) &black, 4); - vt_fd = open (TTY_DEV_NAME, O_WRONLY); - if (vt_doit && vt_fd == -1) - { - mp_msg (MSGT_VO, MSGL_ERR, - "Can't open %s: %s\n", TTY_DEV_NAME, strerror (errno)); + if (vt_doit && (vt_fd = open("/dev/tty", O_WRONLY)) == -1) { + mp_msg(MSGT_VO, MSGL_ERR, "can't open /dev/tty: %s\n", strerror(errno)); vt_doit = 0; } - - vt_fp = fdopen (vt_fd, "w"); - if (vt_doit && !vt_fp) - { - mp_msg (MSGT_VO, MSGL_ERR, - "Can't fdopen %s: %s\n", TTY_DEV_NAME, strerror (errno)); + if (vt_doit && !(vt_fp = fdopen(vt_fd, "w"))) { + mp_msg(MSGT_VO, MSGL_ERR, "can't fdopen /dev/tty: %s\n", strerror(errno)); vt_doit = 0; } if (vt_doit) - vt_set_textarea ((out_height + in_height) / 2, fb_vinfo.yres); + vt_set_textarea((out_height + in_height) / 2, fb_vinfo.yres); return 0; } -static int -query_format (uint32_t format) +static int query_format(uint32_t format) { - if (!fb_preinit (0)) + if (!fb_preinit(0)) return 0; - + if (format != IMGFMT_YUY2) return 0; - + return VFCAP_ACCEPT_STRIDE | VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW; } -static void -draw_alpha (int x0, int y0, int w, int h, - unsigned char *src, unsigned char *srca, int stride) +static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src, + unsigned char *srca, int stride) { unsigned char *dst; - dst = center + fb_line_len * y0 + FB_PIXEL_SIZE * x0; - vo_draw_alpha_yuy2 (w, h, src, srca, stride, dst, fb_line_len); + dst = center + fb_line_len * y0 + fb_pixel_size * x0; + + vo_draw_alpha_yuy2(w, h, src, srca, stride, dst, fb_line_len); } -static int -draw_frame (uint8_t *src[]) +static int draw_frame(uint8_t *src[]) { return 1; } -static int -draw_slice (uint8_t *src[], int stride[], int w, int h, int x, int y) +static int draw_slice(uint8_t *src[], int stride[], int w, int h, int x, int y) { uint8_t *d, *s; - d = center + fb_line_len * y + FB_PIXEL_SIZE * x; - s = src[0]; + d = center + fb_line_len * y + fb_pixel_size * x; - while (h) - { - memcpy (d, s, w * FB_PIXEL_SIZE); + s = src[0]; + while (h) { + memcpy(d, s, w * fb_pixel_size); d += fb_line_len; s += stride[0]; h--; @@ -327,77 +290,58 @@ draw_slice (uint8_t *src[], int stride[], int w, int h, int x, int y) return 0; } -static void -check_events(void) +static void check_events(void) { - /* unused */ } -static void -flip_page (void) +static void flip_page(void) { - /* unused */ } -static void -draw_osd (void) +static void draw_osd(void) { - vo_draw_text (in_width, in_height, draw_alpha); + vo_draw_text(in_width, in_height, draw_alpha); } -static void -uninit (void) +static void uninit(void) { - if (ioctl (fb_dev_fd, FBIOGET_VSCREENINFO, &fb_vinfo)) - mp_msg (MSGT_VO, MSGL_WARN, - "ioctl FBIOGET_VSCREENINFO: %s\n", strerror (errno)); - + if (ioctl(fb_dev_fd, FBIOGET_VSCREENINFO, &fb_vinfo)) + mp_msg(MSGT_VO, MSGL_WARN, "ioctl FBIOGET_VSCREENINFO: %s\n", strerror(errno)); fb_orig_vinfo.xoffset = fb_vinfo.xoffset; fb_orig_vinfo.yoffset = fb_vinfo.yoffset; - - if (ioctl (fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_orig_vinfo)) - mp_msg (MSGT_VO, MSGL_WARN, - "Can't reset original fb_var_screeninfo: %s\n", strerror (errno)); - - if (fb_tty_fd >= 0) - { - if (ioctl (fb_tty_fd, KDSETMODE, KD_TEXT) < 0) - mp_msg (MSGT_VO, MSGL_WARN, - "Can't restore text mode: %s\n", strerror (errno)); + if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_orig_vinfo)) + mp_msg(MSGT_VO, MSGL_WARN, "Can't reset original fb_var_screeninfo: %s\n", strerror(errno)); + if (fb_tty_fd >= 0) { + if (ioctl(fb_tty_fd, KDSETMODE, KD_TEXT) < 0) + mp_msg(MSGT_VO, MSGL_WARN, "Can't restore text mode: %s\n", strerror(errno)); } - if (vt_doit) - vt_set_textarea (0, fb_orig_vinfo.yres); - - close (fb_tty_fd); - close (fb_dev_fd); - + vt_set_textarea(0, fb_orig_vinfo.yres); + close(fb_tty_fd); + close(fb_dev_fd); if (frame_buffer) - munmap (frame_buffer, fb_size); - + munmap(frame_buffer, fb_size); frame_buffer = NULL; - fb_preinit (1); + fb_preinit(1); } -static int -preinit (const char *vo_subdevice) +static int preinit(const char *vo_subdevice) { pre_init_err = 0; if (!pre_init_err) - return pre_init_err = (fb_preinit (0) ? 0 : -1); - + return pre_init_err = (fb_preinit(0) ? 0 : -1); return -1; } -static uint32_t -get_image(mp_image_t *mpi) +static uint32_t get_image(mp_image_t *mpi) { if (((mpi->type != MP_IMGTYPE_STATIC) && (mpi->type != MP_IMGTYPE_TEMP)) || (mpi->flags & MP_IMGFLAG_PLANAR) || (mpi->flags & MP_IMGFLAG_YUV) || (mpi->width != in_width) || - (mpi->height != in_height)) + (mpi->height != in_height) + ) return VO_FALSE; mpi->planes[0] = center; @@ -407,13 +351,12 @@ get_image(mp_image_t *mpi) return VO_TRUE; } -static int -control (uint32_t request, void *data) +static int control(uint32_t request, void *data) { if (request == VOCTRL_GET_IMAGE) - return get_image (data); + return get_image(data); else if (request == VOCTRL_QUERY_FORMAT) - return query_format (*((uint32_t*) data)); + return query_format(*((uint32_t*) data)); return VO_NOTIMPL; } diff --git a/libvo/vo_x11.c b/libvo/vo_x11.c index 66c21ebea7..5c204e417f 100644 --- a/libvo/vo_x11.c +++ b/libvo/vo_x11.c @@ -6,14 +6,12 @@ #include "config.h" #include "video_out.h" #include "video_out_internal.h" +#include "aspect.h" #include <X11/Xlib.h> #include <X11/Xutil.h> -#ifdef CONFIG_XF86VM -#include <X11/extensions/xf86vmode.h> -#endif #include <errno.h> #include "x11_common.h" @@ -83,7 +81,6 @@ static uint32_t out_format = 0; static int out_offset; static int srcW = -1; static int srcH = -1; -static int aspect; // 1<<16 based fixed point aspect, so that the aspect stays correct during resizing static int old_vo_dwidth = -1; static int old_vo_dheight = -1; @@ -92,16 +89,13 @@ static void check_events(void) { int ret = vo_x11_check_events(mDisplay); - /* clear left over borders and redraw frame if we are paused */ - if (ret & VO_EVENT_EXPOSE && int_pause) - { + if (ret & VO_EVENT_RESIZE) + vo_x11_clearwindow(mDisplay, vo_window); + else if (ret & VO_EVENT_EXPOSE) vo_x11_clearwindow_part(mDisplay, vo_window, myximage->width, myximage->height, 0); + if (ret & VO_EVENT_EXPOSE && int_pause) flip_page(); - } else if ((ret & VO_EVENT_RESIZE) || (ret & VO_EVENT_EXPOSE)) - vo_x11_clearwindow_part(mDisplay, vo_window, myximage->width, - myximage->height, 0); - } static void draw_alpha_32(int x0, int y0, int w, int h, unsigned char *src, @@ -306,7 +300,6 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, // int interval, prefer_blank, allow_exp, nothing; unsigned int fg, bg; - XGCValues xgcv; Colormap theCmap; XSetWindowAttributes xswa; unsigned long xswamask; @@ -315,7 +308,6 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, #ifdef CONFIG_XF86VM int vm = flags & VOFLAG_MODESWITCHING; #endif - int fullscreen = flags & (VOFLAG_FULLSCREEN|VOFLAG_MODESWITCHING); Flip_Flag = flags & VOFLAG_FLIPPING; zoomFlag = flags & VOFLAG_SWSCALE; @@ -330,10 +322,6 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, srcW = width; srcH = height; -// if(!fullscreen) zoomFlag=1; //it makes no sense to avoid zooming on windowd mode - -//printf( "w: %d h: %d\n\n",vo_dwidth,vo_dheight ); - XGetWindowAttributes(mDisplay, mRootWin, &attribs); depth = attribs.depth; @@ -354,8 +342,6 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, image_width = (width + 7) & (~7); image_height = height; - aspect = ((1 << 16) * d_width + d_height / 2) / d_height; - #ifdef CONFIG_GUI if (use_gui) guiGetEvent(guiSetShVideo, 0); // the GUI will set up / resize the window @@ -479,6 +465,11 @@ static void Display_Image(XImage * myximage, uint8_t * ImageData) { int x = (vo_dwidth - dst_width) / 2; int y = (vo_dheight - myximage->height) / 2; + + // do not draw if the image needs rescaling + if ((old_vo_dwidth != vo_dwidth || old_vo_dheight != vo_dheight) && zoomFlag) + return; + if (WinID == 0) { x = vo_dx; y = vo_dy; @@ -524,17 +515,13 @@ static int draw_slice(uint8_t * src[], int stride[], int w, int h, { int newW = vo_dwidth; int newH = vo_dheight; - int newAspect = (newW * (1 << 16) + (newH >> 1)) / newH; struct SwsContext *oldContext = swsContext; - if (newAspect > aspect) - newW = (newH * aspect + (1 << 15)) >> 16; - else - newH = ((newW << 16) + (aspect >> 1)) / aspect; - old_vo_dwidth = vo_dwidth; old_vo_dheight = vo_dheight; + if (vo_fs) + aspect(&newW, &newH, A_ZOOM); if (sws_flags == 0) newW &= (~31); // not needed but, if the user wants the FAST_BILINEAR SCALER, then its needed diff --git a/libvo/vo_xvmc.c b/libvo/vo_xvmc.c index 5a13d0e71a..89fb2e6fe8 100644 --- a/libvo/vo_xvmc.c +++ b/libvo/vo_xvmc.c @@ -460,7 +460,7 @@ XWindowAttributes attribs; unsigned long xswamask; int depth; #ifdef CONFIG_XF86VM -int vm=0; +int vm = flags & VOFLAG_MODESWITCHING; #endif //end of vo_xv @@ -632,10 +632,6 @@ found_subpic: skip_surface_allocation: -#ifdef CONFIG_XF86VM - if( flags&VOFLAG_MODESWITCHING ) vm = 1; -#endif - #ifdef CONFIG_GUI if(use_gui) guiGetEvent( guiSetShVideo,0 ); // let the GUI to setup/resize our window @@ -1033,9 +1029,6 @@ int i,cfs; } static void check_events(void){ -Window mRoot; -uint32_t drwBorderWidth,drwDepth; - int e=vo_x11_check_events(mDisplay); if(e&VO_EVENT_RESIZE) { @@ -3194,6 +3194,12 @@ if(stream_dump_type==5){ exit_player(mpctx, MSGTR_Exit_error); } } + if(dvd_last_chapter > 0) { + int chapter = -1; + if (stream_control(mpctx->stream, STREAM_CTRL_GET_CURRENT_CHAPTER, + &chapter) == STREAM_OK && chapter + 1 > dvd_last_chapter) + break; + } } if(fclose(f)) { mp_msg(MSGT_MENCODER,MSGL_FATAL,MSGTR_ErrorWritingFile,stream_dump_name); @@ -3380,6 +3386,11 @@ if((stream_dump_type)&&(stream_dump_type<4)){ if( (mpctx->demuxer->file_format==DEMUXER_TYPE_AVI || mpctx->demuxer->file_format==DEMUXER_TYPE_ASF || mpctx->demuxer->file_format==DEMUXER_TYPE_MOV) && stream_dump_type==2) fwrite(&in_size,1,4,f); if(in_size>0) fwrite(start,in_size,1,f); + if(dvd_last_chapter>0) { + int cur_chapter = demuxer_get_current_chapter(mpctx->demuxer); + if(cur_chapter!=-1 && cur_chapter+1>dvd_last_chapter) + break; + } } fclose(f); mp_msg(MSGT_CPLAYER,MSGL_INFO,MSGTR_CoreDumped); diff --git a/subdir.mak b/subdir.mak index 68850c80ba..7c38b77619 100644 --- a/subdir.mak +++ b/subdir.mak @@ -56,7 +56,7 @@ install-headers:: install -d "$(INCINSTDIR)" install -d "$(LIBDIR)/pkgconfig" install -m 644 $(addprefix "$(SRC_DIR)"/,$(HEADERS)) "$(INCINSTDIR)" - install -m 644 $(BUILD_ROOT)/lib$(NAME).pc "$(LIBDIR)/pkgconfig" + install -m 644 $(BUILD_ROOT)/lib$(NAME)/lib$(NAME).pc "$(LIBDIR)/pkgconfig" uninstall-libs:: -rm -f "$(SHLIBDIR)/$(SLIBNAME_WITH_MAJOR)" \ |