static GstVaapiDecoderStatus
decode_picture (GstVaapiDecoderJpeg * decoder, GstJpegSegment * seg)
{
  GstVaapiDecoderJpegPrivate *const priv = &decoder->priv;
  GstJpegFrameHdr *const frame_hdr = &priv->frame_hdr;

  if (!VALID_STATE (decoder, GOT_SOI))
    return GST_VAAPI_DECODER_STATUS_SUCCESS;

  switch (seg->marker) {
    case GST_JPEG_MARKER_SOF_MIN:
      priv->profile = GST_VAAPI_PROFILE_JPEG_BASELINE;
      break;
    default:
      GST_ERROR ("unsupported profile %d", seg->marker);
      return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
  }

  memset (frame_hdr, 0, sizeof (*frame_hdr));
  if (!gst_jpeg_segment_parse_frame_header (seg, frame_hdr)) {
    GST_ERROR ("failed to parse image");
    return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
  }

  if (priv->height != frame_hdr->height || priv->width != frame_hdr->width)
    priv->size_changed = TRUE;

  priv->height = frame_hdr->height;
  priv->width = frame_hdr->width;

  priv->decoder_state |= GST_JPEG_VIDEO_STATE_GOT_SOF;
  return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
Esempio n. 2
0
static gboolean
parse_jpeg_segment (GstJpegSegment * segment)
{
  switch (segment->marker) {
    case GST_JPEG_MARKER_SOF0:
    case GST_JPEG_MARKER_SOF1:
    case GST_JPEG_MARKER_SOF2:
    case GST_JPEG_MARKER_SOF3:
    case GST_JPEG_MARKER_SOF9:
    case GST_JPEG_MARKER_SOF10:
    case GST_JPEG_MARKER_SOF11:{
      GstJpegFrameHdr hdr;
      int i;

      if (!gst_jpeg_segment_parse_frame_header (segment, &hdr)) {
        g_printerr ("Failed to parse frame header!\n");
        return FALSE;
      }

      g_print ("\t\twidth x height   = %u x %u\n", hdr.width, hdr.height);
      g_print ("\t\tsample precision = %u\n", hdr.sample_precision);
      g_print ("\t\tnum components   = %u\n", hdr.num_components);
      for (i = 0; i < hdr.num_components; ++i) {
        g_print ("\t\t%d: id=%d, h=%d, v=%d, qts=%d\n", i,
            hdr.components[i].identifier, hdr.components[i].horizontal_factor,
            hdr.components[i].vertical_factor,
            hdr.components[i].quant_table_selector);
      }
      break;
    }
    case GST_JPEG_MARKER_DHT:{
      GstJpegHuffmanTables ht;

      if (!gst_jpeg_segment_parse_huffman_table (segment, &ht)) {
        g_printerr ("Failed to parse huffman table!\n");
        return FALSE;
      }
      break;
    }
    case GST_JPEG_MARKER_DQT:{
      GstJpegQuantTables qt;

      if (!gst_jpeg_segment_parse_quantization_table (segment, &qt)) {
        g_printerr ("Failed to parse quantization table!\n");
        return FALSE;
      }
      break;
    }
    case GST_JPEG_MARKER_SOS:{
      GstJpegScanHdr hdr;
      int i;

      if (!gst_jpeg_segment_parse_scan_header (segment, &hdr)) {
        g_printerr ("Failed to parse scan header!\n");
        return FALSE;
      }

      g_print ("\t\tnum components   = %u\n", hdr.num_components);
      for (i = 0; i < hdr.num_components; ++i) {
        g_print ("\t\t  %d: cs=%d, dcs=%d, acs=%d\n", i,
            hdr.components[i].component_selector,
            hdr.components[i].dc_selector, hdr.components[i].ac_selector);
      }
    }
    case GST_JPEG_MARKER_COM:
      /* gst_util_dump_mem (segment->data + segment->offset, segment->size); */
      break;
    default:
      if (segment->marker >= GST_JPEG_MARKER_APP_MIN
          && segment->marker <= GST_JPEG_MARKER_APP_MAX) {
        guint n = segment->marker - GST_JPEG_MARKER_APP_MIN;

        if (app_segments[n] == NULL)
          app_segments[n] = gst_buffer_new ();

        gst_buffer_append_memory (app_segments[n],
            gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
                (guint8 *) segment->data + segment->offset,
                segment->size, 0, segment->size, NULL, NULL));
      }
      break;
  }
  return TRUE;
}