framework2

Форк
0
779 строк · 21.0 Кб
1
//
2
//  ofAVFoundationPlayer.mm
3
//  Created by Lukasz Karluk on 06/07/14.
4
//	Merged with code by Sam Kronick, James George and Elie Zananiri.
5
//
6

7
//--------------------------------------------------------------
8
#import "ofAVFoundationPlayer.h"
9
#import "ofAVFoundationVideoPlayer.h"
10
#include "ofRectangle.h"
11
#include "ofGLUtils.h"
12

13
#ifdef TARGET_OSX
14
	#include "ofTexture.h"
15
#endif
16

17
//--------------------------------------------------------------
18
ofAVFoundationPlayer::ofAVFoundationPlayer() {
19
    videoPlayer = nullptr;
20
    pixelFormat = OF_PIXELS_RGBA;
21

22
    bFrameNew = false;
23
    bResetPixels = false;
24
    bUpdatePixels = false;
25
    bUpdateTexture = false;
26
	bUseTextureCache = true;
27
}
28

29
//--------------------------------------------------------------
30
ofAVFoundationPlayer::~ofAVFoundationPlayer() {
31
    disposePlayer();
32
}
33

34
//--------------------------------------------------------------
35
ofAVFoundationPlayer& ofAVFoundationPlayer::operator=(ofAVFoundationPlayer other)
36
{
37
	// clear pixels
38
	pixels.clear();
39
	videoTexture.clear();
40

41
	// get rid of the textures
42
	killTextureCache();
43

44
	bFrameNew = false;
45
	bResetPixels = false;
46
	bUpdatePixels = false;
47
	bUpdateTexture = false;
48
	bUseTextureCache = true;
49

50
	std::swap(videoPlayer, other.videoPlayer);
51
	return *this;
52
}
53

54
//--------------------------------------------------------------
55
void ofAVFoundationPlayer::loadAsync(std::string name){
56
    loadPlayer(name, true);
57
}
58

59
//--------------------------------------------------------------
60
bool ofAVFoundationPlayer::load(std::string name) {
61
    return loadPlayer(name, false);
62
}
63

64
//--------------------------------------------------------------
65
bool ofAVFoundationPlayer::loadPlayer(std::string name, bool bAsync) {
66
	if( ofGetUsingArbTex() == false ){
67
        killTextureCache();
68
		bUseTextureCache = false;
69
    }
70

71
	NSString * videoPath = [NSString stringWithUTF8String:name.c_str()];
72
	NSString * videoLocalPath = [NSString stringWithUTF8String:ofToDataPath(name).c_str()];
73

74
	BOOL bStream = NO;
75

76
	bStream = bStream || (ofIsStringInString(name, "http://"));
77
	bStream = bStream || (ofIsStringInString(name, "https://"));
78
	bStream = bStream || (ofIsStringInString(name, "rtsp://"));
79

80
	NSURL * url = nil;
81
	if(bStream == YES) {
82
		url = [NSURL URLWithString:videoPath];
83
	} else {
84
		url = [NSURL fileURLWithPath:videoLocalPath];
85
	}
86

87
	bFrameNew = false;
88
	bResetPixels = true;
89
	bUpdatePixels = true;
90
	bUpdateTexture = true;
91

92
	bool bLoaded = false;
93

94
	if(videoPlayer == nullptr) {
95
		// create a new player if its not allocated
96
		videoPlayer = [[ofAVFoundationVideoPlayer alloc] init];
97
		[videoPlayer setWillBeUpdatedExternally:YES];
98
	}
99

100
	bLoaded = [videoPlayer loadWithURL:url async:bAsync stream:bStream];
101

102
	pixels.clear();
103
	videoTexture.clear();
104

105
	bool bCreateTextureCache = bLoaded && bUseTextureCache && (_videoTextureCache == nullptr);
106

107
	if(bCreateTextureCache == true) {
108

109
		CVReturn err;
110

111
#if defined(TARGET_OF_IOS) && defined(__IPHONE_6_0)
112
		err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault,
113
										   nullptr,
114
										   [EAGLContext currentContext],
115
										   nullptr,
116
										   &_videoTextureCache);
117
#endif
118

119
#if defined(TARGET_OF_IOS) && !defined(__IPHONE_6_0)
120
		err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault,
121
										   nullptr,
122
										   (__bridge void *)[EAGLContext currentContext],
123
										   nullptr,
124
										   &_videoTextureCache);
