[Libav-user] libav + multithreading per frame
ahmed mobarack
ahmed.mobarack123 at yahoo.com
Wed Oct 18 10:02:28 EEST 2017
Hello,
Thank for the marvelous work you did on this library. However I'm having a though time to understand how multithreading works.
I understood that the decoders have intern multithreading that they manage themselves. Now I'm trying to achieve something else, i.e. I have several frames (images) that I want to convert at the same time.Now I want to understand if I need several AVFormatContext, AVCodecContext to achieve this (one per thread).
I tried calling this method I wrote in 8 threads but it gives me an exception when calling avcodec_decode_video2.
Here is my sample code :
bool FFmpeg::ConvertHEICPartToRAW(Buffer& in, IFrameInfo& frameInfo, Buffer& out){ if (!IsLoaded()) return false;
try { // create tampon buffer const boost::shared_ptr<unsigned char> pBuffer(reinterpret_cast<unsigned char*>(av_malloc(8192)), av_free);
// create WBuffer<->FFmpeg adapter (AVIOContext) const boost::shared_ptr<AVIOContext> pAvioContext(avio_alloc_context(pBuffer.get(), 8192, 0, reinterpret_cast<void*>(&in), &readFunction, NULL, NULL), av_free);
// create format context that will detect the file format const boost::shared_ptr<AVFormatContext> pAvFormat = boost::shared_ptr<AVFormatContext>( favformat_alloc_context(), favformat_free_context);
// setup the format context with the buffer AVFormatContext* pAvFormatPtr = pAvFormat.get(); pAvFormatPtr->pb = pAvioContext.get();
// open the input int ret = favformat_open_input(&pAvFormatPtr, "dummyFilename", NULL, NULL); if (ret < 0) return false;
// find stream info ret = favformat_find_stream_info(pAvFormatPtr, NULL); if (ret < 0) return false;
// find first video (image) stream std::size_t videoStreamIndex = -1; for (std::size_t a = 0; a < pAvFormatPtr->nb_streams; a++) if (pAvFormatPtr->streams[a]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { videoStreamIndex = a; break; }
if (videoStreamIndex == -1) return false;
// get codec const boost::shared_ptr<AVCodecContext> pCodecCtx(pAvFormatPtr->streams[videoStreamIndex]->codec, avcodec_close);
// find decoder AVCodec *pCodec = avcodec_find_decoder(pCodecCtx->codec_id); if (pCodec == NULL) return false;
// open it ret = avcodec_open2(pCodecCtx.get(), pCodec, NULL); if (ret < 0) return false;
// creat packet to decode with auto destruct AVPacket encodedPacket; const boost::shared_ptr<AVPacket> pAVPacket(&encodedPacket, av_free_packet);
// init packet av_init_packet(pAVPacket.get()); encodedPacket.data = NULL; encodedPacket.size = 0;
// now read a frame into this AVPacket ret = av_read_frame(pAvFormatPtr, &encodedPacket); if (ret < 0) return false;
// create final decoded frame int frameFinished = 0; AVFrame* pDecodedFrame = av_frame_alloc();
// decode frame ret = avcodec_decode_video2(pCodecCtx.get(), pDecodedFrame, &frameFinished, &encodedPacket); if (ret < 0) return false;
// create destination picture AVPicture destPic; AVPixelFormat destFormat = AV_PIX_FMT_RGB24; ret = favpicture_alloc(&destPic, destFormat, pDecodedFrame->width, pDecodedFrame->height); if (ret < 0) return false;
// auto destruct picture const boost::shared_ptr<AVPicture> pAVPicture(&destPic, favpicture_free);
// create picture scaling context const boost::shared_ptr<SwsContext> pSWSCtxt(sws_getContext(pDecodedFrame->width, pDecodedFrame->height, (AVPixelFormat)pDecodedFrame->format, pDecodedFrame->width, pDecodedFrame->height, destFormat, SWS_BILINEAR, NULL, NULL, NULL), sws_freeContext); if (pSWSCtxt.get() == NULL) return false;
// scale picture sws_scale(pSWSCtxt.get(), pDecodedFrame->data, pDecodedFrame->linesize, 0, pDecodedFrame->height, destPic.data, destPic.linesize);
// create destination buffer const std::size_t dataSize = pDecodedFrame->height * pDecodedFrame->width * 3; const boost::shared_ptr<uint8_t> pData(reinterpret_cast<uint8_t*>(::malloc(dataSize)), ::free);
// copy image to buffer ret = av_image_copy_to_buffer(pData.get(), dataSize, destPic.data, destPic.linesize, AV_PIX_FMT_RGB24, pDecodedFrame->width, pDecodedFrame->height, 1); if (ret < 0) return false;
// write to output buffer out.Write(pData.get(), dataSize);
// update frame info frameInfo.m_Width = pDecodedFrame->width; frameInfo.m_Height = pDecodedFrame->height; frameInfo.m_BitsPerPixel = 24;
return true; } catch(...) {}
return false;}
Thank you for your time
Ahmed Mobarack
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20171018/a7e19b75/attachment.html>
More information about the Libav-user
mailing list