FFmpeg
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 
60 const 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 
221 const char *cpl_bad_doc = "<Composition></Composition>";
222 
223 const char *asset_map_doc =
224  "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"
225  "<am:AssetMap xmlns:am=\"http://www.smpte-ra.org/schemas/429-9/2007/AM\">"
226  "<am:Id>urn:uuid:68d9f591-8191-46b5-38b4-affb87a14132</am:Id>"
227  "<am:AnnotationText>IMF_TEST_ASSET_MAP</am:AnnotationText>"
228  "<am:Creator>Some tool</am:Creator>"
229  "<am:VolumeCount>1</am:VolumeCount>"
230  "<am:IssueDate>2021-06-07T12:00:00+00:00</am:IssueDate>"
231  "<am:Issuer>FFmpeg</am:Issuer>"
232  "<am:AssetList>"
233  "<am:Asset>"
234  "<am:Id>urn:uuid:b5d674b8-c6ce-4bce-3bdf-be045dfdb2d0</am:Id>"
235  "<am:ChunkList>"
236  "<am:Chunk>"
237  "<am:Path>IMF_TEST_ASSET_MAP_video.mxf</am:Path>"
238  "<am:VolumeIndex>1</am:VolumeIndex>"
239  "<am:Offset>0</am:Offset>"
240  "<am:Length>1234567</am:Length>"
241  "</am:Chunk>"
242  "</am:ChunkList>"
243  "</am:Asset>"
244  "<am:Asset>"
245  "<am:Id>urn:uuid:ec3467ec-ab2a-4f49-c8cb-89caa3761f4a</am:Id>"
246  "<am:ChunkList>"
247  "<am:Chunk>"
248  "<am:Path>IMF_TEST_ASSET_MAP_video_1.mxf</am:Path>"
249  "<am:VolumeIndex>1</am:VolumeIndex>"
250  "<am:Offset>0</am:Offset>"
251  "<am:Length>234567</am:Length>"
252  "</am:Chunk>"
253  "</am:ChunkList>"
254  "</am:Asset>"
255  "<am:Asset>"
256  "<am:Id>urn:uuid:5cf5b5a7-8bb3-4f08-eaa6-3533d4b77fa6</am:Id>"
257  "<am:ChunkList>"
258  "<am:Chunk>"
259  "<am:Path>IMF_TEST_ASSET_MAP_audio.mxf</am:Path>"
260  "<am:VolumeIndex>1</am:VolumeIndex>"
261  "<am:Offset>0</am:Offset>"
262  "<am:Length>34567</am:Length>"
263  "</am:Chunk>"
264  "</am:ChunkList>"
265  "</am:Asset>"
266  "<am:Asset>"
267  "<am:Id>urn:uuid:559777d6-ec29-4375-f90d-300b0bf73686</am:Id>"
268  "<am:ChunkList>"
269  "<am:Chunk>"
270  "<am:Path>CPL_IMF_TEST_ASSET_MAP.xml</am:Path>"
271  "<am:VolumeIndex>1</am:VolumeIndex>"
272  "<am:Offset>0</am:Offset>"
273  "<am:Length>12345</am:Length>"
274  "</am:Chunk>"
275  "</am:ChunkList>"
276  "</am:Asset>"
277  "<am:Asset>"
278  "<am:Id>urn:uuid:dd04528d-9b80-452a-7a13-805b08278b3d</am:Id>"
279  "<am:PackingList>true</am:PackingList>"
280  "<am:ChunkList>"
281  "<am:Chunk>"
282  "<am:Path>PKL_IMF_TEST_ASSET_MAP.xml</am:Path>"
283  "<am:VolumeIndex>1</am:VolumeIndex>"
284  "<am:Offset>0</am:Offset>"
285  "<am:Length>2345</am:Length>"
286  "</am:Chunk>"
287  "</am:ChunkList>"
288  "</am:Asset>"
289  "</am:AssetList>"
290  "</am:AssetMap>";
291 
292 static int test_cpl_parsing(void)
293 {
294  xmlDocPtr doc;
295  FFIMFCPL *cpl;
296  char tc_buf[AV_TIMECODE_STR_SIZE];
297  int ret;
298 
299  doc = xmlReadMemory(cpl_doc, strlen(cpl_doc), NULL, NULL, 0);
300  if (doc == NULL) {
301  printf("XML parsing failed.\n");
302  return 1;
303  }
304 
305  ret = ff_imf_parse_cpl_from_xml_dom(doc, &cpl);
306  xmlFreeDoc(doc);
307  if (ret) {
308  printf("CPL parsing failed.\n");
309  return 1;
310  }
311 
312  printf("%s\n", cpl->content_title_utf8);
314  printf("%i %i\n", cpl->edit_rate.num, cpl->edit_rate.den);
315  printf("%s\n", av_timecode_make_string(cpl->tc, tc_buf, 0));
316 
317  printf("Marker resource count: %" PRIu32 "\n", cpl->main_markers_track->resource_count);
318  for (uint32_t i = 0; i < cpl->main_markers_track->resource_count; i++) {
319  printf("Marker resource %" PRIu32 "\n", i);
320  for (uint32_t j = 0; j < cpl->main_markers_track->resources[i].marker_count; j++) {
321  printf(" Marker %" PRIu32 "\n", j);
322  printf(" Label %s\n", cpl->main_markers_track->resources[i].markers[j].label_utf8);
323  printf(" Offset %" PRIu32 "\n", cpl->main_markers_track->resources[i].markers[j].offset);
324  }
325  }
326 
327  printf("Main image resource count: %" PRIu32 "\n", cpl->main_image_2d_track->resource_count);
328  for (uint32_t i = 0; i < cpl->main_image_2d_track->resource_count; i++) {
329  printf("Track file resource %" PRIu32 "\n", i);
331  }
332 
333  printf("Main audio track count: %" PRIu32 "\n", cpl->main_audio_track_count);
334  for (uint32_t i = 0; i < cpl->main_audio_track_count; i++) {
335  printf(" Main audio virtual track %" PRIu32 "\n", i);
336  printf(" Main audio resource count: %" PRIu32 "\n", cpl->main_audio_tracks[i].resource_count);
337  for (uint32_t j = 0; j < cpl->main_audio_tracks[i].resource_count; j++) {
338  printf(" Track file resource %" PRIu32 "\n", j);
340  }
341  }
342 
343  ff_imf_cpl_free(cpl);
344 
345  return 0;
346 }
347 
349 {
350  xmlDocPtr doc;
351  int ret;
352 
353  doc = xmlReadMemory(cpl_bad_doc, strlen(cpl_bad_doc), NULL, NULL, 0);
354  if (doc == NULL) {
355  printf("XML parsing failed.\n");
356  return 1;
357  }
358 
360  xmlFreeDoc(doc);
361  if (ret) {
362  printf("CPL parsing failed.\n");
363  return ret;
364  }
365 
366  return 0;
367 }
368 
370 {
371 
372  printf("\tCompare " AV_PRI_URN_UUID " to " AV_PRI_URN_UUID ".\n",
373  AV_UUID_ARG(asset->uuid),
374  AV_UUID_ARG(expected_asset->uuid));
375 
376  for (uint32_t i = 0; i < 16; ++i) {
377  if (asset->uuid[i] != expected_asset->uuid[i]) {
378  printf("Invalid asset locator UUID: found " AV_PRI_URN_UUID " instead of " AV_PRI_URN_UUID " expected.\n",
379  AV_UUID_ARG(asset->uuid),
380  AV_UUID_ARG(expected_asset->uuid));
381  return 1;
382  }
383  }
384 
385  printf("\tCompare %s to %s.\n", asset->absolute_uri, expected_asset->absolute_uri);
386  if (strcmp(asset->absolute_uri, expected_asset->absolute_uri) != 0) {
387  printf("Invalid asset locator URI: found %s instead of %s expected.\n",
388  asset->absolute_uri,
389  expected_asset->absolute_uri);
390  return 1;
391  }
392 
393  return 0;
394 }
395 
397  {.uuid = {0xb5, 0xd6, 0x74, 0xb8, 0xc6, 0xce, 0x4b, 0xce, 0x3b, 0xdf, 0xbe, 0x04, 0x5d, 0xfd, 0xb2, 0xd0},
398  .absolute_uri = (char *)"IMF_TEST_ASSET_MAP_video.mxf"},
399  {.uuid = {0xec, 0x34, 0x67, 0xec, 0xab, 0x2a, 0x4f, 0x49, 0xc8, 0xcb, 0x89, 0xca, 0xa3, 0x76, 0x1f, 0x4a},
400  .absolute_uri = (char *)"IMF_TEST_ASSET_MAP_video_1.mxf"},
401  {.uuid = {0x5c, 0xf5, 0xb5, 0xa7, 0x8b, 0xb3, 0x4f, 0x08, 0xea, 0xa6, 0x35, 0x33, 0xd4, 0xb7, 0x7f, 0xa6},
402  .absolute_uri = (char *)"IMF_TEST_ASSET_MAP_audio.mxf"},
403  {.uuid = {0x55, 0x97, 0x77, 0xd6, 0xec, 0x29, 0x43, 0x75, 0xf9, 0x0d, 0x30, 0x0b, 0x0b, 0xf7, 0x36, 0x86},
404  .absolute_uri = (char *)"CPL_IMF_TEST_ASSET_MAP.xml"},
405  {.uuid = {0xdd, 0x04, 0x52, 0x8d, 0x9b, 0x80, 0x45, 0x2a, 0x7a, 0x13, 0x80, 0x5b, 0x08, 0x27, 0x8b, 0x3d},
406  .absolute_uri = (char *)"PKL_IMF_TEST_ASSET_MAP.xml"},
407 };
408 
409 static int test_asset_map_parsing(void)
410 {
411  IMFAssetLocatorMap asset_locator_map;
412  xmlDoc *doc;
413  int ret;
414 
415  doc = xmlReadMemory(asset_map_doc, strlen(asset_map_doc), NULL, NULL, 0);
416  if (doc == NULL) {
417  printf("Asset map XML parsing failed.\n");
418  return 1;
419  }
420 
421  printf("Allocate asset map\n");
422  imf_asset_locator_map_init(&asset_locator_map);
423 
424  printf("Parse asset map XML document\n");
425  ret = parse_imf_asset_map_from_xml_dom(NULL, doc, &asset_locator_map, doc->name);
426  if (ret) {
427  printf("Asset map parsing failed.\n");
428  goto cleanup;
429  }
430 
431  printf("Compare assets count: %d to 5\n", asset_locator_map.asset_count);
432  if (asset_locator_map.asset_count != 5) {
433  printf("Asset map parsing failed: found %d assets instead of 5 expected.\n",
434  asset_locator_map.asset_count);
435  ret = 1;
436  goto cleanup;
437  }
438 
439  for (uint32_t i = 0; i < asset_locator_map.asset_count; ++i) {
440  printf("For asset: %d:\n", i);
441  ret = check_asset_locator_attributes(&(asset_locator_map.assets[i]),
443  if (ret > 0)
444  goto cleanup;
445  }
446 
447 cleanup:
448  imf_asset_locator_map_deinit(&asset_locator_map);
449  xmlFreeDoc(doc);
450  return ret;
451 }
452 
453 typedef struct PathTypeTestStruct {
454  const char *path;
455  int is_url;
459 
461  {.path = "file://path/to/somewhere", .is_url = 1, .is_unix_absolute_path = 0, .is_dos_absolute_path = 0},
462  {.path = "http://path/to/somewhere", .is_url = 1, .is_unix_absolute_path = 0, .is_dos_absolute_path = 0},
463  {.path = "https://path/to/somewhere", .is_url = 1, .is_unix_absolute_path = 0, .is_dos_absolute_path = 0},
464  {.path = "s3://path/to/somewhere", .is_url = 1, .is_unix_absolute_path = 0, .is_dos_absolute_path = 0},
465  {.path = "ftp://path/to/somewhere", .is_url = 1, .is_unix_absolute_path = 0, .is_dos_absolute_path = 0},
466  {.path = "/path/to/somewhere", .is_url = 0, .is_unix_absolute_path = 1, .is_dos_absolute_path = 0},
467  {.path = "path/to/somewhere", .is_url = 0, .is_unix_absolute_path = 0, .is_dos_absolute_path = 0},
468  {.path = "C:\\path\\to\\somewhere", .is_url = 0, .is_unix_absolute_path = 0, .is_dos_absolute_path = 1},
469  {.path = "C:/path/to/somewhere", .is_url = 0, .is_unix_absolute_path = 0, .is_dos_absolute_path = 1},
470  {.path = "\\\\path\\to\\somewhere", .is_url = 0, .is_unix_absolute_path = 0, .is_dos_absolute_path = 1},
471  {.path = "path\\to\\somewhere", .is_url = 0, .is_unix_absolute_path = 0, .is_dos_absolute_path = 0},
472 };
473 
474 static int test_path_type_functions(void)
475 {
476  PathTypeTestStruct path_type;
477  for (uint32_t i = 0; i < 11; ++i) {
478  path_type = PATH_TYPE_TEST_STRUCTS[i];
479  if (imf_uri_is_url(path_type.path) != path_type.is_url) {
480  fprintf(stderr,
481  "URL comparison test failed for '%s', got %d instead of expected %d\n",
482  path_type.path,
483  path_type.is_url,
484  !path_type.is_url);
485  goto fail;
486  }
487 
488  if (imf_uri_is_unix_abs_path(path_type.path) != path_type.is_unix_absolute_path) {
489  fprintf(stderr,
490  "Unix absolute path comparison test failed for '%s', got %d instead of expected %d\n",
491  path_type.path,
492  path_type.is_unix_absolute_path,
493  !path_type.is_unix_absolute_path);
494  goto fail;
495  }
496 
497  if (imf_uri_is_dos_abs_path(path_type.path) != path_type.is_dos_absolute_path) {
498  fprintf(stderr,
499  "DOS absolute path comparison test failed for '%s', got %d instead of expected %d\n",
500  path_type.path,
501  path_type.is_dos_absolute_path,
502  !path_type.is_dos_absolute_path);
503  goto fail;
504  }
505  }
506 
507  return 0;
508 
509 fail:
510  return 1;
511 }
512 
513 int main(int argc, char *argv[])
514 {
515  FFIMFCPL *cpl;
516  int ret = 0;
517 
518  if (test_cpl_parsing() != 0)
519  ret = 1;
520 
521  if (test_asset_map_parsing() != 0)
522  ret = 1;
523 
524  if (test_path_type_functions() != 0)
525  ret = 1;
526 
527  printf("#### The following should fail ####\n");
528  if (test_bad_cpl_parsing(&cpl) == 0) {
529  ret = 1;
530  } else if (cpl) {
531  printf("Improper cleanup after failed CPL parsing\n");
532  ret = 1;
533  }
534  printf("#### End failing test ####\n");
535 
536  return ret;
537 }
ff_imf_parse_cpl_from_xml_dom
int ff_imf_parse_cpl_from_xml_dom(xmlDocPtr doc, FFIMFCPL **cpl)
Parse an IMF CompositionPlaylist element into the FFIMFCPL data structure.
Definition: imf_cpl.c:758
FFIMFTrackFileVirtualTrack::resources
FFIMFTrackFileResource * resources
Resource elements of the Virtual Track.
Definition: imf.h:114
AV_TIMECODE_STR_SIZE
#define AV_TIMECODE_STR_SIZE
Definition: timecode.h:33
FFIMFCPL::id_uuid
AVUUID id_uuid
CompositionPlaylist/Id element.
Definition: imf.h:131
asset_map_doc
const char * asset_map_doc
Definition: imf.c:223
AV_UUID_ARG
#define AV_UUID_ARG(x)
Definition: uuid.h:51
FFIMFMarkerVirtualTrack::resources
FFIMFMarkerResource * resources
Resource elements of the Virtual Track.
Definition: imf.h:124
main
int main(int argc, char *argv[])
Definition: imf.c:513
PathTypeTestStruct::path
const char * path
Definition: imf.c:454
PATH_TYPE_TEST_STRUCTS
static const PathTypeTestStruct PATH_TYPE_TEST_STRUCTS[11]
Definition: imf.c:460
cleanup
static av_cold void cleanup(FlashSV2Context *s)
Definition: flashsv2enc.c:130
FFIMFTrackFileVirtualTrack::resource_count
uint32_t resource_count
Number of Resource elements present in the Virtual Track.
Definition: imf.h:113
FFIMFCPL::content_title_utf8
xmlChar * content_title_utf8
CompositionPlaylist/ContentTitle element.
Definition: imf.h:132
IMFAssetLocatorMap::asset_count
uint32_t asset_count
Definition: imfdec.c:94
imf_uri_is_unix_abs_path
static int imf_uri_is_unix_abs_path(const char *string)
Definition: imfdec.c:135
FFIMFCPL::main_audio_tracks
FFIMFTrackFileVirtualTrack * main_audio_tracks
Main Audio Virtual Tracks.
Definition: imf.h:138
mxf.h
imf_uri_is_dos_abs_path
static int imf_uri_is_dos_abs_path(const char *string)
Definition: imfdec.c:140
fail
#define fail()
Definition: checkasm.h:134
PathTypeTestStruct::is_dos_absolute_path
int is_dos_absolute_path
Definition: imf.c:457
ff_imf_cpl_free
void ff_imf_cpl_free(FFIMFCPL *cpl)
Deletes an FFIMFCPL data structure previously instantiated with ff_imf_cpl_alloc().
Definition: imf_cpl.c:851
av_timecode_make_string
char * av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum)
Load timecode string in buf.
Definition: timecode.c:103
FFIMFCPL::main_markers_track
FFIMFMarkerVirtualTrack * main_markers_track
Main Marker Virtual Track.
Definition: imf.h:135
AVRational::num
int num
Numerator.
Definition: rational.h:59
IMFAssetLocator::uuid
AVUUID uuid
Definition: imfdec.c:85
FFIMFCPL::tc
AVTimecode * tc
CompositionPlaylist/CompositionTimecode element.
Definition: imf.h:134
PathTypeTestStruct
Definition: imf.c:453
check_asset_locator_attributes
static int check_asset_locator_attributes(IMFAssetLocator *asset, IMFAssetLocator *expected_asset)
Definition: imf.c:369
cpl_doc
const char * cpl_doc
Definition: imf.c:60
test_path_type_functions
static int test_path_type_functions(void)
Definition: imf.c:474
imfdec.c
Demuxes an IMF Composition.
FFIMFCPL::edit_rate
AVRational edit_rate
CompositionPlaylist/EditRate element.
Definition: imf.h:133
IMFAssetLocator
IMF Asset locator.
Definition: imfdec.c:84
PathTypeTestStruct::is_url
int is_url
Definition: imf.c:455
NULL
#define NULL
Definition: coverity.c:32
imf_uri_is_url
static int imf_uri_is_url(const char *string)
Definition: imfdec.c:130
IMFAssetLocator::absolute_uri
char * absolute_uri
Definition: imfdec.c:86
cpl_bad_doc
const char * cpl_bad_doc
Definition: imf.c:221
imf_asset_locator_map_deinit
static void imf_asset_locator_map_deinit(IMFAssetLocatorMap *asset_map)
Free a IMFAssetLocatorMap pointer.
Definition: imfdec.c:288
FFIMFTrackFileResource::track_file_uuid
AVUUID track_file_uuid
TrackFileResourceType/TrackFileId.
Definition: imf.h:80
test_asset_map_parsing
static int test_asset_map_parsing(void)
Definition: imf.c:409
imf_asset_locator_map_init
static void imf_asset_locator_map_init(IMFAssetLocatorMap *asset_map)
Initializes an IMFAssetLocatorMap structure.
Definition: imfdec.c:279
printf
printf("static const uint8_t my_array[100] = {\n")
AV_PRI_URN_UUID
#define AV_PRI_URN_UUID
Definition: uuid.h:43
ASSET_MAP_EXPECTED_LOCATORS
static IMFAssetLocator ASSET_MAP_EXPECTED_LOCATORS[5]
Definition: imf.c:396
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
test_bad_cpl_parsing
static int test_bad_cpl_parsing(FFIMFCPL **cpl)
Definition: imf.c:348
parse_imf_asset_map_from_xml_dom
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
ret
ret
Definition: filter_design.txt:187
IMFAssetLocatorMap
IMF Asset locator map Results from the parsing of one or more ASSETMAP XML files.
Definition: imfdec.c:93
test_cpl_parsing
static int test_cpl_parsing(void)
Definition: imf.c:292
FFIMFMarkerResource::markers
FFIMFMarker * markers
Marker elements.
Definition: imf.h:98
PathTypeTestStruct::is_unix_absolute_path
int is_unix_absolute_path
Definition: imf.c:456
FFIMFMarker::offset
uint32_t offset
Marker/Offset.
Definition: imf.h:89
AVRational::den
int den
Denominator.
Definition: rational.h:60
imf_cpl.c
Implements IMP CPL processing.
FFIMFCPL::main_audio_track_count
uint32_t main_audio_track_count
Number of Main Audio Virtual Tracks.
Definition: imf.h:137
FFIMFMarkerVirtualTrack::resource_count
uint32_t resource_count
Number of Resource elements present in the Virtual Track.
Definition: imf.h:123
FFIMFCPL::main_image_2d_track
FFIMFTrackFileVirtualTrack * main_image_2d_track
Main Image Virtual Track.
Definition: imf.h:136
FFIMFMarkerResource::marker_count
uint32_t marker_count
Number of Marker elements.
Definition: imf.h:97
FFIMFCPL
IMF Composition Playlist.
Definition: imf.h:130
FFIMFMarker::label_utf8
xmlChar * label_utf8
Marker/Label.
Definition: imf.h:87
IMFAssetLocatorMap::assets
IMFAssetLocator * assets
Definition: imfdec.c:95