The decoder did not start predicted frames with missing references but called the end of frame handling on them anyway. This caused an assertion in the VA API HW accelorator since it tried to render a picture with uninitialized buffers.
2481 lines
90 KiB
C
2481 lines
90 KiB
C
/*
|
|
* MPEG-1/2 decoder
|
|
* Copyright (c) 2000, 2001 Fabrice Bellard
|
|
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
|
|
*
|
|
* This file is part of Libav.
|
|
*
|
|
* Libav is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* Libav is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with Libav; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
* MPEG-1/2 decoder
|
|
*/
|
|
|
|
#include "libavutil/attributes.h"
|
|
#include "libavutil/internal.h"
|
|
#include "internal.h"
|
|
#include "avcodec.h"
|
|
#include "dsputil.h"
|
|
#include "mpegvideo.h"
|
|
#include "error_resilience.h"
|
|
#include "mpeg12.h"
|
|
#include "mpeg12data.h"
|
|
#include "mpeg12decdata.h"
|
|
#include "bytestream.h"
|
|
#include "vdpau_internal.h"
|
|
#include "xvmc_internal.h"
|
|
#include "thread.h"
|
|
|
|
typedef struct Mpeg1Context {
|
|
MpegEncContext mpeg_enc_ctx;
|
|
int mpeg_enc_ctx_allocated; /* true if decoding context allocated */
|
|
int repeat_field; /* true if we must repeat the field */
|
|
AVPanScan pan_scan; /**< some temporary storage for the panscan */
|
|
int slice_count;
|
|
int swap_uv;//indicate VCR2
|
|
int save_aspect_info;
|
|
int save_width, save_height, save_progressive_seq;
|
|
AVRational frame_rate_ext; ///< MPEG-2 specific framerate modificator
|
|
int sync; ///< Did we reach a sync point like a GOP/SEQ/KEYFrame?
|
|
int closed_gop; ///< GOP is closed
|
|
int extradata_decoded;
|
|
} Mpeg1Context;
|
|
|
|
/* as H.263, but only 17 codes */
|
|
static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred)
|
|
{
|
|
int code, sign, val, shift;
|
|
|
|
code = get_vlc2(&s->gb, ff_mv_vlc.table, MV_VLC_BITS, 2);
|
|
if (code == 0) {
|
|
return pred;
|
|
}
|
|
if (code < 0) {
|
|
return 0xffff;
|
|
}
|
|
|
|
sign = get_bits1(&s->gb);
|
|
shift = fcode - 1;
|
|
val = code;
|
|
if (shift) {
|
|
val = (val - 1) << shift;
|
|
val |= get_bits(&s->gb, shift);
|
|
val++;
|
|
}
|
|
if (sign)
|
|
val = -val;
|
|
val += pred;
|
|
|
|
/* modulo decoding */
|
|
return sign_extend(val, 5 + shift);
|
|
}
|
|
|
|
static inline int mpeg1_decode_block_intra(MpegEncContext *s, int16_t *block, int n)
|
|
{
|
|
int level, dc, diff, i, j, run;
|
|
int component;
|
|
RLTable *rl = &ff_rl_mpeg1;
|
|
uint8_t * const scantable = s->intra_scantable.permutated;
|
|
const uint16_t *quant_matrix = s->intra_matrix;
|
|
const int qscale = s->qscale;
|
|
|
|
/* DC coefficient */
|
|
component = (n <= 3 ? 0 : n - 4 + 1);
|
|
diff = decode_dc(&s->gb, component);
|
|
if (diff >= 0xffff)
|
|
return -1;
|
|
dc = s->last_dc[component];
|
|
dc += diff;
|
|
s->last_dc[component] = dc;
|
|
block[0] = dc * quant_matrix[0];
|
|
av_dlog(s->avctx, "dc=%d diff=%d\n", dc, diff);
|
|
i = 0;
|
|
{
|
|
OPEN_READER(re, &s->gb);
|
|
/* now quantify & encode AC coefficients */
|
|
for (;;) {
|
|
UPDATE_CACHE(re, &s->gb);
|
|
GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
|
|
|
|
if (level == 127) {
|
|
break;
|
|
} else if (level != 0) {
|
|
i += run;
|
|
j = scantable[i];
|
|
level = (level * qscale * quant_matrix[j]) >> 4;
|
|
level = (level - 1) | 1;
|
|
level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
|
|
LAST_SKIP_BITS(re, &s->gb, 1);
|
|
} else {
|
|
/* escape */
|
|
run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6);
|
|
UPDATE_CACHE(re, &s->gb);
|
|
level = SHOW_SBITS(re, &s->gb, 8); SKIP_BITS(re, &s->gb, 8);
|
|
if (level == -128) {
|
|
level = SHOW_UBITS(re, &s->gb, 8) - 256; LAST_SKIP_BITS(re, &s->gb, 8);
|
|
} else if (level == 0) {
|
|
level = SHOW_UBITS(re, &s->gb, 8) ; LAST_SKIP_BITS(re, &s->gb, 8);
|
|
}
|
|
i += run;
|
|
j = scantable[i];
|
|
if (level < 0) {
|
|
level = -level;
|
|
level = (level * qscale * quant_matrix[j]) >> 4;
|
|
level = (level - 1) | 1;
|
|
level = -level;
|
|
} else {
|
|
level = (level * qscale * quant_matrix[j]) >> 4;
|
|
level = (level - 1) | 1;
|
|
}
|
|
}
|
|
if (i > 63) {
|
|
av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
|
|
return -1;
|
|
}
|
|
|
|
block[j] = level;
|
|
}
|
|
CLOSE_READER(re, &s->gb);
|
|
}
|
|
s->block_last_index[n] = i;
|
|
return 0;
|
|
}
|
|
|
|
int ff_mpeg1_decode_block_intra(MpegEncContext *s, int16_t *block, int n)
|
|
{
|
|
return mpeg1_decode_block_intra(s, block, n);
|
|
}
|
|
|
|
static inline int mpeg1_decode_block_inter(MpegEncContext *s, int16_t *block, int n)
|
|
{
|
|
int level, i, j, run;
|
|
RLTable *rl = &ff_rl_mpeg1;
|
|
uint8_t * const scantable = s->intra_scantable.permutated;
|
|
const uint16_t *quant_matrix = s->inter_matrix;
|
|
const int qscale = s->qscale;
|
|
|
|
{
|
|
OPEN_READER(re, &s->gb);
|
|
i = -1;
|
|
// special case for first coefficient, no need to add second VLC table
|
|
UPDATE_CACHE(re, &s->gb);
|
|
if (((int32_t)GET_CACHE(re, &s->gb)) < 0) {
|
|
level = (3 * qscale * quant_matrix[0]) >> 5;
|
|
level = (level - 1) | 1;
|
|
if (GET_CACHE(re, &s->gb) & 0x40000000)
|
|
level = -level;
|
|
block[0] = level;
|
|
i++;
|
|
SKIP_BITS(re, &s->gb, 2);
|
|
if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
|
|
goto end;
|
|
}
|
|
/* now quantify & encode AC coefficients */
|
|
for (;;) {
|
|
GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
|
|
|
|
if (level != 0) {
|
|
i += run;
|
|
j = scantable[i];
|
|
level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
|
|
level = (level - 1) | 1;
|
|
level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
|
|
SKIP_BITS(re, &s->gb, 1);
|
|
} else {
|
|
/* escape */
|
|
run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6);
|
|
UPDATE_CACHE(re, &s->gb);
|
|
level = SHOW_SBITS(re, &s->gb, 8); SKIP_BITS(re, &s->gb, 8);
|
|
if (level == -128) {
|
|
level = SHOW_UBITS(re, &s->gb, 8) - 256; SKIP_BITS(re, &s->gb, 8);
|
|
} else if (level == 0) {
|
|
level = SHOW_UBITS(re, &s->gb, 8) ; SKIP_BITS(re, &s->gb, 8);
|
|
}
|
|
i += run;
|
|
j = scantable[i];
|
|
if (level < 0) {
|
|
level = -level;
|
|
level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
|
|
level = (level - 1) | 1;
|
|
level = -level;
|
|
} else {
|
|
level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
|
|
level = (level - 1) | 1;
|
|
}
|
|
}
|
|
if (i > 63) {
|
|
av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
|
|
return -1;
|
|
}
|
|
|
|
block[j] = level;
|
|
if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
|
|
break;
|
|
UPDATE_CACHE(re, &s->gb);
|
|
}
|
|
end:
|
|
LAST_SKIP_BITS(re, &s->gb, 2);
|
|
CLOSE_READER(re, &s->gb);
|
|
}
|
|
s->block_last_index[n] = i;
|
|
return 0;
|
|
}
|
|
|
|
static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, int16_t *block, int n)
|
|
{
|
|
int level, i, j, run;
|
|
RLTable *rl = &ff_rl_mpeg1;
|
|
uint8_t * const scantable = s->intra_scantable.permutated;
|
|
const int qscale = s->qscale;
|
|
|
|
{
|
|
OPEN_READER(re, &s->gb);
|
|
i = -1;
|
|
// special case for first coefficient, no need to add second VLC table
|
|
UPDATE_CACHE(re, &s->gb);
|
|
if (((int32_t)GET_CACHE(re, &s->gb)) < 0) {
|
|
level = (3 * qscale) >> 1;
|
|
level = (level - 1) | 1;
|
|
if (GET_CACHE(re, &s->gb) & 0x40000000)
|
|
level = -level;
|
|
block[0] = level;
|
|
i++;
|
|
SKIP_BITS(re, &s->gb, 2);
|
|
if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
|
|
goto end;
|
|
}
|
|
|
|
/* now quantify & encode AC coefficients */
|
|
for (;;) {
|
|
GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
|
|
|
|
if (level != 0) {
|
|
i += run;
|
|
j = scantable[i];
|
|
level = ((level * 2 + 1) * qscale) >> 1;
|
|
level = (level - 1) | 1;
|
|
level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
|
|
SKIP_BITS(re, &s->gb, 1);
|
|
} else {
|
|
/* escape */
|
|
run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6);
|
|
UPDATE_CACHE(re, &s->gb);
|
|
level = SHOW_SBITS(re, &s->gb, 8); SKIP_BITS(re, &s->gb, 8);
|
|
if (level == -128) {
|
|
level = SHOW_UBITS(re, &s->gb, 8) - 256; SKIP_BITS(re, &s->gb, 8);
|
|
} else if (level == 0) {
|
|
level = SHOW_UBITS(re, &s->gb, 8) ; SKIP_BITS(re, &s->gb, 8);
|
|
}
|
|
i += run;
|
|
j = scantable[i];
|
|
if (level < 0) {
|
|
level = -level;
|
|
level = ((level * 2 + 1) * qscale) >> 1;
|
|
level = (level - 1) | 1;
|
|
level = -level;
|
|
} else {
|
|
level = ((level * 2 + 1) * qscale) >> 1;
|
|
level = (level - 1) | 1;
|
|
}
|
|
}
|
|
|
|
block[j] = level;
|
|
if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
|
|
break;
|
|
UPDATE_CACHE(re, &s->gb);
|
|
}
|
|
end:
|
|
LAST_SKIP_BITS(re, &s->gb, 2);
|
|
CLOSE_READER(re, &s->gb);
|
|
}
|
|
s->block_last_index[n] = i;
|
|
return 0;
|
|
}
|
|
|
|
|
|
static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, int16_t *block, int n)
|
|
{
|
|
int level, i, j, run;
|
|
RLTable *rl = &ff_rl_mpeg1;
|
|
uint8_t * const scantable = s->intra_scantable.permutated;
|
|
const uint16_t *quant_matrix;
|
|
const int qscale = s->qscale;
|
|
int mismatch;
|
|
|
|
mismatch = 1;
|
|
|
|
{
|
|
OPEN_READER(re, &s->gb);
|
|
i = -1;
|
|
if (n < 4)
|
|
quant_matrix = s->inter_matrix;
|
|
else
|
|
quant_matrix = s->chroma_inter_matrix;
|
|
|
|
// special case for first coefficient, no need to add second VLC table
|
|
UPDATE_CACHE(re, &s->gb);
|
|
if (((int32_t)GET_CACHE(re, &s->gb)) < 0) {
|
|
level= (3 * qscale * quant_matrix[0]) >> 5;
|
|
if (GET_CACHE(re, &s->gb) & 0x40000000)
|
|
level = -level;
|
|
block[0] = level;
|
|
mismatch ^= level;
|
|
i++;
|
|
SKIP_BITS(re, &s->gb, 2);
|
|
if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
|
|
goto end;
|
|
}
|
|
|
|
/* now quantify & encode AC coefficients */
|
|
for (;;) {
|
|
GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
|
|
|
|
if (level != 0) {
|
|
i += run;
|
|
j = scantable[i];
|
|
level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
|
|
level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
|
|
SKIP_BITS(re, &s->gb, 1);
|
|
} else {
|
|
/* escape */
|
|
run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6);
|
|
UPDATE_CACHE(re, &s->gb);
|
|
level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12);
|
|
|
|
i += run;
|
|
j = scantable[i];
|
|
if (level < 0) {
|
|
level = ((-level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
|
|
level = -level;
|
|
} else {
|
|
level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
|
|
}
|
|
}
|
|
if (i > 63) {
|
|
av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
|
|
return -1;
|
|
}
|
|
|
|
mismatch ^= level;
|
|
block[j] = level;
|
|
if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
|
|
break;
|
|
UPDATE_CACHE(re, &s->gb);
|
|
}
|
|
end:
|
|
LAST_SKIP_BITS(re, &s->gb, 2);
|
|
CLOSE_READER(re, &s->gb);
|
|
}
|
|
block[63] ^= (mismatch & 1);
|
|
|
|
s->block_last_index[n] = i;
|
|
return 0;
|
|
}
|
|
|
|
static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s,
|
|
int16_t *block, int n)
|
|
{
|
|
int level, i, j, run;
|
|
RLTable *rl = &ff_rl_mpeg1;
|
|
uint8_t * const scantable = s->intra_scantable.permutated;
|
|
const int qscale = s->qscale;
|
|
OPEN_READER(re, &s->gb);
|
|
i = -1;
|
|
|
|
// special case for first coefficient, no need to add second VLC table
|
|
UPDATE_CACHE(re, &s->gb);
|
|
if (((int32_t)GET_CACHE(re, &s->gb)) < 0) {
|
|
level = (3 * qscale) >> 1;
|
|
if (GET_CACHE(re, &s->gb) & 0x40000000)
|
|
level = -level;
|
|
block[0] = level;
|
|
i++;
|
|
SKIP_BITS(re, &s->gb, 2);
|
|
if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
|
|
goto end;
|
|
}
|
|
|
|
/* now quantify & encode AC coefficients */
|
|
for (;;) {
|
|
GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
|
|
|
|
if (level != 0) {
|
|
i += run;
|
|
j = scantable[i];
|
|
level = ((level * 2 + 1) * qscale) >> 1;
|
|
level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
|
|
SKIP_BITS(re, &s->gb, 1);
|
|
} else {
|
|
/* escape */
|
|
run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6);
|
|
UPDATE_CACHE(re, &s->gb);
|
|
level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12);
|
|
|
|
i += run;
|
|
j = scantable[i];
|
|
if (level < 0) {
|
|
level = ((-level * 2 + 1) * qscale) >> 1;
|
|
level = -level;
|
|
} else {
|
|
level = ((level * 2 + 1) * qscale) >> 1;
|
|
}
|
|
}
|
|
|
|
block[j] = level;
|
|
if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
|
|
break;
|
|
UPDATE_CACHE(re, &s->gb);
|
|
}
|
|
end:
|
|
LAST_SKIP_BITS(re, &s->gb, 2);
|
|
CLOSE_READER(re, &s->gb);
|
|
s->block_last_index[n] = i;
|
|
return 0;
|
|
}
|
|
|
|
|
|
static inline int mpeg2_decode_block_intra(MpegEncContext *s, int16_t *block, int n)
|
|
{
|
|
int level, dc, diff, i, j, run;
|
|
int component;
|
|
RLTable *rl;
|
|
uint8_t * const scantable = s->intra_scantable.permutated;
|
|
const uint16_t *quant_matrix;
|
|
const int qscale = s->qscale;
|
|
int mismatch;
|
|
|
|
/* DC coefficient */
|
|
if (n < 4) {
|
|
quant_matrix = s->intra_matrix;
|
|
component = 0;
|
|
} else {
|
|
quant_matrix = s->chroma_intra_matrix;
|
|
component = (n & 1) + 1;
|
|
}
|
|
diff = decode_dc(&s->gb, component);
|
|
if (diff >= 0xffff)
|
|
return -1;
|
|
dc = s->last_dc[component];
|
|
dc += diff;
|
|
s->last_dc[component] = dc;
|
|
block[0] = dc << (3 - s->intra_dc_precision);
|
|
av_dlog(s->avctx, "dc=%d\n", block[0]);
|
|
mismatch = block[0] ^ 1;
|
|
i = 0;
|
|
if (s->intra_vlc_format)
|
|
rl = &ff_rl_mpeg2;
|
|
else
|
|
rl = &ff_rl_mpeg1;
|
|
|
|
{
|
|
OPEN_READER(re, &s->gb);
|
|
/* now quantify & encode AC coefficients */
|
|
for (;;) {
|
|
UPDATE_CACHE(re, &s->gb);
|
|
GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
|
|
|
|
if (level == 127) {
|
|
break;
|
|
} else if (level != 0) {
|
|
i += run;
|
|
j = scantable[i];
|
|
level = (level * qscale * quant_matrix[j]) >> 4;
|
|
level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
|
|
LAST_SKIP_BITS(re, &s->gb, 1);
|
|
} else {
|
|
/* escape */
|
|
run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6);
|
|
UPDATE_CACHE(re, &s->gb);
|
|
level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12);
|
|
i += run;
|
|
j = scantable[i];
|
|
if (level < 0) {
|
|
level = (-level * qscale * quant_matrix[j]) >> 4;
|
|
level = -level;
|
|
} else {
|
|
level = (level * qscale * quant_matrix[j]) >> 4;
|
|
}
|
|
}
|
|
if (i > 63) {
|
|
av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
|
|
return -1;
|
|
}
|
|
|
|
mismatch ^= level;
|
|
block[j] = level;
|
|
}
|
|
CLOSE_READER(re, &s->gb);
|
|
}
|
|
block[63] ^= mismatch & 1;
|
|
|
|
s->block_last_index[n] = i;
|
|
return 0;
|
|
}
|
|
|
|
static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, int16_t *block, int n)
|
|
{
|
|
int level, dc, diff, j, run;
|
|
int component;
|
|
RLTable *rl;
|
|
uint8_t * scantable = s->intra_scantable.permutated;
|
|
const uint16_t *quant_matrix;
|
|
const int qscale = s->qscale;
|
|
|
|
/* DC coefficient */
|
|
if (n < 4) {
|
|
quant_matrix = s->intra_matrix;
|
|
component = 0;
|
|
} else {
|
|
quant_matrix = s->chroma_intra_matrix;
|
|
component = (n & 1) + 1;
|
|
}
|
|
diff = decode_dc(&s->gb, component);
|
|
if (diff >= 0xffff)
|
|
return -1;
|
|
dc = s->last_dc[component];
|
|
dc += diff;
|
|
s->last_dc[component] = dc;
|
|
block[0] = dc << (3 - s->intra_dc_precision);
|
|
if (s->intra_vlc_format)
|
|
rl = &ff_rl_mpeg2;
|
|
else
|
|
rl = &ff_rl_mpeg1;
|
|
|
|
{
|
|
OPEN_READER(re, &s->gb);
|
|
/* now quantify & encode AC coefficients */
|
|
for (;;) {
|
|
UPDATE_CACHE(re, &s->gb);
|
|
GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
|
|
|
|
if (level == 127) {
|
|
break;
|
|
} else if (level != 0) {
|
|
scantable += run;
|
|
j = *scantable;
|
|
level = (level * qscale * quant_matrix[j]) >> 4;
|
|
level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
|
|
LAST_SKIP_BITS(re, &s->gb, 1);
|
|
} else {
|
|
/* escape */
|
|
run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6);
|
|
UPDATE_CACHE(re, &s->gb);
|
|
level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12);
|
|
scantable += run;
|
|
j = *scantable;
|
|
if (level < 0) {
|
|
level = (-level * qscale * quant_matrix[j]) >> 4;
|
|
level = -level;
|
|
} else {
|
|
level = (level * qscale * quant_matrix[j]) >> 4;
|
|
}
|
|
}
|
|
|
|
block[j] = level;
|
|
}
|
|
CLOSE_READER(re, &s->gb);
|
|
}
|
|
|
|
s->block_last_index[n] = scantable - s->intra_scantable.permutated;
|
|
return 0;
|
|
}
|
|
|
|
/******************************************/
|
|
/* decoding */
|
|
|
|
static inline int get_dmv(MpegEncContext *s)
|
|
{
|
|
if (get_bits1(&s->gb))
|
|
return 1 - (get_bits1(&s->gb) << 1);
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
static inline int get_qscale(MpegEncContext *s)
|
|
{
|
|
int qscale = get_bits(&s->gb, 5);
|
|
if (s->q_scale_type) {
|
|
return non_linear_qscale[qscale];
|
|
} else {
|
|
return qscale << 1;
|
|
}
|
|
}
|
|
|
|
static void exchange_uv(MpegEncContext *s)
|
|
{
|
|
int16_t (*tmp)[64];
|
|
|
|
tmp = s->pblocks[4];
|
|
s->pblocks[4] = s->pblocks[5];
|
|
s->pblocks[5] = tmp;
|
|
}
|
|
|
|
/* motion type (for MPEG-2) */
|
|
#define MT_FIELD 1
|
|
#define MT_FRAME 2
|
|
#define MT_16X8 2
|
|
#define MT_DMV 3
|
|
|
|
static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64])
|
|
{
|
|
int i, j, k, cbp, val, mb_type, motion_type;
|
|
const int mb_block_count = 4 + (1 << s->chroma_format);
|
|
|
|
av_dlog(s->avctx, "decode_mb: x=%d y=%d\n", s->mb_x, s->mb_y);
|
|
|
|
assert(s->mb_skipped == 0);
|
|
|
|
if (s->mb_skip_run-- != 0) {
|
|
if (s->pict_type == AV_PICTURE_TYPE_P) {
|
|
s->mb_skipped = 1;
|
|
s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride] = MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16;
|
|
} else {
|
|
int mb_type;
|
|
|
|
if (s->mb_x)
|
|
mb_type = s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1];
|
|
else
|
|
mb_type = s->current_picture.mb_type[s->mb_width + (s->mb_y - 1) * s->mb_stride - 1]; // FIXME not sure if this is allowed in MPEG at all
|
|
if (IS_INTRA(mb_type))
|
|
return -1;
|
|
s->current_picture.mb_type[s->mb_x + s->mb_y*s->mb_stride] =
|
|
mb_type | MB_TYPE_SKIP;
|
|
// assert(s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1] & (MB_TYPE_16x16 | MB_TYPE_16x8));
|
|
|
|
if ((s->mv[0][0][0] | s->mv[0][0][1] | s->mv[1][0][0] | s->mv[1][0][1]) == 0)
|
|
s->mb_skipped = 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
switch (s->pict_type) {
|
|
default:
|
|
case AV_PICTURE_TYPE_I:
|
|
if (get_bits1(&s->gb) == 0) {
|
|
if (get_bits1(&s->gb) == 0) {
|
|
av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in I Frame at %d %d\n", s->mb_x, s->mb_y);
|
|
return -1;
|
|
}
|
|
mb_type = MB_TYPE_QUANT | MB_TYPE_INTRA;
|
|
} else {
|
|
mb_type = MB_TYPE_INTRA;
|
|
}
|
|
break;
|
|
case AV_PICTURE_TYPE_P:
|
|
mb_type = get_vlc2(&s->gb, ff_mb_ptype_vlc.table, MB_PTYPE_VLC_BITS, 1);
|
|
if (mb_type < 0) {
|
|
av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in P Frame at %d %d\n", s->mb_x, s->mb_y);
|
|
return -1;
|
|
}
|
|
mb_type = ptype2mb_type[mb_type];
|
|
break;
|
|
case AV_PICTURE_TYPE_B:
|
|
mb_type = get_vlc2(&s->gb, ff_mb_btype_vlc.table, MB_BTYPE_VLC_BITS, 1);
|
|
if (mb_type < 0) {
|
|
av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in B Frame at %d %d\n", s->mb_x, s->mb_y);
|
|
return -1;
|
|
}
|
|
mb_type = btype2mb_type[mb_type];
|
|
break;
|
|
}
|
|
av_dlog(s->avctx, "mb_type=%x\n", mb_type);
|
|
// motion_type = 0; /* avoid warning */
|
|
if (IS_INTRA(mb_type)) {
|
|
s->dsp.clear_blocks(s->block[0]);
|
|
|
|
if (!s->chroma_y_shift) {
|
|
s->dsp.clear_blocks(s->block[6]);
|
|
}
|
|
|
|
/* compute DCT type */
|
|
if (s->picture_structure == PICT_FRAME && // FIXME add an interlaced_dct coded var?
|
|
!s->frame_pred_frame_dct) {
|
|
s->interlaced_dct = get_bits1(&s->gb);
|
|
}
|
|
|
|
if (IS_QUANT(mb_type))
|
|
s->qscale = get_qscale(s);
|
|
|
|
if (s->concealment_motion_vectors) {
|
|
/* just parse them */
|
|
if (s->picture_structure != PICT_FRAME)
|
|
skip_bits1(&s->gb); /* field select */
|
|
|
|
s->mv[0][0][0]= s->last_mv[0][0][0]= s->last_mv[0][1][0] =
|
|
mpeg_decode_motion(s, s->mpeg_f_code[0][0], s->last_mv[0][0][0]);
|
|
s->mv[0][0][1]= s->last_mv[0][0][1]= s->last_mv[0][1][1] =
|
|
mpeg_decode_motion(s, s->mpeg_f_code[0][1], s->last_mv[0][0][1]);
|
|
|
|
skip_bits1(&s->gb); /* marker */
|
|
} else
|
|
memset(s->last_mv, 0, sizeof(s->last_mv)); /* reset mv prediction */
|
|
s->mb_intra = 1;
|
|
// if 1, we memcpy blocks in xvmcvideo
|
|
if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1) {
|
|
ff_xvmc_pack_pblocks(s, -1); // inter are always full blocks
|
|
if (s->swap_uv) {
|
|
exchange_uv(s);
|
|
}
|
|
}
|
|
|
|
if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
|
|
if (s->flags2 & CODEC_FLAG2_FAST) {
|
|
for (i = 0; i < 6; i++) {
|
|
mpeg2_fast_decode_block_intra(s, *s->pblocks[i], i);
|
|
}
|
|
} else {
|
|
for (i = 0; i < mb_block_count; i++) {
|
|
if (mpeg2_decode_block_intra(s, *s->pblocks[i], i) < 0)
|
|
return -1;
|
|
}
|
|
}
|
|
} else {
|
|
for (i = 0; i < 6; i++) {
|
|
if (mpeg1_decode_block_intra(s, *s->pblocks[i], i) < 0)
|
|
return -1;
|
|
}
|
|
}
|
|
} else {
|
|
if (mb_type & MB_TYPE_ZERO_MV) {
|
|
assert(mb_type & MB_TYPE_CBP);
|
|
|
|
s->mv_dir = MV_DIR_FORWARD;
|
|
if (s->picture_structure == PICT_FRAME) {
|
|
if (!s->frame_pred_frame_dct)
|
|
s->interlaced_dct = get_bits1(&s->gb);
|
|
s->mv_type = MV_TYPE_16X16;
|
|
} else {
|
|
s->mv_type = MV_TYPE_FIELD;
|
|
mb_type |= MB_TYPE_INTERLACED;
|
|
s->field_select[0][0] = s->picture_structure - 1;
|
|
}
|
|
|
|
if (IS_QUANT(mb_type))
|
|
s->qscale = get_qscale(s);
|
|
|
|
s->last_mv[0][0][0] = 0;
|
|
s->last_mv[0][0][1] = 0;
|
|
s->last_mv[0][1][0] = 0;
|
|
s->last_mv[0][1][1] = 0;
|
|
s->mv[0][0][0] = 0;
|
|
s->mv[0][0][1] = 0;
|
|
} else {
|
|
assert(mb_type & MB_TYPE_L0L1);
|
|
// FIXME decide if MBs in field pictures are MB_TYPE_INTERLACED
|
|
/* get additional motion vector type */
|
|
if (s->frame_pred_frame_dct)
|
|
motion_type = MT_FRAME;
|
|
else {
|
|
motion_type = get_bits(&s->gb, 2);
|
|
if (s->picture_structure == PICT_FRAME && HAS_CBP(mb_type))
|
|
s->interlaced_dct = get_bits1(&s->gb);
|
|
}
|
|
|
|
if (IS_QUANT(mb_type))
|
|
s->qscale = get_qscale(s);
|
|
|
|
/* motion vectors */
|
|
s->mv_dir = (mb_type >> 13) & 3;
|
|
av_dlog(s->avctx, "motion_type=%d\n", motion_type);
|
|
switch (motion_type) {
|
|
case MT_FRAME: /* or MT_16X8 */
|
|
if (s->picture_structure == PICT_FRAME) {
|
|
mb_type |= MB_TYPE_16x16;
|
|
s->mv_type = MV_TYPE_16X16;
|
|
for (i = 0; i < 2; i++) {
|
|
if (USES_LIST(mb_type, i)) {
|
|
/* MT_FRAME */
|
|
s->mv[i][0][0]= s->last_mv[i][0][0]= s->last_mv[i][1][0] =
|
|
mpeg_decode_motion(s, s->mpeg_f_code[i][0], s->last_mv[i][0][0]);
|
|
s->mv[i][0][1]= s->last_mv[i][0][1]= s->last_mv[i][1][1] =
|
|
mpeg_decode_motion(s, s->mpeg_f_code[i][1], s->last_mv[i][0][1]);
|
|
/* full_pel: only for MPEG-1 */
|
|
if (s->full_pel[i]) {
|
|
s->mv[i][0][0] <<= 1;
|
|
s->mv[i][0][1] <<= 1;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED;
|
|
s->mv_type = MV_TYPE_16X8;
|
|
for (i = 0; i < 2; i++) {
|
|
if (USES_LIST(mb_type, i)) {
|
|
/* MT_16X8 */
|
|
for (j = 0; j < 2; j++) {
|
|
s->field_select[i][j] = get_bits1(&s->gb);
|
|
for (k = 0; k < 2; k++) {
|
|
val = mpeg_decode_motion(s, s->mpeg_f_code[i][k],
|
|
s->last_mv[i][j][k]);
|
|
s->last_mv[i][j][k] = val;
|
|
s->mv[i][j][k] = val;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case MT_FIELD:
|
|
s->mv_type = MV_TYPE_FIELD;
|
|
if (s->picture_structure == PICT_FRAME) {
|
|
mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED;
|
|
for (i = 0; i < 2; i++) {
|
|
if (USES_LIST(mb_type, i)) {
|
|
for (j = 0; j < 2; j++) {
|
|
s->field_select[i][j] = get_bits1(&s->gb);
|
|
val = mpeg_decode_motion(s, s->mpeg_f_code[i][0],
|
|
s->last_mv[i][j][0]);
|
|
s->last_mv[i][j][0] = val;
|
|
s->mv[i][j][0] = val;
|
|
av_dlog(s->avctx, "fmx=%d\n", val);
|
|
val = mpeg_decode_motion(s, s->mpeg_f_code[i][1],
|
|
s->last_mv[i][j][1] >> 1);
|
|
s->last_mv[i][j][1] = val << 1;
|
|
s->mv[i][j][1] = val;
|
|
av_dlog(s->avctx, "fmy=%d\n", val);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED;
|
|
for (i = 0; i < 2; i++) {
|
|
if (USES_LIST(mb_type, i)) {
|
|
s->field_select[i][0] = get_bits1(&s->gb);
|
|
for (k = 0; k < 2; k++) {
|
|
val = mpeg_decode_motion(s, s->mpeg_f_code[i][k],
|
|
s->last_mv[i][0][k]);
|
|
s->last_mv[i][0][k] = val;
|
|
s->last_mv[i][1][k] = val;
|
|
s->mv[i][0][k] = val;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case MT_DMV:
|
|
s->mv_type = MV_TYPE_DMV;
|
|
for (i = 0; i < 2; i++) {
|
|
if (USES_LIST(mb_type, i)) {
|
|
int dmx, dmy, mx, my, m;
|
|
const int my_shift = s->picture_structure == PICT_FRAME;
|
|
|
|
mx = mpeg_decode_motion(s, s->mpeg_f_code[i][0],
|
|
s->last_mv[i][0][0]);
|
|
s->last_mv[i][0][0] = mx;
|
|
s->last_mv[i][1][0] = mx;
|
|
dmx = get_dmv(s);
|
|
my = mpeg_decode_motion(s, s->mpeg_f_code[i][1],
|
|
s->last_mv[i][0][1] >> my_shift);
|
|
dmy = get_dmv(s);
|
|
|
|
|
|
s->last_mv[i][0][1] = my << my_shift;
|
|
s->last_mv[i][1][1] = my << my_shift;
|
|
|
|
s->mv[i][0][0] = mx;
|
|
s->mv[i][0][1] = my;
|
|
s->mv[i][1][0] = mx; // not used
|
|
s->mv[i][1][1] = my; // not used
|
|
|
|
if (s->picture_structure == PICT_FRAME) {
|
|
mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED;
|
|
|
|
// m = 1 + 2 * s->top_field_first;
|
|
m = s->top_field_first ? 1 : 3;
|
|
|
|
/* top -> top pred */
|
|
s->mv[i][2][0] = ((mx * m + (mx > 0)) >> 1) + dmx;
|
|
s->mv[i][2][1] = ((my * m + (my > 0)) >> 1) + dmy - 1;
|
|
m = 4 - m;
|
|
s->mv[i][3][0] = ((mx * m + (mx > 0)) >> 1) + dmx;
|
|
s->mv[i][3][1] = ((my * m + (my > 0)) >> 1) + dmy + 1;
|
|
} else {
|
|
mb_type |= MB_TYPE_16x16;
|
|
|
|
s->mv[i][2][0] = ((mx + (mx > 0)) >> 1) + dmx;
|
|
s->mv[i][2][1] = ((my + (my > 0)) >> 1) + dmy;
|
|
if (s->picture_structure == PICT_TOP_FIELD)
|
|
s->mv[i][2][1]--;
|
|
else
|
|
s->mv[i][2][1]++;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
av_log(s->avctx, AV_LOG_ERROR, "00 motion_type at %d %d\n", s->mb_x, s->mb_y);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
s->mb_intra = 0;
|
|
if (HAS_CBP(mb_type)) {
|
|
s->dsp.clear_blocks(s->block[0]);
|
|
|
|
cbp = get_vlc2(&s->gb, ff_mb_pat_vlc.table, MB_PAT_VLC_BITS, 1);
|
|
if (mb_block_count > 6) {
|
|
cbp <<= mb_block_count - 6;
|
|
cbp |= get_bits(&s->gb, mb_block_count - 6);
|
|
s->dsp.clear_blocks(s->block[6]);
|
|
}
|
|
if (cbp <= 0) {
|
|
av_log(s->avctx, AV_LOG_ERROR, "invalid cbp at %d %d\n", s->mb_x, s->mb_y);
|
|
return -1;
|
|
}
|
|
|
|
//if 1, we memcpy blocks in xvmcvideo
|
|
if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1) {
|
|
ff_xvmc_pack_pblocks(s, cbp);
|
|
if (s->swap_uv) {
|
|
exchange_uv(s);
|
|
}
|
|
}
|
|
|
|
if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
|
|
if (s->flags2 & CODEC_FLAG2_FAST) {
|
|
for (i = 0; i < 6; i++) {
|
|
if (cbp & 32) {
|
|
mpeg2_fast_decode_block_non_intra(s, *s->pblocks[i], i);
|
|
} else {
|
|
s->block_last_index[i] = -1;
|
|
}
|
|
cbp += cbp;
|
|
}
|
|
} else {
|
|
cbp <<= 12-mb_block_count;
|
|
|
|
for (i = 0; i < mb_block_count; i++) {
|
|
if (cbp & (1 << 11)) {
|
|
if (mpeg2_decode_block_non_intra(s, *s->pblocks[i], i) < 0)
|
|
return -1;
|
|
} else {
|
|
s->block_last_index[i] = -1;
|
|
}
|
|
cbp += cbp;
|
|
}
|
|
}
|
|
} else {
|
|
if (s->flags2 & CODEC_FLAG2_FAST) {
|
|
for (i = 0; i < 6; i++) {
|
|
if (cbp & 32) {
|
|
mpeg1_fast_decode_block_inter(s, *s->pblocks[i], i);
|
|
} else {
|
|
s->block_last_index[i] = -1;
|
|
}
|
|
cbp += cbp;
|
|
}
|
|
} else {
|
|
for (i = 0; i < 6; i++) {
|
|
if (cbp & 32) {
|
|
if (mpeg1_decode_block_inter(s, *s->pblocks[i], i) < 0)
|
|
return -1;
|
|
} else {
|
|
s->block_last_index[i] = -1;
|
|
}
|
|
cbp += cbp;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
for (i = 0; i < 12; i++)
|
|
s->block_last_index[i] = -1;
|
|
}
|
|
}
|
|
|
|
s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride] = mb_type;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static av_cold int mpeg_decode_init(AVCodecContext *avctx)
|
|
{
|
|
Mpeg1Context *s = avctx->priv_data;
|
|
MpegEncContext *s2 = &s->mpeg_enc_ctx;
|
|
int i;
|
|
|
|
/* we need some permutation to store matrices,
|
|
* until MPV_common_init() sets the real permutation. */
|
|
for (i = 0; i < 64; i++)
|
|
s2->dsp.idct_permutation[i]=i;
|
|
|
|
ff_MPV_decode_defaults(s2);
|
|
|
|
s->mpeg_enc_ctx.avctx = avctx;
|
|
s->mpeg_enc_ctx.flags = avctx->flags;
|
|
s->mpeg_enc_ctx.flags2 = avctx->flags2;
|
|
ff_mpeg12_common_init(&s->mpeg_enc_ctx);
|
|
ff_mpeg12_init_vlcs();
|
|
|
|
s->mpeg_enc_ctx_allocated = 0;
|
|
s->mpeg_enc_ctx.picture_number = 0;
|
|
s->repeat_field = 0;
|
|
s->mpeg_enc_ctx.codec_id = avctx->codec->id;
|
|
avctx->color_range = AVCOL_RANGE_MPEG;
|
|
if (avctx->codec->id == AV_CODEC_ID_MPEG1VIDEO)
|
|
avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
|
|
else
|
|
avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
|
|
return 0;
|
|
}
|
|
|
|
static int mpeg_decode_update_thread_context(AVCodecContext *avctx, const AVCodecContext *avctx_from)
|
|
{
|
|
Mpeg1Context *ctx = avctx->priv_data, *ctx_from = avctx_from->priv_data;
|
|
MpegEncContext *s = &ctx->mpeg_enc_ctx, *s1 = &ctx_from->mpeg_enc_ctx;
|
|
int err;
|
|
|
|
if (avctx == avctx_from || !ctx_from->mpeg_enc_ctx_allocated || !s1->context_initialized)
|
|
return 0;
|
|
|
|
err = ff_mpeg_update_thread_context(avctx, avctx_from);
|
|
if (err) return err;
|
|
|
|
if (!ctx->mpeg_enc_ctx_allocated)
|
|
memcpy(s + 1, s1 + 1, sizeof(Mpeg1Context) - sizeof(MpegEncContext));
|
|
|
|
if (!(s->pict_type == AV_PICTURE_TYPE_B || s->low_delay))
|
|
s->picture_number++;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void quant_matrix_rebuild(uint16_t *matrix, const uint8_t *old_perm,
|
|
const uint8_t *new_perm)
|
|
{
|
|
uint16_t temp_matrix[64];
|
|
int i;
|
|
|
|
memcpy(temp_matrix, matrix, 64 * sizeof(uint16_t));
|
|
|
|
for (i = 0; i < 64; i++) {
|
|
matrix[new_perm[i]] = temp_matrix[old_perm[i]];
|
|
}
|
|
}
|
|
|
|
static const enum AVPixelFormat pixfmt_xvmc_mpg2_420[] = {
|
|
AV_PIX_FMT_XVMC_MPEG2_IDCT,
|
|
AV_PIX_FMT_XVMC_MPEG2_MC,
|
|
AV_PIX_FMT_NONE };
|
|
|
|
static const enum AVPixelFormat mpeg12_hwaccel_pixfmt_list_420[] = {
|
|
#if CONFIG_MPEG2_DXVA2_HWACCEL
|
|
AV_PIX_FMT_DXVA2_VLD,
|
|
#endif
|
|
#if CONFIG_MPEG2_VAAPI_HWACCEL
|
|
AV_PIX_FMT_VAAPI_VLD,
|
|
#endif
|
|
#if CONFIG_MPEG1_VDPAU_HWACCEL | CONFIG_MPEG2_VDPAU_HWACCEL
|
|
AV_PIX_FMT_VDPAU,
|
|
#endif
|
|
AV_PIX_FMT_YUV420P,
|
|
AV_PIX_FMT_NONE
|
|
};
|
|
|
|
static enum AVPixelFormat mpeg_get_pixelformat(AVCodecContext *avctx)
|
|
{
|
|
Mpeg1Context *s1 = avctx->priv_data;
|
|
MpegEncContext *s = &s1->mpeg_enc_ctx;
|
|
|
|
if (avctx->xvmc_acceleration)
|
|
return avctx->get_format(avctx, pixfmt_xvmc_mpg2_420);
|
|
else if (avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) {
|
|
if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO)
|
|
return AV_PIX_FMT_VDPAU_MPEG1;
|
|
else
|
|
return AV_PIX_FMT_VDPAU_MPEG2;
|
|
} else {
|
|
if (s->chroma_format < 2)
|
|
return avctx->get_format(avctx, mpeg12_hwaccel_pixfmt_list_420);
|
|
else if (s->chroma_format == 2)
|
|
return AV_PIX_FMT_YUV422P;
|
|
else
|
|
return AV_PIX_FMT_YUV444P;
|
|
}
|
|
}
|
|
|
|
/* Call this function when we know all parameters.
|
|
* It may be called in different places for MPEG-1 and MPEG-2. */
|
|
static int mpeg_decode_postinit(AVCodecContext *avctx)
|
|
{
|
|
Mpeg1Context *s1 = avctx->priv_data;
|
|
MpegEncContext *s = &s1->mpeg_enc_ctx;
|
|
uint8_t old_permutation[64];
|
|
|
|
if ((s1->mpeg_enc_ctx_allocated == 0) ||
|
|
avctx->coded_width != s->width ||
|
|
avctx->coded_height != s->height ||
|
|
s1->save_width != s->width ||
|
|
s1->save_height != s->height ||
|
|
s1->save_aspect_info != s->aspect_ratio_info ||
|
|
s1->save_progressive_seq != s->progressive_sequence ||
|
|
0)
|
|
{
|
|
|
|
if (s1->mpeg_enc_ctx_allocated) {
|
|
ParseContext pc = s->parse_context;
|
|
s->parse_context.buffer = 0;
|
|
ff_MPV_common_end(s);
|
|
s->parse_context = pc;
|
|
}
|
|
|
|
if ((s->width == 0) || (s->height == 0))
|
|
return -2;
|
|
|
|
avcodec_set_dimensions(avctx, s->width, s->height);
|
|
avctx->bit_rate = s->bit_rate;
|
|
s1->save_aspect_info = s->aspect_ratio_info;
|
|
s1->save_width = s->width;
|
|
s1->save_height = s->height;
|
|
s1->save_progressive_seq = s->progressive_sequence;
|
|
|
|
/* low_delay may be forced, in this case we will have B-frames
|
|
* that behave like P-frames. */
|
|
avctx->has_b_frames = !s->low_delay;
|
|
|
|
if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
|
|
//MPEG-1 fps
|
|
avctx->time_base.den = ff_mpeg12_frame_rate_tab[s->frame_rate_index].num;
|
|
avctx->time_base.num = ff_mpeg12_frame_rate_tab[s->frame_rate_index].den;
|
|
//MPEG-1 aspect
|
|
avctx->sample_aspect_ratio = av_d2q(1.0/ff_mpeg1_aspect[s->aspect_ratio_info], 255);
|
|
avctx->ticks_per_frame=1;
|
|
} else {//MPEG-2
|
|
//MPEG-2 fps
|
|
av_reduce(&s->avctx->time_base.den,
|
|
&s->avctx->time_base.num,
|
|
ff_mpeg12_frame_rate_tab[s->frame_rate_index].num * s1->frame_rate_ext.num*2,
|
|
ff_mpeg12_frame_rate_tab[s->frame_rate_index].den * s1->frame_rate_ext.den,
|
|
1 << 30);
|
|
avctx->ticks_per_frame = 2;
|
|
//MPEG-2 aspect
|
|
if (s->aspect_ratio_info > 1) {
|
|
AVRational dar =
|
|
av_mul_q(av_div_q(ff_mpeg2_aspect[s->aspect_ratio_info],
|
|
(AVRational) {s1->pan_scan.width, s1->pan_scan.height}),
|
|
(AVRational) {s->width, s->height});
|
|
|
|
// we ignore the spec here and guess a bit as reality does not match the spec, see for example
|
|
// res_change_ffmpeg_aspect.ts and sequence-display-aspect.mpg
|
|
// issue1613, 621, 562
|
|
if ((s1->pan_scan.width == 0) || (s1->pan_scan.height == 0) ||
|
|
(av_cmp_q(dar, (AVRational) {4, 3}) && av_cmp_q(dar, (AVRational) {16, 9}))) {
|
|
s->avctx->sample_aspect_ratio =
|
|
av_div_q(ff_mpeg2_aspect[s->aspect_ratio_info],
|
|
(AVRational) {s->width, s->height});
|
|
} else {
|
|
s->avctx->sample_aspect_ratio =
|
|
av_div_q(ff_mpeg2_aspect[s->aspect_ratio_info],
|
|
(AVRational) {s1->pan_scan.width, s1->pan_scan.height});
|
|
//issue1613 4/3 16/9 -> 16/9
|
|
//res_change_ffmpeg_aspect.ts 4/3 225/44 ->4/3
|
|
//widescreen-issue562.mpg 4/3 16/9 -> 16/9
|
|
// s->avctx->sample_aspect_ratio = av_mul_q(s->avctx->sample_aspect_ratio, (AVRational) {s->width, s->height});
|
|
av_dlog(avctx, "A %d/%d\n",
|
|
ff_mpeg2_aspect[s->aspect_ratio_info].num, ff_mpeg2_aspect[s->aspect_ratio_info].den);
|
|
av_dlog(avctx, "B %d/%d\n", s->avctx->sample_aspect_ratio.num,
|
|
s->avctx->sample_aspect_ratio.den);
|
|
}
|
|
} else {
|
|
s->avctx->sample_aspect_ratio =
|
|
ff_mpeg2_aspect[s->aspect_ratio_info];
|
|
}
|
|
} // MPEG-2
|
|
|
|
avctx->pix_fmt = mpeg_get_pixelformat(avctx);
|
|
avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt);
|
|
// until then pix_fmt may be changed right after codec init
|
|
if (avctx->pix_fmt == AV_PIX_FMT_XVMC_MPEG2_IDCT ||
|
|
avctx->hwaccel ||
|
|
s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
|
|
if (avctx->idct_algo == FF_IDCT_AUTO)
|
|
avctx->idct_algo = FF_IDCT_SIMPLE;
|
|
|
|
/* Quantization matrices may need reordering
|
|
* if DCT permutation is changed. */
|
|
memcpy(old_permutation, s->dsp.idct_permutation, 64 * sizeof(uint8_t));
|
|
|
|
if (ff_MPV_common_init(s) < 0)
|
|
return -2;
|
|
|
|
quant_matrix_rebuild(s->intra_matrix, old_permutation, s->dsp.idct_permutation);
|
|
quant_matrix_rebuild(s->inter_matrix, old_permutation, s->dsp.idct_permutation);
|
|
quant_matrix_rebuild(s->chroma_intra_matrix, old_permutation, s->dsp.idct_permutation);
|
|
quant_matrix_rebuild(s->chroma_inter_matrix, old_permutation, s->dsp.idct_permutation);
|
|
|
|
s1->mpeg_enc_ctx_allocated = 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int mpeg1_decode_picture(AVCodecContext *avctx,
|
|
const uint8_t *buf, int buf_size)
|
|
{
|
|
Mpeg1Context *s1 = avctx->priv_data;
|
|
MpegEncContext *s = &s1->mpeg_enc_ctx;
|
|
int ref, f_code, vbv_delay;
|
|
|
|
init_get_bits(&s->gb, buf, buf_size*8);
|
|
|
|
ref = get_bits(&s->gb, 10); /* temporal ref */
|
|
s->pict_type = get_bits(&s->gb, 3);
|
|
if (s->pict_type == 0 || s->pict_type > 3)
|
|
return -1;
|
|
|
|
vbv_delay = get_bits(&s->gb, 16);
|
|
if (s->pict_type == AV_PICTURE_TYPE_P || s->pict_type == AV_PICTURE_TYPE_B) {
|
|
s->full_pel[0] = get_bits1(&s->gb);
|
|
f_code = get_bits(&s->gb, 3);
|
|
if (f_code == 0 && (avctx->err_recognition & AV_EF_BITSTREAM))
|
|
return -1;
|
|
s->mpeg_f_code[0][0] = f_code;
|
|
s->mpeg_f_code[0][1] = f_code;
|
|
}
|
|
if (s->pict_type == AV_PICTURE_TYPE_B) {
|
|
s->full_pel[1] = get_bits1(&s->gb);
|
|
f_code = get_bits(&s->gb, 3);
|
|
if (f_code == 0 && (avctx->err_recognition & AV_EF_BITSTREAM))
|
|
return -1;
|
|
s->mpeg_f_code[1][0] = f_code;
|
|
s->mpeg_f_code[1][1] = f_code;
|
|
}
|
|
s->current_picture.f.pict_type = s->pict_type;
|
|
s->current_picture.f.key_frame = s->pict_type == AV_PICTURE_TYPE_I;
|
|
|
|
if (avctx->debug & FF_DEBUG_PICT_INFO)
|
|
av_log(avctx, AV_LOG_DEBUG, "vbv_delay %d, ref %d type:%d\n", vbv_delay, ref, s->pict_type);
|
|
|
|
s->y_dc_scale = 8;
|
|
s->c_dc_scale = 8;
|
|
return 0;
|
|
}
|
|
|
|
static void mpeg_decode_sequence_extension(Mpeg1Context *s1)
|
|
{
|
|
MpegEncContext *s= &s1->mpeg_enc_ctx;
|
|
int horiz_size_ext, vert_size_ext;
|
|
int bit_rate_ext;
|
|
|
|
skip_bits(&s->gb, 1); /* profile and level esc*/
|
|
s->avctx->profile = get_bits(&s->gb, 3);
|
|
s->avctx->level = get_bits(&s->gb, 4);
|
|
s->progressive_sequence = get_bits1(&s->gb); /* progressive_sequence */
|
|
s->chroma_format = get_bits(&s->gb, 2); /* chroma_format 1=420, 2=422, 3=444 */
|
|
horiz_size_ext = get_bits(&s->gb, 2);
|
|
vert_size_ext = get_bits(&s->gb, 2);
|
|
s->width |= (horiz_size_ext << 12);
|
|
s->height |= (vert_size_ext << 12);
|
|
bit_rate_ext = get_bits(&s->gb, 12); /* XXX: handle it */
|
|
s->bit_rate += (bit_rate_ext << 18) * 400;
|
|
skip_bits1(&s->gb); /* marker */
|
|
s->avctx->rc_buffer_size += get_bits(&s->gb, 8) * 1024 * 16 << 10;
|
|
|
|
s->low_delay = get_bits1(&s->gb);
|
|
if (s->flags & CODEC_FLAG_LOW_DELAY)
|
|
s->low_delay = 1;
|
|
|
|
s1->frame_rate_ext.num = get_bits(&s->gb, 2) + 1;
|
|
s1->frame_rate_ext.den = get_bits(&s->gb, 5) + 1;
|
|
|
|
av_dlog(s->avctx, "sequence extension\n");
|
|
s->codec_id = s->avctx->codec_id = AV_CODEC_ID_MPEG2VIDEO;
|
|
|
|
if (s->avctx->debug & FF_DEBUG_PICT_INFO)
|
|
av_log(s->avctx, AV_LOG_DEBUG, "profile: %d, level: %d vbv buffer: %d, bitrate:%d\n",
|
|
s->avctx->profile, s->avctx->level, s->avctx->rc_buffer_size, s->bit_rate);
|
|
|
|
}
|
|
|
|
static void mpeg_decode_sequence_display_extension(Mpeg1Context *s1)
|
|
{
|
|
MpegEncContext *s = &s1->mpeg_enc_ctx;
|
|
int color_description, w, h;
|
|
|
|
skip_bits(&s->gb, 3); /* video format */
|
|
color_description = get_bits1(&s->gb);
|
|
if (color_description) {
|
|
s->avctx->color_primaries = get_bits(&s->gb, 8);
|
|
s->avctx->color_trc = get_bits(&s->gb, 8);
|
|
s->avctx->colorspace = get_bits(&s->gb, 8);
|
|
}
|
|
w = get_bits(&s->gb, 14);
|
|
skip_bits(&s->gb, 1); //marker
|
|
h = get_bits(&s->gb, 14);
|
|
// remaining 3 bits are zero padding
|
|
|
|
s1->pan_scan.width = 16 * w;
|
|
s1->pan_scan.height = 16 * h;
|
|
|
|
if (s->avctx->debug & FF_DEBUG_PICT_INFO)
|
|
av_log(s->avctx, AV_LOG_DEBUG, "sde w:%d, h:%d\n", w, h);
|
|
}
|
|
|
|
static void mpeg_decode_picture_display_extension(Mpeg1Context *s1)
|
|
{
|
|
MpegEncContext *s = &s1->mpeg_enc_ctx;
|
|
int i, nofco;
|
|
|
|
nofco = 1;
|
|
if (s->progressive_sequence) {
|
|
if (s->repeat_first_field) {
|
|
nofco++;
|
|
if (s->top_field_first)
|
|
nofco++;
|
|
}
|
|
} else {
|
|
if (s->picture_structure == PICT_FRAME) {
|
|
nofco++;
|
|
if (s->repeat_first_field)
|
|
nofco++;
|
|
}
|
|
}
|
|
for (i = 0; i < nofco; i++) {
|
|
s1->pan_scan.position[i][0] = get_sbits(&s->gb, 16);
|
|
skip_bits(&s->gb, 1); // marker
|
|
s1->pan_scan.position[i][1] = get_sbits(&s->gb, 16);
|
|
skip_bits(&s->gb, 1); // marker
|
|
}
|
|
|
|
if (s->avctx->debug & FF_DEBUG_PICT_INFO)
|
|
av_log(s->avctx, AV_LOG_DEBUG, "pde (%d,%d) (%d,%d) (%d,%d)\n",
|
|
s1->pan_scan.position[0][0], s1->pan_scan.position[0][1],
|
|
s1->pan_scan.position[1][0], s1->pan_scan.position[1][1],
|
|
s1->pan_scan.position[2][0], s1->pan_scan.position[2][1]);
|
|
}
|
|
|
|
static int load_matrix(MpegEncContext *s, uint16_t matrix0[64], uint16_t matrix1[64], int intra)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < 64; i++) {
|
|
int j = s->dsp.idct_permutation[ff_zigzag_direct[i]];
|
|
int v = get_bits(&s->gb, 8);
|
|
if (v == 0) {
|
|
av_log(s->avctx, AV_LOG_ERROR, "matrix damaged\n");
|
|
return -1;
|
|
}
|
|
if (intra && i == 0 && v != 8) {
|
|
av_log(s->avctx, AV_LOG_ERROR, "intra matrix invalid, ignoring\n");
|
|
v = 8; // needed by pink.mpg / issue1046
|
|
}
|
|
matrix0[j] = v;
|
|
if (matrix1)
|
|
matrix1[j] = v;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static void mpeg_decode_quant_matrix_extension(MpegEncContext *s)
|
|
{
|
|
av_dlog(s->avctx, "matrix extension\n");
|
|
|
|
if (get_bits1(&s->gb)) load_matrix(s, s->chroma_intra_matrix, s->intra_matrix, 1);
|
|
if (get_bits1(&s->gb)) load_matrix(s, s->chroma_inter_matrix, s->inter_matrix, 0);
|
|
if (get_bits1(&s->gb)) load_matrix(s, s->chroma_intra_matrix, NULL , 1);
|
|
if (get_bits1(&s->gb)) load_matrix(s, s->chroma_inter_matrix, NULL , 0);
|
|
}
|
|
|
|
static void mpeg_decode_picture_coding_extension(Mpeg1Context *s1)
|
|
{
|
|
MpegEncContext *s = &s1->mpeg_enc_ctx;
|
|
|
|
s->full_pel[0] = s->full_pel[1] = 0;
|
|
s->mpeg_f_code[0][0] = get_bits(&s->gb, 4);
|
|
s->mpeg_f_code[0][1] = get_bits(&s->gb, 4);
|
|
s->mpeg_f_code[1][0] = get_bits(&s->gb, 4);
|
|
s->mpeg_f_code[1][1] = get_bits(&s->gb, 4);
|
|
if (!s->pict_type && s1->mpeg_enc_ctx_allocated) {
|
|
av_log(s->avctx, AV_LOG_ERROR, "Missing picture start code, guessing missing values\n");
|
|
if (s->mpeg_f_code[1][0] == 15 && s->mpeg_f_code[1][1] == 15) {
|
|
if (s->mpeg_f_code[0][0] == 15 && s->mpeg_f_code[0][1] == 15)
|
|
s->pict_type = AV_PICTURE_TYPE_I;
|
|
else
|
|
s->pict_type = AV_PICTURE_TYPE_P;
|
|
} else
|
|
s->pict_type = AV_PICTURE_TYPE_B;
|
|
s->current_picture.f.pict_type = s->pict_type;
|
|
s->current_picture.f.key_frame = s->pict_type == AV_PICTURE_TYPE_I;
|
|
}
|
|
s->intra_dc_precision = get_bits(&s->gb, 2);
|
|
s->picture_structure = get_bits(&s->gb, 2);
|
|
s->top_field_first = get_bits1(&s->gb);
|
|
s->frame_pred_frame_dct = get_bits1(&s->gb);
|
|
s->concealment_motion_vectors = get_bits1(&s->gb);
|
|
s->q_scale_type = get_bits1(&s->gb);
|
|
s->intra_vlc_format = get_bits1(&s->gb);
|
|
s->alternate_scan = get_bits1(&s->gb);
|
|
s->repeat_first_field = get_bits1(&s->gb);
|
|
s->chroma_420_type = get_bits1(&s->gb);
|
|
s->progressive_frame = get_bits1(&s->gb);
|
|
|
|
if (s->progressive_sequence && !s->progressive_frame) {
|
|
s->progressive_frame = 1;
|
|
av_log(s->avctx, AV_LOG_ERROR, "interlaced frame in progressive sequence, ignoring\n");
|
|
}
|
|
|
|
if (s->picture_structure == 0 || (s->progressive_frame && s->picture_structure != PICT_FRAME)) {
|
|
av_log(s->avctx, AV_LOG_ERROR, "picture_structure %d invalid, ignoring\n", s->picture_structure);
|
|
s->picture_structure = PICT_FRAME;
|
|
}
|
|
|
|
if (s->progressive_sequence && !s->frame_pred_frame_dct) {
|
|
av_log(s->avctx, AV_LOG_WARNING, "invalid frame_pred_frame_dct\n");
|
|
}
|
|
|
|
if (s->picture_structure == PICT_FRAME) {
|
|
s->first_field = 0;
|
|
s->v_edge_pos = 16 * s->mb_height;
|
|
} else {
|
|
s->first_field ^= 1;
|
|
s->v_edge_pos = 8 * s->mb_height;
|
|
memset(s->mbskip_table, 0, s->mb_stride * s->mb_height);
|
|
}
|
|
|
|
if (s->alternate_scan) {
|
|
ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable, ff_alternate_vertical_scan);
|
|
ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable, ff_alternate_vertical_scan);
|
|
} else {
|
|
ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable, ff_zigzag_direct);
|
|
ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable, ff_zigzag_direct);
|
|
}
|
|
|
|
/* composite display not parsed */
|
|
av_dlog(s->avctx, "intra_dc_precision=%d\n", s->intra_dc_precision);
|
|
av_dlog(s->avctx, "picture_structure=%d\n", s->picture_structure);
|
|
av_dlog(s->avctx, "top field first=%d\n", s->top_field_first);
|
|
av_dlog(s->avctx, "repeat first field=%d\n", s->repeat_first_field);
|
|
av_dlog(s->avctx, "conceal=%d\n", s->concealment_motion_vectors);
|
|
av_dlog(s->avctx, "intra_vlc_format=%d\n", s->intra_vlc_format);
|
|
av_dlog(s->avctx, "alternate_scan=%d\n", s->alternate_scan);
|
|
av_dlog(s->avctx, "frame_pred_frame_dct=%d\n", s->frame_pred_frame_dct);
|
|
av_dlog(s->avctx, "progressive_frame=%d\n", s->progressive_frame);
|
|
}
|
|
|
|
static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size)
|
|
{
|
|
AVCodecContext *avctx = s->avctx;
|
|
Mpeg1Context *s1 = (Mpeg1Context*)s;
|
|
|
|
/* start frame decoding */
|
|
if (s->first_field || s->picture_structure == PICT_FRAME) {
|
|
AVFrameSideData *pan_scan;
|
|
|
|
if (ff_MPV_frame_start(s, avctx) < 0)
|
|
return -1;
|
|
|
|
ff_mpeg_er_frame_start(s);
|
|
|
|
/* first check if we must repeat the frame */
|
|
s->current_picture_ptr->f.repeat_pict = 0;
|
|
if (s->repeat_first_field) {
|
|
if (s->progressive_sequence) {
|
|
if (s->top_field_first)
|
|
s->current_picture_ptr->f.repeat_pict = 4;
|
|
else
|
|
s->current_picture_ptr->f.repeat_pict = 2;
|
|
} else if (s->progressive_frame) {
|
|
s->current_picture_ptr->f.repeat_pict = 1;
|
|
}
|
|
}
|
|
|
|
pan_scan = av_frame_new_side_data(&s->current_picture_ptr->f,
|
|
|