[Mac] make metadata cue attributes consistent
authoreric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 6 May 2014 20:19:31 +0000 (20:19 +0000)
committereric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 6 May 2014 20:19:31 +0000 (20:19 +0000)
https://bugs.webkit.org/show_bug.cgi?id=132610

Reviewed by Jer Noble.

Source/WebCore:
No new tests, updated http/tests/media/track-in-band-hls-metadata.html.

* platform/mac/SerializedPlatformRepresentationMac.mm:
(WebCore::jsValueWithAVMetadataItemInContext): Don't include keys @dataTypeNamespace
    or @pictureType, @dataType -> @type.

LayoutTests:
* http/tests/media/track-in-band-hls-metadata-expected.txt:
* http/tests/media/track-in-band-hls-metadata.html:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@168377 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/http/tests/media/track-in-band-hls-metadata-expected.txt
LayoutTests/http/tests/media/track-in-band-hls-metadata.html
Source/WebCore/ChangeLog
Source/WebCore/platform/mac/SerializedPlatformRepresentationMac.mm

index aef8afe..ee2a9c7 100644 (file)
@@ -1,3 +1,13 @@
+2014-05-06  Eric Carlson  <eric.carlson@apple.com>
+
+        [Mac] make metadata cue attributes consistent
+        https://bugs.webkit.org/show_bug.cgi?id=132610
+
+        Reviewed by Jer Noble.
+
+        * http/tests/media/track-in-band-hls-metadata-expected.txt:
+        * http/tests/media/track-in-band-hls-metadata.html:
+
 2014-05-06  Mark Hahnenberg  <mhahnenberg@apple.com>
 
         Roll out r167889
index 2da521e..76182cf 100644 (file)
@@ -3,6 +3,8 @@ Test for metadata tracks from Apple HLS stream.
 
 
 ** Set video.src, wait for media data to load
+RUN(video.src = 'http://127.0.0.1:8000/media/resources/hls/metadata/prog_index.m3u8')
+
 EVENT(addtrack)
 EXPECTED (tracks.length == '1') OK
 RUN(track = video.textTracks[0])
@@ -12,6 +14,7 @@ RUN(track.mode = 'hidden')
 EVENT(canplaythrough)
 
 ** Start playback, wait for all cues to load
+RUN(video.play())
 EVENT(cuechange)
 EVENT(cuechange)
 EVENT(cuechange)
@@ -20,34 +23,50 @@ EVENT(cuechange)
 EVENT(cuechange)
 
 ** Validate cue data
+* 1
 EXPECTED (cue.type == 'org.id3') OK
 EXPECTED (cue.data == 'null') OK
-EXPECTED ('{"value":{"key":"TIT2","data":"Stream Counting"}}' == '{"value":{"key":"TIT2","data":"Stream Counting"}}') OK
+EXPECTED (cue.value.key == '"TIT2"') OK
+EXPECTED (cue.value.data == '"Stream Counting"') OK
 
+* 2
 EXPECTED (cue.type == 'org.id3') OK
 EXPECTED (cue.data == 'null') OK
-EXPECTED ('{"value":{"key":"TPE1","data":"Andy"}}' == '{"value":{"key":"TPE1","data":"Andy"}}') OK
+EXPECTED (cue.value.key == '"TPE1"') OK
+EXPECTED (cue.value.data == '"Andy"') OK
 
+* 3
 EXPECTED (cue.type == 'org.id3') OK
 EXPECTED (cue.data == 'null') OK
-EXPECTED ('{"value":{"key":"TALB","data":"Greatest Hits"}}' == '{"value":{"key":"TALB","data":"Greatest Hits"}}') OK
+EXPECTED (cue.value.key == '"TALB"') OK
+EXPECTED (cue.value.data == '"Greatest Hits"') OK
 
+* 4
 EXPECTED (cue.type == 'org.id3') OK
 EXPECTED (cue.data == 'null') OK
-EXPECTED ('{"value":{"data":{},"info":"Our Hero","key":"GEOB","name":"abe.png","type":"image/png"}}' == '{"value":{"data":{},"info":"Our Hero","key":"GEOB","name":"abe.png","type":"image/png"}}') OK
+EXPECTED (cue.value.key == '"GEOB"') OK
+EXPECTED (cue.value.data == '{}') OK
+EXPECTED (cue.value.type == '"image/png"') OK
+EXPECTED (cue.value.info == '"Our Hero"') OK
+EXPECTED (cue.value.name == '"abe.png"') OK
 
+* 5
 EXPECTED (cue.type == 'org.id3') OK
 EXPECTED (cue.data == 'null') OK
-EXPECTED ('{"value":{"data":{},"key":"APIC","type":"image/png","dataType":"Movie/video screen capture"}}' == '{"value":{"data":{},"key":"APIC","type":"image/png","dataType":"Movie/video screen capture"}}') OK
+EXPECTED (cue.value.key == '"APIC"') OK
+EXPECTED (cue.value.data == '{}') OK
+EXPECTED (cue.value.type == '"image/png"') OK
 
+* 6
 EXPECTED (cue.type == 'org.id3') OK
 EXPECTED (cue.data == 'null') OK
-EXPECTED ('{"value":{"key":"TXXX","data":"Text Blob"}}' == '{"value":{"key":"TXXX","data":"Text Blob"}}') OK
+EXPECTED (cue.value.key == '"TXXX"') OK
+EXPECTED (cue.value.data == '"Text Blob"') OK
 
 ** Extract images from cue data, validate by setting img.src
 RUN(cueImageData = track.cues[3].value.data)
 EXPECTED (cueImageData instanceof ArrayBuffer == 'true') OK
-RUN(blobUrl = URL.createObjectURL(new Blob([cueImageData], { type: 'image/png' } )))
+RUN(blobUrl = URL.createObjectURL(new Blob([cueImageData], { type: 'image/png' })))
 RUN(imageElement.src = blobUrl)
 EVENT(load)
 EXPECTED (imageElement.width == '76') OK
@@ -55,7 +74,7 @@ EXPECTED (imageElement.height == '103') OK
 
 RUN(cueImageData = track.cues[4].value.data)
 EXPECTED (cueImageData instanceof ArrayBuffer == 'true') OK
-RUN(blobUrl = URL.createObjectURL(new Blob([cueImageData], { type: 'image/png' } )))
+RUN(blobUrl = URL.createObjectURL(new Blob([cueImageData], { type: 'image/png' })))
 RUN(imageElement.src = blobUrl)
 EVENT(load)
 EXPECTED (imageElement.width == '100') OK
index ab79898..1e055f2 100644 (file)
             var track;
             var cuechangeCount = 0;
             var loadCount = 0;
-            var cueJSON = [
-                 '{"value":{"key":"TIT2","data":"Stream Counting"}}',
-                 '{"value":{"key":"TPE1","data":"Andy"}}',
-                 '{"value":{"key":"TALB","data":"Greatest Hits"}}',
-                 '{"value":{"data":{},"info":"Our Hero","key":"GEOB","name":"abe.png","type":"image/png"}}',
-                 '{"value":{"data":{},"key":"APIC","type":"image/png","dataType":"Movie/video screen capture"}}',
-                 '{"value":{"key":"TXXX","data":"Text Blob"}}'
+            var cueData = [
+                 {"key" : "TIT2", "data" : "Stream Counting"},
+                 {"key" : "TPE1", "data" : "Andy"},
+                 {"key" : "TALB", "data" : "Greatest Hits"},
+                 {"key" : "GEOB", "data" : {}, "type" : "image/png", "info" : "Our Hero", "name" : "abe.png"},
+                 {"key" : "APIC", "data" : {}, "type" : "image/png"},
+                 {"key" : "TXXX", "data" : "Text Blob"},
             ];
             var imageSizes = [ [76, 103], [100, 100] ];
         
@@ -30,7 +30,7 @@
                 run("track.mode = 'hidden'");
                 track.addEventListener('cuechange', cuechange, true);
             }
-            
+
             function imageLoad()
             {
                 testExpected("imageElement.width", imageSizes[loadCount][0]);
             {
                 run("cueImageData = track.cues[" + cueIndex + "].value.data");
                 testExpected("cueImageData instanceof ArrayBuffer", true);
-                run("blobUrl = URL.createObjectURL(new Blob([cueImageData], { type: 'image/png' } ))");
+                run("blobUrl = URL.createObjectURL(new Blob([cueImageData], { type: 'image/png' }))");
                 imageElement = document.querySelector("#photo");
                 run("imageElement.src = blobUrl");
             }
-            
+
+            function compareCues(observed, expected)
+            {
+                // Make a mutable copy of the cue so we can remove attributes as they are processed.
+                observed = JSON.parse(JSON.stringify(observed));
+                for (property in expected) {
+                    observedValue = observed[property];
+                    expectedValue = expected[property];
+                    cue.value[property] = observedValue;
+
+                    observedValue = JSON.stringify(observedValue);
+                    expectedValue = JSON.stringify(expectedValue);
+                    reportExpected(observedValue == expectedValue, "cue.value." + property, "==", expectedValue, observedValue);
+                    delete observed[property];
+                }
+
+                for (property in observed) {
+                    observedName = property;
+                    observedValue = observed[property];
+                    logResult(Failed, "Error: unexpected cue property <em>cue.value." + observedName + "</em> = <em>'" + observedValue + "'</em> ");
+                }
+            }
+
             function cuechange(event)
             {
                 consoleWrite("EVENT(cuechange)");
                 if (++cuechangeCount != 6)
                     return;
 
-                consoleWrite("<br><i>** Validate cue data</i>");
+                consoleWrite("<br><em>** Validate cue data</em>");
                 track.removeEventListener("cuechange", cuechange, true);
                 video.pause();
-                
+
                 for (var i = 0; i < 6; i++) {
+                    consoleWrite("<em>* " + (i + 1) + "</em>");
                     cue = track.cues[i];
                     testExpected("cue.type", "org.id3");
                     testExpected("cue.data", null);
-                    testExpected("'" + JSON.stringify(cue) + "'", cueJSON[i]);
+                    compareCues(cue.value, cueData[i]);
                     consoleWrite("");
                 }
 
-                consoleWrite("<i>** Extract images from cue data, validate by setting img.src</i>");
+                consoleWrite("<em>** Extract images from cue data, validate by setting img.src</em>");
                 imageElement = document.querySelector("#photo");
                 waitForEvent('load', imageLoad, false, false, imageElement)
                 testImage(3);
 
             function canplaythrough()
             {
-                consoleWrite("<br><i>** Start playback, wait for all cues to load</i>");
-                video.play(); 
+                consoleWrite("<br><em>** Start playback, wait for all cues to load</em>");
+                run("video.play()"); 
             }
 
             function start()
             {
-                consoleWrite("<br><i>** Set video.src, wait for media data to load</i>");
+                consoleWrite("<br><em>** Set video.src, wait for media data to load</em>");
                 findMediaElement();
-                video.src = "http://127.0.0.1:8000/media/resources/hls/metadata/prog_index.m3u8";
+                run("video.src = 'http://127.0.0.1:8000/media/resources/hls/metadata/prog_index.m3u8'");
 
+                consoleWrite("");
                 waitForEvent("canplaythrough", canplaythrough);
                 waitForEvent('addtrack', addtrack, false, false, video.textTracks);
             }
index 3c6f8f1..b6ffe35 100644 (file)
@@ -1,3 +1,16 @@
+2014-05-06  Eric Carlson  <eric.carlson@apple.com>
+
+        [Mac] make metadata cue attributes consistent
+        https://bugs.webkit.org/show_bug.cgi?id=132610
+
+        Reviewed by Jer Noble.
+
+        No new tests, updated http/tests/media/track-in-band-hls-metadata.html.
+
+        * platform/mac/SerializedPlatformRepresentationMac.mm:
+        (WebCore::jsValueWithAVMetadataItemInContext): Don't include keys @dataTypeNamespace
+            or @pictureType, @dataType -> @type.
+
 2014-05-06  Brady Eidson  <beidson@apple.com>
 
         "Flash of content without image" when pasting a raw image from the pasteboard
index ab37b61..8d62ab6 100644 (file)
@@ -216,9 +216,17 @@ static JSValue *jsValueWithAVMetadataItemInContext(AVMetadataItemType *item, JSC
 
         if ([key isEqualToString:@"MIMEtype"])
             keyString = @"type";
-        else if ([key isEqualToString:@"info"] && [value isKindOfClass:[NSString class]] && ![value length]) {
-            // An "info" key is added to all TXXX, GEOB, and APIC items but the value may be empty.
+        else if ([key isEqualToString:@"dataTypeNamespace"] || [key isEqualToString:@"pictureType"])
             continue;
+        else if ([key isEqualToString:@"dataType"]) {
+            id dataTypeNamespace = [extras objectForKey:@"dataTypeNamespace"];
+            if (!dataTypeNamespace || ![dataTypeNamespace isKindOfClass:[NSString class]] || ![dataTypeNamespace isEqualToString:@"org.iana.media-type"])
+                continue;
+            keyString = @"type";
+        } else if ([value isKindOfClass:[NSString class]]) {
+            if (![value length])
+                continue;
+            keyString = [key lowercaseString];
         }
 
         [dictionary setObject:value forKey:keyString];