質問

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を取得します。

どんな助けも感謝しています、ありがとう。

役に立ちましたか?

解決

解決策は、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)];

他のヒント

なぜ3番目のパラメーターがありますか CMSampleBufferCreate() あなたのコードで本当ですか?による ドキュメンテーション:

パラメーター

アロケーター

cmsamplebufferオブジェクトのメモリを割り当てるために使用するアロケーター。 kcfallocatordefaultを渡して、現在のデフォルトアロケーターを使用します。

データバッファー

これは、null、バッキングメモリのないcmblockbuffer、バッキングメモリを備えたcmblockbuffer、まだデータがない、または既にメディアデータを含んでいるcmblockbufferです。その最後のケースでのみ(またはnullとnumsamplesが0の場合)、Datareadyが真である必要があります。

dataready

DataBufferが既にメディアデータを含んでいるかどうかを示します。

君の cm_block_buffer_ref バッファにデータが含まれていないため、それは渡されています(安全のためにヌルする必要があります。デフォルトでコンパイラがそれを行うとは思わないので、使用する必要があります。 false ここ。

これには他にも間違っているかもしれませんが、それは私に飛び出す最初のアイテムです。

なぜダブルマロックで、なぜ温度バッファーを介して所定の位置に交換してみませんか?

このようなもの:

    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);
    }
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top