/** \fn markSurfaceUsed \brief mark the surfave as used. Can be called multiple time. */ bool decoderFFLIBVA::markSurfaceUsed(ADM_vaSurface *s) { imageMutex.lock(); s->refCount++; imageMutex.unlock(); return true; }
/** \fn markSurfaceUsed \brief mark the surfave as used. Can be called multiple time. */ static bool libvaMarkSurfaceUsed(void *v, void * cookie) { ADM_vaSurface *img=(ADM_vaSurface *)v; decoderFFLIBVA *decoder=(decoderFFLIBVA *)cookie; imageMutex.lock(); img->refCount++; imageMutex.unlock(); return true; }
/** \fn markSurfaceUnused \brief mark the surfave as unused by the caller. Can be called multiple time. */ bool decoderFFLIBVA::markSurfaceUnused(ADM_vaSurface *img) { imageMutex.lock(); img->refCount--; aprintf("Surface %x, Ref count is now %d\n",img->surface,img->refCount); if(!img->refCount) { vaPool.freeSurfaceQueue.append(img); } imageMutex.unlock(); return true; }
/** \fn markSurfaceUnused \brief mark the surfave as unused by the caller. Can be called multiple time. */ static bool libvaMarkSurfaceUnused(void *v, void * cookie) { ADM_vaSurface *img=(ADM_vaSurface *)v; decoderFFLIBVA *decoder=(decoderFFLIBVA *)cookie; imageMutex.lock(); img->refCount--; aprintf("Ref count is now %d\n",img->refCount); if(!img->refCount) { decoder->reclaimImage(img); } imageMutex.unlock(); return true; }
int FileOutputStream::Open() { char msg[512]; while( !(strm = fopen( cur_filename, "wb" )) ){ if( errno == ENOSPC #ifndef __MINGW32__ || errno == EDQUOT #endif ){ ADM_assert(snprintf(msg,512,"can't open \"%s\": %s\n%s\n", cur_filename, (errno==ENOSPC?"filesystem full":"quota exceeded"), "Please free up some space and press RETRY to try again.")!=-1); mutex_slaveThread_problem.lock(); kind_of_slaveThread_problem = ADM_strdup(msg); cond_slaveThread_problem->wait(); /* implicit mutex_slaveThread_problem.unlock(); */ ADM_dealloc(kind_of_slaveThread_problem); kind_of_slaveThread_problem = NULL; if( kind_of_slaveThread_problem_rc == 0 ){ /* ignore */ /* it doesn't make any sense to continue */ mjpeg_error_exit1( "Could not open for writing: %s", cur_filename ); } }else{ fprintf(stderr,"can't open \"%s\": %u (%s)\n", cur_filename, errno, strerror(errno)); ADM_assert(0); } } strm_fd = fileno(strm); return 0; }
/** * \fn lookupBySurfaceId * @param * @return */ ADM_vaSurface *decoderFFLIBVA::lookupBySurfaceId(VASurfaceID id) { imageMutex.lock(); int n=allSurfaceQueue.size(); for(int i=0;i<n;i++) if(allSurfaceQueue[i]->surface==id) { imageMutex.unlock(); return allSurfaceQueue[i]; } imageMutex.unlock(); ADM_warning("Lookup a non existing surface\n"); ADM_assert(0); return NULL; }
/** * \fn dtor */ decoderFFLIBVA::~decoderFFLIBVA() { imageMutex.lock(); int m=vaPool.allSurfaceQueue.size(); int n=vaPool.freeSurfaceQueue.size(); if(n!=m) { ADM_warning("Some surfaces are not reclaimed! (%d/%d)\n",n,m); } for(int i=0;i<n;i++) { delete vaPool.freeSurfaceQueue[i]; } vaPool.freeSurfaceQueue.clear(); imageMutex.unlock(); }
void ADM_dezalloc(void *ptr) { #ifdef __APPLE__ if (!ptr) return; free(ptr); #else int dome = doMemStat; uint32_t *backdoor; uint32_t size, offset; char *c = (char*)ptr; if (!ptr) return; backdoor = (uint32_t*)ptr; backdoor -= 2; if (*backdoor == 0xbeefbeef) { printf("Double free gotcha!\n"); ADM_assert(0); } ADM_assert(((*backdoor) >> 16) == 0xdead); offset = backdoor[0] & 0xffff; size = backdoor[1]; *backdoor = 0xbeefbeef; // Scratch sig if (dome) memAccess.lock(); free(c - offset); ADM_consumed -= size; if(dome) memAccess.unlock(); #endif }
/** * * @param avctx * @param pic * @return */ int decoderFFLIBVA::getBuffer(AVCodecContext *avctx, AVFrame *pic) { imageMutex.lock(); if(vaPool.freeSurfaceQueue.empty()) { aprintf("Allocating new vaSurface\n"); ADM_vaSurface *img=allocateADMVaSurface(avctx); if(!img) { imageMutex.unlock(); ADM_warning("Cannot allocate new vaSurface!\n"); return -1; } vaPool.freeSurfaceQueue.append(img); vaPool.allSurfaceQueue.append(img); }else { aprintf("Reusing vaSurface from pool\n"); } ADM_vaSurface *s= vaPool.freeSurfaceQueue[0]; vaPool.freeSurfaceQueue.popFront(); imageMutex.unlock(); s->refCount=0; markSurfaceUsed(s); // 1 ref taken by lavcodec pic->buf[0]=av_buffer_create((uint8_t *)&(s->surface), // Maybe a memleak here... sizeof(s->surface), ADM_LIBVAreleaseBuffer, (void *)this, AV_BUFFER_FLAG_READONLY); aprintf("Alloc Buffer : 0x%llx, surfaceid=%x\n",s,(int)s->surface); pic->data[0]=(uint8_t *)s; pic->data[3]=(uint8_t *)(uintptr_t)s->surface; pic->reordered_opaque= avctx->reordered_opaque; return 0; }
/** * \fn dtor */ decoderFFLIBVA::~decoderFFLIBVA() { if(_context) // duplicate ~decoderFF to make sure in transit buffers are // released { avcodec_close (_context); av_free(_context); _context=NULL; } imageMutex.lock(); int m=this->allSurfaceQueue.size(); int n=freeSurfaceQueue.size(); if(n!=m) { ADM_warning("Some surfaces are not reclaimed! (%d/%d)\n",n,m); } for(int i=0;i<n;i++) { delete freeSurfaceQueue[i]; } freeSurfaceQueue.clear(); imageMutex.unlock(); nbSurface=0; if(libva!=VA_INVALID) admLibVA::destroyDecoder(libva); libva=VA_INVALID; if(scratch) delete scratch; scratch=NULL; if(va_context) { delete va_context; va_context=NULL; } }
void *ADM_alloc(size_t size) { char *c; uint64_t l,lorg; uint32_t *backdoor; int dome=doMemStat; if(dome) memAccess.lock(); l=(uint64_t)malloc(size+32); // Get next boundary lorg=l; l=(l+15)& 0xfffffffffffffff0LL; l+=16; c=(char *)l; backdoor=(uint32_t *)(c-8); *backdoor=(0xdead<<16)+l-lorg; backdoor[1]=size; if(dome) memAccess.unlock(); ADM_consumed+=size; return c; }
//******************************************************* int defaultAudioSlave( muxerMT *context ) { DIA_encoding *work=(DIA_encoding *)context->opaque; uint32_t total_sample=0; uint32_t total_size=0; uint32_t samples,audioLen; printf("[AudioThread] Starting\n"); while(context->audioEncoder->getPacket(context->audioBuffer, &audioLen, &samples) && total_sample<context->audioTargetSample) { total_sample+=samples; total_size+=audioLen; accessMutex.lock(); if(context->audioAbort) { context->audioDone=1; context->muxer->audioEof(); accessMutex.unlock(); return 1; } work->setAudioSize(total_size); accessMutex.unlock(); while(!context->muxer->needAudio()) { if(context->audioAbort) { context->muxer->audioEof(); context->audioDone=1; return 1; } }; if(audioLen) { context->muxer->writeAudioPacket(audioLen,context->audioBuffer); } accessMutex.lock(); context->feedAudio+=audioLen; accessMutex.unlock(); } accessMutex.lock(); // Let's say audio is always ok, shall we :) context->audioDone=1; context->muxer->audioEof(); accessMutex.unlock(); printf("[AudioThread] Exiting\n"); printf("[AudioThread] Target %u, got %u, %f %%\n",context->audioTargetSample,total_sample, (float)total_sample/(float)context->audioTargetSample); return 1; }
void FileOutputStream::Write( uint8_t *buf, unsigned int len ) { uint8_t *p = buf; unsigned int plen = len; int rc; ADM_assert(strm_fd != -1); while( (rc=write(strm_fd,p,plen)) != plen ){ if( rc > 0 ){ p+=rc; plen-=rc; continue; } if( rc == -1 && (errno == ENOSPC #ifndef __MINGW32__ || errno == EDQUOT #endif ) ){ char msg[512]; fprintf(stderr,"slaveThread: we have a problem. errno=%u\n",errno); ADM_assert(snprintf(msg,512,"can't write to file \"%s\": %s\n%s\n", cur_filename, (errno==ENOSPC?"filesystem full":"quota exceeded"), "Please free up some space and press RETRY to try again.")!=-1); mutex_slaveThread_problem.lock(); kind_of_slaveThread_problem = ADM_strdup(msg); cond_slaveThread_problem->wait(); /* implicit mutex_slaveThread_problem.unlock(); */ ADM_dealloc(kind_of_slaveThread_problem); kind_of_slaveThread_problem = NULL; if( kind_of_slaveThread_problem_rc == 0 ){ /* ignore */ /* it doesn't make any sense to continue */ mjpeg_error_exit1( "Failed write: %s", cur_filename ); } }else{ mjpeg_error_exit1( "Failed write: %s", cur_filename ); } } }
//******************************************************* int defaultVideoSlave( muxerMT *context ) { DIA_encoding *work=(DIA_encoding *)context->opaque; ADMBitstream *bitstream=context->bitstream; uint32_t mx=context->nbVideoFrame; printf("[VideoThread] Starting\n"); for(uint32_t i=0;i<mx;i++) { bitstream->cleanup(i); if(context->videoAbort) { context->videoDone=1; context->muxer->videoEof(); return 1; } if(!context->videoEncoder->encode( i,bitstream)) { accessMutex.lock(); context->videoDone=2; context->muxer->videoEof(); accessMutex.unlock(); return 1; } if(bitstream->len) context->muxer->writeVideoPacket(bitstream); work->setFrame(i,bitstream->len,bitstream->out_quantizer,mx); accessMutex.lock(); context->currentVideoFrame=i; context->feedVideo+=bitstream->len; accessMutex.unlock(); } accessMutex.lock(); context->videoDone=1; context->muxer->videoEof(); accessMutex.unlock(); printf("[VideoThread] Exiting\n"); return 1; }