125
#endif
126

127
#ifdef TARGET_OSX
128
		err = CVOpenGLTextureCacheCreate(kCFAllocatorDefault,
129
										 nullptr,
130
										 CGLGetCurrentContext(),
131
										 CGLGetPixelFormat(CGLGetCurrentContext()),
132
										 nullptr,
133
										 &_videoTextureCache);
134
#endif
135

136
		if(err) {
137
			ofLogWarning("ofAVFoundationPlayer") << "load(): error when creating texture cache, " << err << ".";
138
		}
139
	}
140

141

142
	if( bAsync == false && bLoaded ){
143
		pixels.allocate(getWidth(), getHeight(), getPixelFormat());
144
	}
145

146
    return bLoaded;
147
}
148

149
//--------------------------------------------------------------
150
void ofAVFoundationPlayer::disposePlayer() {
151

152
	if (videoPlayer != nullptr) {
153

154
		// clear pixels
155
		pixels.clear();
156
		videoTexture.clear();
157

158
		// dispose videoplayer
159
		__block ofAVFoundationVideoPlayer *currentPlayer = videoPlayer;
160
		dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
161
			@autoreleasepool {
162
				[currentPlayer unloadVideo]; // synchronious call to unload video
163
			}
164
		});
165

166
		videoPlayer = nullptr;
167
	}
168

169
	// get rid of the textures
170
	killTextureCache();
171

172

173
	bFrameNew = false;
174
	bResetPixels = false;
175
	bUpdatePixels = false;
176
	bUpdateTexture = false;
177
	bUseTextureCache = true;
178
}
179

180
//--------------------------------------------------------------
181
void ofAVFoundationPlayer::close() {
182
    if(videoPlayer != nullptr) {
183

184
        pixels.clear();
185
        videoTexture.clear();
186

187
		[videoPlayer close];
188
    }
189

190
    bFrameNew = false;
191
    bResetPixels = false;
192
    bUpdatePixels = false;
193
    bUpdateTexture = false;
194
	bUseTextureCache = true;
195
}
196

197
//--------------------------------------------------------------
198
bool ofAVFoundationPlayer::setPixelFormat(ofPixelFormat value) {
199
    bool bValid = false;
200
    bValid = bValid || (value == OF_PIXELS_RGB);
201
    bValid = bValid || (value == OF_PIXELS_RGBA);
202

203
    if(bValid == false) {
204
        ofLogWarning("ofAVFoundationPlayer") << "setPixelFormat(): unsupported ofPixelFormat, "
205
			<< ofToString(value) << ".";
206
        return false;
207
    }
208

209
    if(pixelFormat == value) {
210
        return true;
211
    }
212

213
    pixelFormat = value;
214
    bResetPixels = true;
215

216
    return true;
217
}
218

219
//--------------------------------------------------------------
220
ofPixelFormat ofAVFoundationPlayer::getPixelFormat() const{
221
    return pixelFormat;
222
}
223

224
//--------------------------------------------------------------
225
void ofAVFoundationPlayer::update() {
226

227
    bFrameNew = false; // default.
228

229
    if(!isLoaded() || !isReady()) {
230
        return;
231
    }
232

233
    [videoPlayer update];
234
    bFrameNew = [videoPlayer isNewFrame]; // check for new frame staright after the call to update.
235

236
    if(bFrameNew) {
237
        /**
238
         *  mark pixels to be updated.
239
         *  pixels are then only updated if the getPixels() method is called,
240
         *  internally or externally to this class.
241
         *  this ensures the pixels are updated only once per frame.
242
         */
243
        bUpdatePixels = true;
244
        bUpdateTexture = true;
245
    }
246
}
247

248
//--------------------------------------------------------------
249
void ofAVFoundationPlayer::draw() {
250
    draw(0, 0);
251
}
252

253
void ofAVFoundationPlayer::draw(float x, float y) {
254
    draw(x, y, getWidth(), getHeight());
255
}
256

257
void ofAVFoundationPlayer::draw(const ofRectangle & rect) {
258
    draw(rect.x, rect.y, rect.width, rect.height);
259
}
260

261
void ofAVFoundationPlayer::draw(float x, float y, float w, float h) {
262
    if(isLoaded() && isReady()) {
263

264
		ofTexture * texturePtr = getTexturePtr();
265
		if( texturePtr != NULL ){
266
			if( texturePtr->isAllocated() ){
267
				texturePtr->draw(x, y, w, h);
268
			}
269
		}
270
    }
271
}
272

