func: static void * attribute_align_arg worker(void *v){
  
      AVCodecContext *avctx = v;
  
      ThreadContext *c = avctx->internal->frame_thread_encoder;
  
      AVPacket *pkt = NULL;
  
  
  
      while(!c->exit){
  
          int got_packet, ret;
  
          AVFrame *frame;
  
          Task task;
  
  
  
          if(!pkt) pkt= av_mallocz(sizeof(*pkt));
  
          if(!pkt) continue;
  
          av_init_packet(pkt);
  
  
  
          pthread_mutex_lock(&c->task_fifo_mutex);
  
          while (av_fifo_size(c->task_fifo) <= 0 || c->exit) {
  
              if(c->exit){
  
                  pthread_mutex_unlock(&c->task_fifo_mutex);
  
                  goto end;
  
              }
  
              pthread_cond_wait(&c->task_fifo_cond, &c->task_fifo_mutex);
  
          }
  
          av_fifo_generic_read(c->task_fifo, &task, sizeof(task), NULL);
  
          pthread_mutex_unlock(&c->task_fifo_mutex);
  
          frame = task.indata;
  
  
  
          ret = avcodec_encode_video2(avctx, pkt, frame, &got_packet);
  
          pthread_mutex_lock(&c->buffer_mutex);
  
          av_frame_unref(frame);
  
          pthread_mutex_unlock(&c->buffer_mutex);
  
          av_frame_free(&frame);
  
          if(got_packet) {
  
              int ret2 = av_dup_packet(pkt);
  
              if (ret >= 0 && ret2 < 0)
  
                  ret = ret2;
  
          } else {
  
              pkt->data = NULL;
  
              pkt->size = 0;
  
          }
  
          pthread_mutex_lock(&c->finished_task_mutex);
  
          c->finished_tasks[task.index].outdata = pkt; pkt = NULL;
  
          c->finished_tasks[task.index].return_code = ret;
  
          pthread_cond_signal(&c->finished_task_cond);
  
          pthread_mutex_unlock(&c->finished_task_mutex);
  
      }
  
  end:
  
      av_free(pkt);
  
      pthread_mutex_lock(&c->buffer_mutex);
  
      avcodec_close(avctx);
  
      pthread_mutex_unlock(&c->buffer_mutex);
  
      av_freep(&avctx);
  
      return NULL;
  
  }
  