예제 #1
0
static int
parse_pgs_packet (GstDVDSpu * dvdspu, guint8 type, guint8 * payload,
    guint16 len)
{
  SpuPgsState *pgs_state = &dvdspu->spu_state.pgs;
  int ret = 0;

  if (!pgs_state->in_presentation_segment
      && type != PGS_COMMAND_PRESENTATION_SEGMENT) {
    PGS_DUMP ("Expected BEGIN PRESENTATION SEGMENT command. "
        "Got command type 0x%02x len %u. Skipping\n", type, len);
    return 0;
  }

  switch (type) {
    case PGS_COMMAND_PRESENTATION_SEGMENT:
      PGS_DUMP ("*******************************************\n"
          "Begin PRESENTATION_SEGMENT (0x%02x) packet len %u\n", type, len);
      pgs_state->in_presentation_segment =
          pgs_state->have_presentation_segment = TRUE;
      ret = parse_presentation_segment (dvdspu, type, payload, len);
      break;
    case PGS_COMMAND_SET_OBJECT_DATA:
      PGS_DUMP ("***   Set Object Data (0x%02x) packet len %u\n", type, len);
      ret = parse_set_object_data (dvdspu, type, payload, len);
      break;
    case PGS_COMMAND_SET_PALETTE:
      PGS_DUMP ("***   Set Palette (0x%02x) packet len %u\n", type, len);
      ret = parse_set_palette (dvdspu, type, payload, len);
      break;
    case PGS_COMMAND_SET_WINDOW:
      PGS_DUMP ("***   Set Window command (0x%02x) packet len %u\n", type, len);
      ret = parse_set_window (dvdspu, type, payload, len);
      break;
    case PGS_COMMAND_INTERACTIVE_SEGMENT:
      PGS_DUMP ("***   Interactive Segment command(0x%02x) packet len %u\n",
          type, len);
      dump_bytes (payload, len);
      break;
    case PGS_COMMAND_END_DISPLAY:
      PGS_DUMP ("***   End Display command (0x%02x) packet len %u\n", type,
          len);
      pgs_state->in_presentation_segment = FALSE;
      break;
    default:
      GST_ERROR ("Unknown PGS command: type 0x%02x len %u", type, len);
      dump_bytes (payload, len);
      break;
  }
  PGS_DUMP ("\n");

  return ret;
}
예제 #2
0
파일: pgssubdec.c 프로젝트: andoma/libav
static int decode(AVCodecContext *avctx, void *data, int *data_size,
                  AVPacket *avpkt)
{
    const uint8_t *buf = avpkt->data;
    int buf_size       = avpkt->size;

    const uint8_t *buf_end;
    uint8_t       segment_type;
    int           segment_length;

#ifdef DEBUG_PACKET_CONTENTS
    int i;

    av_log(avctx, AV_LOG_INFO, "PGS sub packet:\n");

    for (i = 0; i < buf_size; i++) {
        av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
        if (i % 16 == 15)
            av_log(avctx, AV_LOG_INFO, "\n");
    }

    if (i & 15)
        av_log(avctx, AV_LOG_INFO, "\n");
#endif

    *data_size = 0;

    /* Ensure that we have received at a least a segment code and segment length */
    if (buf_size < 3)
        return -1;

    buf_end = buf + buf_size;

    /* Step through buffer to identify segments */
    while (buf < buf_end) {
        segment_type   = bytestream_get_byte(&buf);
        segment_length = bytestream_get_be16(&buf);

        av_dlog(avctx, "Segment Length %d, Segment Type %x\n", segment_length, segment_type);

        if (segment_type != DISPLAY_SEGMENT && segment_length > buf_end - buf)
            break;

        switch (segment_type) {
        case PALETTE_SEGMENT:
            parse_palette_segment(avctx, buf, segment_length);
            break;
        case PICTURE_SEGMENT:
            parse_picture_segment(avctx, buf, segment_length);
            break;
        case PRESENTATION_SEGMENT:
            parse_presentation_segment(avctx, buf, segment_length);
            break;
        case WINDOW_SEGMENT:
            /*
             * Window Segment Structure (No new information provided):
             *     2 bytes: Unkown,
             *     2 bytes: X position of subtitle,
             *     2 bytes: Y position of subtitle,
             *     2 bytes: Width of subtitle,
             *     2 bytes: Height of subtitle.
             */
            break;
        case DISPLAY_SEGMENT:
            *data_size = display_end_segment(avctx, data, buf, segment_length);
            break;
        default:
            av_log(avctx, AV_LOG_ERROR, "Unknown subtitle segment type 0x%x, length %d\n",
                   segment_type, segment_length);
            break;
        }

        buf += segment_length;
    }

    return buf_size;
}