|
1 /* |
|
2 * Copyright (c) 2009, Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation and/or its subsidiary(-ies). |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * |
|
15 * Description: |
|
16 * Implementation file for CxeQualityPresetsSymbian class |
|
17 * |
|
18 */ |
|
19 |
|
20 #include <e32std.h> // For Symbian types used in mmsenginedomaincrkeys.h |
|
21 #include <mmsenginedomaincrkeys.h> |
|
22 |
|
23 #include "cxutils.h" |
|
24 #include "cxenamespace.h" |
|
25 #include "cxesettings.h" |
|
26 #include "cxequalitydetails.h" |
|
27 #include "cxequalitypresetssymbian.h" |
|
28 |
|
29 |
|
30 // constants |
|
31 namespace |
|
32 { |
|
33 // Display IDs for cameras, used when requesting data from ICM |
|
34 const int PRIMARY_CAMERA_DISPLAY_ID = 2; |
|
35 const int SECONDARY_CAMERA_DISPLAY_ID = 3; |
|
36 |
|
37 const int ONE_MILLION = 1000000; |
|
38 const qreal ASPECT_16_BY_9 = (16/9.0); |
|
39 const qreal DELTA_ERROR = 0.20; |
|
40 |
|
41 // ICM "camcorderVisible" parameter value below this means sharing aka mms quality. |
|
42 const int MMS_QUALITY_CAMCORDERVISIBLE_LIMIT = 200; |
|
43 } |
|
44 |
|
45 |
|
46 /* ! |
|
47 * Intializes ImagingConfigManager |
|
48 */ |
|
49 CxeQualityPresetsSymbian::CxeQualityPresetsSymbian(CxeSettings &settings) |
|
50 : mSettings(settings) |
|
51 { |
|
52 CX_DEBUG_ENTER_FUNCTION(); |
|
53 |
|
54 TRAPD(err, mIcm = CImagingConfigManager::NewL()); |
|
55 |
|
56 if (err) { |
|
57 CX_DEBUG(("Error during ICM initialization error code = %d", err)); |
|
58 mIcm = NULL; |
|
59 } |
|
60 |
|
61 CX_DEBUG_EXIT_FUNCTION(); |
|
62 |
|
63 } |
|
64 |
|
65 /* ! |
|
66 * CxeQualityPresetsSymbian::~CxeQualityPresetsSymbian() |
|
67 */ |
|
68 CxeQualityPresetsSymbian::~CxeQualityPresetsSymbian() |
|
69 { |
|
70 CX_DEBUG_ENTER_FUNCTION(); |
|
71 |
|
72 delete mIcm; |
|
73 |
|
74 CX_DEBUG_EXIT_FUNCTION(); |
|
75 } |
|
76 |
|
77 /*! |
|
78 This function returns sorted list of image qualities from highest to lowest resolution. |
|
79 i.e. first element in the list represent highest supported image resolution and so on. |
|
80 @param cameraId The CameraIndex which defines which camera we are using primary/secondary. |
|
81 Returns sorted list of image qualities in descending order. |
|
82 */ |
|
83 QList<CxeImageDetails> CxeQualityPresetsSymbian::imageQualityPresets(Cxe::CameraIndex cameraId) |
|
84 { |
|
85 CX_DEBUG_ENTER_FUNCTION(); |
|
86 |
|
87 QList<CxeImageDetails> presetList; |
|
88 |
|
89 if (!mIcm) { |
|
90 CX_DEBUG(("ICM not initialized, returning empty image qualities list")); |
|
91 return presetList; |
|
92 } |
|
93 int totalLevels = mIcm->NumberOfImageQualityLevels(); |
|
94 |
|
95 CX_DEBUG(("Total image quality levels = %d", totalLevels)); |
|
96 CArrayFixFlat<TUint>* levels= new CArrayFixFlat<TUint>(totalLevels); |
|
97 |
|
98 // Get camera display id based on camera index |
|
99 int displayId = cameraId == Cxe::SecondaryCameraIndex |
|
100 ? SECONDARY_CAMERA_DISPLAY_ID : PRIMARY_CAMERA_DISPLAY_ID; |
|
101 |
|
102 TRAPD(err, mIcm->GetImageQualityLevelsL(*levels, displayId)); |
|
103 |
|
104 if (err == KErrNone) { |
|
105 CX_DEBUG(( "Reading image quality sets one by one.")); |
|
106 TImageQualitySet set; |
|
107 int numLevels = levels->Count(); |
|
108 for(int i = 0; i < numLevels; i++) { |
|
109 mIcm->GetImageQualitySet(set, levels->At(i), displayId); |
|
110 if (set.iCamcorderVisible > 0) { |
|
111 // create new quality preset based on the quality set values |
|
112 CxeImageDetails newPreset = createImagePreset(set); |
|
113 |
|
114 // print debug prints |
|
115 debugPrints(newPreset); |
|
116 |
|
117 // append to the list of presets |
|
118 presetList.append(newPreset); |
|
119 } |
|
120 } |
|
121 CX_DEBUG(( "Sorting image qualities")); |
|
122 // Sorting result list according to height pixel size from highest to lowest |
|
123 // i.e. descending order keeping the highest resolution first. |
|
124 qSort(presetList.begin(), presetList.end(), qGreater<CxeImageDetails>()); |
|
125 } |
|
126 |
|
127 delete levels; |
|
128 levels = NULL; |
|
129 |
|
130 CX_DEBUG_EXIT_FUNCTION(); |
|
131 return presetList; |
|
132 } |
|
133 |
|
134 |
|
135 |
|
136 /*! |
|
137 This function returns sorted list of video qualities from highest to lowest resolution. |
|
138 i.e. first element in the list represent highest supported video resolution and so on. |
|
139 @param cameraId The CameraIndex which defines which camera we are using primary/secondary. |
|
140 Returns sorted list if image qualities in descending order. |
|
141 */ |
|
142 QList<CxeVideoDetails> CxeQualityPresetsSymbian::videoQualityPresets(Cxe::CameraIndex cameraId) |
|
143 { |
|
144 CX_DEBUG_ENTER_FUNCTION(); |
|
145 |
|
146 QList<CxeVideoDetails> presetList; |
|
147 |
|
148 if (!mIcm) { |
|
149 CX_DEBUG(("ICM not initialized, returning empty video qualities list")); |
|
150 return presetList; |
|
151 } |
|
152 int totalLevels = mIcm->NumberOfVideoQualityLevels(); |
|
153 |
|
154 CX_DEBUG(("Total video quality levels = %d", totalLevels)); |
|
155 CArrayFixFlat<TUint>* levels= new CArrayFixFlat<TUint>(totalLevels); |
|
156 |
|
157 int displayId = cameraId == Cxe::SecondaryCameraIndex |
|
158 ? SECONDARY_CAMERA_DISPLAY_ID : PRIMARY_CAMERA_DISPLAY_ID; |
|
159 |
|
160 TRAPD(err, mIcm->GetVideoQualityLevelsL(*levels, displayId)); |
|
161 |
|
162 if (err == KErrNone) { |
|
163 CX_DEBUG(( "Reading video quality sets one by one.")); |
|
164 TVideoQualitySet set; |
|
165 int numLevels = levels->Count(); |
|
166 for(int i = 0; i < numLevels; i++) { |
|
167 mIcm->GetVideoQualitySet(set, levels->At(i), displayId); |
|
168 |
|
169 // Disable all video sizes larger than VGA |
|
170 if (set.iCamcorderVisible > 0 && set.iVideoWidth <= 864) { |
|
171 // create new quality preset |
|
172 CxeVideoDetails newPreset = createVideoPreset(set); |
|
173 |
|
174 // print debug prints |
|
175 debugPrints(newPreset); |
|
176 |
|
177 // append to the list of presets |
|
178 presetList.append(newPreset); |
|
179 } |
|
180 } |
|
181 CX_DEBUG(( "Sorting image qualities")); |
|
182 // Sorting result list according to height pixel size from highest to lowest |
|
183 // i.e. descending order keeping the highest resolution first. |
|
184 qSort(presetList.begin(), presetList.end(), qGreater<CxeVideoDetails>()); |
|
185 } |
|
186 |
|
187 delete levels; |
|
188 levels = NULL; |
|
189 |
|
190 // Get the average video bitrate scaler |
|
191 TCamcorderMMFPluginSettings mmfPluginSettings; |
|
192 mIcm->GetCamcorderMMFPluginSettings(mmfPluginSettings); |
|
193 mCMRAvgVideoBitRateScaler = mmfPluginSettings.iCMRAvgVideoBitRateScaler; |
|
194 |
|
195 CX_DEBUG_EXIT_FUNCTION(); |
|
196 return presetList; |
|
197 } |
|
198 |
|
199 |
|
200 |
|
201 /*! |
|
202 * Creates a new image preset based on TImageQualitySet values from ICM. |
|
203 @ param set contains the ICM configuration data |
|
204 @ returns CxeImageQuality struct |
|
205 */ |
|
206 CxeImageDetails CxeQualityPresetsSymbian::createImagePreset(TImageQualitySet set) |
|
207 { |
|
208 CxeImageDetails newPreset; |
|
209 // set setting values from quality set |
|
210 newPreset.mWidth = set.iImageWidth; |
|
211 newPreset.mHeight = set.iImageHeight; |
|
212 newPreset.mImageFileExtension = toString(set.iImageFileExtension); |
|
213 newPreset.mEstimatedSize = set.iEstimatedSize; |
|
214 newPreset.mMpxCount = calculateMegaPixelCount(set.iImageWidth, |
|
215 set.iImageHeight); |
|
216 newPreset.mAspectRatio = calculateAspectRatio(set.iImageWidth, |
|
217 set.iImageHeight); |
|
218 |
|
219 return newPreset; |
|
220 } |
|
221 |
|
222 |
|
223 |
|
224 /*! |
|
225 * Creates a new video preset based on TVideoQualitySet values from ICM. |
|
226 */ |
|
227 CxeVideoDetails CxeQualityPresetsSymbian::createVideoPreset(TVideoQualitySet set) |
|
228 { |
|
229 CxeVideoDetails newPreset; |
|
230 // set setting values from quality set |
|
231 newPreset.mWidth = set.iVideoWidth; |
|
232 newPreset.mHeight = set.iVideoHeight; |
|
233 |
|
234 // Check if this is a sharing (mms) quality, and set size limit accordingly. |
|
235 if (set.iCamcorderVisible < MMS_QUALITY_CAMCORDERVISIBLE_LIMIT) { |
|
236 QVariant size; |
|
237 mSettings.get(KCRUidMmsEngine.iUid, KMmsEngineMaximumSendSize, Cxe::Repository, size); |
|
238 CX_DEBUG(("CxeQualityPresetsSymbian - Got MMS quality size limit: %d", size.toInt())); |
|
239 newPreset.mMaximumSizeInBytes = size.toInt(); |
|
240 } else { |
|
241 // Zero means no limit. |
|
242 newPreset.mMaximumSizeInBytes = 0; |
|
243 } |
|
244 |
|
245 newPreset.mVideoBitRate = set.iVideoBitRate; |
|
246 newPreset.mAudioBitRate = set.iAudioBitRate; |
|
247 newPreset.mVideoFrameRate = set.iVideoFrameRate; |
|
248 newPreset.mVideoFileMimeType = toString(set.iVideoFileMimeType); |
|
249 newPreset.mPreferredSupplier = toString(set.iPreferredSupplier); |
|
250 newPreset.mVideoCodecMimeType = toString(set.iVideoCodecMimeType); |
|
251 newPreset.mAspectRatio = calculateAspectRatio(set.iVideoWidth, |
|
252 set.iVideoHeight); |
|
253 |
|
254 // Convert FourCC value from TFourCC to ascii string |
|
255 const int KFourCCLength = 5; // 4 characters + '\0' |
|
256 TText8 fourCCBuf[KFourCCLength]; |
|
257 TPtr8 fourCC(fourCCBuf, KFourCCLength); |
|
258 set.iAudioFourCCType.FourCC(&fourCC); |
|
259 fourCC.Append('\0'); |
|
260 |
|
261 // set audiotype |
|
262 newPreset.mAudioType = toString(fourCCBuf); |
|
263 |
|
264 return newPreset; |
|
265 } |
|
266 |
|
267 |
|
268 /*! |
|
269 * Returns Aspect ratio of the image. |
|
270 */ |
|
271 qreal CxeQualityPresetsSymbian::avgVideoBitRateScaler() |
|
272 { |
|
273 CX_DEBUG_IN_FUNCTION(); |
|
274 return mCMRAvgVideoBitRateScaler; |
|
275 } |
|
276 |
|
277 |
|
278 /*! |
|
279 @ param width - image/video quality width |
|
280 @ param height - image/video quality height |
|
281 * Returns Aspect ratio of the image/video. |
|
282 */ |
|
283 Cxe::AspectRatio CxeQualityPresetsSymbian::calculateAspectRatio(int width, int height) const |
|
284 { |
|
285 Cxe::AspectRatio aspectRatio = Cxe::AspectRatio4to3; |
|
286 |
|
287 qreal ratio = 0; |
|
288 if (height != 0) { |
|
289 ratio = (1.0 * width) / height; |
|
290 |
|
291 qreal delta16by9 = ratio - ASPECT_16_BY_9; |
|
292 if (abs(delta16by9) < DELTA_ERROR) { |
|
293 aspectRatio = Cxe::AspectRatio16to9; |
|
294 } |
|
295 } |
|
296 |
|
297 return aspectRatio; |
|
298 } |
|
299 |
|
300 |
|
301 |
|
302 /*! |
|
303 * CxeQualityPresetsSymbian::calculateMegaPixelCount |
|
304 @ param imageWidth refers to the image resolution width |
|
305 @ param imageHeight refers to the image resolution height |
|
306 @ returns megapixel count string |
|
307 */ |
|
308 QString |
|
309 CxeQualityPresetsSymbian::calculateMegaPixelCount(int imageWidth, int imageHeight) |
|
310 { |
|
311 QString mpxCountString; |
|
312 qreal size = imageWidth * imageHeight * 1.0; |
|
313 int mpxCount = (size/ONE_MILLION) * 10; |
|
314 |
|
315 if ((mpxCount % 10) == 0) { |
|
316 int value = mpxCount / 10; |
|
317 mpxCountString.setNum(value); |
|
318 } else { |
|
319 qreal value = mpxCount / 10.0; |
|
320 if ((mpxCount % 10) < 5) { |
|
321 mpxCountString.setNum(value, 'f', 1); |
|
322 } else { |
|
323 int temp = ceil(value); |
|
324 mpxCountString.setNum(temp); |
|
325 } |
|
326 } |
|
327 |
|
328 return mpxCountString; |
|
329 |
|
330 |
|
331 } |
|
332 |
|
333 |
|
334 /*! |
|
335 Operator to sort values in ascending order. |
|
336 @param s1 type of data to be sorted. |
|
337 */ |
|
338 bool CxeImageDetails::operator<(const CxeImageDetails& s1) const |
|
339 { |
|
340 return mHeight < s1.mHeight; |
|
341 } |
|
342 |
|
343 |
|
344 /*! |
|
345 Operator to sort values in ascending order. |
|
346 @param s1 type of data to be sorted. |
|
347 */ |
|
348 bool CxeVideoDetails::operator<(const CxeVideoDetails& s1) const |
|
349 { |
|
350 return mHeight < s1.mHeight; |
|
351 } |
|
352 |
|
353 |
|
354 /* |
|
355 * Converts TUint8* to QString |
|
356 */ |
|
357 QString CxeQualityPresetsSymbian::toString(const TUint8* aData) |
|
358 { |
|
359 return QString::fromLatin1((char*)aData); |
|
360 } |
|
361 |
|
362 |
|
363 |
|
364 /*! |
|
365 * Helper method to enable debug prints. |
|
366 @ param Video quality preset values are printed out for debugging |
|
367 */ |
|
368 void CxeQualityPresetsSymbian::debugPrints(CxeVideoDetails preset) |
|
369 { |
|
370 CX_DEBUG(("Video quality details")); |
|
371 CX_DEBUG(("Video resolution (%d,%d)", preset.mWidth, preset.mHeight)); |
|
372 CX_DEBUG(("Audio bitrate = %d)", preset.mAudioBitRate)); |
|
373 CX_DEBUG(("Video bitrate = %d)", preset.mVideoBitRate)); |
|
374 CX_DEBUG(("Video frame rate = %f)", preset.mVideoFrameRate)); |
|
375 CX_DEBUG(("Audio type: %s", preset.mAudioType.toAscii().data())); |
|
376 CX_DEBUG(("Video file MIME type: %s", preset.mVideoFileMimeType.toAscii().data())); |
|
377 CX_DEBUG(("Video preferred supplier: %s", preset.mPreferredSupplier.toAscii().data())); |
|
378 CX_DEBUG(("Video codec MIME type: %s", preset.mVideoCodecMimeType.toAscii().data())); |
|
379 QString aspectRatio; |
|
380 if (preset.mAspectRatio == Cxe::AspectRatio4to3) { |
|
381 aspectRatio = QString("4:3"); |
|
382 } else if (preset.mAspectRatio == Cxe::AspectRatio16to9) { |
|
383 aspectRatio = QString("16:9"); |
|
384 } |
|
385 CX_DEBUG(("Video aspect ratio: %s", aspectRatio.toAscii().data())); |
|
386 } |
|
387 |
|
388 |
|
389 /*! |
|
390 * Helper method to enable debug prints. |
|
391 @ param Image quality preset values are printed out for debugging |
|
392 */ |
|
393 void CxeQualityPresetsSymbian::debugPrints(CxeImageDetails newPreset) |
|
394 { |
|
395 CX_DEBUG(("Image quality details")); |
|
396 CX_DEBUG(("Image resolution (%d,%d)", newPreset.mWidth, newPreset.mHeight)); |
|
397 CX_DEBUG(("Estimated size in bytes = %d)", newPreset.mEstimatedSize)); |
|
398 CX_DEBUG(("Megapixels: %s", newPreset.mMpxCount.toAscii().data())); |
|
399 CX_DEBUG(("Image file extension: %s", newPreset.mImageFileExtension.toAscii().data())); |
|
400 |
|
401 QString aspectRatio; |
|
402 |
|
403 if (newPreset.mAspectRatio == Cxe::AspectRatio4to3) { |
|
404 aspectRatio = QString("4:3"); |
|
405 } else { |
|
406 aspectRatio = QString("16:9"); |
|
407 } |
|
408 CX_DEBUG(("Image aspect ratio: %s", aspectRatio.toAscii().data())); |
|
409 } |