⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spudec.cpp

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 CPP
📖 第 1 页 / 共 3 页
字号:
             memset(scaled_aimageY + y * scaled_strideY + scaled_width, 0, scaled_strideY - scaled_width);
             /* FIXME: Why is self one needed? */
             memset(scaled_imageY + y * scaled_strideY + scaled_width, 0, scaled_strideY - scaled_width);
            }
          /*
          if (scaled_width/2 < scaled_strideUV)
           for (unsigned int y = 0; y < scaled_height/2; ++y)
            {
             memset(scaled_aimageUV + y * scaled_strideUV + scaled_width/2, 128, scaled_strideUV - scaled_width/2);
             memset(scaled_imageUV + y * scaled_strideUV + scaled_width/2, 128, scaled_strideUV - scaled_width/2);
            }*/
            memset(scaled_imageUV ,0,scaled_strideUV*(scaled_height/2));
            memset(scaled_aimageUV,128,scaled_strideUV*((scaled_height+1)/2));
          if (scaled_width <= 1 || scaled_height <= 1) {
            goto nothing_to_do;
          }
          switch(spu_aamode&15) {
          case 4:
          sws_spu_image(scaled_imageY, scaled_aimageY,
                  scaled_width, scaled_height, scaled_strideY,
                  image, aimage, width, height, stride,prefs);
          break;
          case 3:
          table_x = (scale_pixel*)calloc(scaled_width, sizeof(scale_pixel));
          table_y = (scale_pixel*)calloc(scaled_height, sizeof(scale_pixel));
          if (!table_x || !table_y) {
            DPRINTF(_l("Fatal: spudec_draw_scaled: calloc failed"));
          }
          scale_table(0, 0, width - 1, scaled_width - 1, table_x);
          scale_table(0, 0, height - 1, scaled_height - 1, table_y);
          for (unsigned int y = 0; y < scaled_height; y++)
            for (unsigned int x = 0; x < scaled_width; x++)
              scale_image(x, y, table_x, table_y);
          free(table_x);
          free(table_y);
          break;
          case 0:
          /* no antialiasing */
          for (unsigned int y = 0; y < scaled_height; ++y) {
            int unscaled_y = y * 0x100 / scaley;
            int strides = stride * unscaled_y;
            int scaled_strides = scaled_strideY * y;
            for (unsigned int x = 0; x < scaled_width; ++x) {
              int unscaled_x = x * 0x100 / scalex;
              scaled_imageY[scaled_strides + x] = image[strides + unscaled_x];
              scaled_aimageY[scaled_strides + x] = (unsigned char)canon_alpha(aimage[strides + unscaled_x]);
            }
          }
          break;
          case 1:
          {
            /* Intermediate antialiasing. */
            for (unsigned int y = 0; y < scaled_height; ++y) {
              const unsigned int unscaled_top = y * 0x100 / scaley;
              unsigned int unscaled_bottom = (y + 1) * 0x100 / scaley;
              if (unscaled_bottom >= height)
                unscaled_bottom = height - 1;
              for (unsigned int x = 0; x < scaled_width; ++x) {
                const unsigned int unscaled_left = x * 0x100 / scalex;
                unsigned int unscaled_right = (x + 1) * 0x100 / scalex;
                unsigned int color = 0;
                unsigned int alpha = 0;
                unsigned int walkx, walky;
                unsigned int base, tmp;
                if (unscaled_right >= width)
                  unscaled_right = width - 1;
                for (walky = unscaled_top; walky <= unscaled_bottom; ++walky)
                  for (walkx = unscaled_left; walkx <= unscaled_right; ++walkx) {
                    base = walky * stride + walkx;
                    tmp = canon_alpha(aimage[base]);
                    alpha += tmp;
                    color += tmp * image[base];
                  }
                base = y * scaled_strideY + x;
                scaled_imageY[base] = (unsigned char)(alpha ? color / alpha : 0);
                scaled_aimageY[base] = (unsigned char)(alpha * (1 + unscaled_bottom - unscaled_top) * (1 + unscaled_right - unscaled_left));
              }
            }
          }
          break;
          case 2:
          {
            /* Best antialiasing.  Very slow. */
            /* Any pixel (x, y) represents pixels from the original
               rectangular region comprised between the columns
               unscaled_y and unscaled_y + 0x100 / scaley and the rows
               unscaled_x and unscaled_x + 0x100 / scalex

               The original rectangular region that the scaled pixel
               represents is cut in 9 rectangular areas like this:

               +---+-----------------+---+
               | 1 |        2        | 3 |
               +---+-----------------+---+
               |   |                 |   |
               | 4 |        5        | 6 |
               |   |                 |   |
               +---+-----------------+---+
               | 7 |        8        | 9 |
               +---+-----------------+---+

               The width of the left column is at most one pixel and
               it is never null and its right column is at a pixel
               boundary.  The height of the top row is at most one
               pixel it is never null and its bottom row is at a
               pixel boundary. The width and height of region 5 are
               integral values.  The width of the right column is
               what remains and is less than one pixel.  The height
               of the bottom row is what remains and is less than
               one pixel.

               The row above 1, 2, 3 is unscaled_y.  The row between
               1, 2, 3 and 4, 5, 6 is top_low_row.  The row between 4,
               5, 6 and 7, 8, 9 is (unsigned int)unscaled_y_bottom.
               The row beneath 7, 8, 9 is unscaled_y_bottom.

               The column left of 1, 4, 7 is unscaled_x.  The column
               between 1, 4, 7 and 2, 5, 8 is left_right_column.  The
               column between 2, 5, 8 and 3, 6, 9 is (unsigned
               int)unscaled_x_right.  The column right of 3, 6, 9 is
               unscaled_x_right. */
            const double inv_scalex = (double) 0x100 / scalex;
            const double inv_scaley = (double) 0x100 / scaley;
            for (unsigned int y = 0; y < scaled_height; ++y) {
              const double unscaled_y = y * inv_scaley;
              const double unscaled_y_bottom = unscaled_y + inv_scaley;
              const unsigned int top_low_row = (unsigned int)std::min(unscaled_y_bottom, unscaled_y + 1.0);
              const double top = top_low_row - unscaled_y;
              const unsigned int height = unscaled_y_bottom > top_low_row
                ? (unsigned int) unscaled_y_bottom - top_low_row
                : 0;
              const double bottom = unscaled_y_bottom > top_low_row
                ? unscaled_y_bottom - floor(unscaled_y_bottom)
                : 0.0;
              for (unsigned int x = 0; x < scaled_width; ++x) {
                const double unscaled_x = x * inv_scalex;
                const double unscaled_x_right = unscaled_x + inv_scalex;
                const unsigned int left_right_column = (unsigned int)std::min(unscaled_x_right, unscaled_x + 1.0);
                const double left = left_right_column - unscaled_x;
                const unsigned int width = unscaled_x_right > left_right_column
                  ? (unsigned int) unscaled_x_right - left_right_column
                  : 0;
                const double right = unscaled_x_right > left_right_column
                  ? unscaled_x_right - floor(unscaled_x_right)
                  : 0.0;
                double color = 0.0;
                double alpha = 0.0;
                double tmp;
                unsigned int base;
                /* Now use these informations to compute a good alpha,
                   and lightness.  The sum is on each of the 9
                   region's surface and alpha and lightness.

                  transformed alpha = sum(surface * alpha) / sum(surface)
                  transformed color = sum(surface * alpha * color) / sum(surface * alpha)
                */
                /* 1: top left part */
                base = stride * (unsigned int) unscaled_y;
                tmp = left * top * canon_alpha(aimage[base + (unsigned int) unscaled_x]);
                alpha += tmp;
                color += tmp * image[base + (unsigned int) unscaled_x];
                /* 2: top center part */
                if (width > 0) {
                  unsigned int walkx;
                  for (walkx = left_right_column; walkx < (unsigned int) unscaled_x_right; ++walkx) {
                    base = stride * (unsigned int) unscaled_y + walkx;
                    tmp = /* 1.0 * */ top * canon_alpha(aimage[base]);
                    alpha += tmp;
                    color += tmp * image[base];
                  }
                }
                /* 3: top right part */
                if (right > 0.0) {
                  base = stride * (unsigned int) unscaled_y + (unsigned int) unscaled_x_right;
                  tmp = right * top * canon_alpha(aimage[base]);
                  alpha += tmp;
                  color += tmp * image[base];
                }
                /* 4: center left part */
                if (height > 0) {
                  unsigned int walky;
                  for (walky = top_low_row; walky < (unsigned int) unscaled_y_bottom; ++walky) {
                    base = stride * walky + (unsigned int) unscaled_x;
                    tmp = left /* * 1.0 */ * canon_alpha(aimage[base]);
                    alpha += tmp;
                    color += tmp * image[base];
                  }
                }
                /* 5: center part */
                if (width > 0 && height > 0) {
                  unsigned int walky;
                  for (walky = top_low_row; walky < (unsigned int) unscaled_y_bottom; ++walky) {
                    unsigned int walkx;
                    base = stride * walky;
                    for (walkx = left_right_column; walkx < (unsigned int) unscaled_x_right; ++walkx) {
                      tmp = /* 1.0 * 1.0 * */ canon_alpha(aimage[base + walkx]);
                      alpha += tmp;
                      color += tmp * image[base + walkx];
                    }
                  }
                }
                /* 6: center right part */
                if (right > 0.0 && height > 0) {
                  unsigned int walky;
                  for (walky = top_low_row; walky < (unsigned int) unscaled_y_bottom; ++walky) {
                    base = stride * walky + (unsigned int) unscaled_x_right;
                    tmp = right /* * 1.0 */ * canon_alpha(aimage[base]);
                    alpha += tmp;
                    color += tmp * image[base];
                  }
                }
                /* 7: bottom left part */
                if (bottom > 0.0) {
                  base = stride * (unsigned int) unscaled_y_bottom + (unsigned int) unscaled_x;
                  tmp = left * bottom * canon_alpha(aimage[base]);
                  alpha += tmp;
                  color += tmp * image[base];
                }
                /* 8: bottom center part */
                if (width > 0 && bottom > 0.0) {
                  unsigned int walkx;
                  base = stride * (unsigned int) unscaled_y_bottom;
                  for (walkx = left_right_column; walkx < (unsigned int) unscaled_x_right; ++walkx) {
                    tmp = /* 1.0 * */ bottom * canon_alpha(aimage[base + walkx]);
                    alpha += tmp;
                    color += tmp * image[base + walkx];
                  }
                }
                /* 9: bottom right part */
                if (right > 0.0 && bottom > 0.0) {
                  base = stride * (unsigned int) unscaled_y_bottom + (unsigned int) unscaled_x_right;
                  tmp = right * bottom * canon_alpha(aimage[base]);
                  alpha += tmp;
                  color += tmp * image[base];
                }
                /* Finally mix these transparency and brightness information suitably */
                base = scaled_strideY * y + x;
                scaled_imageY[base] = (unsigned char)(alpha > 0 ? color / alpha : 0);
                scaled_aimageY[base] = (unsigned char)(alpha * scalex * scaley / 0x10000);
                /*
                if (scaled_aimage[base]) {
                  scaled_aimage[base] = (unsigned char)(256 - scaled_aimage[base]);
                  if (scaled_aimage[base] + scaled_image[base] > 255)
                    scaled_image[base] = (unsigned char)(256 - scaled_aimage[base]);
                }*/
              }
            }
          }
          }
