diff --git a/iOS/QGVAPlayer/QGVAPlayer/Classes/Controllers/Decoders/QGBaseDecoder.h b/iOS/QGVAPlayer/QGVAPlayer/Classes/Controllers/Decoders/QGBaseDecoder.h index 436da3b8..bb02b491 100644 --- a/iOS/QGVAPlayer/QGVAPlayer/Classes/Controllers/Decoders/QGBaseDecoder.h +++ b/iOS/QGVAPlayer/QGVAPlayer/Classes/Controllers/Decoders/QGBaseDecoder.h @@ -17,6 +17,9 @@ #import "QGAnimatedImageDecodeThread.h" #import "QGBaseDFileInfo.h" +extern NSString* kQGVAPDecoderSeekStart; +extern NSString* kQGVAPDecoderSeekFinish; + @interface QGBaseDecoder : NSObject @property (atomic, assign) NSInteger currentDecodeFrame; //正在解码的帧索引 diff --git a/iOS/QGVAPlayer/QGVAPlayer/Classes/Controllers/Decoders/QGBaseDecoder.m b/iOS/QGVAPlayer/QGVAPlayer/Classes/Controllers/Decoders/QGBaseDecoder.m index 190c57ff..dfa7982e 100644 --- a/iOS/QGVAPlayer/QGVAPlayer/Classes/Controllers/Decoders/QGBaseDecoder.m +++ b/iOS/QGVAPlayer/QGVAPlayer/Classes/Controllers/Decoders/QGBaseDecoder.m @@ -16,6 +16,9 @@ #import "QGBaseDecoder.h" #import "QGAnimatedImageDecodeThreadPool.h" +NSString* kQGVAPDecoderSeekStart = @"kQGVAPDecoderSeekStart"; +NSString* kQGVAPDecoderSeekFinish = @"kQGVAPDecoderSeekFinish"; + @interface QGBaseDecoder() { QGBaseDFileInfo *_fileInfo; diff --git a/iOS/QGVAPlayer/QGVAPlayer/Classes/Controllers/Decoders/QGMP4FrameHWDecoder.m b/iOS/QGVAPlayer/QGVAPlayer/Classes/Controllers/Decoders/QGMP4FrameHWDecoder.m index 3c656cd7..97bfb10b 100644 --- a/iOS/QGVAPlayer/QGVAPlayer/Classes/Controllers/Decoders/QGMP4FrameHWDecoder.m +++ b/iOS/QGVAPlayer/QGVAPlayer/Classes/Controllers/Decoders/QGMP4FrameHWDecoder.m @@ -96,6 +96,8 @@ @interface QGMP4FrameHWDecoder() { /** Video Parameter Set */ @property (nonatomic, strong) NSData *vpsData; +@property (atomic, assign) NSInteger lastDecodeFrame; + @end NSString *const QGMP4HWDErrorDomain = @"QGMP4HWDErrorDomain"; @@ -136,6 +138,7 @@ - (instancetype)initWith:(QGMP4HWDFileInfo *)fileInfo error:(NSError *__autorele if (self = [super initWith:fileInfo error:error]) { _decodeQueue = dispatch_queue_create("com.qgame.vap.decode", DISPATCH_QUEUE_SERIAL); + _lastDecodeFrame = -1; _mp4Parser = fileInfo.mp4Parser; BOOL isOpenSuccess = [self onInputStart]; if (!isOpenSuccess) { @@ -166,6 +169,10 @@ - (void)decodeFrame:(NSInteger)frameIndex buffers:(NSMutableArray *)buffers { self.currentDecodeFrame = frameIndex; _buffers = buffers; dispatch_async(self.decodeQueue, ^{ + if (frameIndex != self.lastDecodeFrame + 1) { + // 必须是依次增大,否则解出来的画面会异常 + return; + } [self _decodeFrame:frameIndex drop:NO]; }); } @@ -294,6 +301,8 @@ - (void)handleDecodePixelBuffer:(CVPixelBufferRef)pixelBuffer status:(OSStatus)status needDrop:(BOOL)dropFlag { + self.lastDecodeFrame = frameIndex; + CFRelease(sampleBuffer); if(status == kVTInvalidSessionErr) { @@ -489,6 +498,9 @@ - (void)resetDecoder { } - (void)findKeyFrameAndDecodeToCurrent:(NSInteger)frameIndex { + + [[NSNotificationCenter defaultCenter] postNotificationName:kQGVAPDecoderSeekStart object:self]; + NSArray *keyframeIndexes = [_mp4Parser videoSyncSampleIndexes]; NSInteger index = [[keyframeIndexes firstObject] integerValue]; for(NSNumber *number in keyframeIndexes) { @@ -506,6 +518,8 @@ - (void)findKeyFrameAndDecodeToCurrent:(NSInteger)frameIndex { index++; } [self _decodeFrame:frameIndex drop:NO]; + + [[NSNotificationCenter defaultCenter] postNotificationName:kQGVAPDecoderSeekFinish object:self]; } - (void)_onInputEnd { diff --git a/iOS/QGVAPlayer/QGVAPlayer/Classes/Controllers/QGAnimatedImageDecodeManager.h b/iOS/QGVAPlayer/QGVAPlayer/Classes/Controllers/QGAnimatedImageDecodeManager.h index abf16331..3cb1aaef 100644 --- a/iOS/QGVAPlayer/QGVAPlayer/Classes/Controllers/QGAnimatedImageDecodeManager.h +++ b/iOS/QGVAPlayer/QGVAPlayer/Classes/Controllers/QGAnimatedImageDecodeManager.h @@ -53,5 +53,6 @@ - (QGBaseAnimatedImageFrame *)consumeDecodedFrame:(NSInteger)frameIndex; - (void)tryToStartAudioPlay; +- (BOOL)containsThisDeocder:(id)decoder; @end diff --git a/iOS/QGVAPlayer/QGVAPlayer/Classes/Controllers/QGAnimatedImageDecodeManager.m b/iOS/QGVAPlayer/QGVAPlayer/Classes/Controllers/QGAnimatedImageDecodeManager.m index 56e64921..78ab6776 100644 --- a/iOS/QGVAPlayer/QGVAPlayer/Classes/Controllers/QGAnimatedImageDecodeManager.m +++ b/iOS/QGVAPlayer/QGVAPlayer/Classes/Controllers/QGAnimatedImageDecodeManager.m @@ -174,4 +174,13 @@ - (void)dealloc { } +- (BOOL)containsThisDeocder:(id)decoder { + for (id d in _decoders) { + if (d == decoder) { + return YES; + } + } + return NO; +} + @end diff --git a/iOS/QGVAPlayer/QGVAPlayer/Classes/UIView+VAP.m b/iOS/QGVAPlayer/QGVAPlayer/Classes/UIView+VAP.m index 01345240..9525f498 100644 --- a/iOS/QGVAPlayer/QGVAPlayer/Classes/UIView+VAP.m +++ b/iOS/QGVAPlayer/QGVAPlayer/Classes/UIView+VAP.m @@ -48,6 +48,7 @@ @interface UIView () )MP4PlayDelegate { //category methods HWDSYNTH_DYNAMIC_PROPERTY_CTYPE(hwd_onPause, setHwd_onPause, BOOL) +HWDSYNTH_DYNAMIC_PROPERTY_CTYPE(hwd_onSeek, setHwd_onSeek, BOOL) HWDSYNTH_DYNAMIC_PROPERTY_CTYPE(hwd_renderByOpenGL, setHwd_renderByOpenGL, BOOL) HWDSYNTH_DYNAMIC_PROPERTY_CTYPE(hwd_isFinish, setHwd_isFinish, BOOL) HWDSYNTH_DYNAMIC_PROPERTY_CTYPE(hwd_fps, setHwd_fps, NSInteger) diff --git a/iOS/QGVAPlayerDemo/QGVAPlayerDemo/ViewController.m b/iOS/QGVAPlayerDemo/QGVAPlayerDemo/ViewController.m index 6d23f01b..3ecbb4ec 100644 --- a/iOS/QGVAPlayerDemo/QGVAPlayerDemo/ViewController.m +++ b/iOS/QGVAPlayerDemo/QGVAPlayerDemo/ViewController.m @@ -114,7 +114,9 @@ - (void)playVapWithWrapView { NSString *resPath = [NSString stringWithFormat:@"%@/Resource/demo.mp4", [[NSBundle mainBundle] resourcePath]]; [wrapView vapWrapView_playHWDMP4:resPath repeatCount:-1 delegate:self]; UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onImageviewTap:)]; - [wrapView addGestureRecognizer:tap]; + [wrapView vapWrapView_addVapGesture:tap callback:^(UIGestureRecognizer *gestureRecognizer, BOOL insideSource, QGVAPSourceDisplayItem *source) { + + }]; } #pragma mark - mp4 hwd delegate