* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
-#include "pipe/p_video_decoder.h"
+#include "pipe/p_video_codec.h"
#include "util/u_memory.h"
#include "vl_vlc.h"
static struct dct_coeff tbl_B14_AC[1 << 17];
static struct dct_coeff tbl_B15[1 << 17];
-static INLINE void
+static inline void
init_dct_coeff_table(struct dct_coeff *dst, const struct dct_coeff_compressed *src,
unsigned size, bool is_DC)
{
break;
}
- for(i=0; i<(1 << (17 - coeff.length)); ++i)
+ for(i = 0; i < (1u << (17 - coeff.length)); ++i)
dst[src->bitcode << 1 | i] = coeff;
if (has_sign) {
coeff.level = -coeff.level;
- for(; i<(1 << (18 - coeff.length)); ++i)
+ for(; i < (1u << (18 - coeff.length)); ++i)
dst[src->bitcode << 1 | i] = coeff;
}
}
}
-static INLINE void
+static inline void
init_tables()
{
- vl_vlc_init_table(tbl_B1, Elements(tbl_B1), macroblock_address_increment, Elements(macroblock_address_increment));
- vl_vlc_init_table(tbl_B2, Elements(tbl_B2), macroblock_type_i, Elements(macroblock_type_i));
- vl_vlc_init_table(tbl_B3, Elements(tbl_B3), macroblock_type_p, Elements(macroblock_type_p));
- vl_vlc_init_table(tbl_B4, Elements(tbl_B4), macroblock_type_b, Elements(macroblock_type_b));
- vl_vlc_init_table(tbl_B9, Elements(tbl_B9), coded_block_pattern, Elements(coded_block_pattern));
- vl_vlc_init_table(tbl_B10, Elements(tbl_B10), motion_code, Elements(motion_code));
- vl_vlc_init_table(tbl_B11, Elements(tbl_B11), dmvector, Elements(dmvector));
- vl_vlc_init_table(tbl_B12, Elements(tbl_B12), dct_dc_size_luminance, Elements(dct_dc_size_luminance));
- vl_vlc_init_table(tbl_B13, Elements(tbl_B13), dct_dc_size_chrominance, Elements(dct_dc_size_chrominance));
- init_dct_coeff_table(tbl_B14_DC, dct_coeff_tbl_zero, Elements(dct_coeff_tbl_zero), true);
- init_dct_coeff_table(tbl_B14_AC, dct_coeff_tbl_zero, Elements(dct_coeff_tbl_zero), false);
- init_dct_coeff_table(tbl_B15, dct_coeff_tbl_one, Elements(dct_coeff_tbl_one), false);
+ vl_vlc_init_table(tbl_B1, ARRAY_SIZE(tbl_B1), macroblock_address_increment, ARRAY_SIZE(macroblock_address_increment));
+ vl_vlc_init_table(tbl_B2, ARRAY_SIZE(tbl_B2), macroblock_type_i, ARRAY_SIZE(macroblock_type_i));
+ vl_vlc_init_table(tbl_B3, ARRAY_SIZE(tbl_B3), macroblock_type_p, ARRAY_SIZE(macroblock_type_p));
+ vl_vlc_init_table(tbl_B4, ARRAY_SIZE(tbl_B4), macroblock_type_b, ARRAY_SIZE(macroblock_type_b));
+ vl_vlc_init_table(tbl_B9, ARRAY_SIZE(tbl_B9), coded_block_pattern, ARRAY_SIZE(coded_block_pattern));
+ vl_vlc_init_table(tbl_B10, ARRAY_SIZE(tbl_B10), motion_code, ARRAY_SIZE(motion_code));
+ vl_vlc_init_table(tbl_B11, ARRAY_SIZE(tbl_B11), dmvector, ARRAY_SIZE(dmvector));
+ vl_vlc_init_table(tbl_B12, ARRAY_SIZE(tbl_B12), dct_dc_size_luminance, ARRAY_SIZE(dct_dc_size_luminance));
+ vl_vlc_init_table(tbl_B13, ARRAY_SIZE(tbl_B13), dct_dc_size_chrominance, ARRAY_SIZE(dct_dc_size_chrominance));
+ init_dct_coeff_table(tbl_B14_DC, dct_coeff_tbl_zero, ARRAY_SIZE(dct_coeff_tbl_zero), true);
+ init_dct_coeff_table(tbl_B14_AC, dct_coeff_tbl_zero, ARRAY_SIZE(dct_coeff_tbl_zero), false);
+ init_dct_coeff_table(tbl_B15, dct_coeff_tbl_one, ARRAY_SIZE(dct_coeff_tbl_one), false);
}
-static INLINE int
+static inline int
DIV2DOWN(int todiv)
{
return (todiv&~1)/2;
}
-static INLINE int
-DIV2UP(int todiv)
-{
- return (todiv+1)/2;
-}
-
-static INLINE void
+static inline void
motion_vector(struct vl_mpg12_bs *bs, int r, int s, int dmv, short delta[2], short dmvector[2])
{
int t;
}
}
-static INLINE int
+static inline int
wrap(short f, int shift)
{
if (f < (-16 << shift))
return f;
}
-static INLINE void
+static inline void
motion_vector_frame(struct vl_mpg12_bs *bs, int s, struct pipe_mpeg12_macroblock *mb)
{
int dmv = mb->macroblock_modes.bits.frame_motion_type == PIPE_MPEG12_MO_TYPE_DUAL_PRIME;
}
}
-static INLINE void
+static inline void
motion_vector_field(struct vl_mpg12_bs *bs, int s, struct pipe_mpeg12_macroblock *mb)
{
int dmv = mb->macroblock_modes.bits.field_motion_type == PIPE_MPEG12_MO_TYPE_DUAL_PRIME;
}
}
-static INLINE void
+static inline void
reset_predictor(struct vl_mpg12_bs *bs) {
bs->pred_dc[0] = bs->pred_dc[1] = bs->pred_dc[2] = 0;
}
-static INLINE void
+static inline void
decode_dct(struct vl_mpg12_bs *bs, struct pipe_mpeg12_macroblock *mb, int scale)
{
static const unsigned blk2cc[] = { 0, 0, 0, 0, 1, 2 };
vl_vlc_eatbits(&bs->vlc, entry->length);
if (entry->run == dct_End_of_Block) {
+next_d:
dst += 64;
cbp <<= 1;
cbp &= 0x3F;
dst[0] = bs->pred_dc[cc];
i = 0;
+ if (bs->desc->picture_coding_type == PIPE_MPEG12_PICTURE_CODING_TYPE_D)
+ goto next_d;
} else {
entry = tbl_B14_DC + vl_vlc_peekbits(&bs->vlc, 17);
i = -1;
continue;
}
+ } else if (entry->run == dct_Escape &&
+ bs->decoder->profile == PIPE_VIDEO_PROFILE_MPEG1) {
+ i += vl_vlc_get_uimsbf(&bs->vlc, 6) + 1;
+ if (i > 64)
+ break;
+
+ dst[i] = vl_vlc_get_simsbf(&bs->vlc, 8);
+ if (dst[i] == -128)
+ dst[i] = vl_vlc_get_uimsbf(&bs->vlc, 8) - 256;
+ else if (dst[i] == 0)
+ dst[i] = vl_vlc_get_uimsbf(&bs->vlc, 8);
+
+ dst[i] *= scale;
} else if (entry->run == dct_Escape) {
i += vl_vlc_get_uimsbf(&bs->vlc, 6) + 1;
if (i > 64)
vl_vlc_fillbits(&bs->vlc);
entry = table + vl_vlc_peekbits(&bs->vlc, 17);
}
+
+ if (bs->desc->picture_coding_type == PIPE_MPEG12_PICTURE_CODING_TYPE_D)
+ vl_vlc_eatbits(&bs->vlc, 1);
}
-static INLINE void
+static inline void
decode_slice(struct vl_mpg12_bs *bs, struct pipe_video_buffer *target)
{
struct pipe_mpeg12_macroblock mb;
signed x = -1;
memset(&mb, 0, sizeof(mb));
- mb.base.codec = PIPE_VIDEO_CODEC_MPEG12;
+ mb.base.codec = PIPE_VIDEO_FORMAT_MPEG12;
mb.y = vl_vlc_get_uimsbf(&bs->vlc, 8) - 1;
mb.blocks = dct_blocks;
vl_vlc_fillbits(&bs->vlc);
vl_vlc_fillbits(&bs->vlc);
- assert(vl_vlc_bits_left(&bs->vlc) > 23 && vl_vlc_peekbits(&bs->vlc, 23));
+ assert(vl_vlc_peekbits(&bs->vlc, 23));
do {
int inc = 0;
- if (bs->decoder->profile == PIPE_VIDEO_PROFILE_MPEG1)
+ while (1) {
+ /* MPEG-1 macroblock stuffing, can appear an arbitrary number of times. */
while (vl_vlc_peekbits(&bs->vlc, 11) == 15) {
vl_vlc_eatbits(&bs->vlc, 11);
vl_vlc_fillbits(&bs->vlc);
}
- while (vl_vlc_peekbits(&bs->vlc, 11) == 8) {
- vl_vlc_eatbits(&bs->vlc, 11);
- vl_vlc_fillbits(&bs->vlc);
- inc += 33;
+ if (vl_vlc_peekbits(&bs->vlc, 11) == 8) {
+ vl_vlc_eatbits(&bs->vlc, 11);
+ vl_vlc_fillbits(&bs->vlc);
+ inc += 33;
+ } else {
+ inc += vl_vlc_get_vlclbf(&bs->vlc, tbl_B1, 11);
+ break;
+ }
}
- inc += vl_vlc_get_vlclbf(&bs->vlc, tbl_B1, 11);
+
if (x != -1) {
+ if (!inc)
+ return;
mb.num_skipped_macroblocks = inc - 1;
bs->decoder->decode_macroblock(bs->decoder, target, &bs->desc->base, &mb.base, 1);
}
mb.x = x += inc;
+ if (bs->decoder->profile == PIPE_VIDEO_PROFILE_MPEG1) {
+ int width = align(bs->decoder->width, 16) / 16;
+ mb.y += mb.x / width;
+ mb.x = x %= width;
+ }
switch (bs->desc->picture_coding_type) {
case PIPE_MPEG12_PICTURE_CODING_TYPE_I:
mb.macroblock_type = vl_vlc_get_vlclbf(&bs->vlc, tbl_B4, 6);
break;
- default:
- mb.macroblock_type = 0;
- /* dumb gcc */
- assert(0);
+ case PIPE_MPEG12_PICTURE_CODING_TYPE_D:
+ vl_vlc_eatbits(&bs->vlc, 1);
+ mb.macroblock_type = PIPE_MPEG12_MB_TYPE_INTRA;
+ break;
}
mb.macroblock_modes.value = 0;
mb.PMV[1][0][0] = mb.PMV[0][0][0];
mb.PMV[1][0][1] = mb.PMV[0][0][1];
assert(extra);
+ (void) extra;
} else if (mb.macroblock_type & PIPE_MPEG12_MB_TYPE_INTRA ||
!(mb.macroblock_type & (PIPE_MPEG12_MB_TYPE_MOTION_FORWARD |
PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD))) {
}
void
-vl_mpg12_bs_init(struct vl_mpg12_bs *bs, struct pipe_video_decoder *decoder)
+vl_mpg12_bs_init(struct vl_mpg12_bs *bs, struct pipe_video_codec *decoder)
{
static bool tables_initialized = false;
bs->intra_dct_tbl = picture->intra_vlc_format ? tbl_B15 : tbl_B14_AC;
vl_vlc_init(&bs->vlc, num_buffers, buffers, sizes);
- while (vl_vlc_bits_left(&bs->vlc) > 32) {
+ while (vl_vlc_search_byte(&bs->vlc, ~0, 0x00) && vl_vlc_bits_left(&bs->vlc) > 32) {
uint32_t code = vl_vlc_peekbits(&bs->vlc, 32);
if (code >= 0x101 && code <= 0x1AF) {