13 * |
13 * |
14 * Description: VideoThumbnailFetcher class implementation |
14 * Description: VideoThumbnailFetcher class implementation |
15 * |
15 * |
16 */ |
16 */ |
17 |
17 |
18 // Version : %version: % |
18 // Version : %version: 4 % |
19 |
19 |
20 // INCLUDE FILES |
20 // INCLUDE FILES |
21 #include <qpixmap.h> |
21 #include <qpixmap.h> |
22 #include <thumbnailmanager_qt.h> |
22 #include <thumbnailmanager_qt.h> |
23 |
23 |
24 #include "videothumbnailfetcher.h" |
24 #include "videothumbnailfetcher.h" |
25 #include "videocollectiontrace.h" |
25 #include "videocollectiontrace.h" |
26 |
26 |
|
27 /** |
|
28 * global qHash function required fo creating hash values for TMPXItemId -keys |
|
29 */ |
|
30 inline uint qHash(TMPXItemId key) |
|
31 { |
|
32 QPair<uint, uint> keyPair(key.iId1, key.iId2); |
|
33 |
|
34 return qHash(keyPair); |
|
35 } |
27 // ================= MEMBER FUNCTIONS ======================= |
36 // ================= MEMBER FUNCTIONS ======================= |
28 // |
37 // |
29 |
38 |
30 // ----------------------------------------------------------------------------- |
39 // ----------------------------------------------------------------------------- |
31 // VideoThumbnailFetcher::VideoThumbnailFetcher() |
40 // VideoThumbnailFetcher::VideoThumbnailFetcher() |
64 |
73 |
65 // ----------------------------------------------------------------------------- |
74 // ----------------------------------------------------------------------------- |
66 // VideoThumbnailFetcher::addFetch() |
75 // VideoThumbnailFetcher::addFetch() |
67 // ----------------------------------------------------------------------------- |
76 // ----------------------------------------------------------------------------- |
68 // |
77 // |
69 void VideoThumbnailFetcher::addFetch(const QString fileName, void *internal, int priority) |
78 void VideoThumbnailFetcher::addFetch(const QString fileName, const TMPXItemId &mediaId, int priority) |
70 { |
79 { |
71 ThumbnailFetchData *fetch = new ThumbnailFetchData; |
80 ThumbnailFetchData *fetch = new ThumbnailFetchData; |
72 fetch->mFileName = fileName; |
81 fetch->mFileName = fileName; |
73 fetch->mInternal = internal; |
82 fetch->mMediaId = mediaId; |
74 fetch->mPriority = priority; |
83 fetch->mPriority = priority; |
75 mFetchList.append(fetch); |
84 fetch->mRequestId = -1; |
|
85 mFetchList.insert(mediaId, fetch); |
76 } |
86 } |
77 |
87 |
78 // ----------------------------------------------------------------------------- |
88 // ----------------------------------------------------------------------------- |
79 // VideoThumbnailFetcher::continueFetching() |
89 // VideoThumbnailFetcher::continueFetching() |
80 // ----------------------------------------------------------------------------- |
90 // ----------------------------------------------------------------------------- |
81 // |
91 // |
82 void VideoThumbnailFetcher::continueFetching() |
92 void VideoThumbnailFetcher::continueFetching(bool cancelOngoingFetches) |
83 { |
93 { |
84 FUNC_LOG; |
94 FUNC_LOG; |
85 mPaused = false; |
95 mPaused = false; |
86 |
96 |
87 // First fetch all thumbnails that have been created already, next |
97 // First fetch all thumbnails that have been created already, next |
88 // start thumbnail creation for one thumbnail at a time. |
98 // start thumbnail creation for one thumbnail at a time. |
89 if(!mFetchList.isEmpty()) |
99 if(!mFetchList.isEmpty()) |
90 { |
100 { |
91 startThumbnailFetches(); |
101 startThumbnailFetches(cancelOngoingFetches); |
92 } |
102 } |
93 else if(!mCreationList.isEmpty()) |
103 else if(!mCreationList.isEmpty()) |
94 { |
104 { |
95 startThumbnailCreation(); |
105 startThumbnailCreation(); |
96 } |
106 } |
104 |
114 |
105 // ----------------------------------------------------------------------------- |
115 // ----------------------------------------------------------------------------- |
106 // VideoThumbnailFetcher::startThumbnailFetches() |
116 // VideoThumbnailFetcher::startThumbnailFetches() |
107 // ----------------------------------------------------------------------------- |
117 // ----------------------------------------------------------------------------- |
108 // |
118 // |
109 void VideoThumbnailFetcher::startThumbnailFetches() |
119 void VideoThumbnailFetcher::startThumbnailFetches(bool cancelOngoingFetches) |
110 { |
120 { |
111 FUNC_LOG; |
121 FUNC_LOG; |
|
122 |
112 if(!mThumbnailManager) |
123 if(!mThumbnailManager) |
113 { |
124 { |
114 return; |
125 return; |
115 } |
126 } |
116 |
127 |
117 // Only fetch those thumbnails that are already been created. |
128 // Only fetch those thumbnails that are already been created. |
118 mThumbnailManager->setMode(ThumbnailManager::DoNotCreate); |
129 mThumbnailManager->setMode(ThumbnailManager::DoNotCreate); |
119 |
130 |
120 // Push all from thumbnail manager. |
131 // Cancel ongoing fetches, but only those that are not in the list of new fetches. |
121 while(!mFetchList.isEmpty()) |
132 if(cancelOngoingFetches) |
122 { |
133 { |
123 ThumbnailFetchData *fetch = mFetchList.takeFirst(); |
134 QHash<TMPXItemId, ThumbnailFetchData*>::iterator iter = mStartedFetchList.begin(); |
124 |
135 while(iter != mStartedFetchList.end()) |
125 int requestId = mThumbnailManager->getThumbnail(fetch->mFileName, |
136 { |
126 fetch->mInternal, fetch->mPriority); |
137 if(!mFetchList.contains(iter.key())) |
127 |
138 { |
128 if(requestId != -1) |
139 ThumbnailFetchData *fetch = iter.value(); |
129 { |
140 INFO_3("VideoThumbnailFetcher::startThumbnailFetches() canceling - mpx id: (%d, %d), requestId: %d", fetch->mMediaId.iId1, fetch->mMediaId.iId2, fetch->mRequestId); |
130 // Request succeed, add to list of started fetches. |
141 mThumbnailManager->cancelRequest(fetch->mRequestId); |
131 mStartedFetchList.insert(requestId, fetch); |
142 iter = mStartedFetchList.erase(iter); |
|
143 delete fetch; |
|
144 } |
|
145 else |
|
146 { |
|
147 iter++; |
|
148 } |
|
149 } |
|
150 } |
|
151 |
|
152 // Start fetches. |
|
153 QHash<TMPXItemId, ThumbnailFetchData*>::iterator iter = mFetchList.begin(); |
|
154 while(iter != mFetchList.end()) |
|
155 { |
|
156 ThumbnailFetchData *fetch = iter.value(); |
|
157 iter = mFetchList.erase(iter); |
|
158 |
|
159 if(!mStartedFetchList.contains(fetch->mMediaId)) |
|
160 { |
|
161 TMPXItemId *internal = new TMPXItemId(fetch->mMediaId.iId1, fetch->mMediaId.iId2); |
|
162 |
|
163 fetch->mRequestId = mThumbnailManager->getThumbnail(fetch->mFileName, |
|
164 internal, fetch->mPriority); |
|
165 INFO_3("VideoThumbnailFetcher::startThumbnailFetches() started - mpx id: (%d, %d), requestId: %d", fetch->mMediaId.iId1, fetch->mMediaId.iId2, fetch->mRequestId); |
|
166 if(fetch->mRequestId != -1) |
|
167 { |
|
168 // Request succeed, add to list of started fetches. |
|
169 mStartedFetchList.insert(fetch->mMediaId, fetch); |
|
170 } |
|
171 else |
|
172 { |
|
173 // Request failed, free data. |
|
174 delete internal; |
|
175 delete fetch; |
|
176 } |
132 } |
177 } |
133 else |
178 else |
134 { |
179 { |
135 // Request failed, free internal data. |
180 INFO_3("VideoThumbnailFetcher::startThumbnailFetches() already fetching - mpx id: (%d, %d), requestId: %d", fetch->mMediaId.iId1, fetch->mMediaId.iId2, fetch->mRequestId); |
136 delete fetch->mInternal; |
181 // Already fetching this one, fetch data not needed anymore. |
137 delete fetch; |
182 delete fetch; |
138 } |
183 } |
139 } |
184 } |
140 } |
185 } |
141 |
186 |
171 highestPriority = mCreationList.at(i)->mPriority; |
216 highestPriority = mCreationList.at(i)->mPriority; |
172 } |
217 } |
173 } |
218 } |
174 |
219 |
175 ThumbnailFetchData *fetch = mCreationList.takeAt(indexWithHighestPriority); |
220 ThumbnailFetchData *fetch = mCreationList.takeAt(indexWithHighestPriority); |
|
221 TMPXItemId *internal = new TMPXItemId(fetch->mMediaId.iId1, fetch->mMediaId.iId2); |
176 |
222 |
177 // Do request to thumbnail manager. |
223 // Do request to thumbnail manager. |
178 int requestId = mThumbnailManager->getThumbnail(fetch->mFileName, |
224 int requestId = mThumbnailManager->getThumbnail(fetch->mFileName, |
179 fetch->mInternal, fetch->mPriority); |
225 internal, fetch->mPriority); |
180 |
226 INFO_3("VideoThumbnailFetcher::startThumbnailCreation() started - mpx id: (%d, %d), requestId: %d", fetch->mMediaId.iId1, fetch->mMediaId.iId2, requestId); |
181 // Request failed, free internal data. |
227 |
|
228 // Request failed, free data. |
182 if(requestId == -1) |
229 if(requestId == -1) |
183 { |
230 { |
184 delete fetch->mInternal; |
231 delete internal; |
|
232 } |
|
233 // No need for the fetch data anymore when creating thumbnails. |
|
234 delete fetch; |
|
235 } |
|
236 |
|
237 // ----------------------------------------------------------------------------- |
|
238 // VideoThumbnailFetcher::pauseFetching() |
|
239 // ----------------------------------------------------------------------------- |
|
240 // |
|
241 void VideoThumbnailFetcher::pauseFetching() |
|
242 { |
|
243 FUNC_LOG; |
|
244 mPaused = true; |
|
245 } |
|
246 |
|
247 // ----------------------------------------------------------------------------- |
|
248 // VideoThumbnailFetcher::cancelFetches() |
|
249 // ----------------------------------------------------------------------------- |
|
250 // |
|
251 void VideoThumbnailFetcher::cancelFetches() |
|
252 { |
|
253 FUNC_LOG; |
|
254 |
|
255 QHash<TMPXItemId, ThumbnailFetchData*>::const_iterator iter = mStartedFetchList.constBegin(); |
|
256 while(iter != mStartedFetchList.constEnd()) |
|
257 { |
|
258 mThumbnailManager->cancelRequest(iter.value()->mRequestId); |
|
259 delete *iter; |
|
260 iter++; |
|
261 } |
|
262 mStartedFetchList.clear(); |
|
263 |
|
264 iter = mFetchList.constBegin(); |
|
265 while(iter != mFetchList.constEnd()) |
|
266 { |
|
267 delete *iter; |
|
268 iter++; |
|
269 } |
|
270 mFetchList.clear(); |
|
271 |
|
272 while(!mCreationList.isEmpty()) |
|
273 { |
|
274 ThumbnailFetchData *fetch = mCreationList.takeFirst(); |
185 delete fetch; |
275 delete fetch; |
186 } |
276 } |
187 else |
|
188 { |
|
189 // Don't keep track of fetches when creating thumbnails, if |
|
190 // it fails with -1 it would be only tried to create again. |
|
191 delete fetch; |
|
192 } |
|
193 } |
|
194 |
|
195 // ----------------------------------------------------------------------------- |
|
196 // VideoThumbnailFetcher::pauseFetching() |
|
197 // ----------------------------------------------------------------------------- |
|
198 // |
|
199 void VideoThumbnailFetcher::pauseFetching() |
|
200 { |
|
201 FUNC_LOG; |
|
202 mPaused = true; |
|
203 } |
|
204 |
|
205 // ----------------------------------------------------------------------------- |
|
206 // VideoThumbnailFetcher::cancelFetches() |
|
207 // ----------------------------------------------------------------------------- |
|
208 // |
|
209 void VideoThumbnailFetcher::cancelFetches() |
|
210 { |
|
211 FUNC_LOG; |
|
212 // Clear list of started fetches, thumbnail manager has the internal |
|
213 // pointer. |
|
214 QList<int> keys = mStartedFetchList.keys(); |
|
215 for(int i = 0; i < keys.count(); i++ ) |
|
216 { |
|
217 delete mStartedFetchList.take(keys[i]); |
|
218 } |
|
219 |
|
220 // Merge lists and free data. |
|
221 mFetchList.append(mCreationList); |
|
222 mCreationList.clear(); |
|
223 while(!mFetchList.isEmpty()) |
|
224 { |
|
225 ThumbnailFetchData *fetch = mFetchList.takeFirst(); |
|
226 delete fetch->mInternal; |
|
227 delete fetch; |
|
228 } |
|
229 } |
277 } |
230 |
278 |
231 // ----------------------------------------------------------------------------- |
279 // ----------------------------------------------------------------------------- |
232 // VideoThumbnailFetcher::fetchCount() |
280 // VideoThumbnailFetcher::fetchCount() |
233 // ----------------------------------------------------------------------------- |
281 // ----------------------------------------------------------------------------- |
251 // VideoThumbnailFetcher::thumbnailReadySlot() |
299 // VideoThumbnailFetcher::thumbnailReadySlot() |
252 // ----------------------------------------------------------------------------- |
300 // ----------------------------------------------------------------------------- |
253 // |
301 // |
254 void VideoThumbnailFetcher::thumbnailReadySlot(QPixmap tnData, void *internal, int requestId, int error) |
302 void VideoThumbnailFetcher::thumbnailReadySlot(QPixmap tnData, void *internal, int requestId, int error) |
255 { |
303 { |
|
304 INFO_2("VideoThumbnailFetcher::thumbnailReadySlot() requestId: %d, error: %d", requestId, error); |
|
305 |
|
306 TMPXItemId mediaId = TMPXItemId::InvalidId(); |
|
307 if(internal) |
|
308 { |
|
309 mediaId = *(static_cast<TMPXItemId*>(internal)); |
|
310 } |
|
311 delete internal; |
|
312 |
256 // Thumbnail has not been generated yet, put it into creation list. |
313 // Thumbnail has not been generated yet, put it into creation list. |
257 if(error == -1 && internal) |
314 if(error == -1) |
258 { |
315 { |
259 if(mStartedFetchList.contains(requestId)) |
316 if(mStartedFetchList.contains(mediaId)) |
260 { |
317 { |
261 ThumbnailFetchData *fetch = mStartedFetchList.take(requestId); |
318 ThumbnailFetchData *fetch = mStartedFetchList.take(mediaId); |
262 mCreationList.append(fetch); |
319 mCreationList.append(fetch); |
263 } |
320 } |
264 else |
321 // If it's not found from started list then cancelFetches has been called and |
265 { |
322 // there's nothing to do with the failed fetch. |
266 // Fetch data was not found, meaning cancelFetches was called. |
|
267 delete internal; |
|
268 } |
|
269 } |
323 } |
270 else |
324 else |
271 { |
325 { |
272 // Report that thumbnail was fetched. |
326 // Report that thumbnail was fetched, internal data pointer ownership moves. |
273 emit thumbnailReady(tnData, internal, error); |
327 emit thumbnailReady(tnData, mediaId, error); |
274 |
328 if(mStartedFetchList.contains(mediaId)) |
275 if(mStartedFetchList.contains(requestId)) |
329 { |
276 { |
330 delete mStartedFetchList.take(mediaId); |
277 delete mStartedFetchList.take(requestId); |
|
278 } |
331 } |
279 } |
332 } |
280 |
333 |
281 // Continue the fetching process. |
334 // Continue the fetching process. |
282 if(!mPaused && mStartedFetchList.isEmpty()) |
335 if(!mPaused && mStartedFetchList.isEmpty()) |
283 { |
336 { |
284 continueFetching(); |
337 continueFetching(false); // No need to cancel fetches because there's none. |
285 } |
338 } |
286 } |
339 } |
287 |
340 |
288 // End of file. |
341 // End of file. |