<html><head></head><body><div style="color:#000; background-color:#fff; font-family:Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif;font-size:13px"><div id="yui_3_16_0_ym19_1_1508309107697_25345">Hello,</div><div id="yui_3_16_0_ym19_1_1508309107697_25346"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25347"></div><div id="yui_3_16_0_ym19_1_1508309107697_25348">Thank for the marvelous work you did on this library. However I'm having a though time to understand how multithreading works.</div><div id="yui_3_16_0_ym19_1_1508309107697_25349"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25350"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25351">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.</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25352">Now I want to understand if I need several AVFormatContext, AVCodecContext to achieve this (one per thread).</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25353"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25354"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25355">I tried calling this method I wrote in 8 threads but it gives me an exception when calling avcodec_decode_video2.</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25356"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25357"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25358">Here is my sample code :</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25359"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25360"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25361">bool FFmpeg::ConvertHEICPartToRAW(Buffer& in, IFrameInfo& frameInfo, Buffer& out)</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25362">{</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25363"> if (!IsLoaded())</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25364"> return false;</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25365"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25366"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25367"> try</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25368"> {</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25369"> // create tampon buffer</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25370"> const boost::shared_ptr<unsigned char> pBuffer(reinterpret_cast<unsigned char*>(av_malloc(8192)),</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25371"> av_free);</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25372"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25373"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25374"> // create WBuffer<->FFmpeg adapter (AVIOContext)</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25375"> const boost::shared_ptr<AVIOContext> pAvioContext(avio_alloc_context(pBuffer.get(), 8192, 0,</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25376"> reinterpret_cast<void*>(&in), &readFunction, NULL, NULL), av_free);</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25377"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25378"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25379"> // create format context that will detect the file format</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25380"> const boost::shared_ptr<AVFormatContext> pAvFormat = boost::shared_ptr<AVFormatContext>(</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25381"> favformat_alloc_context(), favformat_free_context);</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25382"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25383"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25384"> // setup the format context with the buffer</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25385"> AVFormatContext* pAvFormatPtr = pAvFormat.get();</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25386"> pAvFormatPtr->pb = pAvioContext.get();</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25387"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25388"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25389"> // open the input</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25390"> int ret = favformat_open_input(&pAvFormatPtr, "dummyFilename", NULL, NULL);</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25391"> if (ret < 0)</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25392"> return false;</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25393"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25394"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25395"> // find stream info</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25396"> ret = favformat_find_stream_info(pAvFormatPtr, NULL);</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25397"> if (ret < 0)</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25398"> return false;</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25399"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25400"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25401"> // find first video (image) stream</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25402"> std::size_t videoStreamIndex = -1;</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25403"> for (std::size_t a = 0; a < pAvFormatPtr->nb_streams; a++)</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25404"> if (pAvFormatPtr->streams[a]->codec->codec_type == AVMEDIA_TYPE_VIDEO)</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25405"> {</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25406"> videoStreamIndex = a;</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25407"> break;</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25408"> }</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25409"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25410"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25411"> if (videoStreamIndex == -1)</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25412"> return false;</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25413"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25414"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25415"> // get codec</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25416"> const boost::shared_ptr<AVCodecContext> pCodecCtx(pAvFormatPtr->streams[videoStreamIndex]->codec,</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25417"> avcodec_close);</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25418"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25419"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25420"> // find decoder</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25421"> AVCodec *pCodec = avcodec_find_decoder(pCodecCtx->codec_id);</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25422"> if (pCodec == NULL)</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25423"> return false;</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25424"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25425"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25426"> // open it</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25427"> ret = avcodec_open2(pCodecCtx.get(), pCodec, NULL);</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25428"> if (ret < 0)</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25429"> return false;</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25430"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25431"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25432"> // creat packet to decode with auto destruct</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25433"> AVPacket encodedPacket;</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25434"> const boost::shared_ptr<AVPacket> pAVPacket(&encodedPacket, av_free_packet);</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25435"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25436"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25437"> // init packet</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25438"> av_init_packet(pAVPacket.get());</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25439"> encodedPacket.data = NULL;</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25440"> encodedPacket.size = 0;</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25441"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25442"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25443"> // now read a frame into this AVPacket</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25444"> ret = av_read_frame(pAvFormatPtr, &encodedPacket);</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25445"> if (ret < 0)</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25446"> return false;</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25447"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25448"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25449"> // create final decoded frame</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25450"> int frameFinished = 0;</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25451"> AVFrame* pDecodedFrame = av_frame_alloc();</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25523"><br clear="none" id="yiv0248560760yui_3_16_0_ym19_1_1508224967878_21662"> // decode frame</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25455"> ret = avcodec_decode_video2(pCodecCtx.get(), pDecodedFrame, &frameFinished, &encodedPacket);</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25456"> if (ret < 0)</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25457"> return false;</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25458"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25459"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25460"> // create destination picture</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25461"> AVPicture destPic;</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25462"> AVPixelFormat destFormat = AV_PIX_FMT_RGB24;</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25463"> ret = favpicture_alloc(&destPic, destFormat, pDecodedFrame->width, pDecodedFrame->height);</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25464"> if (ret < 0)</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25465"> return false;</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25466"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25467"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25468"> // auto destruct picture</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25469"> const boost::shared_ptr<AVPicture> pAVPicture(&destPic, favpicture_free);</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25470"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25471"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25472"> // create picture scaling context</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25473"> const boost::shared_ptr<SwsContext> pSWSCtxt(sws_getContext(pDecodedFrame->width,</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25474"> pDecodedFrame->height, (AVPixelFormat)pDecodedFrame->format, pDecodedFrame->width,</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25475"> pDecodedFrame->height, destFormat, SWS_BILINEAR, NULL, NULL, NULL), sws_freeContext);</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25476"> if (pSWSCtxt.get() == NULL)</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25477"> return false;</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25478"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25479"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25480"> // scale picture</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25481"> sws_scale(pSWSCtxt.get(), pDecodedFrame->data, pDecodedFrame->linesize, 0, pDecodedFrame->height,</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25482"> destPic.data, destPic.linesize);</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25483"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25484"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25485"> // create destination buffer</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25486"> const std::size_t dataSize = pDecodedFrame->height * pDecodedFrame->width * 3;</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25487"> const boost::shared_ptr<uint8_t> pData(reinterpret_cast<uint8_t*>(::malloc(dataSize)), ::free);</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25488"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25489"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25490"> // copy image to buffer</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25491"> ret = av_image_copy_to_buffer(pData.get(), dataSize, destPic.data, destPic.linesize,</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25492"> AV_PIX_FMT_RGB24, pDecodedFrame->width, pDecodedFrame->height, 1);</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25493"> if (ret < 0)</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25494"> return false;</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25495"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25496"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25497"> // write to output buffer</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25498"> out.Write(pData.get(), dataSize);</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25499"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25500"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25501"> // update frame info</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25502"> frameInfo.m_Width = pDecodedFrame->width;</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25503"> frameInfo.m_Height = pDecodedFrame->height;</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25504"> frameInfo.m_BitsPerPixel = 24;</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25505"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25506"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25507"> return true;</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25508"> }</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25509"> catch(...)</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25510"> {}</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25511"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25512"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25513"> return false;</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25514">}</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25515"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25516"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25517">Thank you for your time</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25518"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25519"></div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25520">Ahmed Mobarack</div><div dir="ltr" id="yui_3_16_0_ym19_1_1508309107697_25521"><br clear="none" id="yui_3_16_0_ym19_1_1508309107697_25522"></div></div></body></html>