Пример #1
0
LIBDE265_API de265_error de265_decode(de265_decoder_context* de265ctx, int* more)
{
  decoder_context* ctx = (decoder_context*)de265ctx;

  // if the stream has ended, and no more NALs are to be decoded, flush all pictures

  if (ctx->NAL_queue_len == 0 && ctx->end_of_stream) {
    if (more) { *more=0; } // 0 if no more pictures in queue

    push_current_picture_to_output_queue(ctx);

    while (ctx->reorder_output_queue_length>0) {
      flush_next_picture_from_reorder_buffer(ctx);
      if (more) { *more=1; }
    }

    return DE265_OK;
  }


  // if NAL-queue is empty, we need more data
  // -> input stalled

  if (ctx->NAL_queue_len == 0) {
    if (more) { *more=1; }

    return DE265_ERROR_WAITING_FOR_INPUT_DATA;
  }


  // when there are no free image buffers in the DPB, pause decoding
  // -> output stalled

  if (!has_free_dpb_picture(ctx, false)) {
    if (more) *more = 1;
    return DE265_ERROR_IMAGE_BUFFER_FULL;
  }


  // decode one NAL from the queue

  NAL_unit* nal = pop_from_NAL_queue(ctx);
  assert(nal);
  de265_error err = de265_decode_NAL(de265ctx, nal);
  free_NAL_unit(ctx,nal);

  if (more) {
    // decoding error is assumed to be unrecoverable
    *more = (err==DE265_OK);
  }

  return err;
}
Пример #2
0
static de265_error process_data(decoder_context* ctx, const uint8_t* data, int len,
                                int* out_nBytesProcessed)
{
  *out_nBytesProcessed=0;

  /*
  printf("len=%d\n",len);

  for (int i=0;i<16;i++) {
    printf("%02x ",data[i]);
  }
  printf("\n");
  */

  // Resize output buffer so that complete input would fit.
  // We add 3, because in the worst case 3 extra bytes are created for an input byte.
  rbsp_buffer_resize(&ctx->nal_data, ctx->nal_data.size + len + 3);

  unsigned char* out = ctx->nal_data.data + ctx->nal_data.size;

  for (int i=0;i<len;i++) {
    (*out_nBytesProcessed)++;

    /*
    printf("state=%d input=%02x (%p) (output size: %d)\n",ctx->input_push_state, *data, data,
           out - ctx->nal_data.data);
    */

    switch (ctx->input_push_state) {
    case 0:
    case 1:
      if (*data == 0) { ctx->input_push_state++; }
      else { return DE265_ERROR_NO_STARTCODE; }
      break;
    case 2:
      if      (*data == 1) { ctx->input_push_state=3; ctx->num_skipped_bytes=0; }
      else if (*data == 0) { } // *out++ = 0; }
      else { return DE265_ERROR_NO_STARTCODE; }
      break;
    case 3:
      /*
      *out++ = 0;
      *out++ = 0;
      *out++ = 1;
      */
      *out++ = *data;
      ctx->input_push_state = 4;
      break;
    case 4:
      *out++ = *data;
      ctx->input_push_state = 5;
      break;

    case 5:
      if (*data==0) { ctx->input_push_state=6; }
      else { *out++ = *data; }
      break;

    case 6:
      if (*data==0) { ctx->input_push_state=7; }
      else {
        *out++ = 0;
        *out++ = *data;
        ctx->input_push_state=5;
      }
      break;

    case 7:
      if      (*data==0) { *out++ = 0; }
      else if (*data==3) {
        *out++ = 0; *out++ = 0; ctx->input_push_state=5;

        // remember which byte we removed

        int* skipped = (int *)malloc((ctx->num_skipped_bytes+1) * sizeof(int));

        if (ctx->num_skipped_bytes>0) {
          memcpy(skipped, ctx->skipped_bytes, ctx->num_skipped_bytes * sizeof(int));
        }

        if (ctx->skipped_bytes) {
          free(ctx->skipped_bytes);
        }

        skipped[ctx->num_skipped_bytes] = (out - ctx->nal_data.data) + ctx->num_skipped_bytes;

        ctx->skipped_bytes = skipped;

        ctx->num_skipped_bytes++;
      }
      else if (*data==1) {

        // decode this NAL
        ctx->nal_data.size = out - ctx->nal_data.data;
        de265_error err = de265_decode_NAL((de265_decoder_context*)ctx, &ctx->nal_data);

        // clear buffer for next NAL
        ctx->nal_data.size = 0;
        out = ctx->nal_data.data;

        ctx->input_push_state=3;
        ctx->num_skipped_bytes=0;

        if (err != DE265_OK) {
          data++;
          return err;
        }

        // when there are no free image buffers in the DPB, pause decoding
        if (!has_free_dpb_picture(ctx)) {
          data++;
          return err;
        }
      }
      else {
        *out++ = 0;
        *out++ = 0;
        *out++ = *data;

        ctx->input_push_state=5;
      }
      break;
    }

    data++;

    /*
    for (int i=0;i<out - ctx->nal_data.data;i++) {
      printf("%02x ",ctx->nal_data.data[i]);
    }
    printf("\n");
    */
  }


  if (*out_nBytesProcessed == len && ctx->end_of_stream &&
      ctx->input_push_state != 8) {
    if      (ctx->input_push_state<5) { return DE265_ERROR_EOF; }
    else if (ctx->input_push_state==6) { *out++ = 0; }
    else if (ctx->input_push_state==7) { *out++ = 0; *out++ = 0; }

    ctx->input_push_state=8; // end of stream, stop all processing

    // decode data
    ctx->nal_data.size = out - ctx->nal_data.data;
    de265_error err = de265_decode_NAL((de265_decoder_context*)ctx, &ctx->nal_data);
    if (err != DE265_OK) {
      return err;
    }

    push_current_picture_to_output_queue(ctx);

    // clear buffer
    ctx->nal_data.size = 0;
    out = ctx->nal_data.data;

    return DE265_OK;
  }


  ctx->nal_data.size = out - ctx->nal_data.data;
  return DE265_OK;
}