void thread_task_deblock_CTBRow::work()
{
  state = Running;
  img->thread_run(this);

  int xStart=0;
  int xEnd = img->get_deblk_width();

  int ctbSize = img->get_sps().CtbSizeY;
  int deblkSize = ctbSize/4;

  int first =  ctb_y    * deblkSize;
  int last  = (ctb_y+1) * deblkSize;
  if (last > img->get_deblk_height()) {
    last = img->get_deblk_height();
  }

  int finalProgress = CTB_PROGRESS_DEBLK_V;
  if (!vertical) finalProgress = CTB_PROGRESS_DEBLK_H;

  int rightCtb = img->get_sps().PicWidthInCtbsY-1;

  if (vertical) {
    // pass 1: vertical

    int CtbRow = std::min(ctb_y+1 , img->get_sps().PicHeightInCtbsY-1);
    img->wait_for_progress(this, rightCtb,CtbRow, CTB_PROGRESS_PREFILTER);
  }
  else {
    // pass 2: horizontal

    if (ctb_y>0) {
      img->wait_for_progress(this, rightCtb,ctb_y-1, CTB_PROGRESS_DEBLK_V);
    }

    img->wait_for_progress(this, rightCtb,ctb_y,  CTB_PROGRESS_DEBLK_V);

    if (ctb_y+1<img->get_sps().PicHeightInCtbsY) {
      img->wait_for_progress(this, rightCtb,ctb_y+1, CTB_PROGRESS_DEBLK_V);
    }
  }

  //printf("deblock %d to %d orientation: %d\n",first,last,vertical);

  bool deblocking_enabled;

  // first pass: check edge flags and whether we have to deblock
  if (vertical) {
    deblocking_enabled = derive_edgeFlags_CTBRow(img, ctb_y);

    //for (int x=0;x<=rightCtb;x++) {
    int x=0; img->set_CtbDeblockFlag(x,ctb_y, deblocking_enabled);
    //}
  }
  else {
    int x=0; deblocking_enabled=img->get_CtbDeblockFlag(x,ctb_y);
  }

  if (deblocking_enabled) {
    derive_boundaryStrength(img, vertical, first,last, xStart,xEnd);

    edge_filtering_luma(img, vertical, first,last, xStart,xEnd);

    if (img->get_sps().ChromaArrayType != CHROMA_MONO) {
      edge_filtering_chroma(img, vertical, first,last, xStart,xEnd);
    }
  }

  for (int x=0;x<=rightCtb;x++) {
    const int CtbWidth = img->get_sps().PicWidthInCtbsY;
    img->ctb_progress[x+ctb_y*CtbWidth].set_progress(finalProgress);
  }

  state = Finished;
  img->thread_finishes(this);
}
void thread_task_deblock_CTBRow::work()
{
  state = Running;
  img->thread_run(this);

  int xStart=0;
  int xEnd = img->get_deblk_width();

  int ctbSize = img->get_sps().CtbSizeY;
  int deblkSize = ctbSize/4;

  int first =  ctb_y    * deblkSize;
  int last  = (ctb_y+1) * deblkSize;
  if (last > img->get_deblk_height()) {
    last = img->get_deblk_height();
  }

  int finalProgress = CTB_PROGRESS_DEBLK_V;
  if (!vertical) finalProgress = CTB_PROGRESS_DEBLK_H;

  int rightCtb = img->get_sps().PicWidthInCtbsY-1;

  if (vertical) {
     

    int CtbRow = std::min(ctb_y+1 , img->get_sps().PicHeightInCtbsY-1);
    img->wait_for_progress(this, rightCtb,CtbRow, CTB_PROGRESS_PREFILTER);
  }
  else {
     

    if (ctb_y>0) {
      img->wait_for_progress(this, rightCtb,ctb_y-1, CTB_PROGRESS_DEBLK_V);
    }

    img->wait_for_progress(this, rightCtb,ctb_y,  CTB_PROGRESS_DEBLK_V);

    if (ctb_y+1<img->get_sps().PicHeightInCtbsY) {
      img->wait_for_progress(this, rightCtb,ctb_y+1, CTB_PROGRESS_DEBLK_V);
    }
  }

   

  bool deblocking_enabled;

   
  if (vertical) {
    deblocking_enabled = derive_edgeFlags_CTBRow(img, ctb_y);

     
    int x=0; img->set_CtbDeblockFlag(x,ctb_y, deblocking_enabled);
     
  }
  else {
    int x=0; deblocking_enabled=img->get_CtbDeblockFlag(x,ctb_y);
  }

  if (deblocking_enabled) {
    derive_boundaryStrength(img, vertical, first,last, xStart,xEnd);

    edge_filtering_luma(img, vertical, first,last, xStart,xEnd);

    if (img->get_sps().ChromaArrayType != CHROMA_MONO) {
      edge_filtering_chroma(img, vertical, first,last, xStart,xEnd);
    }
  }

  for (int x=0;x<=rightCtb;x++) {
    const int CtbWidth = img->get_sps().PicWidthInCtbsY;
    img->ctb_progress[x+ctb_y*CtbWidth].set_progress(finalProgress);
  }

  state = Finished;
  img->thread_finishes(this);
}