Thread: [cgkit-user] cgkit.ffmpeg and the "Dranger Tutorial"
Brought to you by:
mbaas
From: Timothy W. G. <tim...@si...> - 2013-10-09 09:15:04
|
Thanks for including the ffmpeg module within cgkit. For awhile I've been using FFmpeg as a standalone executable; now I'd like to get my hands a little 'dirtier' and learn how to work more directly with audio/video frames. I'm programming with Python 3.3.2 and PyQt4 on Windows 7 and OS X 10.8. I realize that cgkit.ffmpeg is built around an older version of FFmpeg and I've downloaded the shared libraries for v0.7.1 for Win32 from http://ffmpeg.zeranoe.com/builds/win32/shared/. I'm not that familiar with ctypes yet, but is it a HUGE task to build this module for a more current version of FFmpeg? Cgkit.ffmpeg seems to be working okay for me with the FFmpeg libraries that I've downloaded, but I have a couple of questions on how to use it. I'm following an FFmeg tutorial which I've found at http://dranger.com/ffmpeg/ffmpeg.html. It's based on C code, but I'm doing my best to translate it into Python. My results so far follow with some comments/questions further down the page. from cgkit import ffmpeg ffmpeg.avformat.av_register_all() fileName = "C:\\Users\\Public\\Videos\\Sample Videos\\Wildlife.wmv" formatCtx = ffmpeg.avformat.av_open_input_file(fileName, format=None, buf_size=0, params=None) ffmpeg.avformat.av_find_stream_info(formatCtx) codecCtx = ffmpeg.decls.AVCodecContext() ##Find the first video stream videoStream = -1 for i in range(formatCtx.nb_streams): if formatCtx.streams[i].contents.codec.contents.codec_type == ffmpeg.decls.CODEC_TYPE_VIDEO: videoStream = i break ## Get a pointer to the codec context for the video stream codecCtx = formatCtx.streams[videoStream].contents.codec ## Find the decoder for the video stream pCodec = ffmpeg.avcodec.avcodec_find_decoder(codecCtx.contents.codec_id) if pCodec is None: print("Unsupported codec!\n") ## Open codec ffmpeg.avcodec.avcodec_open(codecCtx.contents, pCodec) ## Allocate video frame pFrameRGB = ffmpeg.avcodec.avcodec_alloc_frame() ## Determine required buffer size and allocate buffer numBytes = ffmpeg.avcodec.avpicture_get_size(ffmpeg.decls.PIX_FMT_RGB24, codecCtx.contents.width, codecCtx.contents.height) buffer = (uint8_t *)av_malloc(numBytes*sizeof(uint8_t)); ## not converted into python yet; still c This last line is where I get stuck since I'm not sure how to translate the C into Python; "buffer = av_malloc(numBytes)" perhaps? In any case, I can't find the function "av_malloc" within the cgkit.ffmpeg module. A friend suggested "avpicture_alloc" since it both calculates the picture size and allocates its space. So this is what I would use to replace the last section of code above: picture = ffmpeg.decls.AVPicture() ffmpeg.avcodec.avpicture_alloc(picture, ffmpeg.decls.PIX_FMT_RGB24, codecCtx.contents.width, codecCtx.contents.height) This works okay, but the next step in the Dranger tutorial requires a pointer to the buffer I would have created above. Would there be a pointer to this required buffer somewhere else? // Assign appropriate parts of buffer to image planes in pFrameRGB // Note that pFrameRGB is anAVFrame <http://dranger.com/ffmpeg/data.html#AVFrame>, but AVFrame is a superset // ofAVPicture <http://dranger.com/ffmpeg/data.html#AVPicture> avpicture_fill <http://dranger.com/ffmpeg/functions.html#avpicture_fill>((AVPicture <http://dranger.com/ffmpeg/data.html#AVPicture> *)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height); This Dranger tutorial is teaching me alot but I'm guessing that it is probably working with a different FFmpeg version than cgkit.ffmpeg and I'm also finding that much of the C code doesn't translate directly into Python. Still, its a good place to start. Any other tutorials that you would suggest? My friend also pointed out that there was a 'higher-level' module in cgkit for working with ffmpeg, 'cgkit.mediafile', so I'm going to have a look at that also. Thanks for any comments. Best regards, Tim Grove |
From: Matthias B. <mat...@gm...> - 2013-10-10 20:29:18
|
Hi Timothy, On 09.10.13 10:14, Timothy W. Grove wrote: > I realize that cgkit.ffmpeg is built around an older version of FFmpeg > and I've downloaded the shared libraries for v0.7.1 for Win32 from > http://ffmpeg.zeranoe.com/builds/win32/shared/. I'm not that familiar > with ctypes yet, but is it a HUGE task to build this module for a more > current version of FFmpeg? I'd like to update as I actually cannot run it myself at the moment because meanwhile I also have a newer version of ffmpeg. But the entire approach is probably not such a good idea anyway as it's too hard to maintain. In the past, the ffmpeg API has changed quite a lot and you would have to track their changes constantly which I don't have the time to do. Furthermore, if using ctypes, it's not enough if ffmpeg stays source code compatible, it would have to stay binary compatible which is even less likely. So I'm not sure if I should actually keep those ffmpeg bindings in cgkit. > ## Determine required buffer size and allocate buffer > numBytes = > ffmpeg.avcodec.avpicture_get_size(ffmpeg.decls.PIX_FMT_RGB24, > codecCtx.contents.width, codecCtx.contents.height) > buffer = (uint8_t *)av_malloc(numBytes*sizeof(uint8_t)); ## not > converted into python yet; still c > > This last line is where I get stuck since I'm not sure how to translate > the C into Python; "buffer = av_malloc(numBytes)" perhaps? In any case, > [...] I also would have referred you to the mediafile module which already does what you need, so you could have a look inside that one. As I noticed from your other mail, you have found that module already. :) - Matthias - |