mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 06:58:56 +00:00
codecparsers: VC1: Handle interlaced frames properly
This commit is contained in:
parent
7a689b6805
commit
88766dc738
2 changed files with 99 additions and 26 deletions
|
@ -994,6 +994,12 @@ parse_frame_header_advanced (GstBitReader * br, GstVC1FrameHdr * framehdr,
|
||||||
switch (framehdr->ptype) {
|
switch (framehdr->ptype) {
|
||||||
case GST_VC1_PICTURE_TYPE_I:
|
case GST_VC1_PICTURE_TYPE_I:
|
||||||
case GST_VC1_PICTURE_TYPE_BI:
|
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,
|
if (!bitplane_decoding (br, bitplanes ? bitplanes->acpred : NULL,
|
||||||
seqhdr, &pic->acpred))
|
seqhdr, &pic->acpred))
|
||||||
goto failed;
|
goto failed;
|
||||||
|
@ -1032,7 +1038,14 @@ parse_frame_header_advanced (GstBitReader * br, GstVC1FrameHdr * framehdr,
|
||||||
else
|
else
|
||||||
pic->mvrange = 0;
|
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,
|
if (!bitplane_decoding (br, bitplanes ? bitplanes->directmb : NULL,
|
||||||
seqhdr, &pic->directmb))
|
seqhdr, &pic->directmb))
|
||||||
|
@ -1042,8 +1055,20 @@ parse_frame_header_advanced (GstBitReader * br, GstVC1FrameHdr * framehdr,
|
||||||
seqhdr, &pic->skipmb))
|
seqhdr, &pic->skipmb))
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
READ_UINT8 (br, pic->mvtab, 2);
|
if (pic->fcm == GST_VC1_FRAME_INTERLACE) {
|
||||||
READ_UINT8 (br, pic->cbptab, 2);
|
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) {
|
if (framehdr->dquant) {
|
||||||
parse_vopdquant (br, framehdr, framehdr->dquant);
|
parse_vopdquant (br, framehdr, framehdr->dquant);
|
||||||
|
@ -1072,33 +1097,61 @@ parse_frame_header_advanced (GstBitReader * br, GstVC1FrameHdr * framehdr,
|
||||||
else
|
else
|
||||||
pic->mvrange = 0;
|
pic->mvrange = 0;
|
||||||
|
|
||||||
mvmodeidx = framehdr->pquant > 12;
|
if (pic->fcm == GST_VC1_FRAME_INTERLACE) {
|
||||||
pic->mvmode = vc1_mvmode_table[mvmodeidx][get_unary (br, 1, 4)];
|
if (entrypthdr->extended_dmv)
|
||||||
|
pic->dmvrange = get_unary (br, 0, 3);
|
||||||
|
|
||||||
if (pic->mvmode == GST_VC1_MVMODE_INTENSITY_COMP) {
|
READ_UINT8 (br, pic->mvswitch4, 1);
|
||||||
pic->mvmode2 = vc1_mvmode2_table[mvmodeidx][get_unary (br, 1, 3)];
|
READ_UINT8 (br, pic->intcomp, 1);
|
||||||
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 ||
|
if (pic->intcomp) {
|
||||||
(pic->mvmode == GST_VC1_MVMODE_INTENSITY_COMP &&
|
READ_UINT8 (br, pic->lumscale, 6);
|
||||||
pic->mvmode2 == GST_VC1_MVMODE_MIXED_MV)) {
|
READ_UINT8 (br, pic->lumshift, 6);
|
||||||
if (!bitplane_decoding (br, bitplanes ? bitplanes->mvtypemb : NULL,
|
}
|
||||||
seqhdr, &pic->mvtypemb))
|
} else {
|
||||||
goto failed;
|
|
||||||
GST_DEBUG ("mvtypemb %u", pic->mvtypemb);
|
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,
|
if (!bitplane_decoding (br, bitplanes ? bitplanes->skipmb : NULL,
|
||||||
seqhdr, &pic->skipmb))
|
seqhdr, &pic->skipmb))
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
if (gst_bit_reader_get_remaining (br) < 4)
|
if (pic->fcm == GST_VC1_FRAME_INTERLACE) {
|
||||||
goto failed;
|
if (gst_bit_reader_get_remaining (br) < 9)
|
||||||
pic->mvtab = gst_bit_reader_get_bits_uint8_unchecked (br, 2);
|
goto failed;
|
||||||
pic->cbptab = gst_bit_reader_get_bits_uint8_unchecked (br, 2);
|
|
||||||
|
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) {
|
if (framehdr->dquant) {
|
||||||
parse_vopdquant (br, framehdr, framehdr->dquant);
|
parse_vopdquant (br, framehdr, framehdr->dquant);
|
||||||
|
@ -1891,6 +1944,7 @@ void
|
||||||
gst_vc1_bitplanes_free_1 (GstVC1BitPlanes * bitplanes)
|
gst_vc1_bitplanes_free_1 (GstVC1BitPlanes * bitplanes)
|
||||||
{
|
{
|
||||||
g_free (bitplanes->acpred);
|
g_free (bitplanes->acpred);
|
||||||
|
g_free (bitplanes->fieldtx);
|
||||||
g_free (bitplanes->overflags);
|
g_free (bitplanes->overflags);
|
||||||
g_free (bitplanes->mvtypemb);
|
g_free (bitplanes->mvtypemb);
|
||||||
g_free (bitplanes->skipmb);
|
g_free (bitplanes->skipmb);
|
||||||
|
@ -1920,6 +1974,8 @@ gst_vc1_bitplanes_ensure_size (GstVC1BitPlanes * bitplanes,
|
||||||
bitplanes->size = seqhdr->mb_height * seqhdr->mb_stride;
|
bitplanes->size = seqhdr->mb_height * seqhdr->mb_stride;
|
||||||
bitplanes->acpred =
|
bitplanes->acpred =
|
||||||
g_realloc_n (bitplanes->acpred, bitplanes->size, sizeof (guint8));
|
g_realloc_n (bitplanes->acpred, bitplanes->size, sizeof (guint8));
|
||||||
|
bitplanes->fieldtx =
|
||||||
|
g_realloc_n (bitplanes->fieldtx, bitplanes->size, sizeof (guint8));
|
||||||
bitplanes->overflags =
|
bitplanes->overflags =
|
||||||
g_realloc_n (bitplanes->overflags, bitplanes->size, sizeof (guint8));
|
g_realloc_n (bitplanes->overflags, bitplanes->size, sizeof (guint8));
|
||||||
bitplanes->mvtypemb =
|
bitplanes->mvtypemb =
|
||||||
|
@ -1931,6 +1987,7 @@ gst_vc1_bitplanes_ensure_size (GstVC1BitPlanes * bitplanes,
|
||||||
} else {
|
} else {
|
||||||
bitplanes->size = seqhdr->mb_height * seqhdr->mb_stride;
|
bitplanes->size = seqhdr->mb_height * seqhdr->mb_stride;
|
||||||
bitplanes->acpred = g_malloc0 (bitplanes->size * sizeof (guint8));
|
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->overflags = g_malloc0 (bitplanes->size * sizeof (guint8));
|
||||||
bitplanes->mvtypemb = g_malloc0 (bitplanes->size * sizeof (guint8));
|
bitplanes->mvtypemb = g_malloc0 (bitplanes->size * sizeof (guint8));
|
||||||
bitplanes->skipmb = g_malloc0 (bitplanes->size * sizeof (guint8));
|
bitplanes->skipmb = g_malloc0 (bitplanes->size * sizeof (guint8));
|
||||||
|
|
|
@ -209,15 +209,15 @@ struct _GstVC1AdvancedSeqHdr
|
||||||
{
|
{
|
||||||
GstVC1Level level;
|
GstVC1Level level;
|
||||||
|
|
||||||
guint8 frmrtq_postproc;
|
guint8 frmrtq_postproc;
|
||||||
guint8 bitrtq_postproc;
|
guint8 bitrtq_postproc;
|
||||||
guint8 postprocflag;
|
guint8 postprocflag;
|
||||||
guint16 max_coded_width;
|
guint16 max_coded_width;
|
||||||
guint16 max_coded_height;
|
guint16 max_coded_height;
|
||||||
guint8 pulldown;
|
guint8 pulldown;
|
||||||
guint8 interlace;
|
guint8 interlace;
|
||||||
guint8 tfcntrflag;
|
guint8 tfcntrflag;
|
||||||
guint8 finterpflag;
|
guint8 finterpflag;
|
||||||
guint8 psf;
|
guint8 psf;
|
||||||
guint8 display_ext;
|
guint8 display_ext;
|
||||||
guint16 disp_horiz_size;
|
guint16 disp_horiz_size;
|
||||||
|
@ -236,7 +236,7 @@ struct _GstVC1AdvancedSeqHdr
|
||||||
guint8 transfer_char;
|
guint8 transfer_char;
|
||||||
guint8 matrix_coef;
|
guint8 matrix_coef;
|
||||||
guint8 hrd_param_flag;
|
guint8 hrd_param_flag;
|
||||||
guint8 colordiff_format;
|
guint8 colordiff_format;
|
||||||
|
|
||||||
GstVC1HrdParam hrd_param;
|
GstVC1HrdParam hrd_param;
|
||||||
|
|
||||||
|
@ -426,11 +426,27 @@ struct _GstVC1PicAdvanced
|
||||||
guint8 mvtypemb;
|
guint8 mvtypemb;
|
||||||
guint8 skipmb;
|
guint8 skipmb;
|
||||||
guint8 directmb;
|
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
|
struct _GstVC1BitPlanes
|
||||||
{
|
{
|
||||||
guint8 *acpred;
|
guint8 *acpred;
|
||||||
|
guint8 *fieldtx;
|
||||||
guint8 *overflags;
|
guint8 *overflags;
|
||||||
guint8 *mvtypemb;
|
guint8 *mvtypemb;
|
||||||
guint8 *skipmb;
|
guint8 *skipmb;
|
||||||
|
|
Loading…
Reference in a new issue