273
//--------------------------------------------------------------
274
void ofAVFoundationPlayer::play() {
275
    if(videoPlayer == nullptr) {
276
        ofLogWarning("ofAVFoundationPlayer") << "play(): video not loaded.";
277
    }
278

279
    [videoPlayer play];
280
}
281

282
//--------------------------------------------------------------
283
void ofAVFoundationPlayer::stop() {
284
    if(videoPlayer == nullptr) {
285
        return;
286
    }
287

288
	[videoPlayer stop];
289
}
290

291
//--------------------------------------------------------------
292
bool ofAVFoundationPlayer::isFrameNew() const {
293
    if(videoPlayer != nullptr) {
294
        return bFrameNew;
295
    }
296
    return false;
297
}
298

299
//--------------------------------------------------------------
300
const ofPixels & ofAVFoundationPlayer::getPixels() const {
301
    return const_cast<ofAVFoundationPlayer *>(this)->getPixels();
302
}
303

304
ofPixels & ofAVFoundationPlayer::getPixels() {
305
    if(isLoaded() == false || pixels.size() == 0) {
306
        ofLogError("ofAVFoundationPlayer") << "getPixels(): Returning pixels that may be unallocated. Make sure to initialize the video player before calling getPixels.";
307
        return pixels;
308
    }
309

310
    if(bUpdatePixels == false) {
311
        // if pixels have not changed,
312
        // return the already calculated pixels.
313
        return pixels;
314
    }
315

316
    if(bResetPixels == true) {
317
        pixels.allocate(getWidth(), getHeight(), pixelFormat);
318
        bResetPixels = false;
319
    }
320

321
    CVImageBufferRef imageBuffer = [videoPlayer getCurrentFrame];
322

323
    CVPixelBufferLockBaseAddress(imageBuffer, kCVPixelBufferLock_ReadOnly);
324

325
    unsigned long imageBufferPixelFormat = CVPixelBufferGetPixelFormatType(imageBuffer);
326

327
    vImage_Buffer src = {
328
        CVPixelBufferGetBaseAddress(imageBuffer),
329
        CVPixelBufferGetHeight(imageBuffer),
330
        CVPixelBufferGetWidth(imageBuffer),
331
        CVPixelBufferGetBytesPerRow(imageBuffer)
332
    };
333

334
    vImage_Buffer dest = {
335
        pixels.getData(),
336
        static_cast<vImagePixelCount>(pixels.getHeight()),
337
        static_cast<vImagePixelCount>(pixels.getWidth()),
338
        static_cast<size_t>(pixels.getWidth() * pixels.getNumChannels())
339
    };
340

341
    vImage_Error err = kvImageNoError;
342

343
    if(pixelFormat == OF_PIXELS_RGBA) {
344

345
        if(imageBufferPixelFormat == kCVPixelFormatType_32ARGB) {
346

347
            uint8_t permuteMap[4] = { 1, 2, 3, 0 };
348
            err = vImagePermuteChannels_ARGB8888(&src, &dest, permuteMap, 0);
349

350
        } else if(imageBufferPixelFormat == kCVPixelFormatType_32BGRA) {
351

352
            uint8_t permuteMap[4] = { 2, 1, 0, 3 };
353
            err = vImagePermuteChannels_ARGB8888(&src, &dest, permuteMap, 0);
354
        }
355

356
    } else if(pixelFormat == OF_PIXELS_RGB) {
357

358
        if(imageBufferPixelFormat == kCVPixelFormatType_32ARGB) {
359

360
            err = vImageConvert_ARGB8888toRGB888(&src, &dest, 0);
361

362
        } else if(imageBufferPixelFormat == kCVPixelFormatType_32BGRA) {
363

364
#ifdef __IPHONE_6_0
365
            err = vImageConvert_BGRA8888toRGB888(&src, &dest, 0);
366
#else
367
            ofLogError("ofAVFoundationPlayer") << "getPixels(): OF_PIXELS_RGB is not supported, use setPixelFormat() to set the pixel format to OF_PIXELS_RGBA.";
368
#endif
369
        }
370
    }
371

372
    CVPixelBufferUnlockBaseAddress(imageBuffer, kCVPixelBufferLock_ReadOnly);
373

374
    if(err != kvImageNoError) {
375
        ofLogError("ofAVFoundationPlayer") << "getPixels(): error in pixel copy, vImage_error = " << err << ".";
376
    }
377

378
    bUpdatePixels = false;
379

380
    return pixels;
381
}
382

