Erlang gen_tcp connect question

Простой вопрос ...

Этот код ..

client() ->
    SomeHostInNet = "localhost" % to make it runnable on one machine
    {ok, Sock} = gen_tcp:connect(SomeHostInNet, 5678, 
                                 [binary, {packet, 0}]),
    ok = gen_tcp:send(Sock, "Some Data"),
    ok = gen_tcp:close(Sock).

очень ясно, за исключением того, что Я не совсем понимаю, что [двоичный, {пакет, 0}] означает ? и даже удобно преобразовать CGImageRef в текстуру opengl. Кажется ...

У меня есть AVPlayerLayer, из которого я хотел бы создать текстуру OpenGL. Мне удобно работать с текстурами opengl и даже комфортно конвертировать CGImageRef в текстуру opengl. Мне кажется, что приведенный ниже код должен работать, но я получаю просто черный цвет. Что я делаю неправильно? Нужно ли мне сначала установить какие-либо свойства в CALayer / AVPlayerLayer?

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

int width = (int)[layer bounds].size.width;
int height = (int)[layer bounds].size.height;

CGContextRef context = CGBitmapContextCreate(NULL,
                                 width,
                                 height,
                                 8,
                                 width * 4,
                                 colorSpace,
                                 kCGImageAlphaPremultipliedLast);

CGColorSpaceRelease(colorSpace);

if (context== NULL) {
    ofLog(OF_LOG_ERROR, "getTextureFromLayer: failed to create context 1");
    return;
}

[[layer presentationLayer] renderInContext:context];

CGImageRef cgImage = CGBitmapContextCreateImage(context);

int bytesPerPixel   = CGImageGetBitsPerPixel(cgImage)/8;
if(bytesPerPixel == 3) bytesPerPixel = 4;

GLubyte *pixels     = (GLubyte *) malloc(width * height * bytesPerPixel);

CGContextRelease(context);
context = CGBitmapContextCreate(pixels,
                                width,
                                height,
                                CGImageGetBitsPerComponent(cgImage),
                                width * bytesPerPixel,
                                CGImageGetColorSpace(cgImage),
                                kCGImageAlphaPremultipliedLast);

if(context == NULL) {
    ofLog(OF_LOG_ERROR, "getTextureFromLayer: failed to create context 2");
    free(pixels);
    return;
}

CGContextDrawImage(context, CGRectMake(0.0, 0.0, width, height), cgImage);

int glMode;
switch(bytesPerPixel) {
    case 1:
        glMode = GL_LUMINANCE;
        break;
    case 3: 
        glMode = GL_RGB;
        break;
    case 4: 
    default:
        glMode = GL_RGBA; break;
}

if(texture.bAllocated() == false || texture.getWidth() != width || texture.getHeight() != height) {
    NSLog(@"getTextureFromLayer: allocating texture %i, %i\n", width, height);
    texture.allocate(width, height, glMode, true);
}

// test texture
//        for(int i=0; i<width*height*4; i++) pixels[i] = ofRandomuf() * 255;

texture.loadData(pixels, width, height, glMode);

CGContextRelease(context);
CFRelease(cgImage);
free(pixels);

PS Переменная texture - это объект текстуры C ++ opengl (-es совместимый), который, как я знаю, работает. Если я раскомментирую цикл for «тестовая текстура», заполняющий текстуру случайным шумом, я увижу это, так что проблема определенно возникла раньше.

UPDATE

В ответ на ответ Ника Уивера я попробовал другой подход, и теперь Я' m всегда получает обратно NULL из copyNextSampleBuffer со статусом == 3 (AVAssetReaderStatusFailed). Я что-то упустил?

переменные

AVPlayer                *videoPlayer;
AVPlayerLayer           *videoLayer;
AVAssetReader           *videoReader;
AVAssetReaderTrackOutput*videoOutput;

init

    videoPlayer = [[AVPlayer alloc] initWithURL:[NSURL fileURLWithPath:[NSString stringWithUTF8String:videoPath.c_str()]]];

    if(videoPlayer == nil) {
        NSLog(@"videoPlayer == nil ERROR LOADING %s\n", videoPath.c_str());
    } else {
        NSLog(@"videoPlayer: %@", videoPlayer);
        videoLayer = [[AVPlayerLayer playerLayerWithPlayer:videoPlayer] retain];
        videoLayer.frame = [ThreeDView instance].bounds;
        // [[ThreeDView instance].layer addSublayer:videoLayer]; // test to see if it's loading and running

        AVAsset *asset = videoPlayer.currentItem.asset;
        NSArray *tracks = [asset tracksWithMediaType:AVMediaTypeVideo];
        NSDictionary *settings = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA], (NSString*)kCVPixelBufferPixelFormatTypeKey, nil];

        videoReader = [[AVAssetReader alloc] initWithAsset:asset error:nil];
        videoOutput = [[AVAssetReaderTrackOutput alloc] initWithTrack:[tracks objectAtIndex:0] outputSettings:settings];
        [videoReader addOutput:videoOutput];
        [videoReader startReading];
    }

цикл рисования

    if(videoPlayer == 0) {
        ofLog(OF_LOG_WARNING, "Shot::drawVideo: videoPlayer == 0");
        return;
    }


    if(videoOutput == 0) {
        ofLog(OF_LOG_WARNING, "Shot::drawVideo: videoOutput == 0");
        return;
    }

    CMSampleBufferRef sampleBuffer = [videoOutput copyNextSampleBuffer];

    if(sampleBuffer == 0) {
        ofLog(OF_LOG_ERROR, "Shot::drawVideo: sampleBuffer == 0, status: %i", videoReader.status);
        return;
    }


    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    CFRelease(sampleBuffer);

    CVPixelBufferLockBaseAddress(imageBuffer,0); 

    unsigned char *pixels = ( unsigned char *)CVPixelBufferGetBaseAddress(imageBuffer); 

    int width = CVPixelBufferGetWidth(imageBuffer); 
    int height = CVPixelBufferGetHeight(imageBuffer);

    if(videoTexture.bAllocated() == false || videoTexture.getWidth() != width || videoTexture.getHeight() != height) {
        NSLog(@"Shot::drawVideo() allocating texture %i, %i\n", width, height);
        videoTexture.allocate(width, height, GL_RGBA, true);
    }

    videoTexture.loadData(pixels, width, height, GL_BGRA);

    CVPixelBufferUnlockBaseAddress(imageBuffer,0);
6
задан memo 26 April 2011 в 17:13
поделиться