source: branches/PlayerFramework/CommonMediaPlayer/Media Players/DVD Framework/CMPDVDPlayerController.m @ 1099

Revision 1099, 17.1 KB checked in by lechium, 5 years ago (diff)

Fixed overlay on menus

Line 
1/*
2 * CMPDVDPlayerController.m
3 * CommonMediaPlayer
4 *
5 * Created by Graham Booker on Feb. 3 2010
6 * Copyright 2010 Common Media Player
7 * All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
10 * Lesser General Public License as published by the Free Software Foundation; either version 3 of the
11 * License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
14 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License along with this program; if
18 * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22#import "CMPDVDPlayerController.h"
23#import "CMPDVDPlayer.h"
24#import "CMPDVDWindowCreationAction.h"
25#import "CMPATVVersion.h"
26#import "CoreGraphicsServices.h"
27
28@interface NSObject (compat)
29- (void)setOpacity:(float)opacity;
30@end
31
32@interface CMPDVDPlayerController ()
33- (void)showResumeOverlayWithDismiss:(BOOL)dismiss;
34@end
35
36
37@implementation CMPDVDPlayerController
38
39+ (NSSet *)knownPlayers
40{
41        return [NSSet setWithObject:[CMPDVDPlayer class]];
42}
43
44#ifdef PLAY_WITH_OVERLAY
45static NSTimer *timer = nil;
46#endif
47
48- (id)initWithScene:(BRRenderScene *)scene player:(id <CMPPlayer>)aPlayer
49{
50        if([[BRMenuController class] instancesRespondToSelector:@selector(initWithScene:)])
51                self = [super initWithScene:scene];
52        else
53                self = [super init];
54        if(!self)
55                return self;
56       
57        [[self list] setDatasource:self];
58       
59        player = [aPlayer retain];
60        [player setController:self];
61       
62        [self setListTitle:@"Initiating DVD Playback"];
63        [self setListIcon:nil];
64       
65        windowCreation = [[CMPDVDWindowCreationAction alloc] initWithController:self andSettings:nil];
66#ifdef PLAY_WITH_OVERLAY
67        [timer invalidate];
68        timer = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(something) userInfo:nil repeats:NO];
69#endif
70       
71        return self;
72}
73
74#ifdef PLAY_WITH_OVERLAY
75- (void)setOpacity:(float)opacity
76{
77        CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
78        float clearComp[] = {0, 0, 0, 0};
79        CGColorRef clear = CGColorCreate(space, clearComp);
80        id layer = [[self header] layer];
81        int count = 0;
82        while(layer != nil)
83        {
84//              [layer setOpaque:NO];
85                NSLog(@"Layer is %@ with %d children", layer, [[layer sublayers] count]);
86                id superlayer = [layer superlayer];
87                //              if(count < 6)
88//              [layer setOpacity:opacity];
89                [layer setBackgroundColor:clear];
90                NSLog(@"Set opacity of %d layer", count);
91                layer = superlayer;
92                count++;
93        }
94}
95
96- (void)something
97{
98        static int counter = 0;
99        NSString *str = @"Some really long string for testing";
100        [self setListTitle:[str substringToIndex:counter]];
101//      [self setOpacity:0.0f];
102//      if(counter == 0)
103//      {
104//              CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
105//              float clearComp[] = {0, 0, 0, 0};
106//              CGColorRef clear = CGColorCreate(space, clearComp);
107//              id layer = [[self header] layer];
108//              int count = 0;
109//              while(layer != nil)
110//              {
111//                      [layer setOpaque:NO];
112//                      NSLog(@"Layer is %@ with %d children", layer, [[layer sublayers] count]);
113//                      id superlayer = [layer superlayer];
114////                    if(count < 6)
115//                              [layer setOpacity:0.0f];
116//                      NSLog(@"Set opacity of %d layer", count);
117//                      layer = superlayer;
118//                      count++;
119//              }
120//      }
121        counter++;
122        if(counter < [str length])
123                timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(something) userInfo:nil repeats:NO];
124        else
125        {
126                timer = nil;
127                counter = 0;
128        }
129
130}
131#endif
132
133- (void) dealloc
134{
135#ifdef PLAY_WITH_OVERLAY
136        [timer invalidate];
137        timer = nil;
138#endif
139        [player release];
140        [delegate release];
141        [windowCreation release];
142        [overlayDismiss invalidate];
143        [subtitlesOverlay release];
144        [audioOverlay release];
145        [chapterOverlay release];
146        [blurredMenu release];
147        [super dealloc];
148}
149
150
151- (id <CMPPlayer>)player
152{
153        return player;
154}
155
156- (void)setPlaybackSettings:(NSDictionary *)settings
157{
158        NSNumber *resume = [settings objectForKey:CMPPlayerResumeTimeKey];
159        if(resume != nil)
160        {
161                [player setResumeTime:[resume intValue]];
162        }
163}
164
165- (void)setPlaybackDelegate:(id <CMPPlayerControllerDelegate>)aDelegate
166{
167        delegate = [aDelegate retain];
168}
169
170- (id <CMPPlayerControllerDelegate>)delegate
171{
172        return delegate;
173}
174
175- (void)initiatePlayback
176{
177//      [self setOpacity:0.0f];
178        [windowCreation openWithError:nil];
179        BOOL resume = NO;
180        CMPDVDOverlayWindow *shield = [windowCreation addBlackShieldWindow];
181        [shield display];
182        [player initiatePlaybackWithResume:&resume];
183        if(resume)
184        {
185                [self showResumeOverlayWithDismiss:NO];
186                [windowCreation performSelector:@selector(closeOverlay:) withObject:shield afterDelay:0.5];
187        }
188        else
189                [windowCreation closeOverlay:shield];
190}
191
192- (void)playbackStopped
193{
194        [[self stack] popController];
195}
196
197#ifdef PLAY_WITH_OVERLAY
198- (BOOL)newFrameForTime:(void *)fp8
199{
200        return YES;
201        static int count = 0;
202        if(count == 0)
203        {
204                count = 0;
205                return YES;
206        }
207//      count++;
208        return NO;
209}
210
211- (void)drawFrameInBounds:(struct CGSize)size
212{
213        if(!blacked)
214        {
215                blacked = YES;
216                glColor4f(0, 0, 0, GL_ONE);
217                glBegin(GL_QUADS);
218                glVertex2f(0, 0);
219                glVertex2f(0, size.height);
220                glVertex2f(size.width, size.height);
221                glVertex2f(size.width, 0);
222                glEnd();
223        }
224       
225        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
226        return;
227       
228        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
229        glPixelZoom( 1.0, -1.0 );
230        CGSConnectionID cid = _CGSDefaultConnection();
231        CGRect bounds;
232        CGSWindowID dvdWindow = [windowCreation dvdWindow];
233        if(!dvdWindow)
234                return;
235        CGSGetWindowBounds(cid, dvdWindow, &bounds);
236        NSLog(@"Bounds is %fx%f - %fx%f", bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height);
237//      CGLGetCurrentContext()
238        char *bitmap = malloc(bounds.size.width *bounds.size.height * 4);
239        CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
240        CGContextRef context = CGBitmapContextCreate(bitmap, bounds.size.width, bounds.size.height, 8, bounds.size.width * 4, colorspace, kCGImageAlphaNoneSkipLast);
241    // Copy the contents of the window to the graphic context
242        CGContextCopyWindowCaptureContentsToRect(context, bounds, cid, dvdWindow, bounds);
243       
244        glRasterPos2f(0, 0);
245        glDrawPixels(bounds.size.width, bounds.size.height, GL_RGBA, GL_UNSIGNED_BYTE, bitmap);
246       
247//      GLuint texName;
248//      glGenTextures(1, &texName);
249//      glBindTexture (GL_TEXTURE_RECTANGLE_EXT, texName);
250//      glTexImage2D (GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, bounds.size.width, bounds.size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bitmap);
251//      glBindTexture (GL_TEXTURE_RECTANGLE_EXT, texName);
252//     
253//      glBegin (GL_QUADS);
254//      glTexCoord2f (0.0f, 0.0f); // draw upper left in world coordinates
255//      glVertex2f (bounds.origin.x, bounds.origin.y);
256//   
257//      glTexCoord2f (0.0f, bounds.size.height); // draw lower left in world coordinates
258//      glVertex2f (bounds.origin.x, bounds.origin.y + bounds.size.height);
259//   
260//      glTexCoord2f (bounds.size.width, bounds.size.height); // draw upper right in world coordinates
261//      glVertex2f (bounds.origin.x + bounds.size.width, bounds.origin.y + bounds.size.height);
262//   
263//      glTexCoord2f (bounds.size.width, 0.0f); // draw lower right in world coordinates
264//      glVertex2f (bounds.origin.x + bounds.size.width, bounds.origin.y);
265//      glEnd ();
266//      glDeleteTextures(1, &texName);
267        CGContextRelease(context);
268        CGColorSpaceRelease(colorspace);
269        free(bitmap);
270}
271
272- (void)controlWasActivated
273{
274        [super controlWasActivated];
275        [[BRRenderer singleton] addPlaybackDelegate:self];
276}
277#endif
278
279- (void)wasPushed
280{
281        [super wasPushed];
282        [self performSelector:@selector(initiatePlayback) withObject:nil afterDelay:0.3];
283}
284
285- (void)wasPopped
286{
287        [super wasPopped];
288#ifdef PLAY_WITH_OVERLAY
289        [[BRRenderer singleton] removePlaybackDelegate:self];
290       
291//      id layer = [[self header] layer];
292//      int count = 0;
293//      while(layer != nil)
294//      {
295//              [layer setOpaque:YES];
296//              NSLog(@"Layer is %@ with %d children", layer, [[layer sublayers] count]);
297//              id superlayer = [layer superlayer];
298//              [layer setOpacity:1.0f];
299//              NSLog(@"Set opacity of %d layer", count);
300//              layer = superlayer;
301//              count++;
302//      }       
303       
304#endif
305        NSMutableDictionary *endSettings = [[NSMutableDictionary alloc] init];
306        double elapsed = [player elapsedPlaybackTime];
307        double duration = [player trackDuration];
308       
309        if(elapsed != 0.0)
310                [endSettings setObject:[NSNumber numberWithDouble:elapsed] forKey:CMPPlayerResumeTimeKey];
311        if(duration != 0.0)
312                [endSettings setObject:[NSNumber numberWithDouble:duration] forKey:CMPPlayerDurationTimeKey];
313        [delegate controller:self didEndWithSettings:endSettings];
314        [delegate autorelease];
315        delegate = nil;
316        [endSettings release];
317       
318        [player stopPlayback];
319        [windowCreation closeWithError:nil];
320}
321
322- (void)releaseAllOverlaysWithFadeTime:(float)fadeTime
323{
324        [windowCreation closeAllOverlaysWithFadeTime:fadeTime];
325        [subtitlesOverlay release];
326        subtitlesOverlay = nil;
327        [audioOverlay release];
328        audioOverlay = nil;
329        [chapterOverlay release];
330        chapterOverlay = nil;
331        overlayMode = CMPDVDPlayerControllerOverlayModeNormal;
332}
333
334- (void)dismissOverlaysWithFadeTime:(float)fadeTime
335{
336        [self releaseAllOverlaysWithFadeTime:fadeTime];
337        [overlayDismiss invalidate];
338        overlayDismiss = nil;
339}
340
341- (void)fadeOverlays
342{
343        [self dismissOverlaysWithFadeTime:0.5];
344}
345
346- (void)resetOverlayTimerTo:(NSTimeInterval)time
347{
348        [overlayDismiss invalidate];
349        overlayDismiss = [NSTimer scheduledTimerWithTimeInterval:time target:self selector:@selector(fadeOverlays) userInfo:nil repeats:NO];
350}
351
352- (void)showPlayheadOverlay
353{
354        CMPDVDPlayerPlayHead *playhead = [windowCreation addPlayheadOverlay];
355        [playhead setPlayer:player];
356        [playhead displayWithFadeTime:0.1];
357}
358
359- (void)showSubAndAudioOverlays
360{
361        [self releaseAllOverlaysWithFadeTime:0];
362       
363        subtitlesOverlay = [[windowCreation addTextOverlayInPosition:CMPDVDOverlayUpperLeft] retain];
364        [subtitlesOverlay setText:[player currentSubFormat]];
365        [subtitlesOverlay displayWithFadeTime:0.25];
366        audioOverlay = [[windowCreation addTextOverlayInPosition:CMPDVDOverlayUpperRight] retain];
367        [audioOverlay setText:[player currentAudioFormat]];
368        [audioOverlay displayWithFadeTime:0.25];
369        overlayMode = CMPDVDPlayerControllerOverlayModeSubAndAudio;
370        [self resetOverlayTimerTo:10];
371}
372
373- (void)showChapterOverlay
374{
375        [self releaseAllOverlaysWithFadeTime:0];
376        chapterOverlay = [[windowCreation addTextOverlayInPosition:CMPDVDOverlayUpperLeft] retain];
377        [chapterOverlay setText:[NSString stringWithFormat:@"Chapter %d/%d", [player currentChapter], [player chapters]]];
378        [chapterOverlay displayWithFadeTime:0.25];
379        [self showPlayheadOverlay];
380        overlayMode = CMPDVDPlayerControllerOverlayModeChapters;
381        [self resetOverlayTimerTo:10];
382}
383
384- (void)setOverlayText:(NSString *)text inPosition:(CMPDVDOverlayPosition)position dismissingOthers:(BOOL)dismiss
385{
386        if(overlayMode != CMPDVDPlayerControllerOverlayModeNormal)
387                return;
388        if(dismiss)
389                [self releaseAllOverlaysWithFadeTime:0];
390        CMPDVDTextView *overlay = [windowCreation addTextOverlayInPosition:position];
391        [overlay setText:text];
392        [overlay displayWithFadeTime:0.25];
393        [self resetOverlayTimerTo:3];
394}
395
396- (void)showResumeOverlayWithDismiss:(BOOL)dismiss
397{
398        if(dismiss)
399                [self dismissOverlaysWithFadeTime:0];
400        blurredMenu = [[windowCreation addBlurredMenuOverlayWithItems:[NSArray arrayWithObjects:@"Resume Playback", @"Start From Beginning", @"Main Menu", nil]] retain];
401        [blurredMenu displayWithFadeTime:0.5];
402}
403
404- (NSString *)stringForPlayerState
405{
406        CMPDVDState state = [player state];
407        int speed = [player playSpeed];
408        NSString *text = nil;
409        if(state == CMPDVDStatePlaying)
410                text = [NSString stringWithFormat:@"%C", 0x25B6];
411        if(state == CMPDVDStatePaused)
412                text = [NSString stringWithFormat:@"%C%C", 0x258C, 0x258C];
413        else if(state == CMPDVDStateScanningForward)
414                text = [NSString stringWithFormat:@"%C%C%dx", 0x25B6, 0x25B6, speed];
415        else if(state == CMPDVDStateScanningBackward)
416                text = [NSString stringWithFormat:@"%C%C%dx", 0x25C0, 0x25C0, speed];
417        else if(state == CMPDVDStatePlayingSlowForward)
418                text = [NSString stringWithFormat:@"%C1/%dx", 0x25B6, speed];
419        else if(state == CMPDVDStatePlayingSlowBackward)
420                text = [NSString stringWithFormat:@"%C1/%dx", 0x25C0, speed];
421       
422        return text;
423}
424
425- (void)showStateOverlay
426{
427        [self setOverlayText:[self stringForPlayerState] inPosition:CMPDVDOverlayUpperLeft dismissingOthers:YES];
428        [self showPlayheadOverlay];
429}
430
431- (BOOL)brEventAction:(BREvent *)event
432{
433        NSLog(@"Got event %@", event);
434        BREventRemoteAction action = [CMPATVVersion remoteActionForEvent:event];
435        if(![player playing])
436                return [super brEventAction:event];
437       
438        if([event value] == 0 && action != kBREventRemoteActionMenu)
439                return NO;
440       
441        BOOL inMenu = [player inMenu];
442        CMPDVDState state = [player state];
443        NSLog(@"State is %d and doing %d", state, action);
444        BOOL playingInSomeForm = (state == CMPDVDStatePlaying || state == CMPDVDStateScanningForward || state == CMPDVDStateScanningBackward || state == CMPDVDStatePlayingSlowForward || state == CMPDVDStatePlayingSlowBackward);
445        BOOL supressStateDisplay = NO;
446       
447        switch (action) {
448                case kBREventRemoteActionSwipeRight:
449                case kBREventRemoteActionRight:
450                        if(blurredMenu)
451                                return NO;
452                        else if(inMenu)
453                                [player doUserNavigation:CMPDVDPlayerNavigationRight];
454                        else if(overlayMode == CMPDVDPlayerControllerOverlayModeSubAndAudio)
455                        {
456                                [player nextAudioStream];
457                                [audioOverlay setText:[player currentAudioFormat]];
458                                [self resetOverlayTimerTo:10];
459                        }
460                        else if(overlayMode == CMPDVDPlayerControllerOverlayModeChapters)
461                        {
462                                [player nextChapter];
463                                [chapterOverlay setText:[NSString stringWithFormat:@"Chapter %d/%d", [player currentChapter], [player chapters]]];
464                                [self resetOverlayTimerTo:10];
465                        }
466                        else if(playingInSomeForm)
467                                [player incrementScanRate];
468                        else
469                                [player nextFrame];
470                        break;
471                case kBREventRemoteActionSwipeLeft:
472                case kBREventRemoteActionLeft:
473                        if(blurredMenu)
474                                return NO;
475                        else if(inMenu)
476                                [player doUserNavigation:CMPDVDPlayerNavigationLeft];
477                        else if(overlayMode == CMPDVDPlayerControllerOverlayModeSubAndAudio)
478                        {
479                                [player nextSubStream];
480                                [subtitlesOverlay setText:[player currentSubFormat]];
481                                [self resetOverlayTimerTo:10];
482                        }
483                        else if(overlayMode == CMPDVDPlayerControllerOverlayModeChapters)
484                        {
485                                [player previousChapter];
486                                [chapterOverlay setText:[NSString stringWithFormat:@"Chapter %d/%d", [player currentChapter], [player chapters]]];
487                                [self resetOverlayTimerTo:10];
488                        }
489                        else if(playingInSomeForm)
490                                [player decrementScanRate];
491                        else
492                                //We cannot step frame backwards!!!!
493                                [player decrementScanRate];
494                        break;
495                case kBREventRemoteActionSwipeUp:
496                case kBREventRemoteActionUp:
497                        if(blurredMenu)
498                                return [blurredMenu previousItem];
499                        else if(inMenu)
500                                [player doUserNavigation:CMPDVDPlayerNavigationUp];
501                        else if(overlayMode == CMPDVDPlayerControllerOverlayModeNormal)
502                                [self showSubAndAudioOverlays];
503                        else if(overlayMode == CMPDVDPlayerControllerOverlayModeSubAndAudio)
504                                overlayMode = CMPDVDPlayerControllerOverlayModeNormal;
505                        else if(overlayMode == CMPDVDPlayerControllerOverlayModeChapters)
506                                overlayMode = CMPDVDPlayerControllerOverlayModeNormal;
507                        else
508                                ;//Something else
509                        break;
510                case kBREventRemoteActionSwipeDown:
511                case kBREventRemoteActionDown:
512                        if(blurredMenu)
513                                return [blurredMenu nextItem];
514                        else if(inMenu)
515                                [player doUserNavigation:CMPDVDPlayerNavigationDown];
516                        else if(overlayMode == CMPDVDPlayerControllerOverlayModeNormal)
517                                [self showChapterOverlay];
518                        else if(overlayMode == CMPDVDPlayerControllerOverlayModeSubAndAudio)
519                                overlayMode = CMPDVDPlayerControllerOverlayModeNormal;
520                        else if(overlayMode == CMPDVDPlayerControllerOverlayModeChapters)
521                                overlayMode = CMPDVDPlayerControllerOverlayModeNormal;
522                        else
523                                ;//Something else
524                        break;
525                case kBREventRemoteActionMenu:
526                        if(blurredMenu != nil)
527                                return [super brEventAction:event];
528                       
529                        [player pause];
530                        [self showResumeOverlayWithDismiss:YES];
531                        supressStateDisplay = YES;
532                        break;
533                case kBREventRemoteActionPlay:
534                        if(blurredMenu)
535                        {
536                                int selection = [blurredMenu selectedItem];
537                                [self dismissOverlaysWithFadeTime:0];
538                                [blurredMenu release];
539                                blurredMenu = nil;
540                                switch (selection) {
541                                        case 0:
542                                                [player play];
543                                                break;
544                                        case 1:
545                                                //Need to restart the playback somehow
546                                                [player restart];
547                                                break;
548                                        case 2:
549                                                [player goToMenu];
550                                                break;
551                                        default:
552                                                break;
553                                }
554                                supressStateDisplay = YES;
555                        }
556                        else if(inMenu)
557                                [player doUserNavigation:CMPDVDPlayerNavigationEnter];
558                        else if(state == CMPDVDStatePlaying)
559                                [player pause];
560                        else if(playingInSomeForm || state == CMPDVDStatePaused)
561                                [player play];
562                        else
563                                [player pause];
564                        break;
565                default:
566                        NSLog(@"unknown %d", action);
567                        return [super brEventAction:event];
568        }
569       
570        if (inMenu)
571                supressStateDisplay = YES;
572        else {
573                supressStateDisplay = NO;
574        }
575
576       
577        if(!supressStateDisplay && overlayMode == CMPDVDPlayerControllerOverlayModeNormal)
578                [self showStateOverlay];
579       
580        return YES;
581}
582
583- (NSString *)titleForRow:(long)row {
584        return nil;
585}
586
587-(float)heightForRow:(long)row {
588        return 0.0f;
589}
590
591-(id)itemForRow:(long)row {
592        return nil;
593}
594
595- (long)itemCount {
596        return 0;
597}
598
599- (void)itemSelected:(long)row
600{
601}
602
603- (id<BRMediaPreviewController>)previewControllerForItem:(long)row
604{
605        return nil;
606}
607
608- (id<BRMediaPreviewController>)previewControlForItem:(long)row
609{
610        return [self previewControllerForItem:row];
611}
612
613@end
Note: See TracBrowser for help on using the repository browser.