383
//--------------------------------------------------------------
384
ofTexture * ofAVFoundationPlayer::getTexturePtr() {
385

386
	if( bUseTextureCache == false ){
387
		return NULL;
388
	}
389

390
    if(isLoaded() == false || isReady() == false) {
391
        return &videoTexture;
392
    }
393

394
    if(bUpdateTexture == false) {
395
        return &videoTexture;
396
    }
397

398
    initTextureCache();
399

400
    bUpdateTexture = false;
401

402
    return &videoTexture;
403
}
404

405
//-------------------------------------------------------------- texture cache
406
void ofAVFoundationPlayer::initTextureCache() {
407
	//just in case - we return here if we shouldn't be using a texture cache
408
	if( bUseTextureCache == false ){
409
		return;
410
	}
411

412
    CVImageBufferRef imageBuffer = [videoPlayer getCurrentFrame];
413
    if(imageBuffer == nil) {
414
        return;
415
    }
416

417
    CVPixelBufferLockBaseAddress(imageBuffer, kCVPixelBufferLock_ReadOnly);
418

419
    /**
420
     *  video texture cache is available.
421
     *  this means we don't have to copy any pixels,
422
     *  and we can reuse the already existing video texture.
423
     *  this is very fast! :)
424
     */
425

426
    /**
427
     *  CVOpenGLESTextureCache does this operation for us.
428
     *  it automatically returns a texture reference which means we don't have to create the texture ourselves.
429
     *  this creates a slight problem because when we create an ofTexture objects, it also creates a opengl texture for us,
430
     *  which is unecessary in this case because the texture already exists.
431
     *  so... we can use ofTexture::setUseExternalTextureID() to get around this.
432
     */
433

434
	if (!videoTexture.isAllocated()) {
435
		int videoTextureW = getWidth();
436
		int videoTextureH = getHeight();
437
		videoTexture.allocate(videoTextureW, videoTextureH, GL_RGBA);
438

439
		ofTextureData & texData = videoTexture.getTextureData();
440
		texData.tex_t = 1.0f; // these values need to be reset to 1.0 to work properly.
441
		texData.tex_u = 1.0f; // assuming this is something to do with the way ios creates the texture cache.
442
		videoTexture.setTextureMinMagFilter(GL_LINEAR, GL_LINEAR);
443
		videoTexture.setTextureWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
444
	}
445

446
    CVReturn err;
447
    unsigned int textureCacheID;
448

449
#ifdef TARGET_OF_IOS
450

451
    /**
452
     *  create video texture from video image.
453
     *  inside this function, ios is creating the texture for us.
454
     *  a video texture reference is returned.
455
     */
456
    err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault,     // CFAllocatorRef allocator
457
                                                       _videoTextureCache,      // CVOpenGLESTextureCacheRef textureCache
458
                                                       imageBuffer,             // CVImageBufferRef sourceImage
459
                                                       nullptr,                    // CFDictionaryRef textureAttributes
460
                                                       texData.textureTarget,   // GLenum target
461
                                                       texData.glInternalFormat,  // GLint internalFormat
462
                                                       texData.width,           // GLsizei width
463
                                                       texData.height,          // GLsizei height
464
                                                       GL_BGRA,                 // GLenum format
465
                                                       GL_UNSIGNED_BYTE,        // GLenum type
466
                                                       0,                       // size_t planeIndex
467
                                                       &_videoTextureRef);      // CVOpenGLESTextureRef *textureOut
468

469
    textureCacheID = CVOpenGLESTextureGetName(_videoTextureRef);
470

471
#endif
472

473
#ifdef TARGET_OSX
474

475
    err = CVOpenGLTextureCacheCreateTextureFromImage(nullptr,
476
                                                     _videoTextureCache,
477
                                                     imageBuffer,
478
                                                     nullptr,
479
                                                     &_videoTextureRef);
480

481
    textureCacheID = CVOpenGLTextureGetName(_videoTextureRef);
482

483
#endif
484

485
    videoTexture.setUseExternalTextureID(textureCacheID);
