func: static int decode_frame(AVCodecContext *avctx, void *data,
  
                          int *got_frame, AVPacket *avpkt)
  
  {
  
      const uint8_t *buf = avpkt->data;
  
      int buf_size       = avpkt->size;
  
      H264Context *h     = avctx->priv_data;
  
      AVFrame *pict      = data;
  
      int buf_index      = 0;
  
      Picture *out;
  
      int i, out_idx;
  
      int ret;
  
  
  
      h->flags  = avctx->flags;
  
  
  
      /* end of stream, output what is still in the buffers */
  
      if (buf_size == 0) {
  
   out:
  
  
  
          h->cur_pic_ptr = NULL;
  
          h->first_field = 0;
  
  
  
          // FIXME factorize this with the output code below
  
          out     = h->delayed_pic[0];
  
          out_idx = 0;
  
          for (i = 1;
  
               h->delayed_pic[i] &&
  
               !h->delayed_pic[i]->f.key_frame &&
  
               !h->delayed_pic[i]->mmco_reset;
  
               i++)
  
              if (h->delayed_pic[i]->poc < out->poc) {
  
                  out     = h->delayed_pic[i];
  
                  out_idx = i;
  
              }
  
  
  
          for (i = out_idx; h->delayed_pic[i]; i++)
  
              h->delayed_pic[i] = h->delayed_pic[i + 1];
  
  
  
          if (out) {
  
              out->reference &= ~DELAYED_PIC_REF;
  
              ret = output_frame(h, pict, &out->f);
  
              if (ret < 0)
  
                  return ret;
  
              *got_frame = 1;
  
          }
  
  
  
          return buf_index;
  
      }
  
      if(h->is_avc && buf_size >= 9 && buf[0]==1 && buf[2]==0 && (buf[4]&0xFC)==0xFC && (buf[5]&0x1F) && buf[8]==0x67){
  
          int cnt= buf[5]&0x1f;
  
          const uint8_t *p= buf+6;
  
          while(cnt--){
  
              int nalsize= AV_RB16(p) + 2;
  
              if(nalsize > buf_size - (p-buf) || p[2]!=0x67)
  
                  goto not_extra;
  
              p += nalsize;
  
          }
  
          cnt = *(p++);
  
          if(!cnt)
  
              goto not_extra;
  
          while(cnt--){
  
              int nalsize= AV_RB16(p) + 2;
  
              if(nalsize > buf_size - (p-buf) || p[2]!=0x68)
  
                  goto not_extra;
  
              p += nalsize;
  
          }
  
  
  
          return ff_h264_decode_extradata(h, buf, buf_size);
  
      }
  
  not_extra:
  
  
  
      buf_index = decode_nal_units(h, buf, buf_size, 0);
  
      if (buf_index < 0)
  
          return -1;
  
  
  
      if (!h->cur_pic_ptr && h->nal_unit_type == NAL_END_SEQUENCE) {
  
          av_assert0(buf_index <= buf_size);
  
          goto out;
  
      }
  
  
  
      if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS) && !h->cur_pic_ptr) {
  
          if (avctx->skip_frame >= AVDISCARD_NONREF ||
  
              buf_size >= 4 && !memcmp("Q264", buf, 4))
  
              return buf_size;
  
          av_log(avctx, AV_LOG_ERROR, "no frame!\n");
  
          return -1;
  
      }
  
  
  
      if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS) ||
  
          (h->mb_y >= h->mb_height && h->mb_height)) {
  
          if (avctx->flags2 & CODEC_FLAG2_CHUNKS)
  
              decode_postinit(h, 1);
  
  
  
          field_end(h, 0);
  
  
  
          /* Wait for second field. */
  
          *got_frame = 0;
  
          if (h->next_output_pic && (h->next_output_pic->sync || h->sync>1)) {
  
              ret = output_frame(h, pict, &h->next_output_pic->f);
  
              if (ret < 0)
  
                  return ret;
  
              *got_frame = 1;
  
              if (CONFIG_MPEGVIDEO) {
  
                  ff_print_debug_info2(h->avctx, h->next_output_pic, pict, h->er.mbskip_table,
  
                                      &h->low_delay,
  
                                      h->mb_width, h->mb_height, h->mb_stride, 1);
  
              }
  
          }
  
      }
  
  
  
      assert(pict->data[0] || !*got_frame);
  
  
  
      return get_consumed_bytes(buf_index, buf_size);
  
  }
  