Browse Source

Merge pull request #134 from Tencent/bugfix/fixMp4Parser

bugfix:修复mp4 box 解析size 不完全问题以及添加兼容不含vapc box素材播放的强制enable设置入口
wubiner 4 years ago
parent
commit
e1ce9fb0b9

+ 1 - 1
QGVAPlayer.podspec

@@ -16,7 +16,7 @@ Pod::Spec.new do |spec|
   #
   #
 
 
   spec.name         = "QGVAPlayer"
   spec.name         = "QGVAPlayer"
-  spec.version      = "1.0.13"
+  spec.version      = "1.0.14"
   spec.summary      = "video animation player."
   spec.summary      = "video animation player."
   spec.platform     = :ios, "8.0"
   spec.platform     = :ios, "8.0"
 
 

+ 9 - 0
iOS/CHANGELOG.md

@@ -1,3 +1,12 @@
+## iOS 1.0.14
+
+**bugfix**
+
+- 修复MP4Parser解析box长度逻辑不完成导致解析box异常,无法播放素材问题[#issue133](https://github.com/Tencent/vap/issues/133)
+- UIView(VAP) 增加enableOldVersion接口,若素材非vap工具制作(不包含vapc box),则必须在播放前调用此接口设置enable,才可播放
+
+
+
 ## iOS 1.0.13
 ## iOS 1.0.13
 
 
 **feature**
 **feature**

+ 2 - 0
iOS/QGVAPlayer/QGVAPlayer/Classes/MP4Parser/QGMP4Box.h

@@ -20,6 +20,8 @@
 
 
 extern NSInteger const kQGBoxSizeLengthInBytes;
 extern NSInteger const kQGBoxSizeLengthInBytes;
 extern NSInteger const kQGBoxTypeLengthInBytes;
 extern NSInteger const kQGBoxTypeLengthInBytes;
+extern NSInteger const kQGBoxLargeSizeLengthInBytes;
+extern NSInteger const kQGBoxLargeSizeFlagLengthInBytes;
 
 
 @class QGMP4Box;
 @class QGMP4Box;
 typedef NSData* (^QGMp4BoxDataFetcher)(QGMP4Box *box);
 typedef NSData* (^QGMp4BoxDataFetcher)(QGMP4Box *box);

+ 2 - 0
iOS/QGVAPlayer/QGVAPlayer/Classes/MP4Parser/QGMP4Box.m

@@ -18,6 +18,8 @@
 
 
 NSInteger const kQGBoxSizeLengthInBytes = 4;
 NSInteger const kQGBoxSizeLengthInBytes = 4;
 NSInteger const kQGBoxTypeLengthInBytes = 4;
 NSInteger const kQGBoxTypeLengthInBytes = 4;
+NSInteger const kQGBoxLargeSizeLengthInBytes = 8;
+NSInteger const kQGBoxLargeSizeFlagLengthInBytes = 1;
 
 
 #pragma mark - boxes
 #pragma mark - boxes
 #pragma mark -- base box
 #pragma mark -- base box

+ 18 - 0
iOS/QGVAPlayer/QGVAPlayer/Classes/MP4Parser/QGMP4Parser.m

@@ -173,6 +173,19 @@
     }
     }
 }
 }
 
 
+unsigned long long dataConvertToUInt64(NSData *data) {
+    
+    unsigned long long largeSize = 0;
+    if (data.length < 8) {
+        return largeSize;
+    }
+    const char *bytes = data.bytes;
+    for (int i = 0; i < 8; i++) {
+        largeSize += ((bytes[i]&0xff) << (8 - i - 1) * 8);
+    }
+    return largeSize;
+}
+
 void readBoxTypeAndLength(NSFileHandle *fileHandle, unsigned long long offset, QGMP4BoxType *type, unsigned long long *length) {
 void readBoxTypeAndLength(NSFileHandle *fileHandle, unsigned long long offset, QGMP4BoxType *type, unsigned long long *length) {
     
     
     [fileHandle seekToFileOffset:offset];
     [fileHandle seekToFileOffset:offset];
@@ -180,6 +193,11 @@ void readBoxTypeAndLength(NSFileHandle *fileHandle, unsigned long long offset, Q
     const char *bytes = data.bytes;
     const char *bytes = data.bytes;
     *length = ((bytes[0]&0xff)<<24)+((bytes[1]&0xff)<<16)+((bytes[2]&0xff)<<8)+(bytes[3]&0xff);
     *length = ((bytes[0]&0xff)<<24)+((bytes[1]&0xff)<<16)+((bytes[2]&0xff)<<8)+(bytes[3]&0xff);
     *type = ((bytes[4]&0xff)<<24)+((bytes[5]&0xff)<<16)+((bytes[6]&0xff)<<8)+(bytes[7]&0xff);
     *type = ((bytes[4]&0xff)<<24)+((bytes[5]&0xff)<<16)+((bytes[6]&0xff)<<8)+(bytes[7]&0xff);
+    if (*length == kQGBoxLargeSizeFlagLengthInBytes) {
+        [fileHandle seekToFileOffset:offset + kQGBoxSizeLengthInBytes + kQGBoxTypeLengthInBytes];
+        NSData *largeSizeData = [fileHandle readDataOfLength:kQGBoxLargeSizeLengthInBytes];
+        *length = dataConvertToUInt64(largeSizeData);
+    }
 }
 }
 
 
 @end
 @end

+ 2 - 0
iOS/QGVAPlayer/QGVAPlayer/Classes/UIView+VAP.h

@@ -64,6 +64,8 @@ typedef NS_ENUM(NSUInteger, HWDMP4EBOperationType) {
 
 
 + (void)registerHWDLog:(QGVAPLoggerFunc)logger;
 + (void)registerHWDLog:(QGVAPLoggerFunc)logger;
 
 
+//当素材不包含vapc box时,只有在播放素材前调用此接口设置enable才可播放素材,否则素材无法播放
+- (void)enableOldVersion:(BOOL)enable;
 @end
 @end
 
 
 @interface UIView (VAPGesture)
 @interface UIView (VAPGesture)

+ 12 - 4
iOS/QGVAPlayer/QGVAPlayer/Classes/UIView+VAP.m

@@ -54,9 +54,9 @@ NSInteger const VapMaxCompatibleVersion = 2;
 @property (nonatomic, strong) QGVAPMetalView                *vap_metalView;             //vap格式mp4渲染图层
 @property (nonatomic, strong) QGVAPMetalView                *vap_metalView;             //vap格式mp4渲染图层
 @property (nonatomic, assign) BOOL                          hwd_isFinish;               //标记是否结束
 @property (nonatomic, assign) BOOL                          hwd_isFinish;               //标记是否结束
 @property (nonatomic, assign) NSInteger                     hwd_repeatCount;            //播放次数;-1 表示无限循环
 @property (nonatomic, assign) NSInteger                     hwd_repeatCount;            //播放次数;-1 表示无限循环
-@property (nonatomic, strong) QGVAPConfigManager            *hwd_configManager;             //额外的配置信息
-@property (nonatomic, strong) dispatch_queue_t              vap_renderQueue;                //播放队列
-
+@property (nonatomic, strong) QGVAPConfigManager            *hwd_configManager;         //额外的配置信息
+@property (nonatomic, strong) dispatch_queue_t              vap_renderQueue;            //播放队列
+@property (nonatomic, assign) BOOL                          vap_enableOldVersion;       //标记是否兼容不含vapc box的素材播放
 @end
 @end
 
 
 @implementation UIView (VAP)
 @implementation UIView (VAP)
@@ -339,6 +339,11 @@ NSInteger const VapMaxCompatibleVersion = 2;
         return ;
         return ;
     }
     }
     
     
