Exemplo n.º 1
0
static GstVaapiDecoderStatus
decode_segment (GstVaapiDecoderJpeg * decoder, GstJpegSegment * seg)
{
  GstVaapiDecoderJpegPrivate *const priv = &decoder->priv;
  GstVaapiDecoderStatus status;

  // Decode segment
  status = GST_VAAPI_DECODER_STATUS_SUCCESS;
  switch (seg->marker) {
    case GST_JPEG_MARKER_SOI:
      priv->mcu_restart = 0;
      priv->decoder_state |= GST_JPEG_VIDEO_STATE_GOT_SOI;
      break;
    case GST_JPEG_MARKER_EOI:
      priv->decoder_state = 0;
      break;
    case GST_JPEG_MARKER_DAC:
      GST_ERROR ("unsupported arithmetic coding mode");
      status = GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
      break;
    case GST_JPEG_MARKER_DHT:
      status = decode_huffman_table (decoder, seg);
      break;
    case GST_JPEG_MARKER_DQT:
      status = decode_quant_table (decoder, seg);
      break;
    case GST_JPEG_MARKER_DRI:
      status = decode_restart_interval (decoder, seg);
      break;
    case GST_JPEG_MARKER_SOS:
      status = decode_scan (decoder, seg);
      break;
    default:
      // SOFn segments
      if (seg->marker >= GST_JPEG_MARKER_SOF_MIN &&
          seg->marker <= GST_JPEG_MARKER_SOF_MAX)
        status = decode_picture (decoder, seg);
      break;
  }
  return status;
}
Exemplo n.º 2
0
int process_segment(void)
{
    word marker;
    int err;
    
    marker = fetch_word();
    if (marker == 0xFFD9)
    {
		iceenv.eoi = 1;
#ifdef _JPEG_DEBUG
        printf("EOI detected! Done.\n");
#endif
        return ERR_OK;
    }
    
    iceenv.cur_segment_len = fetch_word();
    
    switch (marker)
    {
        case 0xFFE0:
            err = process_app0();
            break;
        case 0xFFDB:
            err = process_dqt();
            break;
        case 0xFFC0:
            err = process_sof0();
            break;
        case 0xFFC4:
            err = process_dht();
            break;
        case 0xFFDD:
            err = process_dri();
            break;
        case 0xFFDA:
            err = gen_huffman_tables();
            err = process_sos();
            err = decode_scan();
            err = upsample();
            err = create_image();
            break;
		case 0xFFC1:
		case 0xFFC2:
		case 0xFFC3:
		case 0xFFC5:
		case 0xFFC6:
		case 0xFFC7:
		case 0xFFC9:
		case 0xFFCA:
		case 0xFFCB:
		case 0xFFCD:
		case 0xFFCE:
		case 0xFFCF:
			err = ERR_NOT_BASELINE;
			break;
		default:
#ifdef _JPEG_DEBUG
            printf("Skipping unknown segment %X\n", marker & 0xFF);
#endif
            iceenv.buf_pos += iceenv.cur_segment_len - 2;
            err = ERR_OK;
            break;
    }
    
    return err;
}
Exemplo n.º 3
0
static GstVaapiDecoderStatus
decode_buffer(GstVaapiDecoderJpeg *decoder, GstBuffer *buffer)
{
    GstVaapiDecoderJpegPrivate * const priv = decoder->priv;
    GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
    GstJpegMarkerSegment seg;
    GstJpegScanSegment scan_seg;
    GstClockTime pts;
    guchar *buf;
    guint buf_size, ofs;
    gboolean append_ecs;

    buf      = GST_BUFFER_DATA(buffer);
    buf_size = GST_BUFFER_SIZE(buffer);
    if (!buf && buf_size == 0)
        return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;

    memset(&scan_seg, 0, sizeof(scan_seg));

    pts = GST_BUFFER_TIMESTAMP(buffer);
    ofs = 0;
    while (gst_jpeg_parse(&seg, buf, buf_size, ofs)) {
        if (seg.size < 0) {
            GST_DEBUG("buffer to short for parsing");
            return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
        }
        ofs += seg.size;

        /* Decode scan, if complete */
        if (seg.marker == GST_JPEG_MARKER_EOI && scan_seg.header_size > 0) {
            scan_seg.data_size = seg.offset - scan_seg.data_offset;
            scan_seg.is_valid  = TRUE;
        }
        if (scan_seg.is_valid) {
            status = decode_scan(
                decoder,
                buf + scan_seg.header_offset,
                scan_seg.header_size,
                buf + scan_seg.data_offset,
                scan_seg.data_size
            );
            if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
                break;
            memset(&scan_seg, 0, sizeof(scan_seg));
        }

        append_ecs = TRUE;
        switch (seg.marker) {
        case GST_JPEG_MARKER_SOI:
            priv->has_quant_table = FALSE;
            priv->has_huf_table   = FALSE;
            priv->mcu_restart     = 0;
            status = GST_VAAPI_DECODER_STATUS_SUCCESS;
            break;
        case GST_JPEG_MARKER_EOI:
            if (decode_current_picture(decoder)) {
                /* Get out of the loop, trailing data is not needed */
                status = GST_VAAPI_DECODER_STATUS_SUCCESS;
                goto end;
            }
            status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
            break;
        case GST_JPEG_MARKER_DHT:
            status = decode_huffman_table(decoder, buf + seg.offset, seg.size);
            break;
        case GST_JPEG_MARKER_DQT:
            status = decode_quant_table(decoder, buf + seg.offset, seg.size);
            break;
        case GST_JPEG_MARKER_DRI:
            status = decode_restart_interval(decoder, buf + seg.offset, seg.size);
            break;
        case GST_JPEG_MARKER_DAC:
            GST_ERROR("unsupported arithmetic coding mode");
            status = GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
            break;
        case GST_JPEG_MARKER_SOS:
            scan_seg.header_offset = seg.offset;
            scan_seg.header_size   = seg.size;
            scan_seg.data_offset   = seg.offset + seg.size;
            scan_seg.data_size     = 0;
            append_ecs             = FALSE;
            break;
        default:
            /* Restart marker */
            if (seg.marker >= GST_JPEG_MARKER_RST_MIN &&
                seg.marker <= GST_JPEG_MARKER_RST_MAX) {
                append_ecs = FALSE;
                break;
            }

            /* Frame header */
            if (seg.marker >= GST_JPEG_MARKER_SOF_MIN &&
                seg.marker <= GST_JPEG_MARKER_SOF_MAX) {
                status = decode_picture(
                    decoder,
                    seg.marker,
                    buf + seg.offset, seg.size,
                    pts
                );
                break;
            }

            /* Application segments */
            if (seg.marker >= GST_JPEG_MARKER_APP_MIN &&
                seg.marker <= GST_JPEG_MARKER_APP_MAX) {
                status = GST_VAAPI_DECODER_STATUS_SUCCESS;
                break;
            }

            GST_WARNING("unsupported marker (0x%02x)", seg.marker);
            status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
            break;
        }

        /* Append entropy coded segments */
        if (append_ecs)
            scan_seg.data_size = seg.offset - scan_seg.data_offset;

        if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
            break;
    }
end:
    return status;
}