|
1 /* |
|
2 * Copyright (c) 2004 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 - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: This class implements an 3GPExt metadata parser |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 // INCLUDE FILES |
|
21 #include "MetaDataParser3GPExt.h" |
|
22 #include "3GPExtParser.h" |
|
23 #ifdef _DEBUG |
|
24 #include <e32svr.h> |
|
25 #endif |
|
26 |
|
27 // ============================ MEMBER FUNCTIONS =============================== |
|
28 |
|
29 // ----------------------------------------------------------------------------- |
|
30 // CMetaDataParser3GPExt::CMetaDataParser3GPExt |
|
31 // C++ default constructor can NOT contain any code, that |
|
32 // might leave. |
|
33 // ----------------------------------------------------------------------------- |
|
34 // |
|
35 CMetaDataParser3GPExt::CMetaDataParser3GPExt() |
|
36 { |
|
37 } |
|
38 |
|
39 // ----------------------------------------------------------------------------- |
|
40 // CMetaDataParser3GPExt::ConstructL |
|
41 // Symbian 2nd phase constructor can leave. |
|
42 // ----------------------------------------------------------------------------- |
|
43 // |
|
44 void CMetaDataParser3GPExt::ConstructL() |
|
45 { |
|
46 i3GPExtParser = C3GPExtParser::NewL(iMP4Handle); |
|
47 } |
|
48 |
|
49 // ----------------------------------------------------------------------------- |
|
50 // CMetaDataParser3GPExt::NewL |
|
51 // Two-phased constructor. |
|
52 // ----------------------------------------------------------------------------- |
|
53 // |
|
54 CMetaDataParser3GPExt* CMetaDataParser3GPExt::NewL() |
|
55 { |
|
56 #ifdef _DEBUG |
|
57 RDebug::Print(_L("CMetaDataParser3GPExt::NewL")); |
|
58 #endif |
|
59 CMetaDataParser3GPExt* self = new( ELeave ) CMetaDataParser3GPExt; |
|
60 CleanupStack::PushL( self ); |
|
61 self->ConstructL(); |
|
62 CleanupStack::Pop(); |
|
63 return self; |
|
64 } |
|
65 |
|
66 // Destructor |
|
67 CMetaDataParser3GPExt::~CMetaDataParser3GPExt() |
|
68 { |
|
69 delete i3GPExtParser; |
|
70 } |
|
71 |
|
72 // ----------------------------------------------------------------------------- |
|
73 // CMetaDataParser3GPExt::ConvertAndAppendL |
|
74 // ----------------------------------------------------------------------------- |
|
75 void CMetaDataParser3GPExt::ConvertAndAppendL( |
|
76 HBufC8** aBuf8, TMetaDataFieldId aFieldId) |
|
77 { |
|
78 CleanupStack::PushL(*aBuf8); |
|
79 if ((*aBuf8) && (*aBuf8)->Length() > 0) |
|
80 { |
|
81 TInt length = (*aBuf8)->Length(); |
|
82 HBufC* data16 = HBufC::NewLC(length); |
|
83 TPtr16 titleUnicode(data16->Des()); |
|
84 TPtrC8 title((*aBuf8)->Des()); |
|
85 if ( ConvertToUnicodeL(title, titleUnicode) == KErrNone ) |
|
86 { |
|
87 iContainer->AppendL(aFieldId, data16->Des()); |
|
88 } |
|
89 CleanupStack::PopAndDestroy(data16); // data16 |
|
90 } |
|
91 CleanupStack::PopAndDestroy(*aBuf8); // *aBuf8 |
|
92 (*aBuf8) = NULL; |
|
93 } |
|
94 |
|
95 |
|
96 // ----------------------------------------------------------------------------- |
|
97 // CMetaDataParser3GPExt::ParseL |
|
98 // ----------------------------------------------------------------------------- |
|
99 void CMetaDataParser3GPExt::ParseL( |
|
100 const RArray<TMetaDataFieldId>& aWantedFields, |
|
101 CMetaDataFieldContainer& aContainer) |
|
102 { |
|
103 |
|
104 #ifdef _DEBUG |
|
105 RDebug::Print(_L("CMetaDataParser3GPExt::ParseL")); |
|
106 #endif |
|
107 iContainer = &aContainer; |
|
108 TInt err = KErrNone; // ignore err as some entry may be extracted without exception |
|
109 HBufC* buf = NULL; |
|
110 HBufC8* buf8 = NULL; |
|
111 |
|
112 if ( aWantedFields.Count() == 0 ) |
|
113 { |
|
114 TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaTitleFormat, EMetaDataSongTitle, &buf8)); |
|
115 if (KErrNone == err) |
|
116 { |
|
117 ConvertAndAppendL(&buf8, EMetaDataSongTitle); |
|
118 } |
|
119 |
|
120 TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaArtistFormat, EMetaDataArtist, &buf8)); |
|
121 if (KErrNone == err) |
|
122 { |
|
123 ConvertAndAppendL(&buf8, EMetaDataArtist); |
|
124 } |
|
125 |
|
126 TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaComposerFormat, EMetaDataComposer, &buf8)); |
|
127 if (KErrNone == err) |
|
128 { |
|
129 ConvertAndAppendL(&buf8, EMetaDataComposer); |
|
130 } |
|
131 |
|
132 TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaAlbumFormat, EMetaDataAlbum, &buf8)); |
|
133 if (KErrNone == err) |
|
134 { |
|
135 ConvertAndAppendL(&buf8, EMetaDataAlbum); |
|
136 } |
|
137 |
|
138 TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaCommentFormat, EMetaDataComment, &buf8)); |
|
139 if (KErrNone == err) |
|
140 { |
|
141 ConvertAndAppendL(&buf8, EMetaDataComment); |
|
142 } |
|
143 |
|
144 TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaGenre, EMetaDataGenre, &buf)); |
|
145 if (KErrNone == err) |
|
146 { |
|
147 AppendL(&buf, EMetaDataGenre); |
|
148 } |
|
149 |
|
150 TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaYearFormat, EMetaDataYear, &buf)); |
|
151 if (KErrNone == err) |
|
152 { |
|
153 AppendL(&buf, EMetaDataYear); |
|
154 } |
|
155 |
|
156 TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaCustomGenreFormat, EMetaDataRating, &buf8)); |
|
157 if (KErrNone == err) |
|
158 { |
|
159 ConvertAndAppendL(&buf8, EMetaDataGenre); |
|
160 } |
|
161 |
|
162 TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaTrack, EMetaDataAlbumTrack, &buf)); |
|
163 if (KErrNone == err) |
|
164 { |
|
165 AppendL(&buf, EMetaDataAlbumTrack); |
|
166 } |
|
167 |
|
168 TRAP(err, GetDurationL(EMetaDataDuration)); |
|
169 |
|
170 TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaJpeg, EMetaDataJpeg, &buf8)); |
|
171 if (KErrNone == err) |
|
172 { |
|
173 AppendL(&buf8, EMetaDataJpeg); |
|
174 } |
|
175 } |
|
176 |
|
177 else |
|
178 { |
|
179 // Look in the wanted field array |
|
180 TInt count( aWantedFields.Count() ); |
|
181 for ( TInt i = 0; i < count; i++ ) |
|
182 { |
|
183 switch ( aWantedFields[ i ] ) |
|
184 { |
|
185 case EMetaDataSongTitle: |
|
186 TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaTitleFormat, EMetaDataSongTitle, &buf8)); |
|
187 if (KErrNone == err) |
|
188 { |
|
189 ConvertAndAppendL(&buf8, EMetaDataSongTitle); |
|
190 } |
|
191 break; |
|
192 |
|
193 case EMetaDataComment: |
|
194 TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaCommentFormat, EMetaDataComment, &buf8)); |
|
195 if (KErrNone == err) |
|
196 { |
|
197 ConvertAndAppendL(&buf8, EMetaDataComment); |
|
198 } |
|
199 break; |
|
200 |
|
201 case EMetaDataAlbumTrack: |
|
202 TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaTrack, EMetaDataAlbumTrack, &buf)); |
|
203 if (KErrNone == err) |
|
204 { |
|
205 AppendL(&buf, EMetaDataAlbumTrack); |
|
206 } |
|
207 break; |
|
208 |
|
209 case EMetaDataArtist: |
|
210 TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaArtistFormat, EMetaDataArtist, &buf8)); |
|
211 if (KErrNone == err) |
|
212 { |
|
213 ConvertAndAppendL(&buf8, EMetaDataArtist); |
|
214 } |
|
215 break; |
|
216 |
|
217 case EMetaDataComposer: |
|
218 TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaComposerFormat, EMetaDataComposer, &buf8)); |
|
219 if (KErrNone == err) |
|
220 { |
|
221 ConvertAndAppendL(&buf8, EMetaDataComposer); |
|
222 } |
|
223 break; |
|
224 |
|
225 case EMetaDataAlbum: |
|
226 TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaAlbumFormat, EMetaDataAlbum, &buf8)); |
|
227 if (KErrNone == err) |
|
228 { |
|
229 ConvertAndAppendL(&buf8, EMetaDataAlbum); |
|
230 } |
|
231 break; |
|
232 |
|
233 case EMetaDataGenre: |
|
234 TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaGenre, EMetaDataGenre, &buf)); |
|
235 if (KErrNone == err) |
|
236 { |
|
237 AppendL(&buf, EMetaDataGenre); |
|
238 } |
|
239 break; |
|
240 |
|
241 case EMetaDataDuration: |
|
242 TRAP(err, GetDurationL(EMetaDataDuration)); |
|
243 break; |
|
244 |
|
245 case EMetaDataYear: |
|
246 TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaYearFormat, EMetaDataYear, &buf)); |
|
247 if (KErrNone == err) |
|
248 { |
|
249 AppendL(&buf, EMetaDataYear); |
|
250 } |
|
251 break; |
|
252 |
|
253 case EMetaDataRating: |
|
254 TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaCustomGenreFormat, EMetaDataRating, &buf8)); |
|
255 if (KErrNone == err) |
|
256 { |
|
257 ConvertAndAppendL(&buf8, EMetaDataGenre); |
|
258 } |
|
259 break; |
|
260 |
|
261 case EMetaDataJpeg: |
|
262 TRAP(err, i3GPExtParser->GetilstBoxesL(K3GPExtMetaJpeg, EMetaDataJpeg, &buf8)); |
|
263 if (KErrNone == err) |
|
264 { |
|
265 AppendL(&buf8, EMetaDataJpeg); |
|
266 } |
|
267 break; |
|
268 |
|
269 default: |
|
270 break; |
|
271 } |
|
272 } |
|
273 } |
|
274 |
|
275 } |
|
276 |
|
277 // ----------------------------------------------------------------------------- |
|
278 // CMetaDataParser3GPExt::ValidateL |
|
279 // ----------------------------------------------------------------------------- |
|
280 // |
|
281 TBool CMetaDataParser3GPExt::ValidateL() |
|
282 { |
|
283 #ifdef _DEBUG |
|
284 RDebug::Print(_L("CMetaDataParser3GPExt::ValidateL")); |
|
285 #endif |
|
286 mp4_u32 audioLength, audioType, timeScale, averateBitRate; |
|
287 mp4_u8 framesPerSample; |
|
288 |
|
289 MP4Err err; |
|
290 err = MP4ParseRequestAudioDescription(iMP4Handle, &audioLength, &audioType, |
|
291 &framesPerSample, &timeScale, &averateBitRate); |
|
292 if ( err == MP4_OK && i3GPExtParser->Is3GPExtMetadataL()) |
|
293 { |
|
294 iExists = ETrue; |
|
295 return ETrue; |
|
296 } |
|
297 |
|
298 return EFalse; |
|
299 } |
|
300 |
|
301 // ----------------------------------------------------------------------------- |
|
302 // CMetaDataParser3GPExt::AppendL |
|
303 // ----------------------------------------------------------------------------- |
|
304 // |
|
305 void CMetaDataParser3GPExt::AppendL(HBufC** aBuf, TMetaDataFieldId aFieldId) |
|
306 { |
|
307 CleanupStack::PushL(*aBuf); |
|
308 if((*aBuf) && (*aBuf)->Length() > 0) |
|
309 { |
|
310 iContainer->AppendL(aFieldId, (*aBuf)->Des()); // copy to container |
|
311 } |
|
312 CleanupStack::PopAndDestroy(); // *aBuf |
|
313 (*aBuf) = NULL; |
|
314 } |
|
315 |
|
316 // ----------------------------------------------------------------------------- |
|
317 // CMetaDataParser3GPExt::AppendL |
|
318 // ----------------------------------------------------------------------------- |
|
319 // |
|
320 void CMetaDataParser3GPExt::AppendL(HBufC8** aBuf, TMetaDataFieldId aFieldId) |
|
321 { |
|
322 CleanupStack::PushL(*aBuf); |
|
323 if((*aBuf) && (*aBuf)->Length() > 0) |
|
324 { |
|
325 iContainer->AppendL(aFieldId, (*aBuf)->Des()); // copy to container |
|
326 } |
|
327 CleanupStack::PopAndDestroy(); // *aBuf |
|
328 (*aBuf) = NULL; |
|
329 } |
|
330 |
|
331 |
|
332 // ----------------------------------------------------------------------------- |
|
333 // CMetaDataParser3GPExt::ConvertToUnicodeL |
|
334 // ----------------------------------------------------------------------------- |
|
335 // |
|
336 TInt CMetaDataParser3GPExt::ConvertToUnicodeL(const TDesC8& aDesc, TDes16& aUnicode ) |
|
337 { |
|
338 TPtrC8 unicodeData; |
|
339 TUint characterSetId = 0; |
|
340 CCnvCharacterSetConverter* charSetConv = CCnvCharacterSetConverter::NewLC(); |
|
341 TInt state = CCnvCharacterSetConverter::KStateDefault; |
|
342 |
|
343 // M4A file format has UTF-8 BigEndian characters. |
|
344 characterSetId = KCharacterSetIdentifierUtf8; |
|
345 unicodeData.Set( aDesc ); |
|
346 |
|
347 charSetConv->PrepareToConvertToOrFromL(characterSetId, *iCharacterSet, iFs); |
|
348 TInt err = charSetConv->ConvertToUnicode(aUnicode, unicodeData, state); |
|
349 |
|
350 #ifdef _DEBUG |
|
351 RDebug::Print(_L("CMetaDataParserID3v24::ConvertToUnicode :-> Tag Size[%d] Unicode Tag Size[%d]Bytes Unconverted[%d]"), |
|
352 unicodeData.Length(), aUnicode.Length(), err); |
|
353 #endif |
|
354 |
|
355 CleanupStack::PopAndDestroy(); // charSetConv |
|
356 return err; |
|
357 } |
|
358 |
|
359 // End of File |