Reputation: 1
I have a working code for preview of video to a simple textureView. Now I want to buffer several seconds of video (hundreds of frames) before showing them on the textureView.
I do not want any conversion, I just want to take YUV_422_888 frames from the camera, put them in a large buffer, and after a given time (say 10s) start to show them in the same FPS they were recorded, e.g., 30 FPS. I want to do this continously.
I can find several examples and ideas of using ImageReader with RenderScript or OpenGL to manipulate the frames, with lots of code for converting between different formats. Does anyone have a suggestion how to do this in a simple way, without loads of conversion code?!
Upvotes: 0
Views: 898
Reputation: 18117
Hundreds of frames takes a lot of memory. At 720p, each YUV frame takes ~1.3 MB; at 1080p they take 3 MB each.
So 10 seconds of buffering will eat up 390 MB at 720p, 900 MB at 1080p. That may cause problems for you on devices with lower amounts of memory.
You can use an ImageReader and ImageWriter pair, most likely, though selecting the right format is tricky. YUV_420_888 may work, but technically TextureView is not guaranteed to accept them (but will on many, possibly all, devices). So if YV12 is available, that may be a better bet.
Then create an ImageReader and ImageWriter with that format; for ImageWriter, give it a Surface from TextureView. For ImageReader, pass its Surface to the camera device.
Then when a new Image becomes available from the ImageReader, acquire it and copy its contents (from all 3 planes) to your circular buffer. Once your buffer gets full, start copying frames from it to your ImageWriter.
In theory, you could buffer frames in the ImageReader itself without a copy, but it has a maximum of around 64 frames it can queue up inside its queue. That's nowhere near enough for 10 seconds.
Upvotes: 1