2012-02-17 44 views
14

Tôi đang tìm cách nhanh nhất để giải mã khung hình của video mpeg-4 cục bộ trên iPhone. Tôi chỉ đơn giản quan tâm đến các giá trị độ sáng của các pixel trong mỗi khung thứ 10. Tôi không cần phải hiển thị video ở bất cứ đâu.Giải mã khung hình video trên iPhone GPU

Tôi đã thử ffmpeg, AVAssetReader, ImageAssetGenerator, OpenCV và MPMoviePlayer nhưng tất cả đều quá chậm. Tốc độ nhanh nhất tôi có thể nhận được là ~ 2x (2 phút video được quét trong một phút). Tôi muốn một cái gì đó gần hơn đến 10x.

Giả sử những nỗ lực của tôi ở trên không sử dụng GPU, có cách nào để hoàn thành mục tiêu của tôi với một thứ gì đó chạy trên GPU không? OpenGL có vẻ như nó chủ yếu là để render đầu ra nhưng tôi đã thấy nó được sử dụng như các bộ lọc cho video đến. Có lẽ đó là một lựa chọn?

Cảm ơn trước!

Trả lời

3

Nếu bạn sẵn sàng sử dụng giải pháp chỉ iOS 5, hãy xem ứng dụng mẫu ChromaKey từ phiên WWDC 2011 trên AVCaputureSession.

Bản trình diễn đó chụp 30 FPS video từ camera tích hợp và chuyển từng khung hình thành OpenGL dưới dạng kết cấu. Sau đó, nó sử dụng OpenGL để thao tác khung và tùy chọn ghi kết quả ra một tệp video đầu ra.

Mã sử ​​dụng một số phép thuật cấp thấp nghiêm trọng để liên kết bộ đệm Core Video Pixel từ AVCaptureSession với OpenGL để chúng chia sẻ bộ nhớ trong phần cứng đồ họa.

Sẽ khá đơn giản để thay đổi AVCaptureSession để sử dụng tệp phim làm đầu vào thay vì nhập bằng máy ảnh.

Bạn có thể thiết lập phiên để phân phối khung ở dạng Y/UV thay vì RGB, trong đó thành phần Y là độ sáng. Nếu không, nó sẽ là một vấn đề khá đơn giản để viết một shader có thể chuyển đổi các giá trị RGB cho mỗi pixel thành các giá trị độ sáng.

Bạn sẽ có thể thực hiện tất cả điều này trên TẤT CẢ các khung chứ không phải chỉ mỗi khung thứ 10.

+0

bummer có vẻ như tôi cần trở thành người tham dự WWDC 2011 để nhận mẫu đó. Tôi vẫn lo rằng hiệu quả là chuyển mã theo thời gian thực. Tôi muốn có tốc độ 15x (15 phút quét video trong 1 phút). Tôi nghĩ rằng cổ chai là trong giải mã khung. –

+0

@simon.d - Tôi mô tả kỹ thuật được sử dụng trong ví dụ ChromaKey trong câu trả lời của tôi ở đây: http://stackoverflow.com/a/9704392/19679 và bạn có thể lấy mã GPUImage của tôi để xem điều này hoạt động để mã hóa phim. Tuy nhiên, tôi chưa cập nhật mã đọc phim của mình để sử dụng tải lên kết cấu nhanh. Do thực tế là các thiết bị iOS có phần cứng chuyên dụng để giải mã H.264, tôi cảm thấy một cách hợp lý nhất định rằng bạn sẽ không nhận được bất kỳ phân tích cú pháp nhanh hơn cho phim nào bằng cách sử dụng AVFoundation với tải lên kết cấu nhanh iOS 5.0. –

+0

Mã ví dụ RosyWriter của Apple cũng thể hiện liên kết AVCaptureSession -> OpenGL này. Xem [tại đây] (https://developer.apple.com/library/ios/samplecode/RosyWriter/Introduction/Intro.html). – bcattle

0

Dường như vImage có thể phù hợp, giả sử bạn có thể sử dụng iOS 5. Mỗi khung thứ 10 có vẻ là lý do để sử dụng một khung như vImage. Tuy nhiên, bất kỳ loại xử lý thời gian thực thực tế nào gần như chắc chắn sẽ yêu cầu OpenGL.

+0

Cảm ơn @LucasTizma. Tôi sẽ xem xét vImage. Tuy nhiên, mục tiêu của tôi là nhanh hơn xử lý thời gian thực. Đó là lý do tại sao tôi chỉ muốn làm mỗi khung thứ 10. Vì vậy, hãy tưởng tượng video đã được ghi lại trên điện thoại và bây giờ tôi muốn thử quét. Điều đó có loại trừ vImage không? –

+0

vImage chỉ là một phương tiện để nhanh chóng thực hiện các thao tác xử lý hình ảnh. Tôi nghĩ bạn sẽ ổn. Dường như, ngoài OpenGL, đây là giải pháp nhanh nhất có thể của bạn. Những người khác, cảm thấy tự do để sửa tôi nếu tôi sai. – LucasTizma

+0

nhưng vImage chỉ hữu ích khi tôi đã giải mã khung hình? Nếu vậy, tôi không chắc tôi cần nó. 90% công việc thực sự giải mã khung, chứ không phải xử lý pixel. –

0

Giả sử nút cổ chai của ứng dụng nằm trong mã chuyển đổi khung video thành định dạng có thể hiển thị (như RGB), bạn có thể quan tâm đến mã tôi đã chia sẻ đã được sử dụng để convert one .mp4 frame (encoded as YV12) to RGB using Qt and OpenGL. Ứng dụng này tải khung lên GPU và kích hoạt GLSL fragment shader để thực hiện chuyển đổi từ YV12 sang RGB, vì vậy nó có thể được hiển thị trong một QImage.

static const char *p_s_fragment_shader = 
    "#extension GL_ARB_texture_rectangle : enable\n" 
    "uniform sampler2DRect tex;" 
    "uniform float ImgHeight, chromaHeight_Half, chromaWidth;" 
    "void main()" 
    "{" 
    " vec2 t = gl_TexCoord[0].xy;" // get texcoord from fixed-function pipeline 
    " float CbY = ImgHeight + floor(t.y/4.0);" 
    " float CrY = ImgHeight + chromaHeight_Half + floor(t.y/4.0);" 
    " float CbCrX = floor(t.x/2.0) + chromaWidth * floor(mod(t.y, 2.0));" 
    " float Cb = texture2DRect(tex, vec2(CbCrX, CbY)).x - .5;" 
    " float Cr = texture2DRect(tex, vec2(CbCrX, CrY)).x - .5;" 
    " float y = texture2DRect(tex, t).x;" // redundant texture read optimized away by texture cache 
    " float r = y + 1.28033 * Cr;" 
    " float g = y - .21482 * Cb - .38059 * Cr;" 
    " float b = y + 2.12798 * Cb;" 
    " gl_FragColor = vec4(r, g, b, 1.0);" 
    "}" 
Các vấn đề liên quan