summaryrefslogtreecommitdiff
path: root/src/media.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-02-25 12:09:28 +0200
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-02-25 12:09:28 +0200
commit45049903a304a6762d5656890213c8ad5a1db3c3 (patch)
tree11335323e83e268120d69434d14298f6dadf7a2d /src/media.c
parentd8b789caf6f5c2ab6ce435f51075a4a4cc83db4b (diff)
Consolidating media handling
Diffstat (limited to 'src/media.c')
-rw-r--r--src/media.c89
1 files changed, 83 insertions, 6 deletions
diff --git a/src/media.c b/src/media.c
index 8bd635a5..65454756 100644
--- a/src/media.c
+++ b/src/media.c
@@ -37,16 +37,19 @@ iDeclareType(GmMediaProps)
37struct Impl_GmMediaProps { 37struct Impl_GmMediaProps {
38 iGmLinkId linkId; 38 iGmLinkId linkId;
39 iString mime; 39 iString mime;
40 iString url;
40 iBool isPermanent; 41 iBool isPermanent;
41}; 42};
42 43
43static void init_GmMediaProps_(iGmMediaProps *d) { 44static void init_GmMediaProps_(iGmMediaProps *d) {
44 d->linkId = 0; 45 d->linkId = 0;
45 init_String(&d->mime); 46 init_String(&d->mime);
47 init_String(&d->url);
46 d->isPermanent = iFalse; 48 d->isPermanent = iFalse;
47} 49}
48 50
49static void deinit_GmMediaProps_(iGmMediaProps *d) { 51static void deinit_GmMediaProps_(iGmMediaProps *d) {
52 deinit_String(&d->url);
50 deinit_String(&d->mime); 53 deinit_String(&d->mime);
51} 54}
52 55
@@ -125,9 +128,29 @@ iDefineTypeConstruction(GmAudio)
125 128
126/*----------------------------------------------------------------------------------------------*/ 129/*----------------------------------------------------------------------------------------------*/
127 130
131iDeclareType(GmDownload)
132
133struct Impl_GmDownload {
134 iGmMediaProps props;
135 /* TODO: Speed statistics. */
136};
137
138void init_GmDownload(iGmDownload *d) {
139 init_GmMediaProps_(&d->props);
140}
141
142void deinit_GmDownload(iGmDownload *d) {
143 deinit_GmMediaProps_(&d->props);
144}
145
146iDefineTypeConstruction(GmDownload)
147
148/*----------------------------------------------------------------------------------------------*/
149
128struct Impl_Media { 150struct Impl_Media {
129 iPtrArray images; 151 iPtrArray images;
130 iPtrArray audio; 152 iPtrArray audio;
153 iPtrArray downloads;
131}; 154};
132 155
133iDefineTypeConstruction(Media) 156iDefineTypeConstruction(Media)
@@ -135,10 +158,12 @@ iDefineTypeConstruction(Media)
135void init_Media(iMedia *d) { 158void init_Media(iMedia *d) {
136 init_PtrArray(&d->images); 159 init_PtrArray(&d->images);
137 init_PtrArray(&d->audio); 160 init_PtrArray(&d->audio);
161 init_PtrArray(&d->downloads);
138} 162}
139 163
140void deinit_Media(iMedia *d) { 164void deinit_Media(iMedia *d) {
141 clear_Media(d); 165 clear_Media(d);
166 deinit_PtrArray(&d->downloads);
142 deinit_PtrArray(&d->audio); 167 deinit_PtrArray(&d->audio);
143 deinit_PtrArray(&d->images); 168 deinit_PtrArray(&d->images);
144} 169}
@@ -152,6 +177,29 @@ void clear_Media(iMedia *d) {
152 deinit_GmAudio(a.ptr); 177 deinit_GmAudio(a.ptr);
153 } 178 }
154 clear_PtrArray(&d->audio); 179 clear_PtrArray(&d->audio);
180 iForEach(PtrArray, n, &d->downloads) {
181 deinit_GmDownload(n.ptr);
182 }
183 clear_PtrArray(&d->downloads);
184}
185
186iBool setUrl_Media(iMedia *d, iGmLinkId linkId, const iString *url) {
187 iGmDownload *dl = NULL;
188 iMediaId existing = findLinkDownload_Media(d, linkId);
189 iBool isNew = iFalse;
190 if (!existing) {
191 isNew = iTrue;
192 dl = new_GmDownload();
193 dl->props.linkId = linkId;
194 dl->props.isPermanent = iTrue;
195 set_String(&dl->props.url, url);
196 pushBack_PtrArray(&d->downloads, dl);
197 }
198 else {
199 iGmDownload *dl = at_PtrArray(&d->downloads, existing - 1);
200 set_String(&dl->props.url, url);
201 }
202 return isNew;
155} 203}
156 204
157iBool setData_Media(iMedia *d, iGmLinkId linkId, const iString *mime, const iBlock *data, 205iBool setData_Media(iMedia *d, iGmLinkId linkId, const iString *mime, const iBlock *data,
@@ -195,6 +243,18 @@ iBool setData_Media(iMedia *d, iGmLinkId linkId, const iString *mime, const iBlo
195 } 243 }
196 } 244 }
197 } 245 }
246 else if ((existing = findLinkDownload_Media(d, linkId)) != 0) {
247 iGmDownload *dl;
248 if (isDeleting) {
249 take_PtrArray(&d->downloads, existing - 1, (void **) &dl);
250 delete_GmDownload(dl);
251 }
252 else {
253 dl = at_PtrArray(&d->downloads, existing - 1);
254 iAssert(equal_String(&dl->props.mime, mime)); /* MIME cannot change */
255 /* TODO: Write data chunk to file. */
256 }
257 }
198 else if (!isDeleting) { 258 else if (!isDeleting) {
199 if (startsWith_String(mime, "image/")) { 259 if (startsWith_String(mime, "image/")) {
200 /* Copy the image to a texture. */ 260 /* Copy the image to a texture. */
@@ -253,6 +313,24 @@ iMediaId findLinkAudio_Media(const iMedia *d, iGmLinkId linkId) {
253 return 0; 313 return 0;
254} 314}
255 315
316iMediaId findLinkDownload_Media(const iMedia *d, uint16_t linkId) {
317 iConstForEach(PtrArray, i, &d->downloads) {
318 const iGmDownload *dl = i.ptr;
319 if (dl->props.linkId == linkId) {
320 return index_PtrArrayConstIterator(&i) + 1;
321 }
322 }
323 return 0;
324}
325
326iInt2 imageSize_Media(const iMedia *d, iMediaId imageId) {
327 if (imageId > 0 && imageId <= size_PtrArray(&d->images)) {
328 const iGmImage *img = constAt_PtrArray(&d->images, imageId - 1);
329 return img->size;
330 }
331 return zero_I2();
332}
333
256SDL_Texture *imageTexture_Media(const iMedia *d, uint16_t imageId) { 334SDL_Texture *imageTexture_Media(const iMedia *d, uint16_t imageId) {
257 if (imageId > 0 && imageId <= size_PtrArray(&d->images)) { 335 if (imageId > 0 && imageId <= size_PtrArray(&d->images)) {
258 const iGmImage *img = constAt_PtrArray(&d->images, imageId - 1); 336 const iGmImage *img = constAt_PtrArray(&d->images, imageId - 1);
@@ -261,12 +339,11 @@ SDL_Texture *imageTexture_Media(const iMedia *d, uint16_t imageId) {
261 return NULL; 339 return NULL;
262} 340}
263 341
264iBool imageInfo_Media(const iMedia *d, iMediaId imageId, iGmImageInfo *info_out) { 342iBool imageInfo_Media(const iMedia *d, iMediaId imageId, iGmMediaInfo *info_out) {
265 if (imageId > 0 && imageId <= size_PtrArray(&d->images)) { 343 if (imageId > 0 && imageId <= size_PtrArray(&d->images)) {
266 const iGmImage *img = constAt_PtrArray(&d->images, imageId - 1); 344 const iGmImage *img = constAt_PtrArray(&d->images, imageId - 1);
267 info_out->size = img->size;
268 info_out->numBytes = img->numBytes; 345 info_out->numBytes = img->numBytes;
269 info_out->mime = cstr_String(&img->props.mime); 346 info_out->type = cstr_String(&img->props.mime);
270 info_out->isPermanent = img->props.isPermanent; 347 info_out->isPermanent = img->props.isPermanent;
271 return iTrue; 348 return iTrue;
272 } 349 }
@@ -282,10 +359,10 @@ iPlayer *audioData_Media(const iMedia *d, iMediaId audioId) {
282 return NULL; 359 return NULL;
283} 360}
284 361
285iBool audioInfo_Media(const iMedia *d, iMediaId audioId, iGmAudioInfo *info_out) { 362iBool audioInfo_Media(const iMedia *d, iMediaId audioId, iGmMediaInfo *info_out) {
286 if (audioId > 0 && audioId <= size_PtrArray(&d->audio)) { 363 if (audioId > 0 && audioId <= size_PtrArray(&d->audio)) {
287 const iGmAudio *audio = constAt_PtrArray(&d->audio, audioId - 1); 364 const iGmAudio *audio = constAt_PtrArray(&d->audio, audioId - 1);
288 info_out->mime = cstr_String(&audio->props.mime); 365 info_out->type = cstr_String(&audio->props.mime);
289 info_out->isPermanent = audio->props.isPermanent; 366 info_out->isPermanent = audio->props.isPermanent;
290 return iTrue; 367 return iTrue;
291 } 368 }