2011-10-25 17 views
5

Tôi đang sử dụng glReadPixels để đọc dữ liệu vào CVPixelBufferRef. Tôi sử dụng số CVPixelBufferRef làm đầu vào thành AVAssetWriter. Rất tiếc, các định dạng pixel dường như không khớp.Định dạng pixel, CVPixelBufferRefs và glReadPixels

Tôi nghĩ glReadPixels đang trở lại dữ liệu pixel trong RGBA định dạng trong khi AVAssetWriter muốn dữ liệu pixel trong định dạng ARGB. Cách tốt nhất để chuyển đổi RGBA thành ARGB là gì?

Đây là những gì tôi đã cố gắng cho đến nay:

  • thao tác bit dọc theo dòng của ARGB = (rgba >> 8) | (Rgba < < 24)
  • sử dụng một CGImageRef như một bước trung gian

Các thao tác bit đã không làm việc vì CVPixelBufferRef dường như không hỗ trợ subscript. Bước trung gian CGImageRef hoạt động ... nhưng tôi không muốn có thêm 50 dòng mã có khả năng là một lần truy cập hiệu suất.

+2

Bạn nhận được CVPixelBufferRef của mình như thế nào?Bạn đang gọi CVPixelBufferCreate? Nếu vậy, bạn đang chuyển qua tham số pixelFormatType như thế nào? Bạn đang chuyển định dạng nào tới glReadPixels? –

+0

Tôi đang chuyển 'kCVPixelFormatType_32ARGB' thành' CVPixelBufferCreate'. Tôi chuyển 'GL_RBGA' thành' glReadPixels'. Tôi đã thử đi qua một định dạng RBGA để 'CVPixelBufferCreate' nhưng nó không hoạt động (hoặc màu xấu hoặc ứng dụng bị rơi). – MrDatabase

Trả lời

6

Tốt hơn so với sử dụng CPU để trao đổi các thành phần sẽ được để viết một Shader đoạn đơn giản để có hiệu quả làm điều đó trên GPU khi bạn hiển thị hình ảnh.

Và cách tốt nhất tốt nhất là loại bỏ hoàn toàn giai đoạn sao chép bằng cách sử dụng một CV5penViewSTextureCache của iOS5 cho phép bạn kết xuất thẳng tới CVPixelBufferRef, loại bỏ lệnh gọi tới glReadPixels.

p.s. Tôi khá chắc chắn AVAssetWriter muốn dữ liệu ở định dạng BGRA (thực sự nó có thể muốn nó trong yuv, nhưng đó là một câu chuyện khác).

UPDATE: như đối với liên kết, doco dường như vẫn được theo NDA, nhưng có hai đoạn mã ví dụ download miễn phí có sẵn:

GLCameraRippleRosyWriter

tập tin Tiêu đề bản thân chứa tài liệu tốt, và tương đương mac là rất giống nhau (CVOpenGLTextureCache), vì vậy bạn nên có rất nhiều để giúp bạn bắt đầu.

+0

' OpenGLTextureCache' có vẻ tuyệt vời. Bạn có liên kết đến tài liệu liên quan không? – MrDatabase

+1

nếu bạn có đăng nhập ADC, bạn có thể lấy tài liệu. Mã số để trả lời –

+0

Trông rất thú vị! Cảm ơn :-) – MrDatabase

2

Đó là loại ảnh chụp trong bóng tối, nhưng bạn đã thử GL_BGRA cho glReadPixels với kCVPixelFormatType_32BGRA cho CVPixelBufferCreate?

Tôi đề xuất điều này vì Technical Q&A QA1501 không liệt kê bất kỳ định dạng RGBA nào được hỗ trợ.

+0

Thật không may khi chuyển GL_BGRA sang 'glReadPixels' làm cho dữ liệu điểm ảnh đầu ra bằng không :-( – MrDatabase

6

Về thao tác bit, bạn có thể có được một con trỏ đến dữ liệu thô đệm pixel:

CVPixelBufferLockBaseAddress(buffer, 0); 
size_t stride = CVPixelBufferGetBytesPerRow(buffer); 
char *data = (char *)CVPixelBufferGetBaseAddress(buffer); 
for (size_t y = 0; y < CVPixelBufferGetHeight(buffer); ++y) { 
    uint32_t *pixels = (uint32_t *)(data + stride * y); 
    for (size_t x = 0; x < CVPixelBufferGetWidth(buffer); ++x) 
     pixels[x] = (pixels[x] >> 8) | (pixels[x] << 24); 
} 
CVPixelBufferUnlockBaseAddress(buffer, 0); 
1

glReadPixels (0, 0, w * s, h * s, GL_BGRA, GL_UNSIGNED_BYTE, bộ đệm);

Sử dụng GL_BGRA trong glReadPixels. Nó hoạt động, chỉ cần thử nó bản thân mình.

+0

Bạn có nhận được dữ liệu khác không trong bộ đệm đầu ra? – MrDatabase

+0

GL_BGRA tạo ra một tải các lỗi opengl. – emrahgunduz

1
glReadPixels(0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, _buffer); 
    CVPixelBufferRef buffer = NULL; 
    CVReturn ret = CVPixelBufferCreateWithBytes(kCFAllocatorDefault,_size.width,_size.height,kCVPixelFormatType_32BGRA,glubyte,_size.width*4,NULL,NULL,NULL,&buffer);