Ejemplo n.º 1
0
//*******************************************************
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 *ADM_alloc(size_t size)
{
#ifdef __APPLE__
	return malloc(size);
#else
	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;
#endif
}
void ADM_dezalloc(void *ptr)
{
  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();
}
/**
    \fn getBuffer
    \brief returns a VDPAU render masquerading as a AVFrame
*/
int decoderFFLIBVA::getBuffer(AVCodecContext *avctx, AVFrame *pic)
{
    
    decoderFFLIBVA *x=(decoderFFLIBVA *)avctx->opaque;
    
    imageMutex.lock();
    ADM_assert(!freeSurfaceQueue.empty());
    ADM_vaSurface *s= x->freeSurfaceQueue[0];
    x->freeSurfaceQueue.popFront();
    imageMutex.unlock();
    libvaMarkSurfaceUsed(s,this);
    
    aprintf("Alloc Buffer : 0x%llx\n",s);
    uint8_t *p=(uint8_t *)s->surface;
    pic->data[0]=p;
    pic->data[1]=p;
    pic->data[2]=p;
    pic->data[3]=p;
    pic->linesize[0]=0;
    pic->linesize[1]=0;
    pic->linesize[2]=0;
    pic->linesize[3]=0;
    pic->type=FF_BUFFER_TYPE_USER;
//    render->state  =0;
//    render->state |= FF_LIBVA_STATE_USED_FOR_REFERENCE;
//    render->state &= ~FF_LIBVA_STATE_DECODED;
//    render->psf=0;
    pic->reordered_opaque= avctx->reordered_opaque;
   // pic->opaque= avctx->opaque;
    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;
    
}
Ejemplo n.º 6
0
/**
    \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;
    
}
Ejemplo n.º 7
0
//*******************************************************
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;
}
/**
    \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;
    
}
Ejemplo n.º 9
0
/**
    \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;
}
Ejemplo n.º 10
0
/**
 * 
 * @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 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;
}
Ejemplo n.º 12
0
/**
 * \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();
}
/**
 * \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;
    }
}