nothing_to_do:
          scaled_frame_width = dxs;
          scaled_frame_height = dys;
          for (unsigned int y=0;y<scaled_height/2;y++)
           for (unsigned int x=0;x<scaled_width/2;x++)
            {
             scaled_imageUV[x+scaled_strideUV*y]=0;
             scaled_aimageUV[x+scaled_strideUV*y]=scaled_aimageY[x*2+scaled_strideY*(y*2)];
            }
        }
      }
      if (scaled_imageY){
        switch (spu_alignment) {
        case 0:
          scaled_start_row = dys*sub_pos/100;
          if (scaled_start_row + scaled_height > dys)
            scaled_start_row = dys - scaled_height;
          break;
        case 1:
	   y1 = dys*sub_pos/100 - scaled_height/2;
          if (sub_pos < 50) {
	    if (y1 < 0) scaled_start_row = 0; else scaled_start_row = y1;
          } else {
	    if (y1 + scaled_height > dys)
	      scaled_start_row = dys - scaled_height;
	    else
	      scaled_start_row = y1;
          }
          break;
        case 2:
          y1 = dys*sub_pos/100 - scaled_height;
	  if (y1 < 0) scaled_start_row = 0; else scaled_start_row = 0;
          break;
        }
        draw_alpha(scaled_start_col, scaled_start_row, scaled_width, scaled_height,
                   scaled_imageY, scaled_aimageY, scaled_strideY,scaled_imageUV, scaled_aimageUV, scaled_strideUV,prefs);
        spu_changed = 0;
      }
    }
  }
  else
  {
    DPRINTF(_l("SPU not displayed: start_pts=%d  end_pts=%d  now_pts=%d"),start_pts, end_pts, now_pts);
  }
}

