What's the fastest way to access video pixels in as3? - performance

I would like to copy pixels from a 1080p video from one location to another efficiently/with as little CPU impact as possible.
So far my implementation is fairly simple:
using BitmapData's draw() method to grab the pixels from the video
using BitmapData's copyPixels() to shuffle pixels about
Ideally this would have as little CPU impact as possible but I am running out of options and could really use some tips from experienced actionscript 3 developers.
I've profiled my code with Scout and noticed the CPU usage is mostly around 70% but goes above 100% quite a bit. I've looked into StageVideo but one of the main limitations is this:
The video data cannot be copied into a BitmapData object
(BitmapData.draw).
Is there a more direct way to access video pixels, rather than rasterizing a DisplayObject ?
Can I access each video frame as a ByteArray directly and plug it into a BitmapData object ?
(I found appendBytes but it seems to do the reverse of what I need in my setup).
What is the most CPU friendly way to manipulate pixels from an h264 1080p video in actionscript 3 ?
Also, is there a faster way to moving pixels around other than copyPixels() using Flash Player ?Also, I see Scout points out that video is not hardware accelerated( .rend.video.hwrender: false ). Shouldn't h264 video be hardware accelerated (even without stage video) according to this article (or is this for the fullscreen mode only) ?

Latest AIR beta introduced video as texture support which you could possibly use to manipulate the video on GPU (and do that way faster than with BitmapData). But keep in mind that it is currently available for AIR on Windows only and there are some other limitations.

Related

Tango color frames not of best quality, looks like up-scaled from lower resolution. Is it a Tango hardware limitation?

I obtain color frames from TANGO_CAMERA_COLOR. Frames are not of the best quality - looks like they are up-scaled from lower resolution.
This can be easily seen by comparing video quality from standard Android Camera app and "Project Tango Native Augmented Reality" sample app, running on the same device.
Questions: is it what intended to be? If so then why?
Is there a way to improve quality, of if there is a plan to improve quality in future Tango releases?
I set config_color_iso to 400, default exposition time.
Each depth frame has corresponding color frame with the exactly same timestamp. Infrared illumination (artefacts) are seen at just a very few color frames.
You may want to stick with the images coming out of Tango
1) If you snag another camera, or grab the camera directly, then Tango depth information stops coming.
2) More importantly to my eyes, it is the images from Tango that are the source of the point cloud - anything you want to do with coloring cloud points and surfaces and having the faintest hope of success would do better with these images
3) Trying to offload the image stream in real time requires JPEG compression if you're going straight to the cloud - raw images from tango are 1280x720, so they way in at about a megabyte each before compression

high performance video output with Qt

