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; }
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; }