2011-01-28 4 views
5

OpenGLフレーム用のCMSampleBufferを取得する必要があります。私はこれを使用しています:AVAssestWritterを使用したOpenGLのCMSampleBuffer

int s = 1; 
     UIScreen * screen = [UIScreen mainScreen]; 
     if ([screen respondsToSelector:@selector(scale)]){ 
      s = (int)[screen scale]; 
     } 
     const int w = viewController.view.frame.size.width/2; 
     const int h = viewController.view.frame.size.height/2; 
     const NSInteger my_data_length = 4*w*h*s*s; 
     // allocate array and read pixels into it. 
     GLubyte * buffer = malloc(my_data_length); 
     glReadPixels(0, 0, w*s, h*s, GL_RGBA, GL_UNSIGNED_BYTE, buffer); 
     // gl renders "upside down" so swap top to bottom into new array. 
     GLubyte * buffer2 = malloc(my_data_length); 
     for(int y = 0; y < h*s; y++){ 
      memcpy(buffer2 + (h*s - 1 - y)*4*w*s, buffer + (4*y*w*s), 4*w*s); 
     } 
     free(buffer); 
     CMBlockBufferRef * cm_block_buffer_ref; 
     CMBlockBufferAccessDataBytes(cm_block_buffer_ref,0,my_data_length,buffer2,*buffer2); 
     CMSampleBufferRef * cm_buffer; 
     CMSampleBufferCreate (kCFAllocatorDefault,cm_block_buffer_ref,true,NULL,NULL,NULL,1,1,NULL,0,NULL,cm_buffer); 

CMSampleBufferCreateのEXEC_BAD_ACCESSを取得します。

ご協力いただきありがとうございます。

答えて

6

解決策は、AVAssetWriterInputPixelBufferAdaptorクラスを使用することでした。

int s = 1; 
     UIScreen * screen = [UIScreen mainScreen]; 
     if ([screen respondsToSelector:@selector(scale)]){ 
      s = (int)[screen scale]; 
     } 
     const int w = viewController.view.frame.size.width/2; 
     const int h = viewController.view.frame.size.height/2; 
     const NSInteger my_data_length = 4*w*h*s*s; 
     // allocate array and read pixels into it. 
     GLubyte * buffer = malloc(my_data_length); 
     glReadPixels(0, 0, w*s, h*s, GL_RGBA, GL_UNSIGNED_BYTE, buffer); 
     // gl renders "upside down" so swap top to bottom into new array. 
     GLubyte * buffer2 = malloc(my_data_length); 
     for(int y = 0; y < h*s; y++){ 
      memcpy(buffer2 + (h*s - 1 - y)*4*w*s, buffer + (4*y*w*s), 4*w*s); 
     } 
     free(buffer); 
     CVPixelBufferRef pixel_buffer = NULL; 
     CVPixelBufferCreateWithBytes (NULL,w*2,h*2,kCVPixelFormatType_32BGRA,buffer2,4*w*s,NULL,0,NULL,&pixel_buffer); 
     [av_adaptor appendPixelBuffer: pixel_buffer withPresentationTime:CMTimeMakeWithSeconds([[NSDate date] timeIntervalSinceDate: start_time],30)]; 
1

CMSampleBufferCreate()の3番目のパラメータが、コードでtrueの理由は何ですか? CMSampleBuffer オブジェクトにメモリを割り当てるために使用する

パラメータ

アロケータ

アロケータ:documentationによります。 kCFAllocatorDefaultを に渡すと、現在のデフォルトアロケータが使用されます。

のDataBuffer

これは、すでにメディアデータが含まれているバッキングメモリ が、まだデータがない、またはCMBlockBuffer と無バッキングメモリとCMBlockBuffer、 CMBlockBuffer NULLにすることができます。 最後のケースでのみ(または、NULLと numSamplesが0の場合)、dataReadyは になります。

DATAREADY

はDataBufferを、すでにメディア データが含まれているかどうかを示します。

あなたがここにfalseを使用する必要がありますので、あなたのバッファにデータが含まれていないようcm_block_buffer_refで渡されていること、(あなたは安全のためにそれをNULLする必要があり、私は、コンパイラがデフォルトであることありません信じていません)。

これには他にも問題があるかもしれませんが、それは私に飛び出す最初の項目です。

+0

ありがとうございました。 cm_block_buffer_refにOpenGLデータを含めるにはどうすればよいですか? –

+0

@Matthew - CVPixelBufferを作成し、CMSampleBufferCreate()の代わりに '' CMSampleBufferCreateForImageBuffer() 'を使う必要があると思います。実際、AVAssetWriterInputPixelBufferAdaptorを使用するほうが良いでしょう。http://developer.apple.com/library/ios/#documentation/AVFoundation/Reference/AVAssetWriterInputPixelBufferAdaptor_Class/Reference/Reference.html –

+0

ああ、私は私自身。私はそれを動作させることができた(少し遅いが、次にglReadPixelsがあるはずである)。でもありがとう。 –

0

なぜダブルバッファがtempバッファを介して交換されるのでしょうか?

このような何か:

GLubyte * raw = (GLubyte *) wyMalloc(size); 
    LOGD("raw address %p", raw); 
    glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, raw); 
    const size_t end = h/2; 
    const size_t W = 4*w; 
    GLubyte row[4*w]; 
    for (int i=0; i <= end; i++) { 
     void * top = raw + (h - i - 1)*W; 
     void * bottom = raw + i*W; 
     memcpy(row, top, W); 
     memcpy(top, bottom, W); 
     memcpy(bottom, row, W); 
    } 
+0

私は元の生のバッファをもうmallocしなくても、代わりにリサイクルします。バッファプールクラスを作成しました。私は短いループのために少し違ったことをする。私はそれぞれのイメージをストレージに保存し、後でそれらを順番に読み戻します。 – user1524957

関連する問題