I'm writing a video player where my code decodes the video to raw YCbCr frames.
What would be the fastest way to output these through the Qt framework? I want to
avoid copying data around too much as the images are in HD format.
I am afraid that software color conversion into a QImage would be slow and that later the QImage will again be copied when drawing into the GUI.
I have had a look at QAbstractVideoSurface and even have running code,
but cannot grasp how this is faster, since like in the VideoWidget example
(http://idlebox.net/2010/apidocs/qt-everywhere-opensource-4.7.0.zip/multimedia-videowidget.html), rendering is still done by calling QPainter::drawImage with
QImage, which has to be in RGB.
The preferred solution seems to me to have access to a hardware surface directly
into which I could decode the YCbCr or at least directly do the RGB conversion (with libswscale) into.
But I cannot see how I could do this (without using OpenGL, which would give me
free scaling too, though).
One common solution is to use QGL Widget with texture mapping. The application allocates a texture buffer on first frame, then call update texture in remaining frames. This is pure GL call, Qt not supporting texture manipulation yet. But QGLwidget can be used as a container.
Decoding was done using SSE2. Hope this helps.

How to read video frame buffer in windows

I am trying to create a small project wherein I need to capture/read the video frame buffer and calculate the average RGB value of the screen.
I don't need to write anything on the screen. I'm doing this in Windows.
Can anyone help me with any Windows API which will read the video frame buffer and calculate the average RGB value?
What I came to know is that I need to write a kernel driver which will have access to read the frame buffer.
Is this the only solution?
Is there any other way of reading frame buffer?
Is there an algorithm to calculate the RGB value from frame buffer data?
If you want really good performance, you might have to use directx and capture the backbuffer to a texture. Using mipmaps, it will automatically create downsamples all the way to 1X1. Justgrab the color of that 1 pixel and you're good to go.
Good luck, though. I'm working on implimenting this as we speak. I'm creating an ambient light control for my room. I was getting about 15FPS using device contexts and StretchBLT. Only got decent performance if I grabbed 1 pixel with GetPixel(). That's an i5 3570K # 4.5GHz
But with the directx method, you could technically get hundreds if not thousands of frames per second. (when I make a spinning triangle, my 660 gets about 24,000 FPS. It couldn't be TOO much slower, minus the CPU calls.)

Pixel level manipulation windows

I've been using SDL to render graphics in C. I know there are several options to create graphics at the pixel level on Windows, including SDL and OpenGL. But how do these programs do it? Fine, I can use SDL. But I'd like to know what SDL is doing so I don't feel like an ignorant fool. Am I the only one slightly frustrated by the opaque layer of frosting on modern computers?
A short explanation as to how this is done on other operating systems would also be interesting, but I am most concerned with Windows.
Edit: Since this question seems to be somehow unclear, this is precisely what I want:
I would like to know how pixel level graphics manipulations (drawing on the screen pixel by pixel) works on Windows. What do libraries like SDL do with the operating system to allow this to happen. I can manipulate the screen pixel by pixel using SDL, so what magic happens in SDL to let me do this?
Windows has many graphics APIs. Some are layers built on top of others (e.g., GDI+ on top of GDI), and others are completely independent stacks (like the Direct3D family).
In an API like GDI, there are functions like SetPixel which let you change the value of a single pixel on the screen (or within a region of the screen that you have access to). But using SetPixel to setting lots of pixels is generally slow.
If you were to build a photorealistic renderer, like a ray tracer, then you'd probably build up a bitmap in memory (pixel by pixel), and use an API like BitBlt that sends the entire bitmap to the screen at once. This is much faster.
But it still may not be fast enough for rendering something like video. Moving all that data from system memory to the video card memory takes time. For video, it's common to use a graphics stack that's closer to the low-level graphics drivers and hardware. If the graphics card can do the video decompression directly, then sending the compressed video stream to the card will be much more efficient than sending the decompressed data from system memory to the video card--and that's often the limiting factor.
But conceptually, it's the same thing: you're manipulating a bitmap (or texture or surface or raster or ...), but that bitmap lives in graphics memory, and you're issuing commands to the GPU to set the pixels the way you want, and then to display that bitmap at some portion of the screen (often with some sort of transformation).
Modern graphics processors actually run little programs--called shaders--that can (among other things) do calculations to determine the pixel values. The GPUs are optimized to do these types of calculations and can do many of them in parallel. But ultimately, it boils down to getting the pixel values into some sort of bitmap in video memory.

Best video codec for smooth 1920x1080 playback on older machines (quality not important)

I'm new to Video technology, so any feedback (such as if I've underspecified the problem) would be greatly appreciated.
I need to display an animation (currently composed of about a thousand PNGs) on Windows and am trying to determine the best video codec or parameters for the job.
Video playback must be smooth at 30 fps
Output display is 1920x1080 on a secondary monitor
Quality does not matter (within limits)
Will be displaying alpha blended animation on top, so no DXVA
Must run on older hardware (Core Duo 4400 + nVidia 9800)
Currently using DirectShow to display the video.
Question:
Is it easier on the CPU to shrink the source to 1/2 size (or even 1/4) and have the CPU stretch it at run time?
Is there a video codec that is easier on the CPU than others?
Are there parameters for video codecs that mean less decompression is required? (The video will be stored on the HD, so size doesn't matter except as it impacts program performance).
So far:
- H.264 from ffmpeg defaults produces terrible tearing and some stuttering.
- Uncompressed video from VirtualDub produces massive stuttering.
There are so many different degrees of freedom to this problem, I'm flailing. Any suggestions by readers would be much appreciated. Thank you.
MJPEG should work. I used it for 1080i60 some 3 years back, and the playback was never an issue. Even encoding worked on-the-fly with a machine of quite similar performance to what you describe.
File size will be about 10MB/s for good quality video.
Shrinking the video will help, because if you are drawing the video to screen using e.g. DirectX, you can use the GPU to stretch it.

Resources