On Sat, 17 May 2008 08:00:32 -0400, <[EMAIL PROTECTED]> wrote:
> Hello. I am working on a piece of software to play movies in opengl. I
> need to be as nice to the CPU as possible.
>
> I managed to display a movie by converting each frame from
> PIX_FMT_YUV420P to PIX_FMT_RGB24 using sw_scale. It shows the video
> correct but it is slow.
>
> Is there anyway I can bind the data in an AVFrame to an opengl texture
> without having to convert it with swscale.
>
> My problem is not the colourspace stuff I have to do with shaders
> programs or color matrices later, but rather as soon as I try to bind
> the data in my AVFrame with GL_RGB format I get a segfault.
>
> If I do:
> glTexImage2D(GL_TEXTURE_2D, 0, 3,
> movie->codec_ctx->width, movie->codec_ctx->height, 0,
> GL_LUMINANCE, GL_UNSIGNED_BYTE, //GL_RGB, GL_UNSIGNED_BYTE <-
> segfaults
> movie->frame->data[0]);
>
> I get a black and white video with horizontal stripes. I can vaguely
> make out parts of the video but it's greatly disorted.
>
> I pasted all my code here:
> http://pastebin.com/m162f9bab
>
> Anyone have any experience in this?
This will all depend on what hardware you have available, and what
implementations of OpenGL you are working with. here's some things you
might end up dealing with:
1. Some (many?) OpenGL implementations require a square power-of-2
texture. This makes a mess for video uploads, because you often need to
allocate a much larger texture than the video frame. You could try
glTexSubImage2D, but this call is very slow on some implementations.
2. There is no guarantee that the image rows are packed. If they aren't
a multiple of 16, there could be some extra space left between rows.
Check frame->rowsize[i] to see how wide a row is on a given plane. To
solve this problem, check out glPixelStorei(GL_UNPACK_ROW_LENGTH, x);
3. GL implementations may 'like' or 'not like' various color formats.
For our setup, we found that among {RGB, BGR, RGBA, BGRA}, RGBA uploads
the fastest. You might want to try putting timing code around your
operations, to see if swscale or glTexImage2D is the real problem. I
recommend writing a 'calibration' routine that tries several different
formats to see which is the fastest for the system it is running on. (but
these numbers can also be misleading. make sure you upload the texture
and then paint one pixel with it, and then call glFinish to get an
'official' upload speed)
4. swscale is a bit slow because it needs to scale the image. Without
the scale operation, the conversion from YCbCr requires much less
processing. You can try offloading the color conversion to the video
card, but depending on the card's abilities and the processor's abilities,
the processor might do it faster. We got the best performance from
writing a custom YCbCr->RGBA routine in assembly, using SSE2 instructions,
and integer approximations instead of floating point.
5. There are some nifty buffer-object GL extensions out there which can
speed up the uploads. We weren't able to use them because our
implementation didn't support it, but I think several, like on MacOS, do.
btw, You probably want a texture border-value of 1. Otherwise the values
on the right get blended with the values on the left, depending on how
much you scale it.
Hope that helps ;-) And I would definately be interested to hear if you
find a super-fast way of doing the conversion inside OpenGL.
________
Michael Conrad
IntelliTree Solutions llc.
513-552-6362
[EMAIL PROTECTED]
_______________________________________________
libav-user mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/libav-user