2016-08-09 12 views
1

Моя цель - зеркально отобразить экран iDevice до OSX, насколько это возможно.Может ли VideoToolbox декодировать H264 Приложение B изначально? Код ошибки -8969 BadData

Насколько мне известно, есть 2 пути к этому:

  1. Airplay Mirroring (например, отражатель)
  2. CoreMediaIO через Lightning (например Quicktime запись)

Я избрал проводить второй метод , потому что (насколько мне известно) подключенные iDevices могут быть распознаны как устройства DAL автоматически после одноразовой настройки.

Главный ресурс о том, как сделать это этот блог: https://nadavrub.wordpress.com/2015/07/06/macos-media-capture-using-coremediaio/

Этот блог идет очень глубоко в том, как использовать CoreMediaIO, однако, кажется, как вы можете работать с AVFoundation как только вы признали подключенную чтения компакт-дисков в качестве AVCaptureDevice.

Этот вопрос: How to mirror iOS screen via USB? опубликовал решение о том, как захватить каждый кадр потока данных Muxxed H264 (Приложение B), поставляемого iDevice.

Однако проблема заключается в том, что VideoToolbox не будет корректно декодировать (код ошибки -8969, BadData), хотя в коде не должно быть никакой разницы.

vtDecompressionDuctDecodeSingleFrame сигнал заблуждается = -8969 (ERR) (VTVideoDecoderDecodeFrame возвращенной ошибки) в /SourceCache/CoreMedia_frameworks/CoreMedia-1562.240/Sources/VideoToolbox/VTDecompressionSession.c линиях 3241

Полный код:

#import "ViewController.h" 

@import CoreMediaIO; 
@import AVFoundation; 
@import AppKit; 

@implementation ViewController 

AVCaptureSession *session; 
AVCaptureDeviceInput *newVideoDeviceInput; 
AVCaptureVideoDataOutput *videoDataOutput; 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
} 

- (instancetype)initWithCoder:(NSCoder *)coder 
{ 
    self = [super initWithCoder:coder]; 
    if (self) { 
     // Allow iOS Devices Discovery 
     CMIOObjectPropertyAddress prop = 
     { kCMIOHardwarePropertyAllowScreenCaptureDevices, 
      kCMIOObjectPropertyScopeGlobal, 
      kCMIOObjectPropertyElementMaster }; 
     UInt32 allow = 1; 
     CMIOObjectSetPropertyData(kCMIOObjectSystemObject, 
            &prop, 0, NULL, 
            sizeof(allow), &allow); 

     // Get devices 
     NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeMuxed]; 
     BOOL deviceAttahced = false; 
     for (int i = 0; i < [devices count]; i++) { 
      AVCaptureDevice *device = devices[i]; 
      if ([[device uniqueID] isEqualToString:@"b48defcadf92f300baf5821923f7b3e2e9fb3947"]) { 
       deviceAttahced = true; 
       [self startSession:device]; 
       break; 
      } 
     } 

    } 
    return self; 
} 

- (void) deviceConnected:(AVCaptureDevice *)device { 
    if ([[device uniqueID] isEqualToString:@"b48defcadf92f300baf5821923f7b3e2e9fb3947"]) { 
     [self startSession:device]; 
    } 
} 

- (void) startSession:(AVCaptureDevice *)device { 

    // Init capturing session 
    session = [[AVCaptureSession alloc] init]; 

    // Star session configuration 
    [session beginConfiguration]; 

    // Add session input 
    NSError *error; 
    newVideoDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error]; 
     if (newVideoDeviceInput == nil) { 
     dispatch_async(dispatch_get_main_queue(), ^(void) { 
      NSLog(@"%@", error); 
     }); 
    } else { 
     [session addInput:newVideoDeviceInput]; 
    } 

    // Add session output 
    videoDataOutput = [[AVCaptureVideoDataOutput alloc] init]; 
    videoDataOutput.videoSettings = [NSDictionary dictionaryWithObject: [NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey: (id)kCVPixelBufferPixelFormatTypeKey]; 

    dispatch_queue_t videoQueue = dispatch_queue_create("videoQueue", NULL); 

    [videoDataOutput setSampleBufferDelegate:self queue:videoQueue]; 
    [session addOutput:videoDataOutput]; 

    // Finish session configuration 
    [session commitConfiguration]; 

    // Start the session 
    [session startRunning]; 
} 

#pragma mark - AVCaptureAudioDataOutputSampleBufferDelegate 

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { 
    //NSImage *resultNSImage = [self imageFromSampleBuffer:sampleBuffer]; 

    //self.imageView.image = [self nsImageFromSampleBuffer:sampleBuffer]; 
    self.imageView.image = [[NSImage alloc] initWithData:imageToBuffer(sampleBuffer)]; 
}  

NSData* imageToBuffer(CMSampleBufferRef source) { 
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(source); 
    CVPixelBufferLockBaseAddress(imageBuffer,0); 

    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); 
    size_t height = CVPixelBufferGetHeight(imageBuffer); 
    void *src_buff = CVPixelBufferGetBaseAddress(imageBuffer); 

    NSData *data = [NSData dataWithBytes:src_buff length:bytesPerRow * height]; 

    CVPixelBufferUnlockBaseAddress(imageBuffer, 0); 
    return data; 
} 

ответ

1

Нет, вы должны удалить стартовые коды приложения b и заменить их на значения размера. Тот же формат, что и MP4