2014-09-24 15 views
7

Cần phải giải mã dòng h264 và nhận được bộ đệm điểm ảnhh264 giải mã trong iOS 8 với hộp công cụ video

Tôi biết khả năng của mình với hộp công cụ video trên iOS 8

1.How để tôi chuyển đổi dòng h264 đến CMSampleBufferRef?

2.Làm cách nào để sử dụng hộp công cụ video để giải mã?

+0

Bạn đã đọc tài liệu chưa? Bạn đã xem video WWDC về chủ đề chưa? Tại sao bạn thử? – szatmary

+0

Tôi biết đến thế giới phát trực tuyến video & video. Có, tôi đã xem video từ WWDC 2014, nhưng hiện tại nó không đủ khiến tôi nhớ một số chi tiết, điều này có thể hiển nhiên đối với bạn :) – sivan

+1

Ồ, rất rõ ràng đối với tôi bạn đang thiếu chi tiết. Trong thực tế, bạn không có đủ chi tiết trong câu hỏi của bạn để thậm chí trả lời nó. Định dạng luồng h264 của bạn là gì? Là phụ lục B? Bạn có con trỏ đến SPS/PPS không? – szatmary

Trả lời

7

Tôi giả sử bạn nhận được luồng ở định dạng Phụ lục B, nếu nó đã ở định dạng AVCC (đọc MP4), thì bạn có thể là AssetReader và không cần phải làm nhiều.

Đối với luồng Phụ lục B (đây là những gì ppl thường gọi là luồng h264 thô).

  1. trích xuất SPS/PPS Các đơn vị NAL và tạo bộ tham số từ đó. Bạn nhận được chúng định kỳ. Chúng chứa thông tin về giải mã cách một khung được cho là được giải mã.

  2. Tạo mảng TimingInfo với khoảng thời gian (bạn có thể lấy nó từ phân tích phần VUI của SPS) và dấu thời gian trình bày và giải mã dấu thời gian.Iif luồng được nhận dưới dạng MPEG2 TS lấy dấu thời gian từ PESr. Nếu không chỉ cung cấp thông tin còn thiếu dựa trên tính toán của bạn.

  3. Bẻ các đơn vị VLC NAL vào bộ CMBlockBuffer. Bạn có thể đặt nhiều hơn sau đó một vào chúng. Nếu bạn nhận được luồng của mình qua RTP có thể phân mảnh các đơn vị NAL, hãy đảm bảo rằng mọi đơn vị NAL đều hoàn tất.

  4. Khi gói đơn vị NAL vào CMBlockbuffer thay thế mã khởi đầu 3 hoặc 4 byte bằng tiêu đề độ dài.

  5. Cung cấp thông tin để CMSampleBufferCreate và bạn có thể giải mã các khung trong VTDecompressionSession

Có một presetation từ WWDC sẵn mà giải thích các bước thêm một chút chi tiết ans cũng cung cấp mẫu mã.

+0

Từ tài liệu AssetReader không thể trợ giúp với luồng mạng. Hy vọng tôi sai. AVAssetRedaer được khởi tạo với AVAsset. Không tìm được cách để làm cho nó hoạt động với một luồng. Đã xem một số bài viết về cách ghi luồng vào một tệp và đọc tệp bằng AVAssetReader, nhưng điều đó không hoạt động tốt và tôi cần hiệu năng tốt và mức tiêu thụ pin thấp như vậy. – sivan

+0

Đúng, AssetReader không thể xử lý luồng Phụ lục B. Bạn phải chuyển đổi sang định dạng AVCC (về cơ bản là vùng chứa MP4). Điều này về cơ bản giống như trên nhưng thay vì giải mã bạn viết nó vào một tập tin. Nhưng điều này chỉ có ý nghĩa nếu bạn muốn giữ luồng bạn nhận được và muốn chơi nó nhiều lần sau đó với IOS/OSX một cách dễ dàng. – scythe42

+0

