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
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel