жизнь боль )
в продолжении темы Как разблокировать одновременно 2 потока?
3 потока - декодер, енкодер и снимков, декодер ждет переключения между 2 декодированными буферами по барьеру и после переключения отпускает семафоры нужных потоков енкодеров, когда их 2 все работает, только становится на 1 больше и avcodec_send_frame потока снимков начинает переодически слать ошибку -22, даже засегфолился уже ((
для примера обработчик потока снимков
int SnapshotEncode(int (*callback)(const char * topic, const uint8_t * buf, int lbuf), const char * topic)
{
const AVCodec * pCdc = avcodec_find_encoder(AV_CODEC_ID_MJPEG);
if (!pCdc)
{
fprintf(stderr, "ERROR find snapshot encoder for '%s'\n", avcodec_get_name(AV_CODEC_ID_MJPEG));
return -1;
}
struct stEncoder_t * enc = EncoderNew("snapshot");
if (!enc) return -2;
int rt = 0;
AVCodecContext * pCdcCtx = avcodec_alloc_context3(pCdc);
if (!pCdcCtx)
{
PrintErrorAV("alloc snapshot an encoding context", (rt = AVERROR(ENOMEM)));
return rt;
}
pCdcCtx->time_base = DEFAULT_TIME_BASE;
pCdcCtx->pix_fmt = pCdcCtxInp->pix_fmt;
pCdcCtx->height = pCdcCtxInp->height;
pCdcCtx->width = pCdcCtxInp->width;
if ((rt = avcodec_open2(pCdcCtx, pCdc, NULL)))
{
PrintErrorAV("open snapshot encoder", rt);
goto END;
}
AVPacket * pPkt = av_packet_alloc();
if (!pPkt)
{
PrintErrorAV("allocate snapshot AVPacket", (rt = AVERROR(ENOMEM)));
goto END;
}
EncoderRun(enc, 1);
if ((rt = sem_wait(&enc->sem)) < 0)
fprintf(stderr, "ERROR lock encoder semaphore: %d %s\n", errno, strerror(errno));
if (rt)
{
EncoderRun(enc, 0);
pthread_barrier_wait(&stDec.bar);
goto END;
}
if ((rt = avcodec_send_frame(pCdcCtx, stEnc.pFrm)))
PrintErrorAV("snapshot encode send", rt);
else if ((rt = avcodec_receive_packet(pCdcCtx, pPkt)))
PrintErrorAV("snapshot encode receive", rt);
EncoderRun(enc, 0);
pthread_barrier_wait(&stDec.bar);
if (rt == 0) callback(topic, pPkt->data, pPkt->size);
av_packet_unref(pPkt);
END:
EncoderFree(enc);
if (pPkt) av_packet_free(&pPkt);
if (pCdcCtx) avcodec_free_context(&pCdcCtx);
return rt;
}