解码Vision Pro 空间视频格式 MV-HEVC

本文介绍了如何使用videoToolBox的VTDecompressionSession解码空间视频,详细阐述了创建解码会话的步骤及所需参数,并探讨了通过AVPlayer播放并处理MV-HEVC格式视频的方法,包括视频解码、图像转换、文件合并等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、使用videoToolBox解码空间视频

第一步: 创建解码会话
1、创建解码器方法介绍
VTDecompressionSessionCreate(
         CFAllocatorRef                               allocator,
         CMVideoFormatDescriptionRef                  videoFormatDescription,
         CFDictionaryRef                              videoDecoderSpecification,
         CFDictionaryRef                             destinationImageBufferAttributes,
        const VTDecompressionOutputCallbackRecord * CM_NULLABLE outputCallback,
         VTDecompressionSessionRef * CM_NONNULL decompressionSessionOut) API_AVAILABLE(macosx(10.8), ios(8.0), tvos(10.2));
  1. allocator(分配器):
    - 类型:CM_NULLABLE CFAllocatorRef
    - 描述:指定用于分配解压缩会话及其相关数据结构的内存分配器。可以传入 NULL,表示使用默认的内存分配器。
  2. videoFormatDescription(视频格式描述):
    - 类型:CM_NONNULL CMVideoFormatDescriptionRef
    - 描述:包含有关视频数据格式的信息的CoreMedia对象,通常由视频流的元数据提供。此参数用于描述待解压缩的视频数据的格式。
  3. videoDecoderSpecification(视频解码器规格):
    - 类型:CM_NULLABLE CFDictionaryRef
    - 描述:可选参数,允许您指定用于解码视频的特定解码器。传入 NULL 表示使用默认的解码器。
  4. destinationImageBufferAttributes(目标图像缓冲区属性):
    - 类型:CM_NULLABLE CFDictionaryRef
    - 描述:可选参数,允许您指定输出图像缓冲区的属性。例如,可以指定图像的像素格式等信息。
  5. outputCallback(输出回调):
    - 类型:const VTDecompressionOutputCallbackRecord * CM_NULLABLE
    - 描述:可选参数,如果不为 NULL,则在解压缩每帧后调用此回调函数以处理输出。可以为 NULL,表示不需要输出回调。
  6. decompressionSessionOut(解压缩会话输出):
    - 类型:CM_RETURNS_RETAINED_PARAMETER CM_NULLABLE VTDecompressionSessionRef * CM_NONNULL
    - 描述:指向将由此函数创建的解压缩会话的指针的指针。如果函数成功,则此指针将包含对新创建的解压缩会话的引用。需要调用者负责释放这个引用。
2、创建解码器需要的参数-CMFormatDescriptionRef
- (CMFormatDescriptionRef)getVideoFormatDescriptionFromURL:(NSURL *)videoURL {
   
    AVURLAsset *videoAsset = [AVURLAsset assetWithURL:videoURL];
    AVAssetTrack *videoTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] firstObject];
    if (!videoTrack) {
   
        NSLog(@"Video track not found in the asset.");
        return NULL;
    }
    
    CMFormatDescriptionRef formatDescription = (__bridge CMFormatDescriptionRef)videoTrack.formatDescriptions.firstObject;
    if (!formatDescription) {
   
        NSLog(@"Format description not found for the video track.");
        return NULL;
    }
    
    return formatDescription;
}
3、创建解码器需要的参数-CFDictionaryRef
- (NSDictionary *)createDecoderSpecification {
   
    NSDictionary *decoderSpecification = @{
   
        (__bridge NSString *)kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder : @YES,
        (__bridge NSString *)kVTVideoDecoderSpecification_RequireHardwareAcceleratedVideoDecoder : @YES,
        // 可以根据需要添加其他属性...
    };
    
    return decoderSpecification;
}
4、创建解码器
- (VTDecompressionSessionRef)createDecompressionSessionWithFormatDescription:(CMFormatDescriptionRef)videoFormatDescription {
   
    if (!videoFormatDescription) {
   
        NSLog(@"Invalid video format description.");
        return NULL;
    }
    NSDictionary *decoderSpecification = [self createDecoderSpecification];
    VTDecompressionSessionRef decompressionSession;
    OSStatus status = VTDecompressionSessionCreate(NULL,
                                                   videoFormatDescription,
                                                   (__bridge CFDictionaryRef)decoderSpecification,
                                                   NULL,
                                                   NULL,
                                                   &decompressionSession);
    
    NSLog(@"status: %d",status);
    if (status != noErr) {
   
        
        NSLog(@"Failed to create decompression session");
        return NULL;
    }
    return decompressionSession;
}
第二步:设置解码器属性
  NSArray *requestedLayerIDs = @[@0, @1];
    
    // 设置解码器属性
    OSStatus status = VTSessionSetProperty(sessionRef, kVTDecompressionPropertyKey_RequestedMVHEVCVideoLayerIDs, (__bridge CFArrayRef)requestedLayerIDs);
    
    if (status != noErr) {
   
        NSLog(@"设置 kVTDecompressionPropertyKey_RequestedMVHEVCVideoLayerIDs 属性失败,错误代码:%d", (int)status);
    } else {
   
        NSLog(@"成功设置 kVTDecompressionPropertyKey_RequestedMVHEVCVideoLayerIDs 属性");
    }
第三步:解析视频
// 根据 url 将完整视频逐帧去解码
- (void)processVideoWithURLV2:(NSURL *)url {
   
    
    AVAsset *asset = [AVAsset assetWithURL:url];
    NSError *error = nil;
    AVAssetReader *assetReader = [[AVAssetReader alloc] initWithAsset:asset error:&error];
    
    if (error) {
   
        NSLog(@"Error creating asset reader: %@", [error localizedDescription]);
        return;
    }
    AVAssetTrack *videoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] firstObject];
    AVAssetReaderTrackOutput *output = [[AVAssetReaderTrackOutput alloc] initWithTrack:videoTrack outputSettings:nil];
    [assetReader addOutput:output];
    
    [assetReader startRea
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值