如何在 iPhone 下面用 ffmpeg 解码 H.264 流 (2)

如何在 iPhone 下面用 ffmpeg 解码 H.264 流 (2)


  下面是如果解码以及将  YV12 数据转换成 
32 位 ARGB 数据的代码
  1
 
  2  #include  " avcodec.h "
  3  #include  " h264decoder.h " ;
  4 
  5  typedef unsigned  char  byte_t;
  6  typedef unsigned  int  uint_t;
  7 
  8  struct  AVCodec  * fCodec  =  NULL;               //  Codec
  9  struct  AVCodecContext  * fCodecContext  =  NULL;           //  Codec Context
 10  struct  AVFrame  * fVideoFrame  =  NULL;           //  Frame    
 11 
 12  int  fDisplayWidth     =   0 ;
 13  int  fDisplayHeight     =   0 ;
 14  int   * fColorTable  =  NULL;
 15 
 16  int  avcodec_decode_video(AVCodecContext  * avctx, AVFrame  * picture,
 17                            int   * got_picture_ptr,
 18                            const  uint8_t  * buf,  int  buf_size)
 19  {
 20      AVPacket avpkt;
 21      av_init_packet( & avpkt);
 22      avpkt.data  =  buf;
 23      avpkt.size  =  buf_size;
 24       //  HACK for CorePNG to decode as normal PNG by default
 25      avpkt.flags  =  AV_PKT_FLAG_KEY;
 26       return  avcodec_decode_video2(avctx, picture, got_picture_ptr,  & avpkt);
 27  }
 28 
 29  #define  RGB_V(v) ((v < 0) ? 0 : ((v > 255) ? 255 : v))
 30          
 31  void  DeleteYUVTable()
 32  {
 33      av_free(fColorTable);
 34  }
 35 
 36  void  CreateYUVTable()
 37  {
 38       int  i;
 39       int  u, v;
 40       int   * u_b_tab  =  NULL;
 41       int   * u_g_tab  =  NULL;
 42       int   * v_g_tab  =  NULL;
 43       int   * v_r_tab  =  NULL;
 44 
 45      fColorTable  =  ( int   * )av_malloc( 4   *   256   *   sizeof ( int ));
 46      u_b_tab  =   & fColorTable[ 0   *   256 ];
 47      u_g_tab  =   & fColorTable[ 1   *   256 ];
 48      v_g_tab  =   & fColorTable[ 2   *   256 ];
 49      v_r_tab  =   & fColorTable[ 3   *   256 ];
 50 
 51       for  (i  =   0 ; i  <   256 ; i ++ ) {
 52          u  =  v  =  (i  -   128 );
 53          u_b_tab[i]  =  ( int ) (  1.772     *  u);
 54          u_g_tab[i]  =  ( int ) (  0.34414   *  u);
 55          v_g_tab[i]  =  ( int ) (  0.71414   *  v); 
 56          v_r_tab[i]  =  ( int ) (  1.402     *  v);
 57      }
 58  }
 59 
 60  /* * YV12 To RGB888  */
 61  void  DisplayYUV_32(uint_t  * displayBuffer,  int  videoWidth,  int  videoHeight,  int  outPitch)
 62  {
 63       int   * u_b_tab  =   & fColorTable[ 0   *   256 ];
 64       int   * u_g_tab  =   & fColorTable[ 1   *   256 ];
 65       int   * v_g_tab  =   & fColorTable[ 2   *   256 ];
 66       int   * v_r_tab  =   & fColorTable[ 3   *   256 ];
 67      
 68       //  YV12: [Y:MxN] [U:M/2xN/2] [V:M/2xN/2]
 69      byte_t *  y  =  fVideoFrame -> data[ 0 ];
 70      byte_t *  u  =  fVideoFrame -> data[ 1 ];
 71      byte_t *  v  =  fVideoFrame -> data[ 2 ];
 72      
 73       int  src_ystride   =  fVideoFrame -> linesize[ 0 ];
 74       int  src_uvstride  =  fVideoFrame -> linesize[ 1 ];
 75      
 76       int  i, line;
 77       int  r, g, b;
 78      
 79       int  ub, ug, vg, vr;
 80 
 81       int  width   =  videoWidth;
 82       int  height  =  videoHeight;
 83      
 84       //  剪切边框
 85       if  (width  >  fDisplayWidth) {
 86          width  =  fDisplayWidth;        
 87          y  +=  (videoWidth  -  fDisplayWidth)  /   2 ;
 88          u  +=  (videoWidth  -  fDisplayWidth)  /   4 ;
 89          v  +=  (videoWidth  -  fDisplayWidth)  /   4 ;
 90      }
 91      
 92       if  (height  >  fDisplayHeight) {
 93          height  =  fDisplayHeight;
 94      }
 95      
 96       for  (line  =   0 ; line  <  height; line ++ ) {
 97          byte_t *  yoff  =  y  +  line  *  src_ystride;
 98          byte_t *  uoff  =  u  +  (line  /   2 *  src_uvstride;
 99          byte_t *  voff  =  v  +  (line  /   2 *  src_uvstride;
100           // uint_t* buffer = displayBuffer + (height - line - 1) * outPitch;
101          uint_t *  buffer  =  displayBuffer  +  line  *  outPitch;
102          
103           for  (i  =   0 ; i  <  width; i ++ ) {
104              ub  =  u_b_tab[ * uoff];
105              ug  =  u_g_tab[ * uoff];
106              vg  =  v_g_tab[ * voff];
107              vr  =  v_r_tab[ * voff];
108              
109              b  =  RGB_V( * yoff  +  ub);
110              g  =  RGB_V( * yoff  -  ug  -  vg);
111              r  =  RGB_V( * yoff  +  vr);
112              
113               * buffer  =   0xff000000   |  b  <<   16   |  g  <<   8   |  r;
114              
115              buffer ++ ;
116              yoff  ++ ;
117              
118               if  ((i  %   2 ==   1 ) {
119                  uoff ++ ;
120                  voff ++ ;
121              }
122          }
123      }
124  }
125 
126  int  avc_decode_init( int  width,  int  height)
127  {
128       if  (fCodecContext  !=  NULL) {
129           return   0 ;
130      }
131      avcodec_init();      
132      avcodec_register_all();
133      fCodec  =  avcodec_find_decoder(CODEC_ID_H264);
134      
135      fDisplayWidth   =  width;
136      fDisplayHeight  =  height;
137 
138      CreateYUVTable();    
139      
140      fCodecContext  =  avcodec_alloc_context(); 
141      avcodec_open(fCodecContext, fCodec); 
142      fVideoFrame   =  avcodec_alloc_frame();
143          
144       return   1 ;
145  }
146 
147  int  avc_decode_release()
148  {
149       if  (fCodecContext) {
150          avcodec_close(fCodecContext);
151          free(fCodecContext -> priv_data);
152          free(fCodecContext);
153          fCodecContext  =  NULL;
154      }
155 
156       if  (fVideoFrame) {
157          free(fVideoFrame);
158          fVideoFrame  =  NULL;
159      }
160 
161      DeleteYUVTable();
162       return   1 ;
163  }
164 
165  int  avc_decode( char *  buf,  int  nalLen,  char *   out )
166  {
167      byte_t *  data  =  (byte_t * )buf;
168       int  frameSize  =   0 ;
169      
170       int  ret  =  avcodec_decode_video(fCodecContext, fVideoFrame,  & frameSize, data, nalLen); 
171       if  (ret  <=   0 ) {
172           return  ret;
173      }
174      
175       int  width   =  fCodecContext -> width;
176       int  height  =  fCodecContext -> height;
177      DisplayYUV_32((uint32_t * ) out , width, height, fDisplayWidth);
178       return  ret;    
179  }
180 

你可能感兴趣的:(如何在 iPhone 下面用 ffmpeg 解码 H.264 流 (2))