func: static int dirac_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *pkt)
  
  {
  
      DiracContext *s     = avctx->priv_data;
  
      AVFrame *picture    = data;
  
      uint8_t *buf        = pkt->data;
  
      int buf_size        = pkt->size;
  
      int i, data_unit_size, buf_idx = 0;
  
      int ret;
  
  
  
      /* release unused frames */
  
      for (i = 0; i < MAX_FRAMES; i++)
  
          if (s->all_frames[i].avframe->data[0] && !s->all_frames[i].avframe->reference) {
  
              av_frame_unref(s->all_frames[i].avframe);
  
              memset(s->all_frames[i].interpolated, 0, sizeof(s->all_frames[i].interpolated));
  
          }
  
  
  
      s->current_picture = NULL;
  
      *got_frame = 0;
  
  
  
      /* end of stream, so flush delayed pics */
  
      if (buf_size == 0)
  
          return get_delayed_pic(s, (AVFrame *)data, got_frame);
  
  
  
      for (;;) {
  
          /*[DIRAC_STD] Here starts the code from parse_info() defined in 9.6
  
            [DIRAC_STD] PARSE_INFO_PREFIX = "BBCD" as defined in ISO/IEC 646
  
            BBCD start code search */
  
          for (; buf_idx + DATA_UNIT_HEADER_SIZE < buf_size; buf_idx++) {
  
              if (buf[buf_idx  ] == 'B' && buf[buf_idx+1] == 'B' &&
  
                  buf[buf_idx+2] == 'C' && buf[buf_idx+3] == 'D')
  
                  break;
  
          }
  
          /* BBCD found or end of data */
  
          if (buf_idx + DATA_UNIT_HEADER_SIZE >= buf_size)
  
              break;
  
  
  
          data_unit_size = AV_RB32(buf+buf_idx+5);
  
          if (buf_idx + data_unit_size > buf_size || !data_unit_size) {
  
              if(buf_idx + data_unit_size > buf_size)
  
              av_log(s->avctx, AV_LOG_ERROR,
  
                     "Data unit with size %d is larger than input buffer, discarding\n",
  
                     data_unit_size);
  
              buf_idx += 4;
  
              continue;
  
          }
  
          /* [DIRAC_STD] dirac_decode_data_unit makes reference to the while defined in 9.3 inside the function parse_sequence() */
  
          if (dirac_decode_data_unit(avctx, buf+buf_idx, data_unit_size))
  
          {
  
              av_log(s->avctx, AV_LOG_ERROR,"Error in dirac_decode_data_unit\n");
  
              return -1;
  
          }
  
          buf_idx += data_unit_size;
  
      }
  
  
  
      if (!s->current_picture)
  
          return buf_size;
  
  
  
      if (s->current_picture->avframe->display_picture_number > s->frame_number) {
  
          DiracFrame *delayed_frame = remove_frame(s->delay_frames, s->frame_number);
  
  
  
          s->current_picture->avframe->reference |= DELAYED_PIC_REF;
  
  
  
          if (add_frame(s->delay_frames, MAX_DELAY, s->current_picture)) {
  
              int min_num = s->delay_frames[0]->avframe->display_picture_number;
  
              /* Too many delayed frames, so we display the frame with the lowest pts */
  
              av_log(avctx, AV_LOG_ERROR, "Delay frame overflow\n");
  
  
  
              for (i = 1; s->delay_frames[i]; i++)
  
                  if (s->delay_frames[i]->avframe->display_picture_number < min_num)
  
                      min_num = s->delay_frames[i]->avframe->display_picture_number;
  
  
  
              delayed_frame = remove_frame(s->delay_frames, min_num);
  
              add_frame(s->delay_frames, MAX_DELAY, s->current_picture);
  
          }
  
  
  
          if (delayed_frame) {
  
              delayed_frame->avframe->reference ^= DELAYED_PIC_REF;
  
              if((ret=av_frame_ref(data, delayed_frame->avframe)) < 0)
  
                  return ret;
  
              *got_frame = 1;
  
          }
  
      } else if (s->current_picture->avframe->display_picture_number == s->frame_number) {
  
          /* The right frame at the right time :-) */
  
          if((ret=av_frame_ref(data, s->current_picture->avframe)) < 0)
  
              return ret;
  
          *got_frame = 1;
  
      }
  
  
  
      if (*got_frame)
  
          s->frame_number = picture->display_picture_number + 1;
  
  
  
      return buf_idx;
  
  }
  