gst-plugins-bad: codecparsers: VC1: Handle interlaced frames properly
Thibault Saunier
tsaunier at kemper.freedesktop.org
Mon Oct 17 05:37:40 PDT 2011
Module: gst-plugins-bad
Branch: master
Commit: 88766dc738e45b234d97071596ec3f827d4888ab
URL: http://cgit.freedesktop.org/gstreamer/gst-plugins-bad/commit/?id=88766dc738e45b234d97071596ec3f827d4888ab
Author: Thibault Saunier <thibault.saunier at collabora.com>
Date: Mon Oct 10 10:14:12 2011 -0300
codecparsers: VC1: Handle interlaced frames properly
---
gst-libs/gst/codecparsers/gstvc1parser.c | 101 +++++++++++++++++++++++-------
gst-libs/gst/codecparsers/gstvc1parser.h | 24 ++++++-
2 files changed, 99 insertions(+), 26 deletions(-)
diff --git a/gst-libs/gst/codecparsers/gstvc1parser.c b/gst-libs/gst/codecparsers/gstvc1parser.c
index 3d0b757..ef0dee6 100644
--- a/gst-libs/gst/codecparsers/gstvc1parser.c
+++ b/gst-libs/gst/codecparsers/gstvc1parser.c
@@ -994,6 +994,12 @@ parse_frame_header_advanced (GstBitReader * br, GstVC1FrameHdr * framehdr,
switch (framehdr->ptype) {
case GST_VC1_PICTURE_TYPE_I:
case GST_VC1_PICTURE_TYPE_BI:
+ if (pic->fcm == GST_VC1_FRAME_INTERLACE) {
+ if (!bitplane_decoding (br, bitplanes ? bitplanes->fieldtx : NULL,
+ seqhdr, &pic->fieldtx))
+ goto failed;
+ }
+
if (!bitplane_decoding (br, bitplanes ? bitplanes->acpred : NULL,
seqhdr, &pic->acpred))
goto failed;
@@ -1032,7 +1038,14 @@ parse_frame_header_advanced (GstBitReader * br, GstVC1FrameHdr * framehdr,
else
pic->mvrange = 0;
- READ_UINT8 (br, pic->mvmode, 1);
+ if (pic->fcm == GST_VC1_FRAME_INTERLACE) {
+ if (entrypthdr->extended_dmv)
+ pic->dmvrange = get_unary (br, 0, 3);
+ READ_UINT8 (br, pic->intcomp, 1);
+ } else {
+
+ READ_UINT8 (br, pic->mvmode, 1);
+ }
if (!bitplane_decoding (br, bitplanes ? bitplanes->directmb : NULL,
seqhdr, &pic->directmb))
@@ -1042,8 +1055,20 @@ parse_frame_header_advanced (GstBitReader * br, GstVC1FrameHdr * framehdr,
seqhdr, &pic->skipmb))
goto failed;
- READ_UINT8 (br, pic->mvtab, 2);
- READ_UINT8 (br, pic->cbptab, 2);
+ if (pic->fcm == GST_VC1_FRAME_INTERLACE) {
+ if (gst_bit_reader_get_remaining (br) < 11)
+ goto failed;
+
+ pic->mbmodetab = gst_bit_reader_get_bits_uint8_unchecked (br, 2);
+ pic->imvtab = gst_bit_reader_get_bits_uint8_unchecked (br, 2);
+ pic->icbptab = gst_bit_reader_get_bits_uint8_unchecked (br, 3);
+ pic->mvbptab2 = gst_bit_reader_get_bits_uint8_unchecked (br, 2);
+ pic->mvbptab4 = gst_bit_reader_get_bits_uint8_unchecked (br, 2);
+
+ } else {
+ READ_UINT8 (br, pic->mvtab, 2);
+ READ_UINT8 (br, pic->cbptab, 2);
+ }
if (framehdr->dquant) {
parse_vopdquant (br, framehdr, framehdr->dquant);
@@ -1072,33 +1097,61 @@ parse_frame_header_advanced (GstBitReader * br, GstVC1FrameHdr * framehdr,
else
pic->mvrange = 0;
- mvmodeidx = framehdr->pquant > 12;
- pic->mvmode = vc1_mvmode_table[mvmodeidx][get_unary (br, 1, 4)];
+ if (pic->fcm == GST_VC1_FRAME_INTERLACE) {
+ if (entrypthdr->extended_dmv)
+ pic->dmvrange = get_unary (br, 0, 3);
- if (pic->mvmode == GST_VC1_MVMODE_INTENSITY_COMP) {
- pic->mvmode2 = vc1_mvmode2_table[mvmodeidx][get_unary (br, 1, 3)];
- READ_UINT8 (br, pic->lumscale, 6);
- READ_UINT8 (br, pic->lumshift, 6);
- GST_DEBUG ("lumscale %u lumshift %u", pic->lumscale, pic->lumshift);
- }
+ READ_UINT8 (br, pic->mvswitch4, 1);
+ READ_UINT8 (br, pic->intcomp, 1);
- if (pic->mvmode == GST_VC1_MVMODE_MIXED_MV ||
- (pic->mvmode == GST_VC1_MVMODE_INTENSITY_COMP &&
- pic->mvmode2 == GST_VC1_MVMODE_MIXED_MV)) {
- if (!bitplane_decoding (br, bitplanes ? bitplanes->mvtypemb : NULL,
- seqhdr, &pic->mvtypemb))
- goto failed;
- GST_DEBUG ("mvtypemb %u", pic->mvtypemb);
+ if (pic->intcomp) {
+ READ_UINT8 (br, pic->lumscale, 6);
+ READ_UINT8 (br, pic->lumshift, 6);
+ }
+ } else {
+
+ mvmodeidx = framehdr->pquant > 12;
+ pic->mvmode = vc1_mvmode_table[mvmodeidx][get_unary (br, 1, 4)];
+
+ if (pic->mvmode == GST_VC1_MVMODE_INTENSITY_COMP) {
+ pic->mvmode2 = vc1_mvmode2_table[mvmodeidx][get_unary (br, 1, 3)];
+ READ_UINT8 (br, pic->lumscale, 6);
+ READ_UINT8 (br, pic->lumshift, 6);
+ GST_DEBUG ("lumscale %u lumshift %u", pic->lumscale, pic->lumshift);
+ }
+
+ if (pic->mvmode == GST_VC1_MVMODE_MIXED_MV ||
+ (pic->mvmode == GST_VC1_MVMODE_INTENSITY_COMP &&
+ pic->mvmode2 == GST_VC1_MVMODE_MIXED_MV)) {
+ if (!bitplane_decoding (br, bitplanes ? bitplanes->mvtypemb : NULL,
+ seqhdr, &pic->mvtypemb))
+ goto failed;
+ GST_DEBUG ("mvtypemb %u", pic->mvtypemb);
+ }
}
if (!bitplane_decoding (br, bitplanes ? bitplanes->skipmb : NULL,
seqhdr, &pic->skipmb))
goto failed;
- if (gst_bit_reader_get_remaining (br) < 4)
- goto failed;
- pic->mvtab = gst_bit_reader_get_bits_uint8_unchecked (br, 2);
- pic->cbptab = gst_bit_reader_get_bits_uint8_unchecked (br, 2);
+ if (pic->fcm == GST_VC1_FRAME_INTERLACE) {
+ if (gst_bit_reader_get_remaining (br) < 9)
+ goto failed;
+
+ pic->mbmodetab = gst_bit_reader_get_bits_uint8_unchecked (br, 2);
+ pic->imvtab = gst_bit_reader_get_bits_uint8_unchecked (br, 2);
+ pic->icbptab = gst_bit_reader_get_bits_uint8_unchecked (br, 3);
+ pic->mvbptab2 = gst_bit_reader_get_bits_uint8_unchecked (br, 2);
+
+ if (pic->mvswitch4)
+ READ_UINT8 (br, pic->mvbptab4, 2);
+
+ } else {
+ if (gst_bit_reader_get_remaining (br) < 4)
+ goto failed;
+ pic->mvtab = gst_bit_reader_get_bits_uint8_unchecked (br, 2);
+ pic->cbptab = gst_bit_reader_get_bits_uint8_unchecked (br, 2);
+ }
if (framehdr->dquant) {
parse_vopdquant (br, framehdr, framehdr->dquant);
@@ -1891,6 +1944,7 @@ void
gst_vc1_bitplanes_free_1 (GstVC1BitPlanes * bitplanes)
{
g_free (bitplanes->acpred);
+ g_free (bitplanes->fieldtx);
g_free (bitplanes->overflags);
g_free (bitplanes->mvtypemb);
g_free (bitplanes->skipmb);
@@ -1920,6 +1974,8 @@ gst_vc1_bitplanes_ensure_size (GstVC1BitPlanes * bitplanes,
bitplanes->size = seqhdr->mb_height * seqhdr->mb_stride;
bitplanes->acpred =
g_realloc_n (bitplanes->acpred, bitplanes->size, sizeof (guint8));
+ bitplanes->fieldtx =
+ g_realloc_n (bitplanes->fieldtx, bitplanes->size, sizeof (guint8));
bitplanes->overflags =
g_realloc_n (bitplanes->overflags, bitplanes->size, sizeof (guint8));
bitplanes->mvtypemb =
@@ -1931,6 +1987,7 @@ gst_vc1_bitplanes_ensure_size (GstVC1BitPlanes * bitplanes,
} else {
bitplanes->size = seqhdr->mb_height * seqhdr->mb_stride;
bitplanes->acpred = g_malloc0 (bitplanes->size * sizeof (guint8));
+ bitplanes->fieldtx = g_malloc0 (bitplanes->size * sizeof (guint8));
bitplanes->overflags = g_malloc0 (bitplanes->size * sizeof (guint8));
bitplanes->mvtypemb = g_malloc0 (bitplanes->size * sizeof (guint8));
bitplanes->skipmb = g_malloc0 (bitplanes->size * sizeof (guint8));
diff --git a/gst-libs/gst/codecparsers/gstvc1parser.h b/gst-libs/gst/codecparsers/gstvc1parser.h
index 8709aa2..874d2f7 100644
--- a/gst-libs/gst/codecparsers/gstvc1parser.h
+++ b/gst-libs/gst/codecparsers/gstvc1parser.h
@@ -209,15 +209,15 @@ struct _GstVC1AdvancedSeqHdr
{
GstVC1Level level;
- guint8 frmrtq_postproc;
- guint8 bitrtq_postproc;
+ guint8 frmrtq_postproc;
+ guint8 bitrtq_postproc;
guint8 postprocflag;
guint16 max_coded_width;
guint16 max_coded_height;
guint8 pulldown;
guint8 interlace;
guint8 tfcntrflag;
- guint8 finterpflag;
+ guint8 finterpflag;
guint8 psf;
guint8 display_ext;
guint16 disp_horiz_size;
@@ -236,7 +236,7 @@ struct _GstVC1AdvancedSeqHdr
guint8 transfer_char;
guint8 matrix_coef;
guint8 hrd_param_flag;
- guint8 colordiff_format;
+ guint8 colordiff_format;
GstVC1HrdParam hrd_param;
@@ -426,11 +426,27 @@ struct _GstVC1PicAdvanced
guint8 mvtypemb;
guint8 skipmb;
guint8 directmb;
+
+ /* For interlaced pictures only */
+ guint8 fieldtx;
+
+ /* P and B pictures */
+ guint8 intcomp;
+ guint8 dmvrange;
+ guint8 mbmodetab;
+ guint8 imvtab;
+ guint8 icbptab;
+ guint8 mvbptab2;
+ guint8 mvbptab4; /* If 4mvswitch in ppic */
+
+ /* P picture */
+ guint8 mvswitch4;
};
struct _GstVC1BitPlanes
{
guint8 *acpred;
+ guint8 *fieldtx;
guint8 *overflags;
guint8 *mvtypemb;
guint8 *skipmb;
More information about the gstreamer-commits
mailing list