title: using X264 and librtmp to send live camera frame, but the flash can't show
body: <p>I am using X264 and librtmp to send my live camera frame, all the things seems right. but my web test flash can't show the correct video. Sometimes it seems correct, but when I re-click play button, it doesn't show any picture on the flash.</p>
  
  <p>Here is my X264 config code</p>
  
  <pre><code>x264_param_default_preset(&amp;x264param, "ultrafast", "zerolatency");
  x264param.i_threads = 2;
  x264param.i_width = width;
  x264param.i_height = height;
  x264param.i_log_level = X264_LOG_DEBUG;
  x264param.i_fps_num = x264param.i_timebase_num= fps;
  x264param.i_fps_den = x264param.i_timebase_den=1;
  x264param.i_frame_total = 0;
  
  x264param.i_frame_reference =1;
  //x264param.i_frame_reference = 2;
  x264param.i_keyint_min = 25;
  x264param.i_keyint_max = fps*3;
  x264param.i_scenecut_threshold = 40;
  
  x264param.b_deblocking_filter = 1;
  x264param.b_cabac = 0;
  x264param.analyse.i_trellis = 0;
  x264param.analyse.b_chroma_me = 1;
  
  x264param.vui.i_sar_width = 0;
  x264param.vui.i_sar_height = 0;
  x264param.i_bframe_bias = 0;
  x264param.b_interlaced= 0;
  x264param.analyse.i_subpel_refine = 6; /* 0..5 -&gt; 1..6 */
  x264param.analyse.i_me_method = X264_ME_DIA;//X264_ME_HEX?X264_ME_DIA
  x264param.analyse.i_me_range = 16;
  x264param.analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO;
  x264param.i_deblocking_filter_alphac0 = 0;
  x264param.i_deblocking_filter_beta = 0;
  //x264param.analyse.intra = X264_ANALYSE_I4x4;
  x264param.analyse.intra = X264_ANALYSE_I4x4;//  | X264_ANALYSE_PSUB16x16 | X264_ANALYSE_BSUB16x16;
  x264param.analyse.inter = X264_ANALYSE_I4x4 | X264_ANALYSE_PSUB16x16 | X264_ANALYSE_BSUB16x16; 
  //edit 2014-7-28
  x264param.analyse.b_transform_8x8 = 1;
  //x264param.analyse.b_transform_8x8 = 0;
  x264param.analyse.b_fast_pskip = 1;
  x264param.i_bframe = 0;
  //x264param.b_intra_refresh
  x264param.analyse.b_weighted_bipred = 0;
  
  //// Intra refres:
  x264param.i_keyint_max = 250;
  x264param.b_intra_refresh = 0;
  ////Rate control:
  //x264param.rc.i_rc_method = X264_RC_CRF;
  
  //Rate Control
  x264param.rc.f_ip_factor = 1.4f;
  x264param.rc.f_pb_factor = 1.3f;
  x264param.rc.f_qcompress = 1.0;
  x264param.rc.i_qp_min = 20;//20;
  x264param.rc.i_qp_max = 32;
  x264param.rc.i_qp_step = 1;
  
  switch (0)
  {
  case 0: /* 1 PASS ABR */
      x264param.rc.i_rc_method = X264_RC_ABR;
      x264param.rc.i_bitrate = 300; // max = 5000
      x264param.rc.b_mb_tree = 0;
      break;
  case 1: /* 1 PASS CQ */
      x264param.rc.i_rc_method = X264_RC_CQP;
      x264param.rc.i_qp_constant = 26;//10 - 51
      break;
  }
  
  //For streaming:
  x264param.b_repeat_headers = 1;
  x264param.b_annexb = 1;
  x264_param_apply_profile(&amp;x264param, "baseline");
  encoder = x264_encoder_open(&amp;x264param);
  x264_picture_init( &amp;pic_in );
  x264_picture_alloc(&amp;pic_in, X264_CSP_I420, width, height);
  
  pic_in.img.i_csp = X264_CSP_I420|X264_CSP_VFLIP;
  pic_in.img.i_plane = 3;
  pic_in.i_type = X264_TYPE_AUTO;
  </code></pre>
  
  <p>Sending To RTMP:</p>
  
  <pre><code>sws_scale(convertCtx,&amp;a,&amp;scribe,0,height, pic_in.img.plane, pic_in.img.i_stride);
  int i_nal;
  int i_frame_size = x264_encoder_encode( encoder, &amp;nal, &amp;i_nal, &amp;pic_in, &amp;pic_out );
  if(i_frame_size &lt;= 0){
      printf("\t!!!FAILED encode frame \n");
  }else{
      for (int i = 0,last=0; i &lt; i_nal;i++)  
      {
          fwrite(nal[i].p_payload, 1, i_frame_size-last, fpw1);
          if (nal[i].i_type == NAL_SPS) {
              sps_len = nal[i].i_payload-4;
              sps  = new unsigned char[sps_len];
              memcpy(sps,nal[i].p_payload+4,sps_len);
          } else if (nal[i].i_type == NAL_PPS) {
              pps_len = nal[i].i_payload-4;
              pps  = new unsigned char[sps_len];
              memcpy(pps,nal[i].p_payload+4,pps_len);
              send_video_sps_pps(); 
              free(sps);
              free(pps);
          } else {
              send_rtmp_video(nal[i].p_payload,i_frame_size-last);
              break;
          }
          last += nal[i].i_payload;
      }
  }
  </code></pre>
  
  <p>Send PPS and SPS</p>
  
  <pre><code>void send_video_sps_pps(){
  if(rtmp!= NULL){
      RTMPPacket * packet;
      unsigned char * body;
      int i;
  
      packet = (RTMPPacket *)malloc(RTMP_HEAD_SIZE+1024);
      memset(packet,0,RTMP_HEAD_SIZE);
  
      packet-&gt;m_body = (char *)packet + RTMP_HEAD_SIZE;
      body = (unsigned char *)packet-&gt;m_body;
      i = 0;
      body[i++] = 0x17;
      body[i++] = 0x00;
  
      body[i++] = 0x00;
      body[i++] = 0x00;
      body[i++] = 0x00;
  
      /*AVCDecoderConfigurationRecord*/
      body[i++] = 0x01;
      body[i++] = sps[1];
      body[i++] = sps[2];
      body[i++] = sps[3];
      body[i++] = 0xff;
  
      /*sps*/
      body[i++]   = 0xe1;
      body[i++] = (sps_len &gt;&gt; 8) &amp; 0xff;
      body[i++] = sps_len &amp; 0xff;
      memcpy(&amp;body[i],sps,sps_len);
      i +=  sps_len;
  
      /*pps*/
      body[i++]   = 0x01;
      body[i++] = (pps_len &gt;&gt; 8) &amp; 0xff;
      body[i++] = (pps_len) &amp; 0xff;
      memcpy(&amp;body[i],pps,pps_len);
      i +=  pps_len;
  
      packet-&gt;m_packetType = RTMP_PACKET_TYPE_VIDEO;
      packet-&gt;m_nBodySize = i;
      packet-&gt;m_nChannel = 0x04;
      packet-&gt;m_nTimeStamp = 0;
      packet-&gt;m_hasAbsTimestamp = 0;
      packet-&gt;m_headerType = RTMP_PACKET_SIZE_MEDIUM;
      packet-&gt;m_nInfoField2 = rtmp-&gt;m_stream_id;
  
      RTMP_SendPacket(rtmp,packet,TRUE);
      free(packet);   
      rtmp_start_time = GetTickCount();
  }else{
      std::cout&lt;&lt;"RTMP is not ready"&lt;&lt;std::endl;
  }
  }
  </code></pre>
  
  <p>Send video Frame</p>
  
  <pre><code>void send_rtmp_video(unsigned char * buf,int len){
  RTMPPacket * packet;
  long timeoffset = GetTickCount() - rtmp_start_time; 
  
  int type = buf[0]&amp;0x1f;
  
  packet = (RTMPPacket *)malloc(RTMP_HEAD_SIZE+len+9);
  memset(packet,0,RTMP_HEAD_SIZE);
  
  packet-&gt;m_body = (char *)packet + RTMP_HEAD_SIZE;
  packet-&gt;m_nBodySize = len + 9;
  
  /*send video packet*/
  unsigned char *body = (unsigned char *)packet-&gt;m_body;
  memset(body,0,len+9);
  
  /*key frame*/
  body[0] = 0x27;
  if (type == NAL_SLICE_IDR) {
      body[0] = 0x17;
  }
  
  body[1] = 0x01;   /*nal unit*/
  body[2] = 0x00;
  body[3] = 0x00;
  body[4] = 0x00;
  
  body[5] = (len &gt;&gt; 24) &amp; 0xff;
  body[6] = (len &gt;&gt; 16) &amp; 0xff;
  body[7] = (len &gt;&gt;  8) &amp; 0xff;
  body[8] = (len ) &amp; 0xff;
  
  /*copy data*/
  memcpy(&amp;body[9],buf,len);
  
  packet-&gt;m_hasAbsTimestamp = 0;
  packet-&gt;m_packetType = RTMP_PACKET_TYPE_VIDEO;
  if(rtmp != NULL){
      packet-&gt;m_nInfoField2 = rtmp-&gt;m_stream_id;
  }
  packet-&gt;m_nChannel = 0x04;
  packet-&gt;m_headerType = RTMP_PACKET_SIZE_LARGE;
  packet-&gt;m_nTimeStamp = timeoffset;
  
  if(rtmp != NULL){
      RTMP_SendPacket(rtmp,packet,TRUE);
  }
  free(packet);
  </code></pre>
  
  <p>}</p>