1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 Research In Motion
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 #include "mmrenderermetadata.h"
40 
41 #include <QtCore/qdebug.h>
42 #include <QtCore/qfile.h>
43 #include <QtCore/qstringlist.h>
44 
45 #include <mm/renderer/events.h>
46 #include <sys/neutrino.h>
47 #include <sys/strm.h>
48 
strm_string_getx(const strm_string_t * sstr,const char * defaultValue)49 static const char *strm_string_getx(const strm_string_t *sstr, const char *defaultValue)
50 {
51     return sstr ? strm_string_get(sstr) : defaultValue;
52 }
53 
54 #if _NTO_VERSION < 700
mmr_metadata_split(strm_dict_t const *,const char *,unsigned)55 static strm_dict_t *mmr_metadata_split(strm_dict_t const *, const char *, unsigned)
56 {
57     return nullptr;
58 }
59 #endif
60 
61 QT_BEGIN_NAMESPACE
62 
MmRendererMetaData()63 MmRendererMetaData::MmRendererMetaData()
64 {
65     clear();
66 }
67 
68 static const char * titleKey = "md_title_name";
69 static const char * artistKey = "md_title_artist";
70 static const char * commentKey = "md_title_comment";
71 static const char * genreKey = "md_title_genre";
72 static const char * yearKey = "md_title_year";
73 static const char * durationKey = "md_title_duration";
74 static const char * bitRateKey = "md_title_bitrate";
75 static const char * sampleKey = "md_title_samplerate";
76 static const char * albumKey = "md_title_album";
77 static const char * trackKey = "md_title_track";
78 static const char * widthKey = "md_video_width";
79 static const char * heightKey = "md_video_height";
80 static const char * mediaTypeKey = "md_title_mediatype";
81 static const char * pixelWidthKey = "md_video_pixel_width";
82 static const char * pixelHeightKey = "md_video_pixel_height";
83 static const char * seekableKey = "md_title_seekable";
84 static const char * trackSampleKey = "sample_rate";
85 static const char * trackBitRateKey = "bitrate";
86 static const char * trackWidthKey = "width";
87 static const char * trackHeightKey = "height";
88 static const char * trackPixelWidthKey = "pixel_width";
89 static const char * trackPixelHeightKey = "pixel_height";
90 
91 static const int mediaTypeAudioFlag = 4;
92 static const int mediaTypeVideoFlag = 2;
93 
update(const strm_dict_t * dict)94 bool MmRendererMetaData::update(const strm_dict_t *dict)
95 {
96     if (!dict) {
97         clear();
98         return true;
99     }
100 
101     const strm_string_t *value;
102 
103     value = strm_dict_find_rstr(dict, durationKey);
104     m_duration = QByteArray(strm_string_getx(value, "0")).toLongLong();
105 
106     value = strm_dict_find_rstr(dict, mediaTypeKey);
107     m_mediaType = QByteArray(strm_string_getx(value, "-1")).toInt();
108 
109     value = strm_dict_find_rstr(dict, titleKey);
110     m_title = QString::fromLatin1(QByteArray(strm_string_getx(value, nullptr)));
111 
112     value = strm_dict_find_rstr(dict, seekableKey);
113     m_seekable = (strcmp(strm_string_getx(value, "1"), "0") != 0);
114 
115     value = strm_dict_find_rstr(dict, artistKey);
116     m_artist = QString::fromLatin1(QByteArray(strm_string_getx(value, nullptr)));
117 
118     value = strm_dict_find_rstr(dict, commentKey);
119     m_comment = QString::fromLatin1(QByteArray(strm_string_getx(value, nullptr)));
120 
121     value = strm_dict_find_rstr(dict, genreKey);
122     m_genre = QString::fromLatin1(QByteArray(strm_string_getx(value, nullptr)));
123 
124     value = strm_dict_find_rstr(dict, yearKey);
125     m_year = QByteArray(strm_string_getx(value, "0")).toInt();
126 
127     value = strm_dict_find_rstr(dict, albumKey);
128     m_album = QString::fromLatin1(QByteArray(strm_string_getx(value, nullptr)));
129 
130     value = strm_dict_find_rstr(dict, trackKey);
131     m_track = QByteArray(strm_string_getx(value, "0")).toInt();
132 
133     strm_dict_t *at = mmr_metadata_split(dict, "audio", 0);
134     if (at) {
135         value = strm_dict_find_rstr(at, trackSampleKey);
136         m_sampleRate = QByteArray(strm_string_getx(value, "0")).toInt();
137 
138         value = strm_dict_find_rstr(at, trackBitRateKey);
139         m_audioBitRate = QByteArray(strm_string_getx(value, "0")).toInt();
140 
141         strm_dict_destroy(at);
142     } else {
143         value = strm_dict_find_rstr(dict, sampleKey);
144         m_sampleRate = QByteArray(strm_string_getx(value, "0")).toInt();
145 
146         value = strm_dict_find_rstr(dict, bitRateKey);
147         m_audioBitRate = QByteArray(strm_string_getx(value, "0")).toInt();
148     }
149 
150     strm_dict_t *vt = mmr_metadata_split(dict, "video", 0);
151     if (vt) {
152         value = strm_dict_find_rstr(vt, trackWidthKey);
153         m_width = QByteArray(strm_string_getx(value, "0")).toInt();
154 
155         value = strm_dict_find_rstr(vt, trackHeightKey);
156         m_height = QByteArray(strm_string_getx(value, "0")).toInt();
157 
158         value = strm_dict_find_rstr(vt, trackPixelWidthKey);
159         m_pixelWidth = QByteArray(strm_string_getx(value, "1")).toFloat();
160 
161         value = strm_dict_find_rstr(vt, trackPixelHeightKey);
162         m_pixelHeight = QByteArray(strm_string_getx(value, "1")).toFloat();
163 
164         strm_dict_destroy(vt);
165     } else {
166         value = strm_dict_find_rstr(dict, widthKey);
167         m_width = QByteArray(strm_string_getx(value, "0")).toInt();
168 
169         value = strm_dict_find_rstr(dict, heightKey);
170         m_height = QByteArray(strm_string_getx(value, "0")).toInt();
171 
172         value = strm_dict_find_rstr(dict, pixelWidthKey);
173         m_pixelWidth = QByteArray(strm_string_getx(value, "1")).toFloat();
174 
175         value = strm_dict_find_rstr(dict, pixelHeightKey);
176         m_pixelHeight = QByteArray(strm_string_getx(value, "1")).toFloat();
177     }
178 
179     return true;
180 }
181 
clear()182 void MmRendererMetaData::clear()
183 {
184     strm_dict_t *dict;
185     dict = strm_dict_new();
186     update(dict);
187     strm_dict_destroy(dict);
188 }
189 
duration() const190 qlonglong MmRendererMetaData::duration() const
191 {
192     return m_duration;
193 }
194 
195 // Handling of pixel aspect ratio
196 //
197 // If the pixel aspect ratio is different from 1:1, it means the video needs to be stretched in
198 // order to look natural.
199 // For example, if the pixel width is 2, and the pixel height is 1, it means a video of 300x200
200 // pixels needs to be displayed as 600x200 to look correct.
201 // In order to support this the easiest way, we simply pretend that the actual size of the video
202 // is 600x200, which will cause the video to be displayed in an aspect ratio of 3:1 instead of 3:2,
203 // and therefore look correct.
204 
height() const205 int MmRendererMetaData::height() const
206 {
207     return m_height * m_pixelHeight;
208 }
209 
width() const210 int MmRendererMetaData::width() const
211 {
212     return m_width * m_pixelWidth;
213 }
214 
hasVideo() const215 bool MmRendererMetaData::hasVideo() const
216 {
217     // By default, assume no video if we can't extract the information
218     if (m_mediaType == -1)
219         return false;
220 
221     return (m_mediaType & mediaTypeVideoFlag);
222 }
223 
hasAudio() const224 bool MmRendererMetaData::hasAudio() const
225 {
226     // By default, assume audio only if we can't extract the information
227     if (m_mediaType == -1)
228         return true;
229 
230     return (m_mediaType & mediaTypeAudioFlag);
231 }
232 
title() const233 QString MmRendererMetaData::title() const
234 {
235     return m_title;
236 }
237 
isSeekable() const238 bool MmRendererMetaData::isSeekable() const
239 {
240     return m_seekable;
241 }
242 
artist() const243 QString MmRendererMetaData::artist() const
244 {
245     return m_artist;
246 }
247 
comment() const248 QString MmRendererMetaData::comment() const
249 {
250     return m_comment;
251 }
252 
genre() const253 QString MmRendererMetaData::genre() const
254 {
255     return m_genre;
256 }
257 
year() const258 int MmRendererMetaData::year() const
259 {
260     return m_year;
261 }
262 
mediaType() const263 QString MmRendererMetaData::mediaType() const
264 {
265     if (hasVideo())
266         return QLatin1String("video");
267     else if (hasAudio())
268         return QLatin1String("audio");
269     else
270         return QString();
271 }
272 
audioBitRate() const273 int MmRendererMetaData::audioBitRate() const
274 {
275     return m_audioBitRate;
276 }
277 
sampleRate() const278 int MmRendererMetaData::sampleRate() const
279 {
280     return m_sampleRate;
281 }
282 
album() const283 QString MmRendererMetaData::album() const
284 {
285     return m_album;
286 }
287 
track() const288 int MmRendererMetaData::track() const
289 {
290     return m_track;
291 }
292 
resolution() const293 QSize MmRendererMetaData::resolution() const
294 {
295     return QSize(width(), height());
296 }
297 
298 QT_END_NAMESPACE
299