+    if (!configManager.hasValidConfig && !self.vap_enableOldVersion) {
+        VAP_Error(kQGVAPModuleCommon, @"playHWDMP4 error! don't has vapc box and enableOldVersion is false!");
+        [self stopHWDMP4];
+        return ;
+    }
     //reset
     //reset
     self.hwd_currentFrameInstance = nil;
     self.hwd_currentFrameInstance = nil;
     self.hwd_decodeManager = nil;
     self.hwd_decodeManager = nil;
@@ -485,6 +490,9 @@ NSInteger const VapMaxCompatibleVersion = 2;
     [QGVAPLogger registerExternalLog:logger];
     [QGVAPLogger registerExternalLog:logger];
 }
 }
 
 
+- (void)enableOldVersion:(BOOL)enable {
+    self.vap_enableOldVersion = enable;
+}
 #pragma mark - delegate
 #pragma mark - delegate
 
 
 #pragma clang diagnostic push
 #pragma clang diagnostic push
@@ -600,7 +608,7 @@ HWDSYNTH_DYNAMIC_PROPERTY_OBJECT(vap_metalView, setVap_metalView, OBJC_ASSOCIATI
 HWDSYNTH_DYNAMIC_PROPERTY_OBJECT(hwd_attachmentsModel, setHwd_attachmentsModel, OBJC_ASSOCIATION_RETAIN)
 HWDSYNTH_DYNAMIC_PROPERTY_OBJECT(hwd_attachmentsModel, setHwd_attachmentsModel, OBJC_ASSOCIATION_RETAIN)
 HWDSYNTH_DYNAMIC_PROPERTY_OBJECT(hwd_configManager, setHwd_configManager, OBJC_ASSOCIATION_RETAIN)
 HWDSYNTH_DYNAMIC_PROPERTY_OBJECT(hwd_configManager, setHwd_configManager, OBJC_ASSOCIATION_RETAIN)
 HWDSYNTH_DYNAMIC_PROPERTY_OBJECT(vap_renderQueue, setVap_renderQueue, OBJC_ASSOCIATION_RETAIN)
 HWDSYNTH_DYNAMIC_PROPERTY_OBJECT(vap_renderQueue, setVap_renderQueue, OBJC_ASSOCIATION_RETAIN)
-
+HWDSYNTH_DYNAMIC_PROPERTY_CTYPE(vap_enableOldVersion, setVap_enableOldVersion, BOOL)
 @end
 @end
 
 
 
 

+ 3 - 0
iOS/QGVAPlayerDemo/QGVAPlayerDemo/ViewController.m

@@ -105,6 +105,9 @@ void qg_VAP_Logger_handler(VAPLogLevel level, const char* file, int line, const
     //单纯播放的接口
     //单纯播放的接口
     //[mp4View playHWDMp4:resPath];
     //[mp4View playHWDMp4:resPath];
     //指定素材混合模式,重复播放次数,delegate的接口
     //指定素材混合模式,重复播放次数,delegate的接口
+    
+    //注意若素材不含vapc box,则必须用调用如下接口设置enable才可播放
+    //[mp4View enableOldVersion:YES];
     [mp4View playHWDMP4:resPath repeatCount:-1 delegate:self];
     [mp4View playHWDMP4:resPath repeatCount:-1 delegate:self];
 }
 }