Tôi đã thành công trong việc giải mã luồng h264, bây giờ tôi muốn hiển thị luồng trên màn hình của iPhone. bạn có biết làm thế nào ? – sivan

3

Hãy thử mã hoạt động này. Cung cấp CMSampleBufferRef được mã hóa cho sampleBuffer.

if(!decompressionSession) 
    { 
    CMFormatDescriptionRef formatDescription=CMSampleBufferGetFormatDescription(sampleBuffer); 
    decompressionSession = NULL; 
    VTDecompressionOutputCallbackRecord callBackRecord; 
    callBackRecord.decompressionOutputCallback=didDecompress; 
    callBackRecord.decompressionOutputRefCon = (__bridge void *)self; 
    OSStatus status1= VTDecompressionSessionCreate(kCFAllocatorDefault, formatDescription, NULL, NULL, &callBackRecord, &decompressionSession); 
    } 
    else 
    { 
     VTDecodeFrameFlags flags = kVTDecodeFrame_EnableAsynchronousDecompression; 
     VTDecodeInfoFlags flagOut; 
     VTDecompressionSessionDecodeFrame(decompressionSession, sampleBuffer, flags, NULL, &flagOut); 
     VTDecompressionSessionWaitForAsynchronousFrames(decompressionSession); 

    } 



Decompression all back 

static void didDecompress(void *decompressionOutputRefCon, void *sourceFrameRefCon, OSStatus status, VTDecodeInfoFlags infoFlags, CVImageBufferRef imageBuffer, CMTime presentationTimeStamp, CMTime presentationDuration){ 
if(status==noErr) 
    { 
     NSLog(@"SUCCESS PROCEED FROM HERE !!!!"); 
    } 
} 

// Hãy nhớ, bạn cung cấp thời gian trình bày đúng khi encoding.Here tôi đang cung cấp cho bạn các chi tiết mã hóa ..

//ENCODING-------------------ENCODING---------------ENCODING 
if(!_compression_session) 
{ 
    NSDictionary* pixelBufferOptions = @{ 
              (NSString*) kCVPixelBufferWidthKey : @(widthOFCaptureImage), 
              (NSString*) kCVPixelBufferHeightKey : @(heightOFCaptureImage), 
              (NSString*) kCVPixelBufferOpenGLESCompatibilityKey : @YES, 
              (NSString*) kCVPixelBufferIOSurfacePropertiesKey : @{}}; 
_compression_session=NULL; 
CFMutableDictionaryRef encoderSpecifications = NULL; 
    err = VTCompressionSessionCreate(
            kCFAllocatorDefault, 
            widthOFCaptureImage, 
            heightOFCaptureImage, 
            kCMVideoCodecType_H264, 
            encoderSpecifications, 
            (__bridge CFDictionaryRef)pixelBufferOptions, 
            NULL, 
            compressionCallback, 
            (__bridge void *)self, 
            &_compression_session); 
} 
else 
{ 


CMTime presentationTimeStamp = CMSampleBufferGetPresentationTimeStamp(sampleBufferIs); 
    CVPixelBufferRef pixelbufferPassing= CMSampleBufferGetImageBuffer(sampleBufferIs); 
      OSStatus status1= VTCompressionSessionEncodeFrame(_compression_session, pixelbufferPassing, presentationTimeStamp, kCMTimeInvalid, NULL, NULL, NULL); 
VTCompressionSessionEndPass(_compression_session, NO, NULL); 
} 

// Mã hóa GỌI LẠI ------ -----------------------------------

static void compressionCallback(void *outputCallbackRefCon, 
          void *sourceFrameRefCon, 
          OSStatus status, 
          VTEncodeInfoFlags infoFlags, 
          CMSampleBufferRef sampleBuffer){ 
    } 

// Lời chúc tốt đẹp nhất :) chúc mừng mã hóa :)

+3

Vui lòng không chỉ trích xuất mã mà không cung cấp giải thích về cách thức và lý do. – EternalHour

+0

thnx rất nhiều cho việc chia sẻ mã của bạn :) – sivan

Các vấn đề liên quan