Changeset 166719 in webkit
- Timestamp:
- Apr 3, 2014 8:46:05 AM (10 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 10 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r166715 r166719 1 2014-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 1 55 2014-04-03 Andrei Bucur <abucur@adobe.com> 2 56 -
trunk/Source/WebCore/Modules/plugins/QuickTimePluginReplacement.h
r165676 r166719 56 56 virtual RenderPtr<RenderElement> createElementRenderer(HTMLPlugInElement&, PassRef<RenderStyle>) override; 57 57 58 HTMLVideoElement* parentElement() { return m_mediaElement.get(); } 59 58 60 unsigned long long movieSize() const; 59 61 void postEvent(const String&); -
trunk/Source/WebCore/Modules/plugins/QuickTimePluginReplacement.idl
r165676 r166719 30 30 ] interface QuickTimePluginReplacement { 31 31 readonly attribute unsigned long long movieSize; 32 [CustomGetter] readonly attribute any timedMetaData; 33 [CustomGetter] readonly attribute any accessLog; 34 [CustomGetter] readonly attribute any errorLog; 32 35 void postEvent(DOMString eventName); 33 36 }; -
trunk/Source/WebCore/Modules/plugins/QuickTimePluginReplacement.js
r160640 r166719 323 323 timedMetadataUpdates: function() 324 324 { 325 // FIXME: not implemented yet. 325 try { 326 return this.host.timedMetaData; 327 } catch(e) { } 328 326 329 return null; 327 330 }, … … 329 332 accessLog: function() 330 333 { 331 // FIXME: not implemented yet. 334 try { 335 return this.host.accessLog; 336 } catch(e) { } 337 332 338 return null; 333 339 }, … … 335 341 errorLog: function() 336 342 { 337 // FIXME: not implemented yet. 343 try { 344 return this.host.errorLog; 345 } catch(e) { } 346 338 347 return null; 339 348 }, -
trunk/Source/WebCore/Modules/plugins/QuickTimePluginReplacement.mm
r166649 r166719 1 1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2013-2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 24 24 */ 25 25 26 #i nclude"config.h"26 #import "config.h" 27 27 28 28 #if ENABLE(MEDIA_CONTROLS_SCRIPT) 29 29 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 55 SOFT_LINK_FRAMEWORK_OPTIONAL(CoreMedia) 56 SOFT_LINK(CoreMedia, CMTimeCopyAsDictionary, CFDictionaryRef, (CMTime time, CFAllocatorRef allocator), (time, allocator)) 57 58 typedef AVMetadataItem AVMetadataItemType; 59 SOFT_LINK_FRAMEWORK_OPTIONAL(AVFoundation) 60 SOFT_LINK_CLASS(AVFoundation, AVMetadataItem) 61 #define AVMetadataItem getAVMetadataItemClass() 51 62 52 63 namespace WebCore { 64 65 #if PLATFORM(IOS) 66 static JSValue *jsValueWithValueInContext(id, JSContext *); 67 static JSValue *jsValueWithAVMetadataItemInContext(AVMetadataItemType *, JSContext *); 68 #endif 53 69 54 70 static String quickTimePluginReplacementScript() … … 142 158 DOMWrapperWorld& world = isolatedWorld(); 143 159 ScriptController& scriptController = page->mainFrame().script(); 144 JSDOMGlobalObject* globalObject = jsCast<JSDOMGlobalObject*>(scriptController.globalObject(world));145 ExecState* exec = globalObject->globalExec();146 147 JS Value 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")); 148 164 if (replacementFunction.isFunction()) 149 165 return true; … … 168 184 DOMWrapperWorld& world = isolatedWorld(); 169 185 ScriptController& scriptController = page->mainFrame().script(); 170 JSDOMGlobalObject* globalObject = jsCast<JSDOMGlobalObject*>(scriptController.globalObject(world));171 ExecState* exec = globalObject->globalExec();172 JS LockHolder lock(exec);186 JSDOMGlobalObject* globalObject = JSC::jsCast<JSDOMGlobalObject*>(scriptController.globalObject(world)); 187 JSC::ExecState* exec = globalObject->globalExec(); 188 JSC::JSLockHolder lock(exec); 173 189 174 190 // Lookup the "createPluginReplacement" function. 175 JS Value replacementFunction = globalObject->get(exec,Identifier(exec, "createPluginReplacement"));191 JSC::JSValue replacementFunction = globalObject->get(exec, JSC::Identifier(exec, "createPluginReplacement")); 176 192 if (replacementFunction.isUndefinedOrNull()) 177 193 return false; 178 JS Object* 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; 185 201 argList.append(toJS(exec, globalObject, root)); 186 202 argList.append(toJS(exec, globalObject, m_parentElement)); … … 188 204 argList.append(toJS<String>(exec, globalObject, m_names)); 189 205 argList.append(toJS<String>(exec, globalObject, m_values)); 190 JS Value replacement = call(exec, replacementObject, callType, callData, globalObject, argList);206 JSC::JSValue replacement = call(exec, replacementObject, callType, callData, globalObject, argList); 191 207 if (exec->hadException()) { 192 208 exec->clearException(); … … 195 211 196 212 // Get the <video> created to replace the plug-in. 197 JS Value value = replacement.get(exec,Identifier(exec, "video"));213 JSC::JSValue value = replacement.get(exec, JSC::Identifier(exec, "video")); 198 214 if (!exec->hadException() && !value.isUndefinedOrNull()) 199 215 m_mediaElement = toHTMLVideoElement(value); … … 206 222 207 223 // Get the scripting interface. 208 value = replacement.get(exec, Identifier(exec, "scriptObject"));224 value = replacement.get(exec, JSC::Identifier(exec, "scriptObject")); 209 225 if (!exec->hadException() && !value.isUndefinedOrNull()) 210 226 m_scriptObject = value.toObject(exec); … … 234 250 } 235 251 236 } 237 #endif 252 #if PLATFORM(IOS) 253 static 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 267 static 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 290 static 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 315 static 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 333 static 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 371 JSC::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 396 JSC::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 418 JSC::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 150 150 07277E5517D018CC0015534D /* JSMediaStreamTrackEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 07277E4917D018CC0015534D /* JSMediaStreamTrackEvent.h */; settings = {ATTRIBUTES = (Private, ); }; }; 151 151 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 */; }; 153 153 072AE1E8183C0741000A5988 /* QuickTimePluginReplacement.h in Headers */ = {isa = PBXBuildFile; fileRef = 072AE1E2183C0741000A5988 /* QuickTimePluginReplacement.h */; }; 154 154 072C8B11131C518600A4FCE9 /* MediaPlayerPrivateAVFoundation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 076F0D0912B8192700C26AA4 /* MediaPlayerPrivateAVFoundation.cpp */; }; … … 7022 7022 0729B14F17CFCCA0004F1D60 /* MediaStreamCenterMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaStreamCenterMac.h; sourceTree = "<group>"; }; 7023 7023 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>"; }; 7025 7025 072AE1E1183C0741000A5988 /* QuickTimePluginReplacement.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; name = QuickTimePluginReplacement.css; path = plugins/QuickTimePluginReplacement.css; sourceTree = "<group>"; }; 7026 7026 072AE1E2183C0741000A5988 /* QuickTimePluginReplacement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QuickTimePluginReplacement.h; path = plugins/QuickTimePluginReplacement.h; sourceTree = "<group>"; }; … … 14283 14283 children = ( 14284 14284 072AE1DF183C0741000A5988 /* PluginReplacement.h */, 14285 072AE1E0183C0741000A5988 /* QuickTimePluginReplacement. cpp*/,14285 072AE1E0183C0741000A5988 /* QuickTimePluginReplacement.mm */, 14286 14286 072AE1E1183C0741000A5988 /* QuickTimePluginReplacement.css */, 14287 14287 072AE1E2183C0741000A5988 /* QuickTimePluginReplacement.h */, … … 28600 28600 550A0BC9085F6039007353D6 /* QualifiedName.cpp in Sources */, 28601 28601 442AF7AA102CDDEA008FD4D3 /* QuickLook.mm in Sources */, 28602 072AE1E6183C0741000A5988 /* QuickTimePluginReplacement. cppin Sources */,28602 072AE1E6183C0741000A5988 /* QuickTimePluginReplacement.mm in Sources */, 28603 28603 379E371613736A6600B9E919 /* QuotedPrintable.cpp in Sources */, 28604 28604 5A574F28131DB96D00471B88 /* QuotesData.cpp in Sources */, -
trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp
r166250 r166719 641 641 m_private->setVideoFullscreenGravity(gravity); 642 642 } 643 644 NSArray* MediaPlayer::timedMetadata() const 645 { 646 return m_private->timedMetadata(); 647 } 648 649 String MediaPlayer::accessLog() const 650 { 651 return m_private->accessLog(); 652 } 653 654 String MediaPlayer::errorLog() const 655 { 656 return m_private->errorLog(); 657 } 643 658 #endif 644 659 -
trunk/Source/WebCore/platform/graphics/MediaPlayer.h
r166250 r166719 63 63 OBJC_CLASS AVAsset; 64 64 OBJC_CLASS AVPlayer; 65 OBJC_CLASS NSArray; 65 66 OBJC_CLASS QTMovie; 66 67 … … 309 310 enum VideoGravity { VideoGravityResize, VideoGravityResizeAspect, VideoGravityResizeAspectFill }; 310 311 void setVideoFullscreenGravity(VideoGravity); 311 #endif 312 313 NSArray *timedMetadata() const; 314 String accessLog() const; 315 String errorLog() const; 316 #endif 317 312 318 IntSize naturalSize(); 313 319 bool hasVideo() const; -
trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h
r165676 r166719 59 59 virtual void setVideoFullscreenFrame(FloatRect) { } 60 60 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 62 67 virtual void play() = 0; 63 68 virtual void pause() = 0; -
trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h
r166268 r166719 109 109 void durationDidChange(double); 110 110 void rateDidChange(double); 111 void metadataDidArrive(RetainPtr<NSArray>); 111 112 112 113 #if HAVE(AVFOUNDATION_VIDEO_OUTPUT) … … 153 154 virtual void setVideoFullscreenFrame(FloatRect); 154 155 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 156 162 virtual bool supportsAcceleratedRendering() const { return true; } 157 163 virtual float mediaTimeForTimeValue(float) const; … … 302 308 mutable RetainPtr<NSArray> m_cachedLoadedRanges; 303 309 RetainPtr<NSArray> m_cachedTracks; 310 RetainPtr<NSArray> m_currentMetaData; 304 311 FloatSize m_cachedPresentationSize; 305 312 double m_cachedDuration; -
trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm
r166408 r166719 99 99 #endif 100 100 101 typedef AVMetadataItem AVMetadataItemType; 102 101 103 SOFT_LINK_FRAMEWORK_OPTIONAL(AVFoundation) 102 104 SOFT_LINK_FRAMEWORK_OPTIONAL(CoreMedia) … … 133 135 SOFT_LINK_CLASS(AVFoundation, AVURLAsset) 134 136 SOFT_LINK_CLASS(AVFoundation, AVAssetImageGenerator) 137 SOFT_LINK_CLASS(AVFoundation, AVMetadataItem) 138 135 139 SOFT_LINK_CLASS(CoreImage, CIContext) 136 140 SOFT_LINK_CLASS(CoreImage, CIImage) … … 157 161 #define AVURLAsset getAVURLAssetClass() 158 162 #define AVAssetImageGenerator getAVAssetImageGeneratorClass() 163 #define AVMetadataItem getAVMetadataItemClass() 159 164 160 165 #define AVMediaCharacteristicVisual getAVMediaCharacteristicVisual() … … 848 853 [m_videoLayer setVideoGravity:videoGravity]; 849 854 } 855 856 NSArray *MediaPlayerPrivateAVFoundationObjC::timedMetadata() const 857 { 858 if (m_currentMetaData) 859 return m_currentMetaData.get(); 860 return nil; 861 } 862 863 String 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 874 String 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 } 850 884 #endif 851 885 … … 2193 2227 } 2194 2228 2229 void MediaPlayerPrivateAVFoundationObjC::metadataDidArrive(RetainPtr<NSArray> metadata) 2230 { 2231 if (!metadata || [metadata isKindOfClass:[NSNull class]]) 2232 return; 2233 2234 m_currentMetaData = metadata; 2235 } 2236 2195 2237 void MediaPlayerPrivateAVFoundationObjC::tracksDidChange(RetainPtr<NSArray> tracks) 2196 2238 { … … 2271 2313 @"duration", 2272 2314 @"hasEnabledAudio", 2315 @"timedMetadata", 2273 2316 nil]; 2274 2317 } … … 2358 2401 else if ([keyPath isEqualToString:@"duration"]) 2359 2402 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)); 2360 2405 } 2361 2406
Note: See TracChangeset
for help on using the changeset viewer.