Frage

Ich muss einen CMSampleBuffer für den OpenGL -Rahmen erhalten. Ich benutze das:

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);

Ich bekomme exec_bad_access für cmsampleBuffercreate.

Jede Hilfe wird geschätzt, danke.

War es hilfreich?

Lösung

Die Lösung bestand darin, die AvassetwriterInputPixelBufferAdaptor -Klasse zu verwenden.

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)];

Andere Tipps

Warum ist der dritte Parameter zu CMSampleBufferCreate() Richtig in Ihrem Code? Laut dem Dokumentation:

Parameter

Allocator

Der Allocator zum Zuordnen des Speichers für das CMSampleBuffer -Objekt. Übergeben Sie KCFalloCatorDefault, um den aktuellen Standard -Allocator zu verwenden.

Datenbeutel

Dies kann null sein, ein cmblockbuffer ohne Sicherungsspeicher, ein cmblockbuffer mit Sicherungsspeicher, aber noch keine Daten oder ein CmblockBuffer, der bereits die Mediendaten enthält. Nur in diesem letzten Fall sollte DataReady wahr sein.

DataReady

Gibt an, ob der Datenkörper bereits die Mediendaten enthält.

Dein cm_block_buffer_ref Das wird als Puffer übergeben, enthält keine Daten (Sie sollten sie aus Sicherheitsgründen nullten, ich glaube nicht false hier.

Daran können andere Dinge falsch sein, aber das ist der erste Punkt, der mich auf mich ausspringt.

Warum das doppelte Malloc und warum nicht über einen Temperaturpuffer ausgetauscht?

Etwas wie das:

    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);
    }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top