gboolean mpeg4_util_parse_VOS (GstBuffer * buf, Mpeg4VisualObjectSequence * vos) { GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buf); guint8 visual_object_sequence_start_code; /* start code prefix */ SKIP (&reader, 24); READ_UINT8 (&reader, visual_object_sequence_start_code, 8); if (visual_object_sequence_start_code != MPEG4_PACKET_VOS) goto wrong_start_code; READ_UINT8 (&reader, vos->profile_and_level_indication, 8); return TRUE; wrong_start_code: GST_WARNING ("got buffer with wrong start code"); return FALSE; error: GST_WARNING ("error parsing \"Visual Object\""); return FALSE; }
gboolean mpeg_util_parse_gop (MPEGGop * gop, GstBuffer * buffer) { GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buffer); /* skip sync word */ if (!gst_bit_reader_skip (&reader, 8 * 4)) return FALSE; READ_UINT8 (&reader, gop->drop_frame_flag, 1); READ_UINT8 (&reader, gop->hour, 5); READ_UINT8 (&reader, gop->minute, 6); /* skip unused bit */ if (!gst_bit_reader_skip (&reader, 1)) return FALSE; READ_UINT8 (&reader, gop->second, 6); READ_UINT8 (&reader, gop->frame, 6); READ_UINT8 (&reader, gop->closed_gop, 1); READ_UINT8 (&reader, gop->broken_gop, 1); return TRUE; error: GST_WARNING ("error parsing \"GOP\""); return FALSE; }
gboolean mpeg4_util_parse_GOV (GstBuffer * buf, Mpeg4GroupofVideoObjectPlane * gov) { GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buf); guint8 gov_start_code; /* start code prefix */ SKIP (&reader, 24); READ_UINT8 (&reader, gov_start_code, 8); if (gov_start_code != MPEG4_PACKET_GOV) goto wrong_start_code; READ_UINT8 (&reader, gov->hours, 5); READ_UINT8 (&reader, gov->minutes, 6); /* marker bit */ SKIP (&reader, 1); READ_UINT8 (&reader, gov->seconds, 6); READ_UINT8 (&reader, gov->closed, 1); READ_UINT8 (&reader, gov->broken_link, 1); return TRUE; error: GST_WARNING ("error parsing \"Group of Video Object Plane\""); return FALSE; wrong_start_code: GST_WARNING ("got buffer with wrong start code"); goto error; }
gboolean mpeg_util_parse_sequence_hdr (MPEGSeqHdr * hdr, GstBuffer * buffer) { GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buffer); guint8 dar_idx, par_idx; guint8 load_intra_flag, load_non_intra_flag; /* skip sync word */ if (!gst_bit_reader_skip (&reader, 8 * 4)) return FALSE; /* resolution */ READ_UINT16 (&reader, hdr->width, 12); READ_UINT16 (&reader, hdr->height, 12); /* aspect ratio */ READ_UINT8 (&reader, dar_idx, 4); set_par_from_dar (hdr, dar_idx); /* framerate */ READ_UINT8 (&reader, par_idx, 4); set_fps_from_code (hdr, par_idx); /* bitrate */ READ_UINT32 (&reader, hdr->bitrate, 18); if (!gst_bit_reader_skip (&reader, 1)) return FALSE; /* VBV buffer size */ READ_UINT16 (&reader, hdr->vbv_buffer, 10); /* constrained parameters flag */ READ_UINT8 (&reader, hdr->constrained_parameters_flag, 1); /* intra quantizer matrix */ READ_UINT8 (&reader, load_intra_flag, 1); if (load_intra_flag) { gint i; for (i = 0; i < 64; i++) READ_UINT8 (&reader, hdr->intra_quantizer_matrix[mpeg_zigzag_8x8[i]], 8); } else memcpy (hdr->intra_quantizer_matrix, default_intra_quantizer_matrix, 64); /* non intra quantizer matrix */ READ_UINT8 (&reader, load_non_intra_flag, 1); if (load_non_intra_flag) { gint i; for (i = 0; i < 64; i++) READ_UINT8 (&reader, hdr->non_intra_quantizer_matrix[mpeg_zigzag_8x8[i]], 8); } else memset (hdr->non_intra_quantizer_matrix, 16, 64); return TRUE; error: GST_WARNING ("error parsing \"Sequence Header\""); return FALSE; }
gboolean mpeg_util_parse_picture_coding_extension (MPEGPictureExt * ext, GstBuffer * buffer) { GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buffer); /* skip sync word */ if (!gst_bit_reader_skip (&reader, 8 * 4)) return FALSE; /* skip extension code */ if (!gst_bit_reader_skip (&reader, 4)) return FALSE; /* f_code */ READ_UINT8 (&reader, ext->f_code[0][0], 4); READ_UINT8 (&reader, ext->f_code[0][1], 4); READ_UINT8 (&reader, ext->f_code[1][0], 4); READ_UINT8 (&reader, ext->f_code[1][1], 4); /* intra DC precision */ READ_UINT8 (&reader, ext->intra_dc_precision, 2); /* picture structure */ READ_UINT8 (&reader, ext->picture_structure, 2); /* top field first */ READ_UINT8 (&reader, ext->top_field_first, 1); /* frame pred frame dct */ READ_UINT8 (&reader, ext->frame_pred_frame_dct, 1); /* concealment motion vectors */ READ_UINT8 (&reader, ext->concealment_motion_vectors, 1); /* q scale type */ READ_UINT8 (&reader, ext->q_scale_type, 1); /* intra vlc format */ READ_UINT8 (&reader, ext->intra_vlc_format, 1); /* alternate scan */ READ_UINT8 (&reader, ext->alternate_scan, 1); /* repeat first field */ READ_UINT8 (&reader, ext->repeat_first_field, 1); /* chroma_420_type */ READ_UINT8 (&reader, ext->chroma_420_type, 1); /* progressive_frame */ READ_UINT8 (&reader, ext->progressive_frame, 1); return TRUE; error: GST_WARNING ("error parsing \"Picture Coding Extension\""); return FALSE; }
static gboolean gst_ac3_parse_frame_header_eac3 (GstAc3Parse * ac3parse, GstBuffer * buf, gint skip, guint * frame_size, guint * rate, guint * chans, guint * blks, guint * sid) { GstBitReader bits = GST_BIT_READER_INIT_FROM_BUFFER (buf); guint16 frmsiz, sample_rate, blocks; guint8 strmtyp, fscod, fscod2, acmod, lfe_on, strmid, numblkscod; GST_LOG_OBJECT (ac3parse, "parsing e-ac3"); gst_bit_reader_skip_unchecked (&bits, skip * 8); gst_bit_reader_skip_unchecked (&bits, 16); strmtyp = gst_bit_reader_get_bits_uint8_unchecked (&bits, 2); /* strmtyp */ if (G_UNLIKELY (strmtyp == 3)) { GST_DEBUG_OBJECT (ac3parse, "bad strmtyp %d", strmtyp); return FALSE; } strmid = gst_bit_reader_get_bits_uint8_unchecked (&bits, 3); /* substreamid */ frmsiz = gst_bit_reader_get_bits_uint16_unchecked (&bits, 11); /* frmsiz */ fscod = gst_bit_reader_get_bits_uint8_unchecked (&bits, 2); /* fscod */ if (fscod == 3) { fscod2 = gst_bit_reader_get_bits_uint8_unchecked (&bits, 2); /* fscod2 */ if (G_UNLIKELY (fscod2 == 3)) { GST_DEBUG_OBJECT (ac3parse, "invalid fscod2"); return FALSE; } sample_rate = fscod_rates[fscod2] / 2; blocks = 6; } else { numblkscod = gst_bit_reader_get_bits_uint8_unchecked (&bits, 2); /* numblkscod */ sample_rate = fscod_rates[fscod]; blocks = numblks[numblkscod]; } acmod = gst_bit_reader_get_bits_uint8_unchecked (&bits, 3); /* acmod */ lfe_on = gst_bit_reader_get_bits_uint8_unchecked (&bits, 1); /* lfeon */ gst_bit_reader_skip_unchecked (&bits, 5); /* bsid */ if (frame_size) *frame_size = (frmsiz + 1) * 2; if (rate) *rate = sample_rate; if (chans) *chans = acmod_chans[acmod] + lfe_on; if (blks) *blks = blocks; if (sid) *sid = (strmtyp & 0x1) << 3 | strmid; return TRUE; }
gboolean mpeg_util_parse_picture_hdr (MPEGPictureHdr * hdr, GstBuffer * buffer) { GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buffer); /* skip sync word */ if (!gst_bit_reader_skip (&reader, 8 * 4)) return FALSE; /* temperal sequence number */ if (!gst_bit_reader_get_bits_uint16 (&reader, &hdr->tsn, 10)) return FALSE; /* frame type */ if (!gst_bit_reader_get_bits_uint8 (&reader, &hdr->pic_type, 3)) return FALSE; if (hdr->pic_type == 0 || hdr->pic_type > 4) return FALSE; /* Corrupted picture packet */ /* VBV delay */ if (!gst_bit_reader_get_bits_uint16 (&reader, &hdr->vbv_delay, 16)) return FALSE; if (hdr->pic_type == P_FRAME || hdr->pic_type == B_FRAME) { READ_UINT8 (&reader, hdr->full_pel_forward_vector, 1); READ_UINT8 (&reader, hdr->f_code[0][0], 3); hdr->f_code[0][1] = hdr->f_code[0][0]; } else { hdr->full_pel_forward_vector = 0; hdr->f_code[0][0] = hdr->f_code[0][1] = 0; } if (hdr->pic_type == B_FRAME) { READ_UINT8 (&reader, hdr->full_pel_backward_vector, 1); READ_UINT8 (&reader, hdr->f_code[1][0], 3); hdr->f_code[1][1] = hdr->f_code[1][0]; } else { hdr->full_pel_backward_vector = 0; hdr->f_code[1][0] = hdr->f_code[1][1] = 0; } return TRUE; error: GST_WARNING ("error parsing \"Picture Header\""); return FALSE; }
gboolean mpeg_util_parse_sequence_extension (MPEGSeqExtHdr * hdr, GstBuffer * buffer) { GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buffer);; /* skip sync word */ if (!gst_bit_reader_skip (&reader, 8 * 4)) return FALSE; /* skip extension code */ if (!gst_bit_reader_skip (&reader, 4)) return FALSE; /* skip profile and level escape bit */ if (!gst_bit_reader_skip (&reader, 1)) return FALSE; READ_UINT8 (&reader, hdr->profile, 3); READ_UINT8 (&reader, hdr->level, 4); /* progressive */ READ_UINT8 (&reader, hdr->progressive, 1); /* chroma format */ READ_UINT8 (&reader, hdr->chroma_format, 2); /* resolution extension */ READ_UINT8 (&reader, hdr->horiz_size_ext, 2); READ_UINT8 (&reader, hdr->vert_size_ext, 2); READ_UINT16 (&reader, hdr->bitrate_ext, 12); /* skip to framerate extension */ if (!gst_bit_reader_skip (&reader, 9)) return FALSE; /* framerate extension */ READ_UINT8 (&reader, hdr->fps_n_ext, 2); READ_UINT8 (&reader, hdr->fps_d_ext, 2); return TRUE; error: GST_WARNING ("error parsing \"Sequence Extension\""); return FALSE; }
gboolean mpeg_util_parse_quant_matrix (MPEGQuantMatrix * qm, GstBuffer * buffer) { GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buffer); guint8 load_intra_flag, load_non_intra_flag; /* skip sync word */ if (!gst_bit_reader_skip (&reader, 8 * 4)) return FALSE; /* skip extension code */ if (!gst_bit_reader_skip (&reader, 4)) return FALSE; /* intra quantizer matrix */ READ_UINT8 (&reader, load_intra_flag, 1); if (load_intra_flag) { gint i; for (i = 0; i < 64; i++) { READ_UINT8 (&reader, qm->intra_quantizer_matrix[mpeg_zigzag_8x8[i]], 8); } } else memcpy (qm->intra_quantizer_matrix, default_intra_quantizer_matrix, 64); /* non intra quantizer matrix */ READ_UINT8 (&reader, load_non_intra_flag, 1); if (load_non_intra_flag) { gint i; for (i = 0; i < 64; i++) { READ_UINT8 (&reader, qm->non_intra_quantizer_matrix[mpeg_zigzag_8x8[i]], 8); } } else memset (qm->non_intra_quantizer_matrix, 16, 64); return TRUE; error: GST_WARNING ("error parsing \"Quant Matrix Extension\""); return FALSE; }
gboolean mpeg4_util_parse_VO (GstBuffer * buf, Mpeg4VisualObject * vo) { GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buf); guint8 visual_object_start_code; guint8 is_visual_object_identifier; /* set defualt values */ vo->verid = 0x1; vo->priority = 1; /* start code prefix */ SKIP (&reader, 24); READ_UINT8 (&reader, visual_object_start_code, 8); if (visual_object_start_code != MPEG4_PACKET_VO) goto wrong_start_code; READ_UINT8 (&reader, is_visual_object_identifier, 1); if (is_visual_object_identifier) { READ_UINT8 (&reader, vo->verid, 4); READ_UINT8 (&reader, vo->priority, 3); } READ_UINT8 (&reader, vo->type, 4); return TRUE; wrong_start_code: GST_WARNING ("got buffer with wrong start code"); return FALSE; error: GST_WARNING ("error parsing \"Visual Object\""); return FALSE; }
static gboolean gst_ac3_parse_frame_header (GstAc3Parse * parse, GstBuffer * buf, gint skip, guint * framesize, guint * rate, guint * chans, guint * blocks, guint * sid, gboolean * eac) { GstBitReader bits = GST_BIT_READER_INIT_FROM_BUFFER (buf); guint16 sync; guint8 bsid; GST_MEMDUMP_OBJECT (parse, "AC3 frame sync", GST_BUFFER_DATA (buf), 16); gst_bit_reader_skip_unchecked (&bits, skip * 8); sync = gst_bit_reader_get_bits_uint16_unchecked (&bits, 16); gst_bit_reader_skip_unchecked (&bits, 16 + 8); bsid = gst_bit_reader_peek_bits_uint8_unchecked (&bits, 5); if (G_UNLIKELY (sync != 0x0b77)) return FALSE; GST_LOG_OBJECT (parse, "bsid = %d", bsid); if (bsid <= 10) { if (eac) *eac = FALSE; return gst_ac3_parse_frame_header_ac3 (parse, buf, skip, framesize, rate, chans, blocks, sid); } else if (bsid <= 16) { if (eac) *eac = TRUE; return gst_ac3_parse_frame_header_eac3 (parse, buf, skip, framesize, rate, chans, blocks, sid); } else { GST_DEBUG_OBJECT (parse, "unexpected bsid %d", bsid); return FALSE; } }
gboolean mpeg4_util_parse_VOP (GstBuffer * buf, Mpeg4VideoObjectLayer * vol, Mpeg4VideoObjectPlane * vop) { GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buf); guint8 vop_start_code; guint8 modulo_time_base; /* set default values */ vop->modulo_time_base = 0; vop->rounding_type = 0; vop->top_field_first = 1; vop->alternate_vertical_scan_flag = 0; vop->fcode_forward = 1; vop->fcode_backward = 1; /* start code prefix */ SKIP (&reader, 24); READ_UINT8 (&reader, vop_start_code, 8); if (vop_start_code != MPEG4_PACKET_VOP) goto wrong_start_code; READ_UINT8 (&reader, vop->coding_type, 2); READ_UINT8 (&reader, modulo_time_base, 1); while (modulo_time_base) { vop->modulo_time_base++; READ_UINT8 (&reader, modulo_time_base, 1); } /* marker bit */ SKIP (&reader, 1); READ_UINT16 (&reader, vop->time_increment, vol->vop_time_increment_bits); /* marker bit */ SKIP (&reader, 1); READ_UINT8 (&reader, vop->coded, 1); if (!vop->coded) return TRUE; if (vop->coding_type == P_VOP) READ_UINT8 (&reader, vop->rounding_type, 1); READ_UINT8 (&reader, vop->intra_dc_vlc_thr, 3); if (vol->interlaced) { READ_UINT8 (&reader, vop->top_field_first, 1); READ_UINT8 (&reader, vop->alternate_vertical_scan_flag, 1); } READ_UINT16 (&reader, vop->quant, vol->quant_precision); if (vop->coding_type != I_VOP) { READ_UINT8 (&reader, vop->fcode_forward, 3); CHECK_ALLOWED (vop->fcode_forward, 1, 7); } if (vop->coding_type == B_VOP) { READ_UINT8 (&reader, vop->fcode_backward, 3); CHECK_ALLOWED (vop->fcode_backward, 1, 7); } return TRUE; error: GST_WARNING ("error parsing \"Video Object Plane\""); return FALSE; wrong_start_code: GST_WARNING ("got buffer with wrong start code"); goto error; }
gboolean mpeg4_util_parse_VOL (GstBuffer * buf, Mpeg4VisualObject * vo, Mpeg4VideoObjectLayer * vol) { GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buf); guint8 video_object_layer_start_code; guint8 aspect_ratio_info; guint8 control_parameters; guint8 not_8_bit; /* set default values */ vol->verid = vo->verid; vol->priority = vo->priority; vol->low_delay = FALSE; vol->chroma_format = 1; vol->vbv_parameters = FALSE; vol->quant_precision = 5; vol->bits_per_pixel = 8; vol->quarter_sample = FALSE; /* start code prefix */ SKIP (&reader, 24); READ_UINT8 (&reader, video_object_layer_start_code, 8); if (!(video_object_layer_start_code >= MPEG4_PACKET_VOL_MIN && video_object_layer_start_code <= MPEG4_PACKET_VOL_MAX)) goto wrong_start_code; READ_UINT8 (&reader, vol->random_accesible_vol, 1); READ_UINT8 (&reader, vol->video_object_type_indication, 8); READ_UINT8 (&reader, vol->is_object_layer_identifier, 1); if (vol->is_object_layer_identifier) { READ_UINT8 (&reader, vol->verid, 4); READ_UINT8 (&reader, vol->priority, 3); } READ_UINT8 (&reader, aspect_ratio_info, 4); if (aspect_ratio_info != 0xff) mpeg4_util_par_from_info (aspect_ratio_info, &vol->par_n, &vol->par_d); else { READ_UINT8 (&reader, vol->par_n, 8); CHECK_ALLOWED (vol->par_n, 1, 255); READ_UINT8 (&reader, vol->par_d, 8); CHECK_ALLOWED (vol->par_d, 1, 255); } READ_UINT8 (&reader, control_parameters, 1); if (control_parameters) { READ_UINT8 (&reader, vol->chroma_format, 2); READ_UINT8 (&reader, vol->low_delay, 1); READ_UINT8 (&reader, vol->vbv_parameters, 1); if (vol->vbv_parameters) { guint16 first_half, latter_half; guint8 latter_part; READ_UINT16 (&reader, first_half, 15); SKIP (&reader, 1); READ_UINT16 (&reader, latter_half, 15); SKIP (&reader, 1); vol->bit_rate = (first_half << 15) | latter_half; READ_UINT16 (&reader, first_half, 15); SKIP (&reader, 1); READ_UINT8 (&reader, latter_part, 3); SKIP (&reader, 1); vol->vbv_buffer_size = (first_half << 15) | latter_part; } } READ_UINT8 (&reader, vol->shape, 2); if (vol->shape != 0x0) goto invalid_shape; /* marker_bit */ SKIP (&reader, 1); READ_UINT16 (&reader, vol->vop_time_increment_resolution, 16); CHECK_ALLOWED (vol->vop_time_increment_resolution, 1, G_MAXUINT16); vol->vop_time_increment_bits = g_bit_storage (vol->vop_time_increment_resolution); /* marker_bit */ SKIP (&reader, 1); READ_UINT8 (&reader, vol->fixed_vop_rate, 1); if (vol->fixed_vop_rate) READ_UINT16 (&reader, vol->fixed_vop_time_increment, vol->vop_time_increment_bits); /* marker bit */ SKIP (&reader, 1); READ_UINT16 (&reader, vol->width, 13); /* marker bit */ SKIP (&reader, 1); READ_UINT16 (&reader, vol->height, 13); /* marker bit */ SKIP (&reader, 1); READ_UINT8 (&reader, vol->interlaced, 1); READ_UINT8 (&reader, vol->obmc_disable, 1); if (vol->verid == 0x1) { READ_UINT8 (&reader, vol->sprite_enable, 1); } else READ_UINT8 (&reader, vol->sprite_enable, 2); if (vol->sprite_enable != 0x0) goto invalid_sprite_enable; READ_UINT8 (&reader, not_8_bit, 1); if (not_8_bit) { READ_UINT8 (&reader, vol->quant_precision, 4); CHECK_ALLOWED (vol->quant_precision, 3, 9); READ_UINT8 (&reader, vol->bits_per_pixel, 4); CHECK_ALLOWED (vol->bits_per_pixel, 4, 12); } READ_UINT8 (&reader, vol->quant_type, 1); if (vol->quant_type) { if (!mpeg4_util_parse_quant (&reader, vol->intra_quant_mat, default_intra_quant_mat)) goto error; if (!mpeg4_util_parse_quant (&reader, vol->non_intra_quant_mat, default_non_intra_quant_mat)) goto error; } else { memset (&vol->intra_quant_mat, 0, 64); memset (&vol->non_intra_quant_mat, 0, 64); } if (vol->verid != 0x1) READ_UINT8 (&reader, vol->quarter_sample, 1); READ_UINT8 (&reader, vol->complexity_estimation_disable, 1); if (!vol->complexity_estimation_disable) goto complexity_estimation_error; READ_UINT8 (&reader, vol->resync_marker_disable, 1); return TRUE; error: GST_WARNING ("error parsing \"Video Object Layer\""); return FALSE; wrong_start_code: GST_WARNING ("got buffer with wrong start code"); goto error; invalid_shape: GST_WARNING ("we only support rectangular shape"); goto error; invalid_sprite_enable: GST_WARNING ("we only support sprite_enable == 0"); goto error; complexity_estimation_error: GST_WARNING ("don't support complexity estimation"); goto error; }
static GstFlowReturn gst_vdp_mpeg_dec_chain (GstPad * pad, GstBuffer * buffer) { GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (gst_pad_get_parent (pad)); GstVdpMpegPacketizer packetizer; GstBuffer *buf; GstFlowReturn ret = GST_FLOW_OK; if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT))) { GST_DEBUG_OBJECT (mpeg_dec, "Received discont buffer"); gst_vdp_mpeg_dec_flush (mpeg_dec); } gst_vdp_mpeg_packetizer_init (&packetizer, buffer); while ((buf = gst_vdp_mpeg_packetizer_get_next_packet (&packetizer))) { GstBitReader b_reader = GST_BIT_READER_INIT_FROM_BUFFER (buf); guint32 sync_code; guint8 start_code; /* skip sync_code */ gst_bit_reader_get_bits_uint32 (&b_reader, &sync_code, 8 * 3); /* start_code */ gst_bit_reader_get_bits_uint8 (&b_reader, &start_code, 8); if (start_code >= MPEG_PACKET_SLICE_MIN && start_code <= MPEG_PACKET_SLICE_MAX) { GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SLICE"); gst_buffer_ref (buf); gst_adapter_push (mpeg_dec->adapter, buf); mpeg_dec->vdp_info.slice_count++; } switch (start_code) { case MPEG_PACKET_PICTURE: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_PICTURE"); if (!gst_vdp_mpeg_dec_parse_picture (mpeg_dec, buf)) goto done; break; case MPEG_PACKET_SEQUENCE: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SEQUENCE"); gst_vdp_mpeg_dec_parse_sequence (mpeg_dec, buf); break; case MPEG_PACKET_EXTENSION: { guint8 ext_code; GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXTENSION"); /* ext_code */ gst_bit_reader_get_bits_uint8 (&b_reader, &ext_code, 4); switch (ext_code) { case MPEG_PACKET_EXT_PICTURE_CODING: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_PICTURE_CODING"); gst_vdp_mpeg_dec_parse_picture_coding (mpeg_dec, buf); break; case MPEG_PACKET_EXT_QUANT_MATRIX: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_QUANT_MATRIX"); gst_vdp_mpeg_dec_parse_quant_matrix (mpeg_dec, buf); break; default: break; } break; } case MPEG_PACKET_GOP: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_GOP"); gst_vdp_mpeg_dec_parse_gop (mpeg_dec, buf); break; default: break; } gst_buffer_unref (buf); } if (mpeg_dec->state == GST_VDP_MPEG_DEC_NEED_SEQUENCE || mpeg_dec->state == GST_VDP_MPEG_DEC_NEED_GOP) { gst_adapter_clear (mpeg_dec->adapter); goto done; } if (mpeg_dec->vdp_info.slice_count > 0) ret = gst_vdp_mpeg_dec_decode (mpeg_dec, GST_BUFFER_TIMESTAMP (buffer), GST_BUFFER_SIZE (buffer)); done: gst_object_unref (mpeg_dec); return ret; }
static GstFlowReturn gst_vdp_mpeg4_dec_parse_data (GstBaseVideoDecoder * base_video_decoder, GstBuffer * buf, gboolean at_eos, GstVideoFrame * frame) { GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buf); guint8 start_code; GstMpeg4Frame *mpeg4_frame; GstFlowReturn ret = GST_FLOW_OK; /* start code prefix */ SKIP (&reader, 24); /* start_code */ READ_UINT8 (&reader, start_code, 8); mpeg4_frame = GST_MPEG4_FRAME_CAST (frame); /* collect packages */ if (start_code == MPEG4_PACKET_VOS) { if (mpeg4_frame->vop_buf) ret = gst_base_video_decoder_have_frame (base_video_decoder, FALSE, (GstVideoFrame **) & mpeg4_frame); gst_buffer_replace (&mpeg4_frame->vos_buf, buf); } else if (start_code == MPEG4_PACKET_EVOS) { if (mpeg4_frame->vop_buf) ret = gst_base_video_decoder_have_frame (base_video_decoder, FALSE, (GstVideoFrame **) & mpeg4_frame); } else if (start_code == MPEG4_PACKET_VO) gst_buffer_replace (&mpeg4_frame->vo_buf, buf); else if (start_code >= MPEG4_PACKET_VOL_MIN && start_code <= MPEG4_PACKET_VOL_MAX) gst_buffer_replace (&mpeg4_frame->vol_buf, buf); else if (start_code == MPEG4_PACKET_GOV) { if (mpeg4_frame->vop_buf) ret = gst_base_video_decoder_have_frame (base_video_decoder, FALSE, (GstVideoFrame **) & mpeg4_frame); gst_buffer_replace (&mpeg4_frame->gov_buf, buf); } else if (start_code == MPEG4_PACKET_VOP) { if (mpeg4_frame->vop_buf) ret = gst_base_video_decoder_have_frame (base_video_decoder, FALSE, (GstVideoFrame **) & mpeg4_frame); mpeg4_frame->vop_buf = buf; } else gst_buffer_unref (buf); if (at_eos && mpeg4_frame->vop_buf) ret = gst_base_video_decoder_have_frame (base_video_decoder, TRUE, (GstVideoFrame **) & mpeg4_frame); return ret; error: gst_buffer_unref (buf); GST_WARNING ("error parsing packet"); return GST_FLOW_OK; }
static GstFlowReturn gst_vdp_mpeg_dec_parse_data (GstBaseVideoDecoder * base_video_decoder, GstBuffer * buf, gboolean at_eos, GstVideoFrame * frame) { GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (base_video_decoder); GstVdpMpegFrame *mpeg_frame; GstFlowReturn ret = GST_FLOW_OK; GstBitReader b_reader = GST_BIT_READER_INIT_FROM_BUFFER (buf); guint8 start_code; if (gst_bit_reader_get_remaining (&b_reader) < 8 * 3 + 8) return GST_FLOW_ERROR; /* skip sync_code */ gst_bit_reader_skip_unchecked (&b_reader, 8 * 3); /* start_code */ start_code = gst_bit_reader_get_bits_uint8_unchecked (&b_reader, 8); mpeg_frame = GST_VDP_MPEG_FRAME_CAST (frame); if (start_code >= MPEG_PACKET_SLICE_MIN && start_code <= MPEG_PACKET_SLICE_MAX) { GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SLICE"); gst_vdp_mpeg_frame_add_slice (mpeg_frame, buf); goto done; } switch (start_code) { case MPEG_PACKET_SEQUENCE: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SEQUENCE"); if (mpeg_dec->prev_packet != -1) ret = gst_base_video_decoder_have_frame (base_video_decoder, FALSE, (GstVideoFrame **) & mpeg_frame); mpeg_frame->seq = buf; break; case MPEG_PACKET_PICTURE: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_PICTURE"); if (mpeg_dec->prev_packet != MPEG_PACKET_SEQUENCE && mpeg_dec->prev_packet != MPEG_PACKET_GOP) ret = gst_base_video_decoder_have_frame (base_video_decoder, FALSE, (GstVideoFrame **) & mpeg_frame); mpeg_frame->pic = buf; break; case MPEG_PACKET_GOP: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_GOP"); if (mpeg_dec->prev_packet != MPEG_PACKET_SEQUENCE) ret = gst_base_video_decoder_have_frame (base_video_decoder, FALSE, (GstVideoFrame **) & mpeg_frame); mpeg_frame->gop = buf; break; case MPEG_PACKET_EXTENSION: { guint8 ext_code; /* ext_code */ if (!gst_bit_reader_get_bits_uint8 (&b_reader, &ext_code, 4)) { ret = GST_FLOW_ERROR; gst_buffer_unref (buf); goto done; } GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXTENSION: %d", ext_code); switch (ext_code) { case MPEG_PACKET_EXT_SEQUENCE: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_SEQUENCE"); mpeg_frame->seq_ext = buf; /* so that we don't finish the frame if we get a MPEG_PACKET_PICTURE * or MPEG_PACKET_GOP after this */ start_code = MPEG_PACKET_SEQUENCE; break; case MPEG_PACKET_EXT_SEQUENCE_DISPLAY: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_SEQUENCE_DISPLAY"); /* so that we don't finish the frame if we get a MPEG_PACKET_PICTURE * or MPEG_PACKET_GOP after this */ start_code = MPEG_PACKET_SEQUENCE; break; case MPEG_PACKET_EXT_PICTURE_CODING: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_PICTURE_CODING"); mpeg_frame->pic_ext = buf; break; case MPEG_PACKET_EXT_QUANT_MATRIX: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_QUANT_MATRIX"); mpeg_frame->qm_ext = buf; break; default: gst_buffer_unref (buf); } break; } default: gst_buffer_unref (buf); } if (at_eos && mpeg_frame->slices) ret = gst_base_video_decoder_have_frame (base_video_decoder, TRUE, NULL); done: mpeg_dec->prev_packet = start_code; return ret; }
static gboolean gst_ac3_parse_frame_header_ac3 (GstAc3Parse * ac3parse, GstBuffer * buf, gint skip, guint * frame_size, guint * rate, guint * chans, guint * blks, guint * sid) { GstBitReader bits = GST_BIT_READER_INIT_FROM_BUFFER (buf); guint8 fscod, frmsizcod, bsid, acmod, lfe_on, rate_scale; GST_LOG_OBJECT (ac3parse, "parsing ac3"); gst_bit_reader_skip_unchecked (&bits, skip * 8); gst_bit_reader_skip_unchecked (&bits, 16 + 16); fscod = gst_bit_reader_get_bits_uint8_unchecked (&bits, 2); frmsizcod = gst_bit_reader_get_bits_uint8_unchecked (&bits, 6); if (G_UNLIKELY (fscod == 3 || frmsizcod >= G_N_ELEMENTS (frmsizcod_table))) { GST_DEBUG_OBJECT (ac3parse, "bad fscod=%d frmsizcod=%d", fscod, frmsizcod); return FALSE; } bsid = gst_bit_reader_get_bits_uint8_unchecked (&bits, 5); gst_bit_reader_skip_unchecked (&bits, 3); /* bsmod */ acmod = gst_bit_reader_get_bits_uint8_unchecked (&bits, 3); /* spec not quite clear here: decoder should decode if less than 8, * but seemingly only defines 6 and 8 cases */ /* Files with 9 and 10 happen, and seem to comply with the <= 8 format, so let them through. The spec says nothing about 9 and 10 */ if (bsid > 10) { GST_DEBUG_OBJECT (ac3parse, "unexpected bsid=%d", bsid); return FALSE; } else if (bsid != 8 && bsid != 6) { GST_DEBUG_OBJECT (ac3parse, "undefined bsid=%d", bsid); } if ((acmod & 0x1) && (acmod != 0x1)) /* 3 front channels */ gst_bit_reader_skip_unchecked (&bits, 2); if ((acmod & 0x4)) /* if a surround channel exists */ gst_bit_reader_skip_unchecked (&bits, 2); if (acmod == 0x2) /* if in 2/0 mode */ gst_bit_reader_skip_unchecked (&bits, 2); lfe_on = gst_bit_reader_get_bits_uint8_unchecked (&bits, 1); /* 6/8->0, 9->1, 10->2, see http://matroska.org/technical/specs/codecid/index.html */ rate_scale = (CLAMP (bsid, 8, 10) - 8); if (frame_size) *frame_size = frmsizcod_table[frmsizcod].frame_size[fscod] * 2; if (rate) *rate = fscod_rates[fscod] >> rate_scale; if (chans) *chans = acmod_chans[acmod] + lfe_on; if (blks) *blks = 6; if (sid) *sid = 0; return TRUE; }