486
    if(ofIsGLProgrammableRenderer() == false) {
487
        videoTexture.bind();
488
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
489
        videoTexture.unbind();
490
    }
491

492
    if(err) {
493
        ofLogError("ofAVFoundationPlayer") << "initTextureCache(): error creating texture cache from image " << err << ".";
494
    }
495
	
496
    CVPixelBufferUnlockBaseAddress(imageBuffer, kCVPixelBufferLock_ReadOnly);
497

498
#ifdef TARGET_OF_IOS
499
    CVOpenGLESTextureCacheFlush(_videoTextureCache, 0);
500
#endif
501

502
#ifdef TARGET_OSX
503
    CVOpenGLTextureCacheFlush(_videoTextureCache, 0);
504
#endif
505
	killTexture();
506
}
507

508
void ofAVFoundationPlayer::killTexture() {
509
#ifdef TARGET_OF_IOS
510
    if(_videoTextureRef) {
511
        CFRelease(_videoTextureRef);
512
        _videoTextureRef = nullptr;
513
    }
514
#elif defined TARGET_OSX
515
    if (_videoTextureRef != nullptr) {
516
        CVOpenGLTextureRelease(_videoTextureRef);
517
        _videoTextureRef = nullptr;
518
    }
519
#endif
520
}
521

522
void ofAVFoundationPlayer::killTextureCache() {
523

524
    killTexture();
525

526
#ifdef TARGET_OF_IOS
527
    if(_videoTextureCache) {
528
        CFRelease(_videoTextureCache);
529
        _videoTextureCache = nullptr;
530
    }
531
#endif
532

533
#ifdef TARGET_OSX
534
    if(_videoTextureCache != nullptr) {
535
        CVOpenGLTextureCacheRelease(_videoTextureCache);
536
        _videoTextureCache = nullptr;
537
    }
538

539
#endif
540
}
541

542
//--------------------------------------------------------------
543
float ofAVFoundationPlayer::getWidth() const {
544
    if(videoPlayer == nullptr) {
545
        return 0;
546
    }
547

548
    return [videoPlayer getWidth];
549
}
550

551
//--------------------------------------------------------------
552
float ofAVFoundationPlayer::getHeight() const {
553
    if(videoPlayer == nullptr) {
554
        return 0;
555
    }
556

557
    return [videoPlayer getHeight];
558
}
559

560
//--------------------------------------------------------------
561
bool ofAVFoundationPlayer::isPaused() const {
562
    if(videoPlayer == nullptr) {
563
        return false;
564
    }
565

566
	return [videoPlayer isPaused];
567
}
568

569
//--------------------------------------------------------------
570
bool ofAVFoundationPlayer::isLoaded() const {
571
    if(videoPlayer == nullptr) {
572
        return false;
573
    }
574

575
    return [videoPlayer isLoaded];
576
}
577

578
//--------------------------------------------------------------
579
bool ofAVFoundationPlayer::isReady() const {
580
    if(videoPlayer == nullptr) {
581
        return false;
582
    }
583

584
    return [videoPlayer isReady];
585
}
586

587
//--------------------------------------------------------------
588
bool ofAVFoundationPlayer::isPlaying() const {
589
    if(videoPlayer == nullptr) {
590
        return false;
591
    }
592

593
    return [videoPlayer isPlaying];
594
}
595

596
//--------------------------------------------------------------
597
float ofAVFoundationPlayer::getPosition() const {
598
    if(videoPlayer == nullptr) {
599
        return 0;
600
    }
601

602
    return [videoPlayer getPosition];
603
}
604

605
//--------------------------------------------------------------
606
float ofAVFoundationPlayer::getSpeed() const {
607
    if(videoPlayer == nullptr) {
608
        return 0;
609
    }
610

611
    return [videoPlayer getSpeed];
612
}
613

614
//--------------------------------------------------------------
615
float ofAVFoundationPlayer::getDuration() const {
616
    if(videoPlayer == nullptr) {
617
        return 0;
618
    }
619

620
    return [videoPlayer getDurationInSec];
621
}
622

623
//--------------------------------------------------------------
624
bool ofAVFoundationPlayer::getIsMovieDone() const {
625
    if(videoPlayer == nullptr) {
626
        return false;
627
    }
628

629
    return [videoPlayer isFinished];
630
}
631