void Tspudec::spudec_update_palette( unsigned int *palette)
{
  if (palette) {
    memcpy(global_palette, palette, sizeof(global_palette));
  }
}

void Tspudec::spudec_set_font_factor( double factor)
{
  font_start_level = (int)(0xF0-(0xE0*factor));
}
/*
Tspudec::Tspudec(unsigned int *palette, unsigned int frame_width, unsigned int frame_height)
{
 Tspudec(palette, NULL, 0, frame_width, frame_height);
}
*/
/* get palette custom color, width, height from .idx file */
Tspudec::Tspudec(IffdshowBase *Ideci,const AM_DVD_YUV *palette, const AM_DVD_YUV *cuspal, unsigned int custom, unsigned int frame_width, unsigned int frame_height)
{
 memset(this,0,sizeof(*this));
 deci=Ideci;
 spu_aamode = 4;
 spu_alignment = -1;
 sub_pos=0;
 oldgauss=-1;
 deci->getPostproc(&libmplayer);
    this->packet = NULL;
    this->image = NULL;
    this->scaled_imageY=this->scaled_imageUV = NULL;
    /* XXX Although the video frame is some size, the SPU frame is
       always maximum size i.e. 720 wide and 576 or 480 high */
    this->orig_frame_width = 720;
    this->orig_frame_height = (frame_height == 480 || frame_height == 240) ? 480 : 576;
    this->custom = custom;
    // set up palette:
    this->auto_palette = 1;
    if (palette){
      memcpy(this->global_palette, palette, sizeof(this->global_palette));
      this->auto_palette = 0;
    }
    this->custom = custom;
    if (custom && cuspal) {
      memcpy(this->cuspal, cuspal, sizeof(this->cuspal));
      this->auto_palette = 0;
    }
    // forced subtitles default: show all subtitles
    this->forced_subs_only=0;
    this->is_forced_sub=0;
    packet_pts=0;
}
/*
Tspudec::Tspudec(unsigned int *palette)
{
    Tspudec(palette, 0, 0);
}
*/
Tspudec::~Tspudec()
{
    if (filter.lumH) libmplayer->sws_freeVec(filter.lumH);
    while (queue_head)
      spudec_free_packet(spudec_dequeue_packet());
    if (packet)
      free(packet);
    if (scaled_imageY)
        free(scaled_imageY);
    if (scaled_imageUV)
        free(scaled_imageUV);
    if (image)
      free(image);
    libmplayer->Release();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -