FFmpeg
Loading...
Searching...
No Matches
imf.c
Go to the documentation of this file.
1/*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19/*
20 *
21 * Copyright (c) Sandflow Consulting LLC
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions are met:
25 *
26 * * Redistributions of source code must retain the above copyright notice, this
27 * list of conditions and the following disclaimer.
28 * * Redistributions in binary form must reproduce the above copyright notice,
29 * this list of conditions and the following disclaimer in the documentation
30 * and/or other materials provided with the distribution.
31 *
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
33 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
36 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
37 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
39 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
40 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGE.
43 */
44
45/**
46 * Tests for IMF CPL and ASSETMAP processing
47 *
48 * @author Valentin Noel
49 * @author Pierre-Anthony Lemieux
50 * @file
51 * @ingroup lavu_imf
52 */
53
54#include "libavformat/imf_cpl.c"
55#include "libavformat/imfdec.c"
56#include "libavformat/mxf.h"
57
58#include <stdio.h>
59
60const char *cpl_doc =
61 "<CompositionPlaylist xmlns=\"http://www.smpte-ra.org/schemas/2067-3/2016\""
62 " xmlns:cc=\"http://www.smpte-ra.org/schemas/2067-2/2016\""
63 " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
64 "<Id>urn:uuid:8713c020-2489-45f5-a9f7-87be539e20b5</Id>"
65 "<IssueDate>2021-07-13T17:06:22Z</IssueDate>"
66 "<Creator language=\"en\">FFMPEG</Creator>"
67 "<ContentTitle>FFMPEG sample content</ContentTitle>"
68 "<EssenceDescriptorList>"
69 " <EssenceDescriptor>"
70 " <Id>urn:uuid:8e097bb0-cff7-4969-a692-bad47bfb528f</Id>"
71 " </EssenceDescriptor>"
72 "</EssenceDescriptorList>"
73 "<CompositionTimecode>"
74 "<TimecodeDropFrame>false</TimecodeDropFrame>"
75 "<TimecodeRate>24</TimecodeRate>"
76 "<TimecodeStartAddress>02:10:01.23</TimecodeStartAddress>"
77 "</CompositionTimecode>"
78 "<EditRate>24000 1001</EditRate>"
79 "<SegmentList>"
80 "<Segment>"
81 "<Id>urn:uuid:81fed4e5-9722-400a-b9d1-7f2bd21df4b6</Id>"
82 "<SequenceList>"
83 "<MarkerSequence>"
84 "<Id>urn:uuid:16327185-9205-47ef-a17b-ee28df251db7</Id>"
85 "<TrackId>urn:uuid:461f5424-8f6e-48a9-a385-5eda46fda381</TrackId>"
86 "<ResourceList>"
87 "<Resource xsi:type=\"MarkerResourceType\">"
88 "<Id>urn:uuid:ea3d0f23-55d6-4e03-86ec-cfe0666f0e6a</Id>"
89 "<IntrinsicDuration>24</IntrinsicDuration>"
90 "<Marker>"
91 "<Label>LFOA</Label>"
92 "<Offset>5</Offset>"
93 "</Marker>"
94 "</Resource>"
95 "</ResourceList>"
96 "</MarkerSequence>"
97 "<cc:MainImageSequence>"
98 "<Id>urn:uuid:6ae100b0-92d1-41be-9321-85e0933dfc42</Id>"
99 "<TrackId>urn:uuid:e8ef9653-565c-479c-8039-82d4547973c5</TrackId>"
100 "<ResourceList>"
101 "<Resource xsi:type=\"TrackFileResourceType\">"
102 "<Id>urn:uuid:7d418acb-07a3-4e57-984c-b8ea2f7de4ec</Id>"
103 "<IntrinsicDuration>24</IntrinsicDuration>"
104 "<SourceEncoding>urn:uuid:f00e49a8-0dec-4e6c-95e7-078df988b751</SourceEncoding>"
105 "<TrackFileId>urn:uuid:6f768ca4-c89e-4dac-9056-a29425d40ba1</TrackFileId>"
106 "</Resource>"
107 "</ResourceList>"
108 "</cc:MainImageSequence>"
109 "<cc:MainAudioSequence>"
110 "<Id>urn:uuid:754dae53-c25f-4f3c-97e4-2bfe5463f83b</Id>"
111 "<TrackId>urn:uuid:68e3fae5-d94b-44d2-92a6-b94877fbcdb5</TrackId>"
112 "<ResourceList>"
113 "<Resource xsi:type=\"TrackFileResourceType\">"
114 "<Id>urn:uuid:61ce2a70-10a2-4521-850b-4218755ff3c9</Id>"
115 "<IntrinsicDuration>24</IntrinsicDuration>"
116 "<SourceEncoding>urn:uuid:f00e49a8-0dec-4e6c-95e7-078df988b751</SourceEncoding>"
117 "<TrackFileId>urn:uuid:381dadd2-061e-46cc-a63a-e3d58ce7f488</TrackFileId>"
118 "</Resource>"
119 "</ResourceList>"
120 "</cc:MainAudioSequence>"
121 "<cc:MainAudioSequence>"
122 "<Id>urn:uuid:d29b3884-6633-4dad-9c67-7154af342bc6</Id>"
123 "<TrackId>urn:uuid:6978c106-95bc-424b-a17c-628206a5892d</TrackId>"
124 "<ResourceList>"
125 "<Resource xsi:type=\"TrackFileResourceType\">"
126 "<Id>urn:uuid:001ea472-f5da-436c-86de-acaa68c1a7e4</Id>"
127 "<IntrinsicDuration>24</IntrinsicDuration>"
128 "<SourceEncoding>urn:uuid:f00e49a8-0dec-4e6c-95e7-078df988b751</SourceEncoding>"
129 "<TrackFileId>urn:uuid:381dadd2-061e-46cc-a63a-e3d58ce7f488</TrackFileId>"
130 "</Resource>"
131 "</ResourceList>"
132 "</cc:MainAudioSequence>"
133 "<cc:SubtitlesSequence>"
134 "<Id>urn:uuid:02af22bf-f776-488a-b001-eb6e16953119</Id>"
135 "<TrackId>urn:uuid:19ff6da1-be79-4235-8d04-42201ad06e65</TrackId>"
136 "<ResourceList>"
137 "<Resource xsi:type=\"TrackFileResourceType\">"
138 "<Id>urn:uuid:dfa84292-0609-4097-824c-8e2e15e2ce4d</Id>"
139 "<IntrinsicDuration>24</IntrinsicDuration>"
140 "<SourceEncoding>urn:uuid:f00e49a8-0dec-4e6c-95e7-078df988b751</SourceEncoding>"
141 "<TrackFileId>urn:uuid:bd6272b6-511e-47c1-93bc-d56ebd314a70</TrackFileId>"
142 "</Resource>"
143 "</ResourceList>"
144 "</cc:SubtitlesSequence>"
145 "</SequenceList>"
146 "</Segment>"
147 "<Segment>"
148 "<Id>urn:uuid:a94be493-cd55-4bf7-b496-ea87bfe38632</Id>"
149 "<SequenceList>"
150 "<MarkerSequence>"
151 "<Id>urn:uuid:20c6020b-1fc0-4080-bcf7-89f09f95bea8</Id>"
152 "<TrackId>urn:uuid:461f5424-8f6e-48a9-a385-5eda46fda381</TrackId>"
153 "<ResourceList>"
154 "<Resource xsi:type=\"MarkerResourceType\">"
155 "<Id>urn:uuid:d1f93845-d3e5-4c3b-aa67-8d96c45cfe9c</Id>"
156 "<IntrinsicDuration>36</IntrinsicDuration>"
157 "<Marker>"
158 "<Label>FFOA</Label>"
159 "<Offset>20</Offset>"
160 "</Marker>"
161 "<Marker>"
162 "<Label>LFOC</Label>"
163 "<Offset>24</Offset>"
164 "</Marker>"
165 "</Resource>"
166 "</ResourceList>"
167 "</MarkerSequence>"
168 "<cc:MainImageSequence>"
169 "<Id>urn:uuid:9b509f42-e4e8-4f78-8c2a-12ddd79ef3c5</Id>"
170 "<TrackId>urn:uuid:e8ef9653-565c-479c-8039-82d4547973c5</TrackId>"
171 "<ResourceList>"
172 "<Resource xsi:type=\"TrackFileResourceType\">"
173 "<Id>urn:uuid:a733d812-a3d7-45e9-ba50-13b856d5d35a</Id>"
174 "<IntrinsicDuration>36</IntrinsicDuration>"
175 "<SourceEncoding>urn:uuid:f00e49a8-0dec-4e6c-95e7-078df988b751</SourceEncoding>"
176 "<TrackFileId>urn:uuid:f3b263b3-096b-4360-a952-b1a9623cd0ca</TrackFileId>"
177 "</Resource>"
178 "</ResourceList>"
179 "</cc:MainImageSequence>"
180 "<cc:MainAudioSequence>"
181 "<Id>urn:uuid:19a282e6-beac-4d99-a008-afa61378eb6c</Id>"
182 "<TrackId>urn:uuid:68e3fae5-d94b-44d2-92a6-b94877fbcdb5</TrackId>"
183 "<ResourceList>"
184 "<Resource xsi:type=\"TrackFileResourceType\">"
185 "<Id>urn:uuid:53de5ff9-f5f7-47c5-a2d8-117c36cce517</Id>"
186 "<IntrinsicDuration>36</IntrinsicDuration>"
187 "<SourceEncoding>urn:uuid:f00e49a8-0dec-4e6c-95e7-078df988b751</SourceEncoding>"
188 "<TrackFileId>urn:uuid:2484d613-bb7d-4bcc-8b0f-2e65938f0535</TrackFileId>"
189 "</Resource>"
190 "</ResourceList>"
191 "</cc:MainAudioSequence>"
192 "<cc:MainAudioSequence>"
193 "<Id>urn:uuid:94b0ef77-0621-4086-95a2-85432fa97d40</Id>"
194 "<TrackId>urn:uuid:6978c106-95bc-424b-a17c-628206a5892d</TrackId>"
195 "<ResourceList>"
196 "<Resource xsi:type=\"TrackFileResourceType\">"
197 "<Id>urn:uuid:2ce499f2-59bc-4053-87bc-80f4b7e7b73e</Id>"
198 "<IntrinsicDuration>36</IntrinsicDuration>"
199 "<SourceEncoding>urn:uuid:f00e49a8-0dec-4e6c-95e7-078df988b751</SourceEncoding>"
200 "<TrackFileId>urn:uuid:2484d613-bb7d-4bcc-8b0f-2e65938f0535</TrackFileId>"
201 "</Resource>"
202 "</ResourceList>"
203 "</cc:MainAudioSequence>"
204 "<cc:SubtitlesSequence>"
205 "<Id>urn:uuid:9ac3b905-c599-4da8-8f0f-fc07e619899d</Id>"
206 "<TrackId>urn:uuid:19ff6da1-be79-4235-8d04-42201ad06e65</TrackId>"
207 "<ResourceList>"
208 "<Resource xsi:type=\"TrackFileResourceType\">"
209 "<Id>urn:uuid:0239017b-2ad9-4235-b46d-c4c1126e29fc</Id>"
210 "<IntrinsicDuration>36</IntrinsicDuration>"
211 "<SourceEncoding>urn:uuid:f00e49a8-0dec-4e6c-95e7-078df988b751</SourceEncoding>"
212 "<TrackFileId>urn:uuid:bd6272b6-511e-47c1-93bc-d56ebd314a70</TrackFileId>"
213 "</Resource>"
214 "</ResourceList>"
215 "</cc:SubtitlesSequence>"
216 "</SequenceList>"
217 "</Segment>"
218 "</SegmentList>"
219 "</CompositionPlaylist>";
220
222 "<CompositionPlaylist xmlns=\"http://www.smpte-ra.org/schemas/2067-3/2016\""
223 " xmlns:cc=\"http://www.smpte-ra.org/schemas/2067-2/2016\""
224 " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
225 "<Id>urn:uuid:8713c020-2489-45f5-a9f7-87be539e20b5</Id>"
226 "<IssueDate>2021-07-13T17:06:22Z</IssueDate>"
227 "<Creator language=\"en\">FFMPEG</Creator>"
228 "<ContentTitle>FFMPEG sample content</ContentTitle>"
229 "<EssenceDescriptorList>"
230 " <EssenceDescriptor>"
231 " <Id>urn:uuid:8e097bb0-cff7-4969-a692-bad47bfb528f</Id>"
232 " </EssenceDescriptor>"
233 "</EssenceDescriptorList>"
234 "<CompositionTimecode>"
235 "<TimecodeDropFrame>false</TimecodeDropFrame>"
236 "<TimecodeRate>24</TimecodeRate>"
237 "<TimecodeStartAddress>02:10:01.23</TimecodeStartAddress>"
238 "</CompositionTimecode>"
239 "<EditRate>24000 1001</EditRate>"
240 "<SegmentList>"
241 "<Segment>"
242 "<Id>urn:uuid:81fed4e5-9722-400a-b9d1-7f2bd21df4b6</Id>"
243 "<SequenceList>"
244 "<cc:MainImageSequence>"
245 "<Id>urn:uuid:6ae100b0-92d1-41be-9321-85e0933dfc42</Id>"
246 "<TrackId>urn:uuid:e8ef9653-565c-479c-8039-82d4547973c5</TrackId>"
247 "<ResourceList>"
248 "<Resource xsi:type=\"TrackFileResourceType\">"
249 "<Id>urn:uuid:7d418acb-07a3-4e57-984c-b8ea2f7de4ec</Id>"
250 "<IntrinsicDuration>24</IntrinsicDuration>"
251 "<SourceEncoding>urn:uuid:f00e49a8-0dec-4e6c-95e7-078df988b751</SourceEncoding>"
252 "</Resource>"
253 "</ResourceList>"
254 "</cc:MainImageSequence>"
255 "</SequenceList>"
256 "</Segment>"
257 "</SegmentList>"
258 "</CompositionPlaylist>";
259
260const char *cpl_bad_empty_doc = "<Composition></Composition>";
261
262const char *asset_map_doc =
263 "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"
264 "<am:AssetMap xmlns:am=\"http://www.smpte-ra.org/schemas/429-9/2007/AM\">"
265 "<am:Id>urn:uuid:68d9f591-8191-46b5-38b4-affb87a14132</am:Id>"
266 "<am:AnnotationText>IMF_TEST_ASSET_MAP</am:AnnotationText>"
267 "<am:Creator>Some tool</am:Creator>"
268 "<am:VolumeCount>1</am:VolumeCount>"
269 "<am:IssueDate>2021-06-07T12:00:00+00:00</am:IssueDate>"
270 "<am:Issuer>FFmpeg</am:Issuer>"
271 "<am:AssetList>"
272 "<am:Asset>"
273 "<am:Id>urn:uuid:b5d674b8-c6ce-4bce-3bdf-be045dfdb2d0</am:Id>"
274 "<am:ChunkList>"
275 "<am:Chunk>"
276 "<am:Path>IMF_TEST_ASSET_MAP_video.mxf</am:Path>"
277 "<am:VolumeIndex>1</am:VolumeIndex>"
278 "<am:Offset>0</am:Offset>"
279 "<am:Length>1234567</am:Length>"
280 "</am:Chunk>"
281 "</am:ChunkList>"
282 "</am:Asset>"
283 "<am:Asset>"
284 "<am:Id>urn:uuid:ec3467ec-ab2a-4f49-c8cb-89caa3761f4a</am:Id>"
285 "<am:ChunkList>"
286 "<am:Chunk>"
287 "<am:Path>IMF_TEST_ASSET_MAP_video_1.mxf</am:Path>"
288 "<am:VolumeIndex>1</am:VolumeIndex>"
289 "<am:Offset>0</am:Offset>"
290 "<am:Length>234567</am:Length>"
291 "</am:Chunk>"
292 "</am:ChunkList>"
293 "</am:Asset>"
294 "<am:Asset>"
295 "<am:Id>urn:uuid:5cf5b5a7-8bb3-4f08-eaa6-3533d4b77fa6</am:Id>"
296 "<am:ChunkList>"
297 "<am:Chunk>"
298 "<am:Path>IMF_TEST_ASSET_MAP_audio.mxf</am:Path>"
299 "<am:VolumeIndex>1</am:VolumeIndex>"
300 "<am:Offset>0</am:Offset>"
301 "<am:Length>34567</am:Length>"
302 "</am:Chunk>"
303 "</am:ChunkList>"
304 "</am:Asset>"
305 "<am:Asset>"
306 "<am:Id>urn:uuid:559777d6-ec29-4375-f90d-300b0bf73686</am:Id>"
307 "<am:ChunkList>"
308 "<am:Chunk>"
309 "<am:Path>CPL_IMF_TEST_ASSET_MAP.xml</am:Path>"
310 "<am:VolumeIndex>1</am:VolumeIndex>"
311 "<am:Offset>0</am:Offset>"
312 "<am:Length>12345</am:Length>"
313 "</am:Chunk>"
314 "</am:ChunkList>"
315 "</am:Asset>"
316 "<am:Asset>"
317 "<am:Id>urn:uuid:dd04528d-9b80-452a-7a13-805b08278b3d</am:Id>"
318 "<am:PackingList>true</am:PackingList>"
319 "<am:ChunkList>"
320 "<am:Chunk>"
321 "<am:Path>PKL_IMF_TEST_ASSET_MAP.xml</am:Path>"
322 "<am:VolumeIndex>1</am:VolumeIndex>"
323 "<am:Offset>0</am:Offset>"
324 "<am:Length>2345</am:Length>"
325 "</am:Chunk>"
326 "</am:ChunkList>"
327 "</am:Asset>"
328 "</am:AssetList>"
329 "</am:AssetMap>";
330
331static int test_cpl_parsing(void)
332{
333 xmlDocPtr doc;
334 FFIMFCPL *cpl;
335 char tc_buf[AV_TIMECODE_STR_SIZE];
336 int ret;
337
338 doc = xmlReadMemory(cpl_doc, strlen(cpl_doc), NULL, NULL, 0);
339 if (doc == NULL) {
340 printf("XML parsing failed.\n");
341 return 1;
342 }
343
344 ret = ff_imf_parse_cpl_from_xml_dom(NULL, doc, &cpl);
345 xmlFreeDoc(doc);
346 if (ret) {
347 printf("CPL parsing failed.\n");
348 return 1;
349 }
350
351 printf("%s\n", cpl->content_title_utf8);
353 printf("%i %i\n", cpl->edit_rate.num, cpl->edit_rate.den);
354 printf("%s\n", av_timecode_make_string(cpl->tc, tc_buf, 0));
355
356 printf("Marker resource count: %" PRIu32 "\n", cpl->main_markers_track->resource_count);
357 for (uint32_t i = 0; i < cpl->main_markers_track->resource_count; i++) {
358 printf("Marker resource %" PRIu32 "\n", i);
359 for (uint32_t j = 0; j < cpl->main_markers_track->resources[i].marker_count; j++) {
360 printf(" Marker %" PRIu32 "\n", j);
361 printf(" Label %s\n", cpl->main_markers_track->resources[i].markers[j].label_utf8);
362 printf(" Offset %" PRIu32 "\n", cpl->main_markers_track->resources[i].markers[j].offset);
363 }
364 }
365
366 printf("Main image resource count: %" PRIu32 "\n", cpl->main_image_2d_track->resource_count);
367 for (uint32_t i = 0; i < cpl->main_image_2d_track->resource_count; i++) {
368 printf("Track file resource %" PRIu32 "\n", i);
370 }
371
372 printf("Main audio track count: %" PRIu32 "\n", cpl->main_audio_track_count);
373 for (uint32_t i = 0; i < cpl->main_audio_track_count; i++) {
374 printf(" Main audio virtual track %" PRIu32 "\n", i);
375 printf(" Main audio resource count: %" PRIu32 "\n", cpl->main_audio_tracks[i].resource_count);
376 for (uint32_t j = 0; j < cpl->main_audio_tracks[i].resource_count; j++) {
377 printf(" Track file resource %" PRIu32 "\n", j);
379 }
380 }
381
382 ff_imf_cpl_free(cpl);
383
384 return 0;
385}
386
387static int test_cpl_from_doc(FFIMFCPL **cpl, const char* cpl_doc, int should_pass) {
388 xmlDocPtr doc;
389 int ret;
390
391 doc = xmlReadMemory(cpl_doc, strlen(cpl_doc), NULL, NULL, 0);
392 if (doc == NULL) {
393 printf("XML parsing failed.\n");
394 return should_pass;
395 }
396
397 ret = ff_imf_parse_cpl_from_xml_dom(NULL, doc, cpl);
398 xmlFreeDoc(doc);
399 if (ret) {
400 printf("CPL parsing failed.\n");
401 if (*cpl) {
402 printf("Improper cleanup after failed CPL parsing\n");
403 return 1;
404 }
405 return should_pass;
406 }
407
408 ff_imf_cpl_free(*cpl);
409 *cpl = NULL;
410
411 return !should_pass;
412}
413
415{
416
417 printf("\tCompare " AV_PRI_URN_UUID " to " AV_PRI_URN_UUID ".\n",
418 AV_UUID_ARG(asset->uuid),
419 AV_UUID_ARG(expected_asset->uuid));
420
421 for (uint32_t i = 0; i < 16; ++i) {
422 if (asset->uuid[i] != expected_asset->uuid[i]) {
423 printf("Invalid asset locator UUID: found " AV_PRI_URN_UUID " instead of " AV_PRI_URN_UUID " expected.\n",
424 AV_UUID_ARG(asset->uuid),
425 AV_UUID_ARG(expected_asset->uuid));
426 return 1;
427 }
428 }
429
430 printf("\tCompare %s to %s.\n", asset->absolute_uri, expected_asset->absolute_uri);
431 if (strcmp(asset->absolute_uri, expected_asset->absolute_uri) != 0) {
432 printf("Invalid asset locator URI: found %s instead of %s expected.\n",
433 asset->absolute_uri,
434 expected_asset->absolute_uri);
435 return 1;
436 }
437
438 return 0;
439}
440
442 {.uuid = {0xb5, 0xd6, 0x74, 0xb8, 0xc6, 0xce, 0x4b, 0xce, 0x3b, 0xdf, 0xbe, 0x04, 0x5d, 0xfd, 0xb2, 0xd0},
443 .absolute_uri = (char *)"IMF_TEST_ASSET_MAP_video.mxf"},
444 {.uuid = {0xec, 0x34, 0x67, 0xec, 0xab, 0x2a, 0x4f, 0x49, 0xc8, 0xcb, 0x89, 0xca, 0xa3, 0x76, 0x1f, 0x4a},
445 .absolute_uri = (char *)"IMF_TEST_ASSET_MAP_video_1.mxf"},
446 {.uuid = {0x5c, 0xf5, 0xb5, 0xa7, 0x8b, 0xb3, 0x4f, 0x08, 0xea, 0xa6, 0x35, 0x33, 0xd4, 0xb7, 0x7f, 0xa6},
447 .absolute_uri = (char *)"IMF_TEST_ASSET_MAP_audio.mxf"},
448 {.uuid = {0x55, 0x97, 0x77, 0xd6, 0xec, 0x29, 0x43, 0x75, 0xf9, 0x0d, 0x30, 0x0b, 0x0b, 0xf7, 0x36, 0x86},
449 .absolute_uri = (char *)"CPL_IMF_TEST_ASSET_MAP.xml"},
450 {.uuid = {0xdd, 0x04, 0x52, 0x8d, 0x9b, 0x80, 0x45, 0x2a, 0x7a, 0x13, 0x80, 0x5b, 0x08, 0x27, 0x8b, 0x3d},
451 .absolute_uri = (char *)"PKL_IMF_TEST_ASSET_MAP.xml"},
452};
453
455{
456 IMFAssetLocatorMap asset_locator_map;
457 xmlDoc *doc;
458 int ret;
459
460 doc = xmlReadMemory(asset_map_doc, strlen(asset_map_doc), NULL, NULL, 0);
461 if (doc == NULL) {
462 printf("Asset map XML parsing failed.\n");
463 return 1;
464 }
465
466 printf("Allocate asset map\n");
467 imf_asset_locator_map_init(&asset_locator_map);
468
469 printf("Parse asset map XML document\n");
470 ret = parse_imf_asset_map_from_xml_dom(NULL, doc, &asset_locator_map, doc->name);
471 if (ret) {
472 printf("Asset map parsing failed.\n");
473 goto cleanup;
474 }
475
476 printf("Compare assets count: %d to 5\n", asset_locator_map.asset_count);
477 if (asset_locator_map.asset_count != 5) {
478 printf("Asset map parsing failed: found %d assets instead of 5 expected.\n",
479 asset_locator_map.asset_count);
480 ret = 1;
481 goto cleanup;
482 }
483
484 for (uint32_t i = 0; i < asset_locator_map.asset_count; ++i) {
485 printf("For asset: %d:\n", i);
486 ret = check_asset_locator_attributes(&(asset_locator_map.assets[i]),
488 if (ret > 0)
489 goto cleanup;
490 }
491
492cleanup:
493 imf_asset_locator_map_deinit(&asset_locator_map);
494 xmlFreeDoc(doc);
495 return ret;
496}
497
504
506 {.path = "file://path/to/somewhere", .is_url = 1, .is_unix_absolute_path = 0, .is_dos_absolute_path = 0},
507 {.path = "http://path/to/somewhere", .is_url = 1, .is_unix_absolute_path = 0, .is_dos_absolute_path = 0},
508 {.path = "https://path/to/somewhere", .is_url = 1, .is_unix_absolute_path = 0, .is_dos_absolute_path = 0},
509 {.path = "s3://path/to/somewhere", .is_url = 1, .is_unix_absolute_path = 0, .is_dos_absolute_path = 0},
510 {.path = "ftp://path/to/somewhere", .is_url = 1, .is_unix_absolute_path = 0, .is_dos_absolute_path = 0},
511 {.path = "/path/to/somewhere", .is_url = 0, .is_unix_absolute_path = 1, .is_dos_absolute_path = 0},
512 {.path = "path/to/somewhere", .is_url = 0, .is_unix_absolute_path = 0, .is_dos_absolute_path = 0},
513 {.path = "C:\\path\\to\\somewhere", .is_url = 0, .is_unix_absolute_path = 0, .is_dos_absolute_path = 1},
514 {.path = "C:/path/to/somewhere", .is_url = 0, .is_unix_absolute_path = 0, .is_dos_absolute_path = 1},
515 {.path = "\\\\path\\to\\somewhere", .is_url = 0, .is_unix_absolute_path = 0, .is_dos_absolute_path = 1},
516 {.path = "path\\to\\somewhere", .is_url = 0, .is_unix_absolute_path = 0, .is_dos_absolute_path = 0},
517};
518
520{
521 PathTypeTestStruct path_type;
522 for (uint32_t i = 0; i < 11; ++i) {
523 path_type = PATH_TYPE_TEST_STRUCTS[i];
524 if (imf_uri_is_url(path_type.path) != path_type.is_url) {
525 fprintf(stderr,
526 "URL comparison test failed for '%s', got %d instead of expected %d\n",
527 path_type.path,
528 path_type.is_url,
529 !path_type.is_url);
530 goto fail;
531 }
532
533 if (imf_uri_is_unix_abs_path(path_type.path) != path_type.is_unix_absolute_path) {
534 fprintf(stderr,
535 "Unix absolute path comparison test failed for '%s', got %d instead of expected %d\n",
536 path_type.path,
537 path_type.is_unix_absolute_path,
538 !path_type.is_unix_absolute_path);
539 goto fail;
540 }
541
542 if (imf_uri_is_dos_abs_path(path_type.path) != path_type.is_dos_absolute_path) {
543 fprintf(stderr,
544 "DOS absolute path comparison test failed for '%s', got %d instead of expected %d\n",
545 path_type.path,
546 path_type.is_dos_absolute_path,
547 !path_type.is_dos_absolute_path);
548 goto fail;
549 }
550 }
551
552 return 0;
553
554fail:
555 return 1;
556}
557
558int main(int argc, char *argv[])
559{
560 FFIMFCPL *cpl;
561 int ret = 0;
562
563 if (test_cpl_parsing() != 0)
564 ret = 1;
565
566 if (test_asset_map_parsing() != 0)
567 ret = 1;
568
569 if (test_path_type_functions() != 0)
570 ret = 1;
571
572 printf("#### The following should fail ####\n");
573 if (test_cpl_from_doc(&cpl, cpl_bad_empty_doc, 0) != 0)
574 ret = 1;
575 printf("#### End failing test ####\n");
576
577 printf("#### The following should emit errors ####\n");
578 if (test_cpl_from_doc(&cpl, cpl_bad_resource_doc, 1) != 0)
579 ret = 1;
580 printf("#### End emission of errors ####\n");
581
582 return ret;
583}
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define NULL
Definition coverity.c:32
__device__ int printf(const char *,...)
int main
Definition dovi_rpuenc.c:38
static av_cold void cleanup(FlashSV2Context *s)
#define fail
Definition test.h:479
static int check_asset_locator_attributes(IMFAssetLocator *asset, IMFAssetLocator *expected_asset)
Definition imf.c:414
const char * cpl_bad_resource_doc
Definition imf.c:221
static int test_path_type_functions(void)
Definition imf.c:519
static int test_cpl_from_doc(FFIMFCPL **cpl, const char *cpl_doc, int should_pass)
Definition imf.c:387
const char * cpl_doc
Definition imf.c:60
static IMFAssetLocator ASSET_MAP_EXPECTED_LOCATORS[5]
Definition imf.c:441
static int test_asset_map_parsing(void)
Definition imf.c:454
static int test_cpl_parsing(void)
Definition imf.c:331
const char * asset_map_doc
Definition imf.c:262
static const PathTypeTestStruct PATH_TYPE_TEST_STRUCTS[11]
Definition imf.c:505
const char * cpl_bad_empty_doc
Definition imf.c:260
int ff_imf_parse_cpl_from_xml_dom(void *log_ctx, xmlDocPtr doc, FFIMFCPL **cpl)
Parse an IMF CompositionPlaylist element into the FFIMFCPL data structure.
Definition imf_cpl.c:745
void ff_imf_cpl_free(FFIMFCPL *cpl)
Deletes an FFIMFCPL data structure previously instantiated with ff_imf_cpl_alloc().
Definition imf_cpl.c:846
Implements IMP CPL processing.
Demuxes an IMF Composition.
static void imf_asset_locator_map_init(IMFAssetLocatorMap *asset_map)
Initializes an IMFAssetLocatorMap structure.
Definition imfdec.c:292
static int imf_uri_is_url(const char *string)
Definition imfdec.c:130
static int imf_uri_is_unix_abs_path(const char *string)
Definition imfdec.c:135
static int imf_uri_is_dos_abs_path(const char *string)
Definition imfdec.c:140
static void imf_asset_locator_map_deinit(IMFAssetLocatorMap *asset_map)
Free a IMFAssetLocatorMap pointer.
Definition imfdec.c:301
static int parse_imf_asset_map_from_xml_dom(AVFormatContext *s, xmlDocPtr doc, IMFAssetLocatorMap *asset_map, const char *base_url)
Parse a ASSETMAP XML file to extract the UUID-URI mapping of assets.
Definition imfdec.c:184
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
IMF Composition Playlist.
Definition imf.h:130
FFIMFMarkerVirtualTrack * main_markers_track
Main Marker Virtual Track.
Definition imf.h:135
AVRational edit_rate
CompositionPlaylist/EditRate element.
Definition imf.h:133
FFIMFTrackFileVirtualTrack * main_audio_tracks
Main Audio Virtual Tracks.
Definition imf.h:138
xmlChar * content_title_utf8
CompositionPlaylist/ContentTitle element.
Definition imf.h:132
uint32_t main_audio_track_count
Number of Main Audio Virtual Tracks.
Definition imf.h:137
FFIMFTrackFileVirtualTrack * main_image_2d_track
Main Image Virtual Track.
Definition imf.h:136
AVUUID id_uuid
CompositionPlaylist/Id element.
Definition imf.h:131
AVTimecode * tc
CompositionPlaylist/CompositionTimecode element.
Definition imf.h:134
uint32_t marker_count
Number of Marker elements.
Definition imf.h:97
FFIMFMarker * markers
Marker elements.
Definition imf.h:98
uint32_t resource_count
Number of Resource elements present in the Virtual Track.
Definition imf.h:123
FFIMFMarkerResource * resources
Resource elements of the Virtual Track.
Definition imf.h:124
xmlChar * label_utf8
Marker/Label.
Definition imf.h:87
uint32_t offset
Marker/Offset.
Definition imf.h:89
AVUUID track_file_uuid
TrackFileResourceType/TrackFileId.
Definition imf.h:80
FFIMFTrackFileResource * resources
Resource elements of the Virtual Track.
Definition imf.h:114
uint32_t resource_count
Number of Resource elements present in the Virtual Track.
Definition imf.h:113
IMF Asset locator map Results from the parsing of one or more ASSETMAP XML files.
Definition imfdec.c:93
uint32_t asset_count
Definition imfdec.c:94
IMFAssetLocator * assets
Definition imfdec.c:95
IMF Asset locator.
Definition imfdec.c:84
char * absolute_uri
Definition imfdec.c:86
AVUUID uuid
Definition imfdec.c:85
const char * path
Definition imf.c:499
int is_unix_absolute_path
Definition imf.c:501
int is_dos_absolute_path
Definition imf.c:502
char * av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum_arg)
Load timecode string in buf.
Definition timecode.c:104
#define AV_TIMECODE_STR_SIZE
Definition timecode.h:33
#define AV_PRI_URN_UUID
Definition uuid.h:43
#define AV_UUID_ARG(x)
Definition uuid.h:51