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

📄 vlc.cpp

📁 H.264完整的C语言代码和DCT的代码
💻 CPP
字号:

#ifdef _MSC_VER
extern "C"
{
#endif
#include "global.h"
#ifdef _MSC_VER
}
#endif

//#define DUMP_RLE

#include <fstream.h>

// do not change this (it must occur _after_ your header)
#include "idb_streamc.hpp"

#include "vector.hpp"

int run(unsigned int val)
{
  return val >> 16;
}

int sext(unsigned int val)
{
  val &= 0xffff;
  if (val & 0x8000)
    return 0xffff0000 | val;
  else
    return val;
}

int get_cbp(int mb_idx, vector<unsigned int>& rl);
void slicehdr(int row, int q_scale);

void encode_stream(StreamSchedulerInterface& scd,
                   im_stream<im_half2> run_levels)
{
  static int frame = 0;
#ifdef DUMP_RLE
  String fname("frame");
  fname = fname + String(frame, 10) + "mpeg_sc/rl.txt";
  ofstream dbg(fname.char_ptr());
  frame++;
#endif

  vector<unsigned int> rl;
  streamSaveVect(rl, run_levels);

  int idx = 0;

  int num_macroblocks = mb_height*mb_width;
  int rl_min_length = num_macroblocks*2;

  if (rl.size() < rl_min_length)
  {
    cerr << "Unexpected run/level stream length.  Minimum: ";
    cerr << rl_min_length << "  Actual: " << rl.size() << endl;
    return;
  }

  for (int row = 0; row < mb_height; row++)
  {
    int mb_increment = 1;
    int mb_type = MB_INTRA;

    // motion vector predictions
    int pdx = 0;
    int pdy = 0;

    int sliceblocks = mb_width;
    int pl, pcr, pcb;   // dc predictors

    for (int col = 0; col < mb_width; col++)
    {
      // encode macroblock
      int q_scale = rl[idx++];

      // luminance prediction
      pl = (col == 0) ? (0x400 >> (3 - dc_prec)) / q_scale : pl;
      // chromanance prediction
      pcr = (col == 0) ? pl : pcr;
      pcb = (col == 0) ? pl : pcb;

      if ((col % sliceblocks) == 0)
      {
        slicehdr(row, q_scale);
        pdx = 0;
        pdy = 0;
      }

      // put macroblock increment
      putaddrinc(mb_increment);       

      // macroblock type - hardwired for now, should get from im_stream?
      if (pict_type == I_TYPE)
        mb_type = MB_INTRA;
      else if (pict_type == P_TYPE)
        mb_type = MB_FORWARD | MB_PATTERN;
      else
        cerr << "INVALID 'pict_type'!!" << endl;

      int cbp = rl[idx++];

      if (!(mb_type & MB_PATTERN))
        cbp = 0x3f;

      if (cbp == 0)
        mb_type &= ~MB_PATTERN;

      // put macroblock type
      putmbtype(pict_type, mb_type); 

      if (mb_type & MB_FORWARD)
      {
        int dx, dy;

        // Get motion vectors
        dx = sext(rl[idx]);
        dy = sext(rl[idx] >> 16);

        // put motion vectors
        putmv(dx-pdx, forw_hor_f_code);
        putmv(dy-pdy, forw_vert_f_code);

        pdx = dx;
        pdy = dy;

        idx++;
      }

      if (mb_type & MB_PATTERN)
        putcbp(cbp);

      if (cbp != 0x3f)
        cerr << "cbp: " << hex << cbp << dec << endl;

      if ((mb_type & MB_INTRA) 
          || (pict_type==P_TYPE && !(mb_type & MB_FORWARD)))
      {
        pdx = 0;
        pdy = 0;
      }

      for (int i = 0; i < 6; i++)
      {
        bool valid_block = (cbp & (1<<(5-i))) != 0;
        if (!valid_block)
        {
          while ((idx < rl.size()) && ((rl[idx] == -1) || (rl[idx] == -2)))
            idx++;
          continue;
        }

#ifdef DUMP_RLE
        if (pict_type == P_TYPE)
        {
          dbg << "**************************************************" << endl;
          dbg << "row: " << row << " col: " << col << " block: " << i << endl;
          dbg << "**************************************************" << endl;
        }
#endif

        int values = 0;

        if (mb_type & MB_INTRA)
        {
          // DC coefficient
          if (i < 4)
          {
            int val = sext(rl[idx]) - pl;
            pl = sext(rl[idx]);
            putDClum(val);
          }
          else
          {
            int val;
            if (i == 4)
            {
              val = sext(rl[idx]) - pcb;
              pcb = sext(rl[idx]);
            }
            else
            {
              val = sext(rl[idx]) - pcr;
              pcr = sext(rl[idx]);
            }
            putDCchrom(val);
          }

#ifdef DUMP_RLE
          dbg << "DC level: " << sext(rl[idx]) << endl;
#endif

          values++;
          idx++;

          // AC coefficients
          while ((rl[idx] != -1) && (values <= 64))
          {
            putAC(run(rl[idx]), sext(rl[idx]), intravlc);
            values += run(rl[idx]);
#ifdef DUMP_RLE
            dbg << "    run: " << run(rl[idx]);
            dbg << " absolute: " << values;
            dbg << " level: " << sext(rl[idx]) << endl;
#endif
            values++;
            idx++;
          }
            
          if (rl[idx] != -1)
            cerr << "Block too long!  run >= " << values << endl;

          idx++;

          // End of Block
          if (intravlc)
            putbits(6,4); /* 0110 (Table B-15) */
          else
            putbits(2,2); /* 10 (Table B-14) */
        }
        else
        {
          putACfirst(run(rl[idx]), sext(rl[idx]));
          values += run(rl[idx]);
#ifdef DUMP_RLE
          dbg << "    run: " << run(rl[idx]);
          dbg << " absolute: " << values;
          dbg << " level: " << sext(rl[idx]) << endl;
#endif
          values++;
          idx++;

          while ((rl[idx] != -1) && (values <= 64))
          {
            putAC(run(rl[idx]), sext(rl[idx]), 0);
            values += run(rl[idx]);
#ifdef DUMP_RLE
            dbg << "    run: " << run(rl[idx]);
            dbg << " absolute: " << values;
            dbg << " level: " << sext(rl[idx]) << endl;
#endif
            values++;
            idx++;
          }

          if (rl[idx] != -1)
            cerr << "Block too long!  run >= " << values << endl;

          idx++;

          // End of Block
          putbits(2,2);
        }

        if (values == 0)
          cerr << "Outputting zero length block!" << endl;

        while ((idx < rl.size()) && (rl[idx] == -2))
          idx++;
      }
    }
  }

  cout << "Length of rle vector: " << idx << endl;

#ifdef DUMP_RLE
  dbg.close();
#endif
}

int get_cbp(int mb_idx, vector<unsigned int>& rl)
{
  int cbp = 0;

  for (int blk = 0; blk < 6; blk++)
  {
    int valid_blk = 0;

    for (int y = 0; y < 8; y++, mb_idx += 8)
    {
      for (int x = 0; x < 8; x++)
      {
        if (rl[mb_idx+x])
          valid_blk = 1;
        else
          break;
      }
    }

    cbp = (cbp << 1) | valid_blk;
  }

  return cbp;
}

void slicehdr(int row, int q_scale)
{
  alignbits();
  if (mpeg1 || vertical_size<=2800)
    putbits(SLICE_MIN_START + row, 32); 
  else
  {
    putbits(SLICE_MIN_START + ( row & 127), 32);
    putbits(row >> 7, 3);
  }
  
  // put quantization
  putbits(q_scale, 5);
  
  // putbits(0, 1); // intra_slice_flag  ?? Should this be there ??
  putbits(0, 1); // extra_bit_slice
}

⌨️ 快捷键说明

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