Changeset 166719 in webkit


Ignore:
Timestamp:
Apr 3, 2014 8:46:05 AM (10 years ago)
Author:
eric.carlson@apple.com
Message:

[iOS] add missing QuickTime plug-in replacement API
https://bugs.webkit.org/show_bug.cgi?id=131042

Reviewed by Dean Jackson.

Rename QuickTimePluginReplacement.cpp to QuickTimePluginReplacement.mm to make it possible
to use the ObjC JSC API.

  • Modules/plugins/QuickTimePluginReplacement.cpp:
  • Modules/plugins/QuickTimePluginReplacement.h:

(WebCore::QuickTimePluginReplacement::parentElement):

  • Modules/plugins/QuickTimePluginReplacement.idl:
  • Modules/plugins/QuickTimePluginReplacement.js:

(Replacement.prototype.timedMetadataUpdates): Implement.
(Replacement.prototype.accessLog): Ditto.
(Replacement.prototype.errorLog): Ditto.

Use the JSC ObjC API to create a JavaScript object from an array of AVMetadataItems. The
JSC ObjC API supports basic NSTypes, but an AVMetadataItem can also contain NSData which
the existing plug-in returns as base-64 encoded data, so create wrappers for NSDictionary
and NSArray.

  • Modules/plugins/QuickTimePluginReplacement.mm: Copied from Source/WebCore/Modules/plugins/QuickTimePluginReplacement.cpp.

(WebCore::QuickTimePluginReplacement::ensureReplacementScriptInjected): Disambiguate with "JSC::"
(WebCore::QuickTimePluginReplacement::installReplacement): Ditto.
(WebCore::jsValueWithDataInContext): Create JSValue* from NSData.
(WebCore::jsValueWithArrayInContext): Create JSValue* from NSArray.
(WebCore::jsValueWithDictionaryInContext): Create JSValue* from NSDictionary.
(WebCore::jsValueWithValueInContext): Create JSValue* from basic NSTypes plus AVMetadataItem

and NSData.

(WebCore::jsValueWithAVMetadataItemInContext): Create JSValue* from AVMetadataItem.
(WebCore::JSQuickTimePluginReplacement::timedMetaData): Script interface.
(WebCore::JSQuickTimePluginReplacement::accessLog): Ditto.
(WebCore::JSQuickTimePluginReplacement::errorLog): Ditto.

  • WebCore.xcodeproj/project.pbxproj: QuickTimePluginReplacement.cpp -> QuickTimePluginReplacement.mm.
  • platform/graphics/MediaPlayer.cpp:

(WebCore::MediaPlayer::timedMetadata): iOS only accessor.
(WebCore::MediaPlayer::accessLog): Ditto.
(WebCore::MediaPlayer::errorLog): Ditto.

  • platform/graphics/MediaPlayer.h:
  • platform/graphics/MediaPlayerPrivate.h:
  • platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
  • platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:

(WebCore::MediaPlayerPrivateAVFoundationObjC::timedMetadata):
(WebCore::MediaPlayerPrivateAVFoundationObjC::accessLog):
(WebCore::MediaPlayerPrivateAVFoundationObjC::errorLog):
(WebCore::MediaPlayerPrivateAVFoundationObjC::metadataDidArrive):
(WebCore::itemKVOProperties):
(-[WebCoreAVFMovieObserver observeValueForKeyPath:ofObject:change:context:]):

Location:
trunk/Source/WebCore
Files:
10 edited
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r166715 r166719  
     12014-04-03  Eric Carlson  <eric.carlson@apple.com>
     2
     3        [iOS] add missing QuickTime plug-in replacement API
     4        https://bugs.webkit.org/show_bug.cgi?id=131042
     5
     6        Reviewed by Dean Jackson.
     7
     8        Rename QuickTimePluginReplacement.cpp to QuickTimePluginReplacement.mm to make it possible
     9        to use the ObjC JSC API.
     10        * Modules/plugins/QuickTimePluginReplacement.cpp:
     11        * Modules/plugins/QuickTimePluginReplacement.h:
     12        (WebCore::QuickTimePluginReplacement::parentElement):
     13        * Modules/plugins/QuickTimePluginReplacement.idl:
     14
     15        * Modules/plugins/QuickTimePluginReplacement.js:
     16        (Replacement.prototype.timedMetadataUpdates): Implement.
     17        (Replacement.prototype.accessLog): Ditto.
     18        (Replacement.prototype.errorLog): Ditto.
     19
     20        Use the JSC ObjC API to create a JavaScript object from an array of AVMetadataItems. The
     21        JSC ObjC API supports basic NSTypes, but an AVMetadataItem can also contain NSData which
     22        the existing plug-in returns as base-64 encoded data, so create wrappers for NSDictionary
     23        and NSArray.
     24        * Modules/plugins/QuickTimePluginReplacement.mm: Copied from Source/WebCore/Modules/plugins/QuickTimePluginReplacement.cpp.
     25        (WebCore::QuickTimePluginReplacement::ensureReplacementScriptInjected): Disambiguate with "JSC::"
     26        (WebCore::QuickTimePluginReplacement::installReplacement): Ditto.
     27        (WebCore::jsValueWithDataInContext): Create JSValue* from NSData.
     28        (WebCore::jsValueWithArrayInContext): Create JSValue* from NSArray.
     29        (WebCore::jsValueWithDictionaryInContext): Create JSValue* from NSDictionary.
     30        (WebCore::jsValueWithValueInContext): Create JSValue* from basic NSTypes plus AVMetadataItem
     31            and NSData.
     32        (WebCore::jsValueWithAVMetadataItemInContext): Create JSValue* from AVMetadataItem.
     33        (WebCore::JSQuickTimePluginReplacement::timedMetaData): Script interface.
     34        (WebCore::JSQuickTimePluginReplacement::accessLog): Ditto.
     35        (WebCore::JSQuickTimePluginReplacement::errorLog): Ditto.
     36
     37        * WebCore.xcodeproj/project.pbxproj: QuickTimePluginReplacement.cpp -> QuickTimePluginReplacement.mm.
     38
     39        * platform/graphics/MediaPlayer.cpp:
     40        (WebCore::MediaPlayer::timedMetadata): iOS only accessor.
     41        (WebCore::MediaPlayer::accessLog): Ditto.
     42        (WebCore::MediaPlayer::errorLog): Ditto.
     43        * platform/graphics/MediaPlayer.h:
     44        * platform/graphics/MediaPlayerPrivate.h:
     45
     46        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
     47        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
     48        (WebCore::MediaPlayerPrivateAVFoundationObjC::timedMetadata):
     49        (WebCore::MediaPlayerPrivateAVFoundationObjC::accessLog):
     50        (WebCore::MediaPlayerPrivateAVFoundationObjC::errorLog):
     51        (WebCore::MediaPlayerPrivateAVFoundationObjC::metadataDidArrive):
     52        (WebCore::itemKVOProperties):
     53        (-[WebCoreAVFMovieObserver observeValueForKeyPath:ofObject:change:context:]):
     54
    1552014-04-03  Andrei Bucur  <abucur@adobe.com>
    256
  • trunk/Source/WebCore/Modules/plugins/QuickTimePluginReplacement.h

    r165676 r166719  
    5656    virtual RenderPtr<RenderElement> createElementRenderer(HTMLPlugInElement&, PassRef<RenderStyle>) override;
    5757
     58    HTMLVideoElement* parentElement() { return m_mediaElement.get(); }
     59
    5860    unsigned long long movieSize() const;
    5961    void postEvent(const String&);
  • trunk/Source/WebCore/Modules/plugins/QuickTimePluginReplacement.idl

    r165676 r166719  
    3030] interface QuickTimePluginReplacement {
    3131    readonly attribute unsigned long long movieSize;
     32    [CustomGetter] readonly attribute any timedMetaData;
     33    [CustomGetter] readonly attribute any accessLog;
     34    [CustomGetter] readonly attribute any errorLog;
    3235    void postEvent(DOMString eventName);
    3336};
  • trunk/Source/WebCore/Modules/plugins/QuickTimePluginReplacement.js

    r160640 r166719  
    323323    timedMetadataUpdates: function()
    324324    {
    325         // FIXME: not implemented yet.
     325        try {
     326            return this.host.timedMetaData;
     327        } catch(e) { }
     328
    326329        return null;
    327330    },
     
    329332    accessLog: function()
    330333    {
    331         // FIXME: not implemented yet.
     334        try {
     335            return this.host.accessLog;
     336        } catch(e) { }
     337
    332338        return null;
    333339    },
     
    335341    errorLog: function()
    336342    {
    337         // FIXME: not implemented yet.
     343        try {
     344            return this.host.errorLog;
     345        } catch(e) { }
     346
    338347        return null;
    339348    },
  • trunk/Source/WebCore/Modules/plugins/QuickTimePluginReplacement.mm

    r166649 r166719  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2014 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 #include "config.h"
     26#import "config.h"
    2727
    2828#if ENABLE(MEDIA_CONTROLS_SCRIPT)
    2929
    30 #include "QuickTimePluginReplacement.h"
    31 
    32 #include "Event.h"
    33 #include "HTMLPlugInElement.h"
    34 #include "HTMLVideoElement.h"
    35 #include "JSDOMBinding.h"
    36 #include "JSDOMGlobalObject.h"
    37 #include "JSHTMLVideoElement.h"
    38 #include "JSQuickTimePluginReplacement.h"
    39 #include "Logging.h"
    40 #include "MainFrame.h"
    41 #include "Page.h"
    42 #include "RenderElement.h"
    43 #include "ScriptController.h"
    44 #include "ScriptSourceCode.h"
    45 #include "UserAgentScripts.h"
    46 #include <JavaScriptCore/APICast.h>
    47 #include <JavaScriptCore/JSBase.h>
    48 #include <JavaScriptCore/JSCJSValueInlines.h>
    49 
    50 using namespace JSC;
     30#import "QuickTimePluginReplacement.h"
     31
     32#import "Event.h"
     33#import "HTMLPlugInElement.h"
     34#import "HTMLVideoElement.h"
     35#import "JSDOMBinding.h"
     36#import "JSDOMGlobalObject.h"
     37#import "JSHTMLVideoElement.h"
     38#import "JSQuickTimePluginReplacement.h"
     39#import "Logging.h"
     40#import "MainFrame.h"
     41#import "Page.h"
     42#import "RenderElement.h"
     43#import "ScriptController.h"
     44#import "ScriptSourceCode.h"
     45#import "SoftLinking.h"
     46#import "UserAgentScripts.h"
     47#import <objc/runtime.h>
     48#import <AVFoundation/AVFoundation.h>
     49#import <CoreMedia/CoreMedia.h>
     50#import <Foundation/NSString.h>
     51#import <JavaScriptCore/JavaScriptCore.h>
     52#import <JavaScriptCore/APICast.h>
     53#import <wtf/text/Base64.h>
     54
     55SOFT_LINK_FRAMEWORK_OPTIONAL(CoreMedia)
     56SOFT_LINK(CoreMedia, CMTimeCopyAsDictionary, CFDictionaryRef, (CMTime time, CFAllocatorRef allocator), (time, allocator))
     57
     58typedef AVMetadataItem AVMetadataItemType;
     59SOFT_LINK_FRAMEWORK_OPTIONAL(AVFoundation)
     60SOFT_LINK_CLASS(AVFoundation, AVMetadataItem)
     61#define AVMetadataItem getAVMetadataItemClass()
    5162
    5263namespace WebCore {
     64
     65#if PLATFORM(IOS)
     66static JSValue *jsValueWithValueInContext(id, JSContext *);
     67static JSValue *jsValueWithAVMetadataItemInContext(AVMetadataItemType *, JSContext *);
     68#endif
    5369
    5470static String quickTimePluginReplacementScript()
     
    142158    DOMWrapperWorld& world = isolatedWorld();
    143159    ScriptController& scriptController = page->mainFrame().script();
    144     JSDOMGlobalObject* globalObject = jsCast<JSDOMGlobalObject*>(scriptController.globalObject(world));
    145     ExecState* exec = globalObject->globalExec();
    146    
    147     JSValue replacementFunction = globalObject->get(exec, Identifier(exec, "createPluginReplacement"));
     160    JSDOMGlobalObject* globalObject = JSC::jsCast<JSDOMGlobalObject*>(scriptController.globalObject(world));
     161    JSC::ExecState* exec = globalObject->globalExec();
     162   
     163    JSC::JSValue replacementFunction = globalObject->get(exec, JSC::Identifier(exec, "createPluginReplacement"));
    148164    if (replacementFunction.isFunction())
    149165        return true;
     
    168184    DOMWrapperWorld& world = isolatedWorld();
    169185    ScriptController& scriptController = page->mainFrame().script();
    170     JSDOMGlobalObject* globalObject = jsCast<JSDOMGlobalObject*>(scriptController.globalObject(world));
    171     ExecState* exec = globalObject->globalExec();
    172     JSLockHolder lock(exec);
     186    JSDOMGlobalObject* globalObject = JSC::jsCast<JSDOMGlobalObject*>(scriptController.globalObject(world));
     187    JSC::ExecState* exec = globalObject->globalExec();
     188    JSC::JSLockHolder lock(exec);
    173189   
    174190    // Lookup the "createPluginReplacement" function.
    175     JSValue replacementFunction = globalObject->get(exec, Identifier(exec, "createPluginReplacement"));
     191    JSC::JSValue replacementFunction = globalObject->get(exec, JSC::Identifier(exec, "createPluginReplacement"));
    176192    if (replacementFunction.isUndefinedOrNull())
    177193        return false;
    178     JSObject* replacementObject = replacementFunction.toObject(exec);
    179     CallData callData;
    180     CallType callType = replacementObject->methodTable()->getCallData(replacementObject, callData);
    181     if (callType == CallTypeNone)
    182         return false;
    183 
    184     MarkedArgumentBuffer argList;
     194    JSC::JSObject* replacementObject = replacementFunction.toObject(exec);
     195    JSC::CallData callData;
     196    JSC::CallType callType = replacementObject->methodTable()->getCallData(replacementObject, callData);
     197    if (callType == JSC::CallTypeNone)
     198        return false;
     199
     200    JSC::MarkedArgumentBuffer argList;
    185201    argList.append(toJS(exec, globalObject, root));
    186202    argList.append(toJS(exec, globalObject, m_parentElement));
     
    188204    argList.append(toJS<String>(exec, globalObject, m_names));
    189205    argList.append(toJS<String>(exec, globalObject, m_values));
    190     JSValue replacement = call(exec, replacementObject, callType, callData, globalObject, argList);
     206    JSC::JSValue replacement = call(exec, replacementObject, callType, callData, globalObject, argList);
    191207    if (exec->hadException()) {
    192208        exec->clearException();
     
    195211
    196212    // Get the <video> created to replace the plug-in.
    197     JSValue value = replacement.get(exec, Identifier(exec, "video"));
     213    JSC::JSValue value = replacement.get(exec, JSC::Identifier(exec, "video"));
    198214    if (!exec->hadException() && !value.isUndefinedOrNull())
    199215        m_mediaElement = toHTMLVideoElement(value);
     
    206222
    207223    // Get the scripting interface.
    208     value = replacement.get(exec, Identifier(exec, "scriptObject"));
     224    value = replacement.get(exec, JSC::Identifier(exec, "scriptObject"));
    209225    if (!exec->hadException() && !value.isUndefinedOrNull())
    210226        m_scriptObject = value.toObject(exec);
     
    234250}
    235251
    236 }
    237 #endif
     252#if PLATFORM(IOS)
     253static JSValue *jsValueWithDataInContext(NSData *data, const String& mimeType, JSContext *context)
     254{
     255    Vector<char> base64Data;
     256    base64Encode([data bytes], [data length], base64Data);
     257
     258    String data64;
     259    if (!mimeType.isEmpty())
     260        data64 = "data:" + mimeType + ";base64," + base64Data;
     261    else
     262        data64 = "data:text/plain;base64," + base64Data;
     263
     264    return [JSValue valueWithObject:(id)data64.createCFString().get() inContext:context];
     265}
     266
     267static JSValue *jsValueWithArrayInContext(NSArray *array, JSContext *context)
     268{
     269    JSValueRef exception = 0;
     270    JSValue *result = [JSValue valueWithNewArrayInContext:context];
     271    JSObjectRef resultObject = JSValueToObject([context JSGlobalContextRef], [result JSValueRef], &exception);
     272    if (exception)
     273        return [JSValue valueWithUndefinedInContext:context];
     274
     275    NSUInteger count = [array count];
     276    for (NSUInteger i = 0; i < count; ++i) {
     277        JSValue *value = jsValueWithValueInContext([array objectAtIndex:i], context);
     278        if (!value)
     279            continue;
     280
     281        JSObjectSetPropertyAtIndex([context JSGlobalContextRef], resultObject, (unsigned)i, [value JSValueRef], &exception);
     282        if (exception)
     283            continue;
     284    }
     285
     286    return result;
     287}
     288
     289
     290static JSValue *jsValueWithDictionaryInContext(NSDictionary *dictionary, JSContext *context)
     291{
     292    JSValueRef exception = 0;
     293    JSValue *result = [JSValue valueWithNewObjectInContext:context];
     294    JSObjectRef resultObject = JSValueToObject([context JSGlobalContextRef], [result JSValueRef], &exception);
     295    if (exception)
     296        return [JSValue valueWithUndefinedInContext:context];
     297
     298    for (id key in [dictionary keyEnumerator]) {
     299        if (![key isKindOfClass:[NSString class]])
     300            continue;
     301
     302        JSValue *value = jsValueWithValueInContext([dictionary objectForKey:key], context);
     303        if (!value)
     304            continue;
     305
     306        JSStringRef name = JSStringCreateWithCFString((CFStringRef)key);
     307        JSObjectSetProperty([context JSGlobalContextRef], resultObject, name, [value JSValueRef], 0, &exception);
     308        if (exception)
     309            continue;
     310    }
     311
     312    return result;
     313}
     314
     315static JSValue *jsValueWithValueInContext(id value, JSContext *context)
     316{
     317    if ([value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSNumber class]])
     318        return [JSValue valueWithObject:value inContext:context];
     319    else if ([value isKindOfClass:[NSLocale class]])
     320        return [JSValue valueWithObject:[value localeIdentifier] inContext:context];
     321    else if ([value isKindOfClass:[NSDictionary class]])
     322        return jsValueWithDictionaryInContext(value, context);
     323    else if ([value isKindOfClass:[NSArray class]])
     324        return jsValueWithArrayInContext(value, context);
     325    else if ([value isKindOfClass:[NSData class]])
     326        return jsValueWithDataInContext(value, emptyString(), context);
     327    else if ([value isKindOfClass:[AVMetadataItem class]])
     328        return jsValueWithAVMetadataItemInContext(value, context);
     329
     330    return nil;
     331}
     332
     333static JSValue *jsValueWithAVMetadataItemInContext(AVMetadataItemType *item, JSContext *context)
     334{
     335    NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithDictionary:[item extraAttributes]];
     336
     337    if (item.keySpace)
     338        [dictionary setObject:item.keySpace forKey:@"keyspace"];
     339
     340    if (item.key)
     341        [dictionary setObject:item.key forKey:@"key"];
     342
     343    if (item.locale)
     344        [dictionary setObject:item.locale forKey:@"locale"];
     345
     346    if (CMTIME_IS_VALID(item.time)) {
     347        CFDictionaryRef timeDict = CMTimeCopyAsDictionary(item.time, kCFAllocatorDefault);
     348
     349        if (timeDict) {
     350            [dictionary setObject:(id)timeDict forKey:@"timestamp"];
     351            CFRelease(timeDict);
     352        }
     353    }
     354   
     355    if (item.value) {
     356        id value = item.value;
     357        NSString *mimeType = [[item extraAttributes] objectForKey:@"MIMEtype"];
     358        if ([value isKindOfClass:[NSData class]] && mimeType) {
     359            Vector<char> base64Data;
     360            base64Encode([value bytes], [value length], base64Data);
     361            String data64 = "data:" + String(mimeType) + ";base64," + base64Data;
     362            [dictionary setObject:(id)data64.createCFString().get() forKey:@"value"];
     363        } else
     364            [dictionary setObject:value forKey:@"value"];
     365    }
     366
     367    return jsValueWithDictionaryInContext(dictionary, context);
     368}
     369#endif
     370
     371JSC::JSValue JSQuickTimePluginReplacement::timedMetaData(JSC::ExecState* exec) const
     372{
     373#if PLATFORM(IOS)
     374    HTMLVideoElement* parent = impl().parentElement();
     375    if (!parent || !parent->player())
     376        return JSC::jsNull();
     377
     378    Frame* frame = parent->document().frame();
     379    if (!frame)
     380        return JSC::jsNull();
     381
     382    NSArray *metaData = parent->player()->timedMetadata();
     383    if (!metaData)
     384        return JSC::jsNull();
     385
     386    JSContext *jsContext = frame->script().javaScriptContext();
     387    JSValue *metaDataValue = jsValueWithValueInContext(metaData, jsContext);
     388   
     389    return toJS(exec, [metaDataValue JSValueRef]);
     390#else
     391    UNUSED_PARAM(exec);
     392    return JSC::jsNull();
     393#endif
     394}
     395
     396JSC::JSValue JSQuickTimePluginReplacement::accessLog(JSC::ExecState* exec) const
     397{
     398#if PLATFORM(IOS)
     399    HTMLVideoElement* parent = impl().parentElement();
     400    if (!parent || !parent->player())
     401        return JSC::jsNull();
     402
     403    Frame* frame = parent->document().frame();
     404    if (!frame)
     405        return JSC::jsNull();
     406
     407    JSValue *dictionary = [JSValue valueWithNewObjectInContext:frame->script().javaScriptContext()];
     408    String accessLogString = parent->player()->accessLog();
     409    [dictionary setValue:static_cast<NSString *>(accessLogString) forProperty:(NSString *)CFSTR("extendedLog")];
     410
     411    return toJS(exec, [dictionary JSValueRef]);
     412#else
     413    UNUSED_PARAM(exec);
     414    return JSC::jsNull();
     415#endif
     416}
     417
     418JSC::JSValue JSQuickTimePluginReplacement::errorLog(JSC::ExecState* exec) const
     419{
     420#if PLATFORM(IOS)
     421    HTMLVideoElement* parent = impl().parentElement();
     422    if (!parent || !parent->player())
     423        return JSC::jsNull();
     424
     425    Frame* frame = parent->document().frame();
     426    if (!frame)
     427        return JSC::jsNull();
     428
     429    JSValue *dictionary = [JSValue valueWithNewObjectInContext:frame->script().javaScriptContext()];
     430    String errorLogString = parent->player()->errorLog();
     431    [dictionary setValue:static_cast<NSString *>(errorLogString) forProperty:(NSString *)CFSTR("extendedLog")];
     432
     433    return toJS(exec, [dictionary JSValueRef]);
     434#else
     435    UNUSED_PARAM(exec);
     436    return JSC::jsNull();
     437#endif
     438}
     439
     440}
     441
     442#endif
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r166682 r166719  
    150150                07277E5517D018CC0015534D /* JSMediaStreamTrackEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 07277E4917D018CC0015534D /* JSMediaStreamTrackEvent.h */; settings = {ATTRIBUTES = (Private, ); }; };
    151151                072AE1E5183C0741000A5988 /* PluginReplacement.h in Headers */ = {isa = PBXBuildFile; fileRef = 072AE1DF183C0741000A5988 /* PluginReplacement.h */; };
    152                 072AE1E6183C0741000A5988 /* QuickTimePluginReplacement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 072AE1E0183C0741000A5988 /* QuickTimePluginReplacement.cpp */; };
     152                072AE1E6183C0741000A5988 /* QuickTimePluginReplacement.mm in Sources */ = {isa = PBXBuildFile; fileRef = 072AE1E0183C0741000A5988 /* QuickTimePluginReplacement.mm */; };
    153153                072AE1E8183C0741000A5988 /* QuickTimePluginReplacement.h in Headers */ = {isa = PBXBuildFile; fileRef = 072AE1E2183C0741000A5988 /* QuickTimePluginReplacement.h */; };
    154154                072C8B11131C518600A4FCE9 /* MediaPlayerPrivateAVFoundation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 076F0D0912B8192700C26AA4 /* MediaPlayerPrivateAVFoundation.cpp */; };
     
    70227022                0729B14F17CFCCA0004F1D60 /* MediaStreamCenterMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaStreamCenterMac.h; sourceTree = "<group>"; };
    70237023                072AE1DF183C0741000A5988 /* PluginReplacement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PluginReplacement.h; path = plugins/PluginReplacement.h; sourceTree = "<group>"; };
    7024                 072AE1E0183C0741000A5988 /* QuickTimePluginReplacement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = QuickTimePluginReplacement.cpp; path = plugins/QuickTimePluginReplacement.cpp; sourceTree = "<group>"; };
     7024                072AE1E0183C0741000A5988 /* QuickTimePluginReplacement.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = QuickTimePluginReplacement.mm; path = plugins/QuickTimePluginReplacement.mm; sourceTree = "<group>"; };
    70257025                072AE1E1183C0741000A5988 /* QuickTimePluginReplacement.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; name = QuickTimePluginReplacement.css; path = plugins/QuickTimePluginReplacement.css; sourceTree = "<group>"; };
    70267026                072AE1E2183C0741000A5988 /* QuickTimePluginReplacement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QuickTimePluginReplacement.h; path = plugins/QuickTimePluginReplacement.h; sourceTree = "<group>"; };
     
    1428314283                        children = (
    1428414284                                072AE1DF183C0741000A5988 /* PluginReplacement.h */,
    14285                                 072AE1E0183C0741000A5988 /* QuickTimePluginReplacement.cpp */,
     14285                                072AE1E0183C0741000A5988 /* QuickTimePluginReplacement.mm */,
    1428614286                                072AE1E1183C0741000A5988 /* QuickTimePluginReplacement.css */,
    1428714287                                072AE1E2183C0741000A5988 /* QuickTimePluginReplacement.h */,
     
    2860028600                                550A0BC9085F6039007353D6 /* QualifiedName.cpp in Sources */,
    2860128601                                442AF7AA102CDDEA008FD4D3 /* QuickLook.mm in Sources */,
    28602                                 072AE1E6183C0741000A5988 /* QuickTimePluginReplacement.cpp in Sources */,
     28602                                072AE1E6183C0741000A5988 /* QuickTimePluginReplacement.mm in Sources */,
    2860328603                                379E371613736A6600B9E919 /* QuotedPrintable.cpp in Sources */,
    2860428604                                5A574F28131DB96D00471B88 /* QuotesData.cpp in Sources */,
  • trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp

    r166250 r166719  
    641641    m_private->setVideoFullscreenGravity(gravity);
    642642}
     643
     644NSArray* MediaPlayer::timedMetadata() const
     645{
     646    return m_private->timedMetadata();
     647}
     648
     649String MediaPlayer::accessLog() const
     650{
     651    return m_private->accessLog();
     652}
     653
     654String MediaPlayer::errorLog() const
     655{
     656    return m_private->errorLog();
     657}
    643658#endif
    644659
  • trunk/Source/WebCore/platform/graphics/MediaPlayer.h

    r166250 r166719  
    6363OBJC_CLASS AVAsset;
    6464OBJC_CLASS AVPlayer;
     65OBJC_CLASS NSArray;
    6566OBJC_CLASS QTMovie;
    6667
     
    309310    enum VideoGravity { VideoGravityResize, VideoGravityResizeAspect, VideoGravityResizeAspectFill };
    310311    void setVideoFullscreenGravity(VideoGravity);
    311 #endif
     312
     313    NSArray *timedMetadata() const;
     314    String accessLog() const;
     315    String errorLog() const;
     316#endif
     317
    312318    IntSize naturalSize();
    313319    bool hasVideo() const;
  • trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h

    r165676 r166719  
    5959    virtual void setVideoFullscreenFrame(FloatRect) { }
    6060    virtual void setVideoFullscreenGravity(MediaPlayer::VideoGravity) { }
    61 #endif
     61
     62    virtual NSArray *timedMetadata() const { return 0; }
     63    virtual String accessLog() const { return emptyString(); }
     64    virtual String errorLog() const { return emptyString(); }
     65#endif
     66
    6267    virtual void play() = 0;
    6368    virtual void pause() = 0;   
  • trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h

    r166268 r166719  
    109109    void durationDidChange(double);
    110110    void rateDidChange(double);
     111    void metadataDidArrive(RetainPtr<NSArray>);
    111112
    112113#if HAVE(AVFOUNDATION_VIDEO_OUTPUT)
     
    153154    virtual void setVideoFullscreenFrame(FloatRect);
    154155    virtual void setVideoFullscreenGravity(MediaPlayer::VideoGravity);
    155 #endif
     156
     157    virtual NSArray *timedMetadata() const override;
     158    virtual String accessLog() const;
     159    virtual String errorLog() const;
     160#endif
     161
    156162    virtual bool supportsAcceleratedRendering() const { return true; }
    157163    virtual float mediaTimeForTimeValue(float) const;
     
    302308    mutable RetainPtr<NSArray> m_cachedLoadedRanges;
    303309    RetainPtr<NSArray> m_cachedTracks;
     310    RetainPtr<NSArray> m_currentMetaData;
    304311    FloatSize m_cachedPresentationSize;
    305312    double m_cachedDuration;
  • trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm

    r166408 r166719  
    9999#endif
    100100
     101typedef AVMetadataItem AVMetadataItemType;
     102
    101103SOFT_LINK_FRAMEWORK_OPTIONAL(AVFoundation)
    102104SOFT_LINK_FRAMEWORK_OPTIONAL(CoreMedia)
     
    133135SOFT_LINK_CLASS(AVFoundation, AVURLAsset)
    134136SOFT_LINK_CLASS(AVFoundation, AVAssetImageGenerator)
     137SOFT_LINK_CLASS(AVFoundation, AVMetadataItem)
     138
    135139SOFT_LINK_CLASS(CoreImage, CIContext)
    136140SOFT_LINK_CLASS(CoreImage, CIImage)
     
    157161#define AVURLAsset getAVURLAssetClass()
    158162#define AVAssetImageGenerator getAVAssetImageGeneratorClass()
     163#define AVMetadataItem getAVMetadataItemClass()
    159164
    160165#define AVMediaCharacteristicVisual getAVMediaCharacteristicVisual()
     
    848853    [m_videoLayer setVideoGravity:videoGravity];
    849854}
     855
     856NSArray *MediaPlayerPrivateAVFoundationObjC::timedMetadata() const
     857{
     858    if (m_currentMetaData)
     859        return m_currentMetaData.get();
     860    return nil;
     861}
     862
     863String MediaPlayerPrivateAVFoundationObjC::accessLog() const
     864{
     865    if (!m_avPlayerItem)
     866        return emptyString();
     867   
     868    AVPlayerItemAccessLog *log = [m_avPlayerItem.get() accessLog];
     869    RetainPtr<NSString> logString = adoptNS([[NSString alloc] initWithData:[log extendedLogData] encoding:[log extendedLogDataStringEncoding]]);
     870
     871    return logString.get();
     872}
     873
     874String MediaPlayerPrivateAVFoundationObjC::errorLog() const
     875{
     876    if (!m_avPlayerItem)
     877        return emptyString();
     878
     879    AVPlayerItemErrorLog *log = [m_avPlayerItem.get() errorLog];
     880    RetainPtr<NSString> logString = adoptNS([[NSString alloc] initWithData:[log extendedLogData] encoding:[log extendedLogDataStringEncoding]]);
     881
     882    return logString.get();
     883}
    850884#endif
    851885
     
    21932227}
    21942228
     2229void MediaPlayerPrivateAVFoundationObjC::metadataDidArrive(RetainPtr<NSArray> metadata)
     2230{
     2231    if (!metadata || [metadata isKindOfClass:[NSNull class]])
     2232        return;
     2233
     2234    m_currentMetaData = metadata;
     2235}
     2236
    21952237void MediaPlayerPrivateAVFoundationObjC::tracksDidChange(RetainPtr<NSArray> tracks)
    21962238{
     
    22712313                @"duration",
    22722314                @"hasEnabledAudio",
     2315                @"timedMetadata",
    22732316                nil];
    22742317    }
     
    23582401        else if ([keyPath isEqualToString:@"duration"])
    23592402            function = WTF::bind(&MediaPlayerPrivateAVFoundationObjC::durationDidChange, m_callback, CMTimeGetSeconds([newValue CMTimeValue]));
     2403        else if ([keyPath isEqualToString:@"timedMetadata"] && newValue)
     2404            function = WTF::bind(&MediaPlayerPrivateAVFoundationObjC::metadataDidArrive, m_callback, RetainPtr<NSArray>(newValue));
    23602405    }
    23612406
Note: See TracChangeset for help on using the changeset viewer.