1 /*
2 Copyright (C) 2012 Harald Sitter <sitter@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include "videomemorystream.h"
19
20 #include "mediaplayer.h"
21
22 namespace Phonon {
23 namespace VLC {
24
p_this(void * opaque)25 static inline VideoMemoryStream *p_this(void *opaque) { return static_cast<VideoMemoryStream *>(opaque); }
p_this(void ** opaque)26 static inline VideoMemoryStream *p_this(void **opaque) { return static_cast<VideoMemoryStream *>(*opaque); }
27 #define P_THIS p_this(opaque)
28
VideoMemoryStream()29 VideoMemoryStream::VideoMemoryStream()
30 {
31 }
32
~VideoMemoryStream()33 VideoMemoryStream::~VideoMemoryStream()
34 {
35 }
36
gcd(qint64 a,qint64 b)37 static inline qint64 gcd(qint64 a, qint64 b)
38 {
39 while( b )
40 {
41 qint64 c = a % b;
42 a = b;
43 b = c;
44 }
45 return a;
46 }
47
lcm(int a,int b)48 static int lcm(int a, int b)
49 {
50 return a * b / GCD( a, b );
51 }
52
setPitchAndLines(const vlc_chroma_description_t * desc,unsigned width,unsigned height,unsigned * pitches,unsigned * lines,unsigned * visiblePitches,unsigned * visibleLines)53 unsigned VideoMemoryStream::setPitchAndLines(const vlc_chroma_description_t *desc,
54 unsigned width, unsigned height,
55 unsigned *pitches, unsigned *lines,
56 unsigned *visiblePitches, unsigned *visibleLines)
57 {
58 // Mostly taken from vlc/src/misc/picture.c
59 // Simple alignment would be an option but I trust the VLC guys they know what they are doing.
60 int i_modulo_w = 1;
61 int i_modulo_h = 1;
62 unsigned int i_ratio_h = 1;
63 for( unsigned i = 0; i < desc->plane_count; i++ )
64 {
65 i_modulo_w = lcm( i_modulo_w, 8 * desc->p[i].w.den );
66 i_modulo_h = lcm( i_modulo_h, 8 * desc->p[i].h.den );
67 if( i_ratio_h < desc->p[i].h.den )
68 i_ratio_h = desc->p[i].h.den;
69
70 }
71 i_modulo_h = lcm( i_modulo_h, 32 );
72
73 const int i_width_aligned = ( width + i_modulo_w - 1 ) / i_modulo_w * i_modulo_w;
74 const int i_height_aligned = ( height + i_modulo_h - 1 ) / i_modulo_h * i_modulo_h;
75 const int i_height_extra = 2 * i_ratio_h; /* This one is a hack for some ASM functions */
76
77 unsigned int bufferSize = 0;
78 for(unsigned i = 0; i < desc->plane_count; ++i)
79 {
80 pitches[i] = i_width_aligned * desc->p[i].w.num / desc->p[i].w.den * desc->pixel_size;
81 if (visiblePitches)
82 visiblePitches[i] = width * desc->p[i].w.num / desc->p[i].w.den * desc->pixel_size;
83
84 lines[i] = (i_height_aligned + i_height_extra ) * desc->p[i].h.num / desc->p[i].h.den;
85 if (visibleLines)
86 visibleLines[i] = height * desc->p[i].h.num / desc->p[i].h.den;
87
88 bufferSize += pitches[i] * lines[i];
89 }
90
91 return bufferSize;
92 }
93
setCallbacks(MediaPlayer * player)94 void VideoMemoryStream::setCallbacks(MediaPlayer *player)
95 {
96 libvlc_video_set_callbacks(player->libvlc_media_player(),
97 lockCallbackInternal,
98 unlockCallbackInternal,
99 displayCallbackInternal,
100 this);
101 libvlc_video_set_format_callbacks(player->libvlc_media_player(),
102 formatCallbackInternal,
103 formatCleanUpCallbackInternal);
104 }
105
unsetCallbacks(MediaPlayer * player)106 void VideoMemoryStream::unsetCallbacks(MediaPlayer *player)
107 {
108 libvlc_video_set_callbacks(player->libvlc_media_player(),
109 0,
110 0,
111 0,
112 0);
113 libvlc_video_set_format_callbacks(player->libvlc_media_player(),
114 0,
115 0);
116 }
117
118
lockCallbackInternal(void * opaque,void ** planes)119 void *VideoMemoryStream::lockCallbackInternal(void *opaque, void **planes)
120 {
121 return P_THIS->lockCallback(planes);
122 }
123
unlockCallbackInternal(void * opaque,void * picture,void * const * planes)124 void VideoMemoryStream::unlockCallbackInternal(void *opaque, void *picture, void *const*planes)
125 {
126 P_THIS->unlockCallback(picture, planes);
127 }
128
displayCallbackInternal(void * opaque,void * picture)129 void VideoMemoryStream::displayCallbackInternal(void *opaque, void *picture)
130 {
131 P_THIS->displayCallback(picture);
132 }
133
formatCallbackInternal(void ** opaque,char * chroma,unsigned * width,unsigned * height,unsigned * pitches,unsigned * lines)134 unsigned VideoMemoryStream::formatCallbackInternal(void **opaque, char *chroma,
135 unsigned *width, unsigned *height,
136 unsigned *pitches, unsigned *lines)
137 {
138 return P_THIS->formatCallback(chroma, width, height, pitches, lines);
139 }
140
formatCleanUpCallbackInternal(void * opaque)141 void VideoMemoryStream::formatCleanUpCallbackInternal(void *opaque)
142 {
143 P_THIS->formatCleanUpCallback();
144 }
145
146 } // namespace VLC
147 } // namespace Phonon
148