632
//--------------------------------------------------------------
633
void ofAVFoundationPlayer::setPaused(bool bPause) {
634
    if(videoPlayer == nullptr) {
635
        return;
636
    }
637

638
    if(bPause) {
639
        [videoPlayer pause];
640
    } else {
641
        [videoPlayer play];
642
    }
643
}
644

645
//--------------------------------------------------------------
646
void ofAVFoundationPlayer::setPosition(float pct) {
647
    if(videoPlayer == nullptr) {
648
        return;
649
    }
650

651
    [videoPlayer setPosition:pct];
652
}
653

654
//--------------------------------------------------------------
655
void ofAVFoundationPlayer::setVolume(float volume) {
656
    if(videoPlayer == nullptr) {
657
        return;
658
    }
659
    if(volume > 1.0) {
660
        ofLogWarning("ofAVFoundationPlayer") << "setVolume(): expected range is 0-1, limiting requested volume " << volume << " to 1.0.";
661
        volume = 1.0;
662
    }
663
    [videoPlayer setVolume:volume];
664
}
665

666
//--------------------------------------------------------------
667
void ofAVFoundationPlayer::setLoopState(ofLoopType state) {
668
    if(videoPlayer == nullptr) {
669
        return;
670
    }
671

672
    [videoPlayer setLoop:(playerLoopType)state];
673
}
674

675
//--------------------------------------------------------------
676
void ofAVFoundationPlayer::setSpeed(float speed) {
677
    if(videoPlayer == nullptr) {
678
        return;
679
    }
680

681
    [videoPlayer setSpeed:speed];
682
}
683

684
//--------------------------------------------------------------
685
void ofAVFoundationPlayer::setFrame(int frame) {
686
    if(videoPlayer == nullptr) {
687
        return;
688
    }
689

690
    [videoPlayer setFrame:frame];
691
}
692

693
//--------------------------------------------------------------
694
int	ofAVFoundationPlayer::getCurrentFrame() const {
695
    if(videoPlayer == nullptr){
696
        return 0;
697
    }
698
    return [videoPlayer getCurrentFrameNum];
699
}
700

701
//--------------------------------------------------------------
702
int	ofAVFoundationPlayer::getTotalNumFrames() const {
703
    if(videoPlayer == nullptr){
704
        return 0;
705
    }
706
    return [videoPlayer getDurationInFrames];
707
}
708

709
//--------------------------------------------------------------
710
ofLoopType	ofAVFoundationPlayer::getLoopState() const {
711
    if(videoPlayer == nullptr) {
712
        return OF_LOOP_NONE;
713
    }
714

715
    bool bLoop =  [videoPlayer getLoop];
716
    if(bLoop) {
717
        return OF_LOOP_NORMAL;
718
    }
719
    return OF_LOOP_NONE;
720
}
721

722
//--------------------------------------------------------------
723
void ofAVFoundationPlayer::firstFrame() {
724
    if(videoPlayer == nullptr) {
725
        return;
726
    }
727

728
    [videoPlayer setPosition:0];
729
}
730

731
//--------------------------------------------------------------
732
void ofAVFoundationPlayer::nextFrame() {
733
    if(videoPlayer == nullptr) {
734
        return;
735
    }
736

737
    [videoPlayer stepByCount:1];
738
}
739

740
//--------------------------------------------------------------
741
void ofAVFoundationPlayer::previousFrame() {
742
    if(videoPlayer == nullptr) {
743
        return;
744
    }
745

746
    [videoPlayer stepByCount:-1];
747
}
748

749
//--------------------------------------------------------------
750
#ifdef __OBJC__
751

752
ofAVFoundationVideoPlayer * ofAVFoundationPlayer::getAVFoundationVideoPlayer() {
753
    return videoPlayer;
754
}
755

756
#else
757

758
void * ofAVFoundationPlayer::getAVFoundationVideoPlayer() {
759
	return videoPlayer;
760
}
761

762
#endif
763

764
//-------------------------------------------------------------- DEPRECATED.
765
bool ofAVFoundationPlayer::loadMovie(std::string name) {
766
    return load(name);
767
}
768

769
ofPixels & ofAVFoundationPlayer::getPixelsRef() {
770
    return getPixels();
771
}
772

773
const ofPixels & ofAVFoundationPlayer::getPixelsRef() const {
774
    return getPixels();
775
}
776

777
ofTexture * ofAVFoundationPlayer::getTexture() {
778
    return getTexturePtr();
779
}
780

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.