mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-29 22:00:58 +02:00
mpeg4video: Add support for MPEG-4 Simple Studio Profile.
This is a profile supporting > 8-bit video and has a higher quality DCT
This commit is contained in:
parent
699fa8f382
commit
f9d3841ae6
@ -814,7 +814,8 @@ static int er_supported(ERContext *s)
|
||||
{
|
||||
if(s->avctx->hwaccel && s->avctx->hwaccel->decode_slice ||
|
||||
!s->cur_pic.f ||
|
||||
s->cur_pic.field_picture
|
||||
s->cur_pic.field_picture ||
|
||||
s->avctx->profile == FF_PROFILE_MPEG4_SIMPLE_STUDIO
|
||||
)
|
||||
return 0;
|
||||
return 1;
|
||||
|
@ -47,6 +47,12 @@
|
||||
|
||||
static enum AVPixelFormat h263_get_format(AVCodecContext *avctx)
|
||||
{
|
||||
/* MPEG-4 Studio Profile only, not supported by hardware */
|
||||
if (avctx->bits_per_raw_sample > 8) {
|
||||
av_assert1(avctx->profile == FF_PROFILE_MPEG4_SIMPLE_STUDIO);
|
||||
return avctx->pix_fmt;
|
||||
}
|
||||
|
||||
if (avctx->codec->id == AV_CODEC_ID_MSS2)
|
||||
return AV_PIX_FMT_YUV420P;
|
||||
|
||||
@ -197,6 +203,11 @@ static int decode_slice(MpegEncContext *s)
|
||||
|
||||
ff_set_qscale(s, s->qscale);
|
||||
|
||||
if (s->studio_profile) {
|
||||
if ((ret = ff_mpeg4_decode_studio_slice_header(s->avctx->priv_data)) < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (s->avctx->hwaccel) {
|
||||
const uint8_t *start = s->gb.buffer + get_bits_count(&s->gb) / 8;
|
||||
ret = s->avctx->hwaccel->decode_slice(s->avctx, start, s->gb.buffer_end - start);
|
||||
|
@ -256,9 +256,15 @@ av_cold void ff_idctdsp_init(IDCTDSPContext *c, AVCodecContext *avctx)
|
||||
c->perm_type = FF_IDCT_PERM_NONE;
|
||||
} else {
|
||||
if (avctx->bits_per_raw_sample == 10 || avctx->bits_per_raw_sample == 9) {
|
||||
c->idct_put = ff_simple_idct_put_int16_10bit;
|
||||
c->idct_add = ff_simple_idct_add_int16_10bit;
|
||||
c->idct = ff_simple_idct_int16_10bit;
|
||||
/* 10-bit MPEG-4 Simple Studio Profile requires a higher precision IDCT
|
||||
However, it only uses idct_put */
|
||||
if (avctx->codec_id == AV_CODEC_ID_MPEG4 && avctx->profile == FF_PROFILE_MPEG4_SIMPLE_STUDIO)
|
||||
c->idct_put = ff_simple_idct_put_int32_10bit;
|
||||
else {
|
||||
c->idct_put = ff_simple_idct_put_int16_10bit;
|
||||
c->idct_add = ff_simple_idct_add_int16_10bit;
|
||||
c->idct = ff_simple_idct_int16_10bit;
|
||||
}
|
||||
c->perm_type = FF_IDCT_PERM_NONE;
|
||||
} else if (avctx->bits_per_raw_sample == 12) {
|
||||
c->idct_put = ff_simple_idct_put_int16_12bit;
|
||||
|
@ -207,12 +207,27 @@ static int h263_decode_gob_header(MpegEncContext *s)
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode the group of blocks / video packet header.
|
||||
* Decode the group of blocks / video packet header / slice header (MPEG-4 Studio).
|
||||
* @return bit position of the resync_marker, or <0 if none was found
|
||||
*/
|
||||
int ff_h263_resync(MpegEncContext *s){
|
||||
int left, pos, ret;
|
||||
|
||||
/* In MPEG-4 studio mode look for a new slice startcode
|
||||
* and decode slice header */
|
||||
if(s->codec_id==AV_CODEC_ID_MPEG4 && s->studio_profile) {
|
||||
align_get_bits(&s->gb);
|
||||
|
||||
while (get_bits_left(&s->gb) >= 32 && show_bits_long(&s->gb, 32) != SLICE_START_CODE) {
|
||||
get_bits(&s->gb, 8);
|
||||
}
|
||||
|
||||
if (show_bits_long(&s->gb, 32) == SLICE_START_CODE)
|
||||
return get_bits_count(&s->gb);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(s->codec_id==AV_CODEC_ID_MPEG4){
|
||||
skip_bits1(&s->gb);
|
||||
align_get_bits(&s->gb);
|
||||
|
@ -649,16 +649,6 @@ static inline int get_dmv(MpegEncContext *s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int get_qscale(MpegEncContext *s)
|
||||
{
|
||||
int qscale = get_bits(&s->gb, 5);
|
||||
if (s->q_scale_type)
|
||||
return ff_mpeg2_non_linear_qscale[qscale];
|
||||
else
|
||||
return qscale << 1;
|
||||
}
|
||||
|
||||
|
||||
/* motion type (for MPEG-2) */
|
||||
#define MT_FIELD 1
|
||||
#define MT_FRAME 2
|
||||
@ -751,7 +741,7 @@ static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64])
|
||||
s->interlaced_dct = get_bits1(&s->gb);
|
||||
|
||||
if (IS_QUANT(mb_type))
|
||||
s->qscale = get_qscale(s);
|
||||
s->qscale = mpeg_get_qscale(s);
|
||||
|
||||
if (s->concealment_motion_vectors) {
|
||||
/* just parse them */
|
||||
@ -819,7 +809,7 @@ static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64])
|
||||
}
|
||||
|
||||
if (IS_QUANT(mb_type))
|
||||
s->qscale = get_qscale(s);
|
||||
s->qscale = mpeg_get_qscale(s);
|
||||
|
||||
s->last_mv[0][0][0] = 0;
|
||||
s->last_mv[0][0][1] = 0;
|
||||
@ -840,7 +830,7 @@ static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64])
|
||||
}
|
||||
|
||||
if (IS_QUANT(mb_type))
|
||||
s->qscale = get_qscale(s);
|
||||
s->qscale = mpeg_get_qscale(s);
|
||||
|
||||
/* motion vectors */
|
||||
s->mv_dir = (mb_type >> 13) & 3;
|
||||
@ -1728,7 +1718,7 @@ static int mpeg_decode_slice(MpegEncContext *s, int mb_y,
|
||||
ff_mpeg1_clean_buffers(s);
|
||||
s->interlaced_dct = 0;
|
||||
|
||||
s->qscale = get_qscale(s);
|
||||
s->qscale = mpeg_get_qscale(s);
|
||||
|
||||
if (s->qscale == 0) {
|
||||
av_log(s->avctx, AV_LOG_ERROR, "qscale == 0\n");
|
||||
|
@ -373,4 +373,120 @@ const uint8_t ff_mpeg4_dc_threshold[8]={
|
||||
99, 13, 15, 17, 19, 21, 23, 0
|
||||
};
|
||||
|
||||
/* Note these are different in studio mode */
|
||||
const uint16_t ff_mpeg4_studio_dc_luma[19][2]={
|
||||
{0x0e, 6}, {0x06, 5}, {0x00, 4}, {0x02, 4},
|
||||
{0x07, 3}, {0x05, 3}, {0x03, 3}, {0x02, 3},
|
||||
{0x04, 3}, {0x06, 3}, {0x01, 4}, {0x1e, 7},
|
||||
{0x3e, 8}, {0x7e, 9}, {0xfe, 10}, {0x1fe, 11},
|
||||
{0x3fe, 12}, {0x7fe, 13}, {0x7ff, 13}
|
||||
};
|
||||
|
||||
const uint16_t ff_mpeg4_studio_dc_chroma[19][2]={
|
||||
{0x00, 4}, {0x02, 4}, {0x07, 3}, {0x05, 3},
|
||||
{0x03, 3}, {0x02, 3}, {0x04, 3}, {0x06, 3},
|
||||
{0x01, 4}, {0x06, 5}, {0x0e, 6}, {0x1e, 7},
|
||||
{0x3e, 8}, {0x7e, 9}, {0xfe, 10}, {0x1fe, 11},
|
||||
{0x3fe, 12}, {0x7fe, 13}, {0x7ff, 13}
|
||||
};
|
||||
|
||||
const uint16_t ff_mpeg4_studio_intra[12][22][2]={
|
||||
{
|
||||
{0x05, 4}, {0x04, 4}, {0x05, 7}, {0x09, 9},
|
||||
{0x21, 11}, {0x41, 12}, {0x81, 13}, {0x03, 4},
|
||||
{0x03, 5}, {0x05, 6}, {0x04, 7}, {0x03, 7},
|
||||
{0x05, 8}, {0x03, 2}, {0x05, 3}, {0x04, 3},
|
||||
{0x03, 3}, {0x02, 4}, {0x04, 6}, {0x03, 6},
|
||||
{0x11, 10}, {0x80, 13}
|
||||
},
|
||||
{
|
||||
{0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
|
||||
{0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
|
||||
{0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0},
|
||||
{0x00, 0}, {0x00, 0}, {0x01, 1}, {0x01, 2},
|
||||
{0x01, 3}, {0x01, 4}, {0x01, 5}, {0x03, 7},
|
||||
{0x05, 8}, {0x04, 8}
|
||||
},
|
||||
{
|
||||
{0x05, 3}, {0x03, 5}, {0x02, 5}, {0x03, 7},
|
||||
{0x09, 9}, {0x103, 14}, {0x102, 14}, {0x04, 3},
|
||||
{0x03, 3}, {0x03, 4}, {0x02, 4}, {0x03, 6},
|
||||
{0x11, 10}, {0x03, 2}, {0x02, 3}, {0x02, 6},
|
||||
{0x05, 8}, {0x21, 11}, {0x83, 13}, {0x101, 14},
|
||||
{0x201, 15}, {0x82, 13}
|
||||
},
|
||||
{
|
||||
{0x05, 5}, {0x05, 4}, {0x04, 5}, {0x03, 6},
|
||||
{0x09, 9}, {0x83, 13}, {0x82, 13}, {0x03, 3},
|
||||
{0x04, 4}, {0x03, 4}, {0x03, 5}, {0x05, 8},
|
||||
{0x81, 13}, {0x03, 2}, {0x02, 2}, {0x02, 5},
|
||||
{0x02, 6}, {0x03, 7}, {0x11, 10}, {0x43, 12},
|
||||
{0x80, 13}, {0x42, 12}
|
||||
},
|
||||
{
|
||||
{0x05, 7}, {0x03, 4}, {0x03, 5}, {0x04, 7},
|
||||
{0x09, 9}, {0x83, 13}, {0x101, 14}, {0x03, 3},
|
||||
{0x02, 4}, {0x05, 6}, {0x03, 7}, {0x11, 10},
|
||||
{0x201, 15}, {0x03, 2}, {0x02, 2}, {0x02, 3},
|
||||
{0x04, 6}, {0x03, 6}, {0x05, 8}, {0x21, 11},
|
||||
{0x82, 13}, {0x81, 13}
|
||||
},
|
||||
{
|
||||
{0x13, 10}, {0x03, 5}, {0x05, 7}, {0x12, 10},
|
||||
{0x43, 12}, {0x83, 13}, {0x82, 13}, {0x02, 5},
|
||||
{0x04, 7}, {0x05, 8}, {0x23, 11}, {0x81, 13},
|
||||
{0x101, 14}, {0x03, 2}, {0x02, 2}, {0x01, 2},
|
||||
{0x01, 3}, {0x03, 6}, {0x03, 7}, {0x22, 11},
|
||||
{0x201, 15}, {0x42, 12}
|
||||
},
|
||||
{
|
||||
{0x23, 11}, {0x01, 4}, {0x07, 8}, {0x13, 10},
|
||||
{0x22, 11}, {0x103, 14}, {0x102, 14}, {0x03, 6},
|
||||
{0x06, 8}, {0x12, 10}, {0x43, 12}, {0x101, 14},
|
||||
{0x201, 15}, {0x03, 3}, {0x02, 3}, {0x03, 2},
|
||||
{0x02, 2}, {0x01, 3}, {0x02, 6}, {0x05, 8},
|
||||
{0x42, 12}, {0x41, 12}
|
||||
},
|
||||
{
|
||||
{0x0b, 9}, {0x03, 5}, {0x07, 8}, {0x07, 7},
|
||||
{0x06, 7}, {0x23, 11}, {0x41, 12}, {0x05, 7},
|
||||
{0x06, 8}, {0x0a, 9}, {0x13, 10}, {0x22, 11},
|
||||
{0x40, 12}, {0x03, 4}, {0x02, 4}, {0x03, 2},
|
||||
{0x02, 2}, {0x01, 2}, {0x02, 5}, {0x04, 7},
|
||||
{0x12, 10}, {0x21, 11}
|
||||
},
|
||||
{
|
||||
{0x15, 10}, {0x03, 6}, {0x14, 10}, {0x23, 11},
|
||||
{0x07, 8}, {0x43, 12}, {0x81, 13}, {0x06, 8},
|
||||
{0x0b, 9}, {0x13, 10}, {0x12, 10}, {0x42, 12},
|
||||
{0x80, 13}, {0x01, 4}, {0x03, 3}, {0x02, 3},
|
||||
{0x03, 2}, {0x02, 2}, {0x01, 3}, {0x02, 6},
|
||||
{0x22, 11}, {0x41, 12}
|
||||
},
|
||||
{
|
||||
{0x43, 12}, {0x05, 6}, {0x07, 8}, {0x04, 6},
|
||||
{0x03, 6}, {0x13, 10}, {0x42, 12}, {0x05, 7},
|
||||
{0x04, 7}, {0x06, 8}, {0x12, 10}, {0x41, 12},
|
||||
{0x40, 12}, {0x03, 5}, {0x03, 4}, {0x03, 3},
|
||||
{0x02, 3}, {0x03, 2}, {0x02, 2}, {0x02, 4},
|
||||
{0x05, 8}, {0x11, 10}
|
||||
},
|
||||
{
|
||||
{0x83, 13}, {0x05, 7}, {0x07, 8}, {0x03, 4},
|
||||
{0x21, 11}, {0x82, 13}, {0x81, 13}, {0x04, 7},
|
||||
{0x06, 8}, {0x0b, 9}, {0x0a, 9}, {0x11, 10},
|
||||
{0x80, 13}, {0x03, 5}, {0x02, 5}, {0x02, 4},
|
||||
{0x03, 3}, {0x02, 3}, {0x03, 2}, {0x02, 2},
|
||||
{0x03, 6}, {0x09, 9}
|
||||
},
|
||||
{
|
||||
{0x13, 10}, {0x03, 5}, {0x03, 6}, {0x0d, 9},
|
||||
{0x0c, 9}, {0x21, 11}, {0x20, 11}, {0x02, 5},
|
||||
{0x02, 6}, {0x07, 8}, {0x0b, 9}, {0x12, 10},
|
||||
{0x11, 10}, {0x05, 3}, {0x04, 3}, {0x05, 4},
|
||||
{0x04, 4}, {0x03, 4}, {0x02, 4}, {0x03, 3},
|
||||
{0x03, 2}, {0x0a, 9}
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* AVCODEC_MPEG4DATA_H */
|
||||
|
@ -61,6 +61,10 @@
|
||||
#define GOP_STARTCODE 0x1B3
|
||||
#define VISUAL_OBJ_STARTCODE 0x1B5
|
||||
#define VOP_STARTCODE 0x1B6
|
||||
#define SLICE_STARTCODE 0x1B7
|
||||
#define EXT_STARTCODE 0x1B8
|
||||
|
||||
#define QUANT_MATRIX_EXT_ID 0x3
|
||||
|
||||
/* smaller packets likely don't contain a real frame */
|
||||
#define MAX_NVOP_SIZE 19
|
||||
@ -108,8 +112,16 @@ typedef struct Mpeg4DecContext {
|
||||
int cplx_estimation_trash_i;
|
||||
int cplx_estimation_trash_p;
|
||||
int cplx_estimation_trash_b;
|
||||
|
||||
VLC studio_intra_tab[12];
|
||||
VLC studio_luma_dc;
|
||||
VLC studio_chroma_dc;
|
||||
|
||||
int rgb;
|
||||
} Mpeg4DecContext;
|
||||
|
||||
static const uint8_t mpeg4_block_count[4] = {0, 6, 8, 12};
|
||||
|
||||
/* dc encoding for MPEG-4 */
|
||||
extern const uint8_t ff_mpeg4_DCtab_lum[13][2];
|
||||
extern const uint8_t ff_mpeg4_DCtab_chrom[13][2];
|
||||
@ -137,6 +149,10 @@ extern const uint16_t ff_mpeg4_resync_prefix[8];
|
||||
|
||||
extern const uint8_t ff_mpeg4_dc_threshold[8];
|
||||
|
||||
extern const uint16_t ff_mpeg4_studio_dc_luma[19][2];
|
||||
extern const uint16_t ff_mpeg4_studio_dc_chroma[19][2];
|
||||
extern const uint16_t ff_mpeg4_studio_intra[12][22][2];
|
||||
|
||||
void ff_mpeg4_encode_mb(MpegEncContext *s,
|
||||
int16_t block[6][64],
|
||||
int motion_x, int motion_y);
|
||||
@ -155,6 +171,7 @@ void ff_clean_mpeg4_qscales(MpegEncContext *s);
|
||||
int ff_mpeg4_decode_partitions(Mpeg4DecContext *ctx);
|
||||
int ff_mpeg4_get_video_packet_prefix_length(MpegEncContext *s);
|
||||
int ff_mpeg4_decode_video_packet_header(Mpeg4DecContext *ctx);
|
||||
int ff_mpeg4_decode_studio_slice_header(Mpeg4DecContext *ctx);
|
||||
void ff_mpeg4_init_direct_mv(MpegEncContext *s);
|
||||
void ff_mpeg4videodec_static_init(void);
|
||||
int ff_mpeg4_workaround_bugs(AVCodecContext *avctx);
|
||||
|
@ -44,6 +44,7 @@
|
||||
#define SPRITE_TRAJ_VLC_BITS 6
|
||||
#define DC_VLC_BITS 9
|
||||
#define MB_TYPE_B_VLC_BITS 4
|
||||
#define STUDIO_INTRA_BITS 9
|
||||
|
||||
static VLC dc_lum, dc_chrom;
|
||||
static VLC sprite_trajectory;
|
||||
@ -528,6 +529,55 @@ int ff_mpeg4_decode_video_packet_header(Mpeg4DecContext *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void reset_studio_dc_predictors(MpegEncContext *s)
|
||||
{
|
||||
/* Reset DC Predictors */
|
||||
s->last_dc[0] =
|
||||
s->last_dc[1] =
|
||||
s->last_dc[2] = 1 << (s->avctx->bits_per_raw_sample + s->dct_precision + s->intra_dc_precision - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode the next video packet.
|
||||
* @return <0 if something went wrong
|
||||
*/
|
||||
int ff_mpeg4_decode_studio_slice_header(Mpeg4DecContext *ctx)
|
||||
{
|
||||
MpegEncContext *s = &ctx->m;
|
||||
GetBitContext *gb = &s->gb;
|
||||
unsigned vlc_len;
|
||||
uint16_t mb_num;
|
||||
|
||||
if (get_bits_left(gb) >= 32 && get_bits_long(gb, 32) == SLICE_START_CODE) {
|
||||
vlc_len = av_log2(s->mb_width * s->mb_height) + 1;
|
||||
mb_num = get_bits(gb, vlc_len);
|
||||
|
||||
if (mb_num >= s->mb_num)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
s->mb_x = mb_num % s->mb_width;
|
||||
s->mb_y = mb_num / s->mb_width;
|
||||
|
||||
if (ctx->shape != BIN_ONLY_SHAPE)
|
||||
s->qscale = mpeg_get_qscale(s);
|
||||
|
||||
if (get_bits1(gb)) { /* slice_extension_flag */
|
||||
skip_bits1(gb); /* intra_slice */
|
||||
skip_bits1(gb); /* slice_VOP_id_enable */
|
||||
skip_bits(gb, 6); /* slice_VOP_id */
|
||||
while (get_bits1(gb)) /* extra_bit_slice */
|
||||
skip_bits(gb, 8); /* extra_information_slice */
|
||||
}
|
||||
|
||||
reset_studio_dc_predictors(s);
|
||||
}
|
||||
else {
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the average motion vector for a GMC MB.
|
||||
* @param n either 0 for the x component or 1 for y
|
||||
@ -1723,6 +1773,189 @@ end:
|
||||
return SLICE_OK;
|
||||
}
|
||||
|
||||
/* As per spec, studio start code search isn't the same as the old type of start code */
|
||||
static void next_start_code_studio(GetBitContext *gb)
|
||||
{
|
||||
align_get_bits(gb);
|
||||
|
||||
while (get_bits_left(gb) >= 24 && show_bits_long(gb, 24) != 0x1) {
|
||||
get_bits(gb, 8);
|
||||
}
|
||||
}
|
||||
|
||||
/* additional_code, vlc index */
|
||||
static const uint8_t ac_state_tab[22][2] =
|
||||
{
|
||||
{0, 0},
|
||||
{0, 1},
|
||||
{1, 1},
|
||||
{2, 1},
|
||||
{3, 1},
|
||||
{4, 1},
|
||||
{5, 1},
|
||||
{1, 2},
|
||||
{2, 2},
|
||||
{3, 2},
|
||||
{4, 2},
|
||||
{5, 2},
|
||||
{6, 2},
|
||||
{1, 3},
|
||||
{2, 4},
|
||||
{3, 5},
|
||||
{4, 6},
|
||||
{5, 7},
|
||||
{6, 8},
|
||||
{7, 9},
|
||||
{8, 10},
|
||||
{0, 11}
|
||||
};
|
||||
|
||||
static int mpeg4_decode_studio_block(MpegEncContext *s, int32_t block[64], int n)
|
||||
{
|
||||
Mpeg4DecContext *ctx = s->avctx->priv_data;
|
||||
|
||||
int cc, dct_dc_size, dct_diff, code, j, idx = 1, group = 0, run = 0,
|
||||
additional_code_len, sign, mismatch;
|
||||
VLC *cur_vlc = &ctx->studio_intra_tab[0];
|
||||
uint8_t *const scantable = s->intra_scantable.permutated;
|
||||
const uint16_t *quant_matrix;
|
||||
uint32_t flc;
|
||||
const int min = -1 * (1 << (s->avctx->bits_per_raw_sample + 6));
|
||||
const int max = ((1 << (s->avctx->bits_per_raw_sample + 6)) - 1);
|
||||
|
||||
mismatch = 1;
|
||||
|
||||
memset(block, 0, 64 * sizeof(int32_t));
|
||||
|
||||
if (n < 4) {
|
||||
cc = 0;
|
||||
dct_dc_size = get_vlc2(&s->gb, ctx->studio_luma_dc.table, STUDIO_INTRA_BITS, 2);
|
||||
quant_matrix = s->intra_matrix;
|
||||
} else {
|
||||
cc = (n & 1) + 1;
|
||||
if (ctx->rgb)
|
||||
dct_dc_size = get_vlc2(&s->gb, ctx->studio_luma_dc.table, STUDIO_INTRA_BITS, 2);
|
||||
else
|
||||
dct_dc_size = get_vlc2(&s->gb, ctx->studio_chroma_dc.table, STUDIO_INTRA_BITS, 2);
|
||||
quant_matrix = s->chroma_intra_matrix;
|
||||
}
|
||||
|
||||
if (dct_dc_size < 0) {
|
||||
av_log(s->avctx, AV_LOG_ERROR, "illegal dct_dc_size vlc\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
} else if (dct_dc_size == 0) {
|
||||
dct_diff = 0;
|
||||
} else {
|
||||
dct_diff = get_xbits(&s->gb, dct_dc_size);
|
||||
|
||||
if (dct_dc_size > 8) {
|
||||
if(!check_marker(s->avctx, &s->gb, "dct_dc_size > 8"))
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
s->last_dc[cc] += dct_diff;
|
||||
|
||||
if (s->mpeg_quant)
|
||||
block[0] = s->last_dc[cc] * (8 >> s->intra_dc_precision);
|
||||
else
|
||||
block[0] = s->last_dc[cc] * (8 >> s->intra_dc_precision) * (8 >> s->dct_precision);
|
||||
/* TODO: support mpeg_quant for AC coefficients */
|
||||
|
||||
block[0] = av_clip(block[0], min, max);
|
||||
mismatch ^= block[0];
|
||||
|
||||
/* AC Coefficients */
|
||||
while (1) {
|
||||
group = get_vlc2(&s->gb, cur_vlc->table, STUDIO_INTRA_BITS, 2);
|
||||
|
||||
if (group < 0) {
|
||||
av_log(s->avctx, AV_LOG_ERROR, "illegal ac coefficient group vlc\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
additional_code_len = ac_state_tab[group][0];
|
||||
cur_vlc = &ctx->studio_intra_tab[ac_state_tab[group][1]];
|
||||
|
||||
if (group == 0) {
|
||||
/* End of Block */
|
||||
break;
|
||||
} else if (group >= 1 && group <= 6) {
|
||||
/* Zero run length (Table B.47) */
|
||||
run = 1 << additional_code_len;
|
||||
if (additional_code_len)
|
||||
run += get_bits(&s->gb, additional_code_len);
|
||||
idx += run;
|
||||
continue;
|
||||
} else if (group >= 7 && group <= 12) {
|
||||
/* Zero run length and +/-1 level (Table B.48) */
|
||||
code = get_bits(&s->gb, additional_code_len);
|
||||
sign = code & 1;
|
||||
code >>= 1;
|
||||
run = (1 << (additional_code_len - 1)) + code;
|
||||
idx += run;
|
||||
j = scantable[idx++];
|
||||
block[j] = sign ? 1 : -1;
|
||||
} else if (group >= 13 && group <= 20) {
|
||||
/* Level value (Table B.49) */
|
||||
j = scantable[idx++];
|
||||
block[j] = get_xbits(&s->gb, additional_code_len);
|
||||
} else if (group == 21) {
|
||||
/* Escape */
|
||||
j = scantable[idx++];
|
||||
additional_code_len = s->avctx->bits_per_raw_sample + s->dct_precision + 4;
|
||||
flc = get_bits(&s->gb, additional_code_len);
|
||||
if (flc >> (additional_code_len-1))
|
||||
block[j] = -1 * (( flc ^ ((1 << additional_code_len) -1)) + 1);
|
||||
else
|
||||
block[j] = flc;
|
||||
}
|
||||
block[j] = ((8 * 2 * block[j] * quant_matrix[j] * s->qscale) >> s->dct_precision) / 32;
|
||||
block[j] = av_clip(block[j], min, max);
|
||||
mismatch ^= block[j];
|
||||
}
|
||||
|
||||
block[63] ^= mismatch & 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpeg4_decode_studio_mb(MpegEncContext *s, int16_t block_[12][64])
|
||||
{
|
||||
int i;
|
||||
|
||||
/* StudioMacroblock */
|
||||
/* Assumes I-VOP */
|
||||
s->mb_intra = 1;
|
||||
if (get_bits1(&s->gb)) { /* compression_mode */
|
||||
/* DCT */
|
||||
/* macroblock_type, 1 or 2-bit VLC */
|
||||
if (!get_bits1(&s->gb)) {
|
||||
skip_bits1(&s->gb);
|
||||
s->qscale = mpeg_get_qscale(s);
|
||||
}
|
||||
|
||||
for (i = 0; i < mpeg4_block_count[s->chroma_format]; i++) {
|
||||
if (mpeg4_decode_studio_block(s, (*s->block32)[i], i) < 0)
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
} else {
|
||||
/* DPCM */
|
||||
check_marker(s->avctx, &s->gb, "DPCM block start");
|
||||
avpriv_request_sample(s->avctx, "DPCM encoded block");
|
||||
next_start_code_studio(&s->gb);
|
||||
return SLICE_ERROR;
|
||||
}
|
||||
|
||||
if (get_bits_left(&s->gb) >= 24 && show_bits(&s->gb, 23) == 0) {
|
||||
next_start_code_studio(&s->gb);
|
||||
return SLICE_END;
|
||||
}
|
||||
|
||||
return SLICE_OK;
|
||||
}
|
||||
|
||||
static int mpeg4_decode_gop_header(MpegEncContext *s, GetBitContext *gb)
|
||||
{
|
||||
int hours, minutes, seconds;
|
||||
@ -1791,6 +2024,23 @@ static int mpeg4_decode_visual_object(MpegEncContext *s, GetBitContext *gb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mpeg4_load_default_matrices(MpegEncContext *s)
|
||||
{
|
||||
int i, v;
|
||||
|
||||
/* load default matrices */
|
||||
for (i = 0; i < 64; i++) {
|
||||
int j = s->idsp.idct_permutation[i];
|
||||
v = ff_mpeg4_default_intra_matrix[i];
|
||||
s->intra_matrix[j] = v;
|
||||
s->chroma_intra_matrix[j] = v;
|
||||
|
||||
v = ff_mpeg4_default_non_intra_matrix[i];
|
||||
s->inter_matrix[j] = v;
|
||||
s->chroma_inter_matrix[j] = v;
|
||||
}
|
||||
}
|
||||
|
||||
static int decode_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb)
|
||||
{
|
||||
MpegEncContext *s = &ctx->m;
|
||||
@ -1954,17 +2204,7 @@ static int decode_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb)
|
||||
if ((s->mpeg_quant = get_bits1(gb))) { /* vol_quant_type */
|
||||
int i, v;
|
||||
|
||||
/* load default matrixes */
|
||||
for (i = 0; i < 64; i++) {
|
||||
int j = s->idsp.idct_permutation[i];
|
||||
v = ff_mpeg4_default_intra_matrix[i];
|
||||
s->intra_matrix[j] = v;
|
||||
s->chroma_intra_matrix[j] = v;
|
||||
|
||||
v = ff_mpeg4_default_non_intra_matrix[i];
|
||||
s->inter_matrix[j] = v;
|
||||
s->chroma_inter_matrix[j] = v;
|
||||
}
|
||||
mpeg4_load_default_matrices(s);
|
||||
|
||||
/* load custom intra matrix */
|
||||
if (get_bits1(gb)) {
|
||||
@ -2608,6 +2848,232 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void read_quant_matrix_ext(MpegEncContext *s, GetBitContext *gb)
|
||||
{
|
||||
int i, j, v;
|
||||
|
||||
if (get_bits1(gb)) {
|
||||
/* intra_quantiser_matrix */
|
||||
for (i = 0; i < 64; i++) {
|
||||
v = get_bits(gb, 8);
|
||||
j = s->idsp.idct_permutation[ff_zigzag_direct[i]];
|
||||
s->intra_matrix[j] = v;
|
||||
s->chroma_intra_matrix[j] = v;
|
||||
}
|
||||
}
|
||||
|
||||
if (get_bits1(gb)) {
|
||||
/* non_intra_quantiser_matrix */
|
||||
for (i = 0; i < 64; i++) {
|
||||
get_bits(gb, 8);
|
||||
}
|
||||
}
|
||||
|
||||
if (get_bits1(gb)) {
|
||||
/* chroma_intra_quantiser_matrix */
|
||||
for (i = 0; i < 64; i++) {
|
||||
v = get_bits(gb, 8);
|
||||
j = s->idsp.idct_permutation[ff_zigzag_direct[i]];
|
||||
s->chroma_intra_matrix[j] = v;
|
||||
}
|
||||
}
|
||||
|
||||
if (get_bits1(gb)) {
|
||||
/* chroma_non_intra_quantiser_matrix */
|
||||
for (i = 0; i < 64; i++) {
|
||||
get_bits(gb, 8);
|
||||
}
|
||||
}
|
||||
|
||||
next_start_code_studio(gb);
|
||||
}
|
||||
|
||||
static void extension_and_user_data(MpegEncContext *s, GetBitContext *gb, int id)
|
||||
{
|
||||
uint32_t startcode;
|
||||
uint8_t extension_type;
|
||||
|
||||
startcode = show_bits_long(gb, 32);
|
||||
if (startcode == USER_DATA_STARTCODE || startcode == EXT_STARTCODE) {
|
||||
|
||||
if ((id == 2 || id == 4) && startcode == EXT_STARTCODE) {
|
||||
skip_bits_long(gb, 32);
|
||||
extension_type = get_bits(gb, 4);
|
||||
if (extension_type == QUANT_MATRIX_EXT_ID)
|
||||
read_quant_matrix_ext(s, gb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void decode_smpte_tc(Mpeg4DecContext *ctx, GetBitContext *gb)
|
||||
{
|
||||
MpegEncContext *s = &ctx->m;
|
||||
|
||||
skip_bits(gb, 16); /* Time_code[63..48] */
|
||||
check_marker(s->avctx, gb, "after Time_code[63..48]");
|
||||
skip_bits(gb, 16); /* Time_code[47..32] */
|
||||
check_marker(s->avctx, gb, "after Time_code[47..32]");
|
||||
skip_bits(gb, 16); /* Time_code[31..16] */
|
||||
check_marker(s->avctx, gb, "after Time_code[31..16]");
|
||||
skip_bits(gb, 16); /* Time_code[15..0] */
|
||||
check_marker(s->avctx, gb, "after Time_code[15..0]");
|
||||
skip_bits(gb, 4); /* reserved_bits */
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode the next studio vop header.
|
||||
* @return <0 if something went wrong
|
||||
*/
|
||||
static int decode_studio_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb)
|
||||
{
|
||||
MpegEncContext *s = &ctx->m;
|
||||
|
||||
if (get_bits_left(gb) <= 32)
|
||||
return 0;
|
||||
|
||||
if (get_bits_long(gb, 32) != VOP_STARTCODE)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
s->decode_mb = mpeg4_decode_studio_mb;
|
||||
|
||||
decode_smpte_tc(ctx, gb);
|
||||
|
||||
skip_bits(gb, 10); /* temporal_reference */
|
||||
skip_bits(gb, 2); /* vop_structure */
|
||||
s->pict_type = get_bits(gb, 2) + AV_PICTURE_TYPE_I; /* vop_coding_type */
|
||||
if (get_bits1(gb)) { /* vop_coded */
|
||||
skip_bits1(gb); /* top_field_first */
|
||||
skip_bits1(gb); /* repeat_first_field */
|
||||
s->progressive_frame = get_bits1(gb) ^ 1; /* progressive_frame */
|
||||
}
|
||||
|
||||
if (s->pict_type == AV_PICTURE_TYPE_I) {
|
||||
if (get_bits1(gb))
|
||||
reset_studio_dc_predictors(s);
|
||||
}
|
||||
|
||||
if (ctx->shape != BIN_ONLY_SHAPE) {
|
||||
s->alternate_scan = get_bits1(gb);
|
||||
s->frame_pred_frame_dct = get_bits1(gb);
|
||||
s->dct_precision = get_bits(gb, 2);
|
||||
s->intra_dc_precision = get_bits(gb, 2);
|
||||
s->q_scale_type = get_bits1(gb);
|
||||
}
|
||||
|
||||
if (s->alternate_scan) {
|
||||
ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_alternate_vertical_scan);
|
||||
ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_alternate_vertical_scan);
|
||||
ff_init_scantable(s->idsp.idct_permutation, &s->intra_h_scantable, ff_alternate_vertical_scan);
|
||||
ff_init_scantable(s->idsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan);
|
||||
} else {
|
||||
ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_zigzag_direct);
|
||||
ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_zigzag_direct);
|
||||
ff_init_scantable(s->idsp.idct_permutation, &s->intra_h_scantable, ff_alternate_horizontal_scan);
|
||||
ff_init_scantable(s->idsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan);
|
||||
}
|
||||
|
||||
mpeg4_load_default_matrices(s);
|
||||
|
||||
next_start_code_studio(gb);
|
||||
extension_and_user_data(s, gb, 4);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decode_studiovisualobject(Mpeg4DecContext *ctx, GetBitContext *gb)
|
||||
{
|
||||
uint32_t startcode;
|
||||
MpegEncContext *s = &ctx->m;
|
||||
int visual_object_type, width, height;
|
||||
|
||||
startcode = get_bits_long(gb, 32);
|
||||
|
||||
/* StudioVisualObject() */
|
||||
if (startcode == VISUAL_OBJ_STARTCODE) {
|
||||
skip_bits(gb, 4); /* visual_object_verid */
|
||||
visual_object_type = get_bits(gb, 4);
|
||||
|
||||
next_start_code_studio(gb);
|
||||
extension_and_user_data(s, gb, 1);
|
||||
|
||||
if (visual_object_type == VOT_VIDEO_ID) {
|
||||
/* StudioVideoObjectLayer */
|
||||
skip_bits_long(gb, 32); /* video_object_start_code */
|
||||
skip_bits_long(gb, 32); /* video_object_layer_start_code */
|
||||
skip_bits1(gb); /* random_accessible_vol */
|
||||
skip_bits(gb, 8); /* video_object_type_indication */
|
||||
skip_bits(gb, 4); /* video_object_layer_verid */
|
||||
ctx->shape = get_bits(gb, 2); /* video_object_layer_shape */
|
||||
skip_bits(gb, 4); /* video_object_layer_shape_extension */
|
||||
skip_bits1(gb); /* progressive_sequence */
|
||||
if (ctx->shape != BIN_ONLY_SHAPE) {
|
||||
ctx->rgb = get_bits1(gb); /* rgb_components */
|
||||
s->chroma_format = get_bits(gb, 2); /* chroma_format */
|
||||
if (!s->chroma_format) {
|
||||
av_log(s->avctx, AV_LOG_ERROR, "illegal chroma format\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
s->avctx->bits_per_raw_sample = get_bits(gb, 4); /* bit_depth */
|
||||
if (s->avctx->bits_per_raw_sample == 10) {
|
||||
if (ctx->rgb) {
|
||||
s->avctx->pix_fmt = AV_PIX_FMT_GBRP10;
|
||||
}
|
||||
else {
|
||||
s->avctx->pix_fmt = s->chroma_format == CHROMA_422 ? AV_PIX_FMT_YUV422P10 : AV_PIX_FMT_YUV444P10;
|
||||
}
|
||||
}
|
||||
else {
|
||||
avpriv_request_sample(s->avctx, "MPEG-4 Studio profile bit-depth %u", s->avctx->bits_per_raw_sample);
|
||||
return AVERROR_PATCHWELCOME;
|
||||
}
|
||||
}
|
||||
if (ctx->shape == RECT_SHAPE) {
|
||||
check_marker(s->avctx, gb, "before video_object_layer_width");
|
||||
width = get_bits(gb, 14); /* video_object_layer_width */
|
||||
check_marker(s->avctx, gb, "before video_object_layer_height");
|
||||
height = get_bits(gb, 14); /* video_object_layer_height */
|
||||
check_marker(s->avctx, gb, "after video_object_layer_height");
|
||||
|
||||
/* Do the same check as non-studio profile */
|
||||
if (width && height) {
|
||||
if (s->width && s->height &&
|
||||
(s->width != width || s->height != height))
|
||||
s->context_reinit = 1;
|
||||
s->width = width;
|
||||
s->height = height;
|
||||
}
|
||||
}
|
||||
s->aspect_ratio_info = get_bits(gb, 4);
|
||||
if (s->aspect_ratio_info == FF_ASPECT_EXTENDED) {
|
||||
s->avctx->sample_aspect_ratio.num = get_bits(gb, 8); // par_width
|
||||
s->avctx->sample_aspect_ratio.den = get_bits(gb, 8); // par_height
|
||||
} else {
|
||||
s->avctx->sample_aspect_ratio = ff_h263_pixel_aspect[s->aspect_ratio_info];
|
||||
}
|
||||
skip_bits(gb, 4); /* frame_rate_code */
|
||||
skip_bits(gb, 15); /* first_half_bit_rate */
|
||||
check_marker(s->avctx, gb, "after first_half_bit_rate");
|
||||
skip_bits(gb, 15); /* latter_half_bit_rate */
|
||||
check_marker(s->avctx, gb, "after latter_half_bit_rate");
|
||||
skip_bits(gb, 15); /* first_half_vbv_buffer_size */
|
||||
check_marker(s->avctx, gb, "after first_half_vbv_buffer_size");
|
||||
skip_bits(gb, 3); /* latter_half_vbv_buffer_size */
|
||||
skip_bits(gb, 11); /* first_half_vbv_buffer_size */
|
||||
check_marker(s->avctx, gb, "after first_half_vbv_buffer_size");
|
||||
skip_bits(gb, 15); /* latter_half_vbv_occupancy */
|
||||
check_marker(s->avctx, gb, "after latter_half_vbv_occupancy");
|
||||
s->low_delay = get_bits1(gb);
|
||||
s->mpeg_quant = get_bits1(gb); /* mpeg2_stream */
|
||||
|
||||
next_start_code_studio(gb);
|
||||
extension_and_user_data(s, gb, 2);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode MPEG-4 headers.
|
||||
* @return <0 if no VOP found (or a damaged one)
|
||||
@ -2721,6 +3187,16 @@ int ff_mpeg4_decode_picture_header(Mpeg4DecContext *ctx, GetBitContext *gb)
|
||||
mpeg4_decode_gop_header(s, gb);
|
||||
} else if (startcode == VOS_STARTCODE) {
|
||||
mpeg4_decode_profile_level(s, gb);
|
||||
if (s->avctx->profile == FF_PROFILE_MPEG4_SIMPLE_STUDIO &&
|
||||
(s->avctx->level > 0 && s->avctx->level < 9)) {
|
||||
s->studio_profile = 1;
|
||||
next_start_code_studio(gb);
|
||||
extension_and_user_data(s, gb, 0);
|
||||
|
||||
if ((ret = decode_studiovisualobject(ctx, gb)) < 0)
|
||||
return ret;
|
||||
break;
|
||||
}
|
||||
} else if (startcode == VISUAL_OBJ_STARTCODE) {
|
||||
mpeg4_decode_visual_object(s, gb);
|
||||
} else if (startcode == VOP_STARTCODE) {
|
||||
@ -2736,7 +3212,10 @@ end:
|
||||
s->low_delay = 1;
|
||||
s->avctx->has_b_frames = !s->low_delay;
|
||||
|
||||
return decode_vop_header(ctx, gb);
|
||||
if (s->studio_profile)
|
||||
return decode_studio_vop_header(ctx, gb);
|
||||
else
|
||||
return decode_vop_header(ctx, gb);
|
||||
}
|
||||
|
||||
av_cold void ff_mpeg4videodec_static_init(void) {
|
||||
@ -2836,6 +3315,37 @@ static int mpeg4_update_thread_context(AVCodecContext *dst,
|
||||
}
|
||||
#endif
|
||||
|
||||
static av_cold int init_studio_vlcs(Mpeg4DecContext *ctx)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < 12; i++) {
|
||||
ret = init_vlc(&ctx->studio_intra_tab[i], STUDIO_INTRA_BITS, 22,
|
||||
&ff_mpeg4_studio_intra[i][0][1], 4, 2,
|
||||
&ff_mpeg4_studio_intra[i][0][0], 4, 2,
|
||||
0);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = init_vlc(&ctx->studio_luma_dc, STUDIO_INTRA_BITS, 19,
|
||||
&ff_mpeg4_studio_dc_luma[0][1], 4, 2,
|
||||
&ff_mpeg4_studio_dc_luma[0][0], 4, 2,
|
||||
0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = init_vlc(&ctx->studio_chroma_dc, STUDIO_INTRA_BITS, 19,
|
||||
&ff_mpeg4_studio_dc_chroma[0][1], 4, 2,
|
||||
&ff_mpeg4_studio_dc_chroma[0][0], 4, 2,
|
||||
0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_cold int decode_init(AVCodecContext *avctx)
|
||||
{
|
||||
Mpeg4DecContext *ctx = avctx->priv_data;
|
||||
@ -2851,6 +3361,8 @@ static av_cold int decode_init(AVCodecContext *avctx)
|
||||
return ret;
|
||||
|
||||
ff_mpeg4videodec_static_init();
|
||||
if ((ret = init_studio_vlcs(ctx)) < 0)
|
||||
return ret;
|
||||
|
||||
s->h263_pred = 1;
|
||||
s->low_delay = 0; /* default, might be overridden in the vol header during header parsing */
|
||||
|
@ -386,6 +386,9 @@ static int init_duplicate_context(MpegEncContext *s)
|
||||
for (i = 0; i < 12; i++) {
|
||||
s->pblocks[i] = &s->block[i];
|
||||
}
|
||||
|
||||
FF_ALLOCZ_OR_GOTO(s->avctx, s->block32, sizeof(*s->block32), fail)
|
||||
|
||||
if (s->avctx->codec_tag == AV_RL32("VCR2")) {
|
||||
// exchange uv
|
||||
FFSWAP(void *, s->pblocks[4], s->pblocks[5]);
|
||||
@ -421,6 +424,7 @@ static void free_duplicate_context(MpegEncContext *s)
|
||||
av_freep(&s->me.map);
|
||||
av_freep(&s->me.score_map);
|
||||
av_freep(&s->blocks);
|
||||
av_freep(&s->block32);
|
||||
av_freep(&s->ac_val_base);
|
||||
s->block = NULL;
|
||||
}
|
||||
@ -438,6 +442,7 @@ static void backup_duplicate_context(MpegEncContext *bak, MpegEncContext *src)
|
||||
COPY(me.score_map);
|
||||
COPY(blocks);
|
||||
COPY(block);
|
||||
COPY(block32);
|
||||
COPY(start_mb_y);
|
||||
COPY(end_mb_y);
|
||||
COPY(me.map_generation);
|
||||
@ -811,6 +816,7 @@ static void clear_context(MpegEncContext *s)
|
||||
s->dct_error_sum = NULL;
|
||||
s->block = NULL;
|
||||
s->blocks = NULL;
|
||||
s->block32 = NULL;
|
||||
memset(s->pblocks, 0, sizeof(s->pblocks));
|
||||
s->ac_val_base = NULL;
|
||||
s->ac_val[0] =
|
||||
@ -2120,8 +2126,31 @@ void mpv_reconstruct_mb_internal(MpegEncContext *s, int16_t block[12][64],
|
||||
ff_wmv2_add_mb(s, block, dest_y, dest_cb, dest_cr);
|
||||
}
|
||||
} else {
|
||||
/* Only MPEG-4 Simple Studio Profile is supported in > 8-bit mode.
|
||||
TODO: Integrate 10-bit properly into mpegvideo.c so that ER works properly */
|
||||
if (s->avctx->bits_per_raw_sample > 8){
|
||||
const int act_block_size = block_size * 2;
|
||||
s->idsp.idct_put(dest_y, dct_linesize, (int16_t*)(*s->block32)[0]);
|
||||
s->idsp.idct_put(dest_y + act_block_size, dct_linesize, (int16_t*)(*s->block32)[1]);
|
||||
s->idsp.idct_put(dest_y + dct_offset, dct_linesize, (int16_t*)(*s->block32)[2]);
|
||||
s->idsp.idct_put(dest_y + dct_offset + act_block_size, dct_linesize, (int16_t*)(*s->block32)[3]);
|
||||
|
||||
dct_linesize = uvlinesize << s->interlaced_dct;
|
||||
dct_offset = s->interlaced_dct ? uvlinesize : uvlinesize*block_size;
|
||||
|
||||
s->idsp.idct_put(dest_cb, dct_linesize, (int16_t*)(*s->block32)[4]);
|
||||
s->idsp.idct_put(dest_cr, dct_linesize, (int16_t*)(*s->block32)[5]);
|
||||
s->idsp.idct_put(dest_cb + dct_offset, dct_linesize, (int16_t*)(*s->block32)[6]);
|
||||
s->idsp.idct_put(dest_cr + dct_offset, dct_linesize, (int16_t*)(*s->block32)[7]);
|
||||
if(!s->chroma_x_shift){//Chroma444
|
||||
s->idsp.idct_put(dest_cb + act_block_size, dct_linesize, (int16_t*)(*s->block32)[8]);
|
||||
s->idsp.idct_put(dest_cr + act_block_size, dct_linesize, (int16_t*)(*s->block32)[9]);
|
||||
s->idsp.idct_put(dest_cb + act_block_size + dct_offset, dct_linesize, (int16_t*)(*s->block32)[10]);
|
||||
s->idsp.idct_put(dest_cr + act_block_size + dct_offset, dct_linesize, (int16_t*)(*s->block32)[11]);
|
||||
}
|
||||
}
|
||||
/* dct only in intra block */
|
||||
if(s->encoding || !(s->codec_id==AV_CODEC_ID_MPEG1VIDEO || s->codec_id==AV_CODEC_ID_MPEG2VIDEO)){
|
||||
else if(s->encoding || !(s->codec_id==AV_CODEC_ID_MPEG1VIDEO || s->codec_id==AV_CODEC_ID_MPEG2VIDEO)){
|
||||
put_dct(s, block[0], 0, dest_y , dct_linesize, s->qscale);
|
||||
put_dct(s, block[1], 1, dest_y + block_size, dct_linesize, s->qscale);
|
||||
put_dct(s, block[2], 2, dest_y + dct_offset , dct_linesize, s->qscale);
|
||||
@ -2202,7 +2231,8 @@ void ff_mpeg_draw_horiz_band(MpegEncContext *s, int y, int h)
|
||||
void ff_init_block_index(MpegEncContext *s){ //FIXME maybe rename
|
||||
const int linesize = s->current_picture.f->linesize[0]; //not s->linesize as this would be wrong for field pics
|
||||
const int uvlinesize = s->current_picture.f->linesize[1];
|
||||
const int mb_size= 4 - s->avctx->lowres;
|
||||
const int width_of_mb = (4 + (s->avctx->bits_per_raw_sample > 8)) - s->avctx->lowres;
|
||||
const int height_of_mb = 4 - s->avctx->lowres;
|
||||
|
||||
s->block_index[0]= s->b8_stride*(s->mb_y*2 ) - 2 + s->mb_x*2;
|
||||
s->block_index[1]= s->b8_stride*(s->mb_y*2 ) - 1 + s->mb_x*2;
|
||||
@ -2212,20 +2242,20 @@ void ff_init_block_index(MpegEncContext *s){ //FIXME maybe rename
|
||||
s->block_index[5]= s->mb_stride*(s->mb_y + s->mb_height + 2) + s->b8_stride*s->mb_height*2 + s->mb_x - 1;
|
||||
//block_index is not used by mpeg2, so it is not affected by chroma_format
|
||||
|
||||
s->dest[0] = s->current_picture.f->data[0] + (int)((s->mb_x - 1U) << mb_size);
|
||||
s->dest[1] = s->current_picture.f->data[1] + (int)((s->mb_x - 1U) << (mb_size - s->chroma_x_shift));
|
||||
s->dest[2] = s->current_picture.f->data[2] + (int)((s->mb_x - 1U) << (mb_size - s->chroma_x_shift));
|
||||
s->dest[0] = s->current_picture.f->data[0] + (int)((s->mb_x - 1U) << width_of_mb);
|
||||
s->dest[1] = s->current_picture.f->data[1] + (int)((s->mb_x - 1U) << (width_of_mb - s->chroma_x_shift));
|
||||
s->dest[2] = s->current_picture.f->data[2] + (int)((s->mb_x - 1U) << (width_of_mb - s->chroma_x_shift));
|
||||
|
||||
if(!(s->pict_type==AV_PICTURE_TYPE_B && s->avctx->draw_horiz_band && s->picture_structure==PICT_FRAME))
|
||||
{
|
||||
if(s->picture_structure==PICT_FRAME){
|
||||
s->dest[0] += s->mb_y * linesize << mb_size;
|
||||
s->dest[1] += s->mb_y * uvlinesize << (mb_size - s->chroma_y_shift);
|
||||
s->dest[2] += s->mb_y * uvlinesize << (mb_size - s->chroma_y_shift);
|
||||
s->dest[0] += s->mb_y * linesize << height_of_mb;
|
||||
s->dest[1] += s->mb_y * uvlinesize << (height_of_mb - s->chroma_y_shift);
|
||||
s->dest[2] += s->mb_y * uvlinesize << (height_of_mb - s->chroma_y_shift);
|
||||
}else{
|
||||
s->dest[0] += (s->mb_y>>1) * linesize << mb_size;
|
||||
s->dest[1] += (s->mb_y>>1) * uvlinesize << (mb_size - s->chroma_y_shift);
|
||||
s->dest[2] += (s->mb_y>>1) * uvlinesize << (mb_size - s->chroma_y_shift);
|
||||
s->dest[0] += (s->mb_y>>1) * linesize << height_of_mb;
|
||||
s->dest[1] += (s->mb_y>>1) * uvlinesize << (height_of_mb - s->chroma_y_shift);
|
||||
s->dest[2] += (s->mb_y>>1) * uvlinesize << (height_of_mb - s->chroma_y_shift);
|
||||
av_assert1((s->mb_y&1) == (s->picture_structure == PICT_BOTTOM_FIELD));
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "mpegpicture.h"
|
||||
#include "mpegvideodsp.h"
|
||||
#include "mpegvideoencdsp.h"
|
||||
#include "mpegvideodata.h"
|
||||
#include "pixblockdsp.h"
|
||||
#include "put_bits.h"
|
||||
#include "ratecontrol.h"
|
||||
@ -71,6 +72,8 @@
|
||||
#define SLICE_MAX_START_CODE 0x000001af
|
||||
#define EXT_START_CODE 0x000001b5
|
||||
#define USER_START_CODE 0x000001b2
|
||||
#define SLICE_START_CODE 0x000001b7
|
||||
|
||||
|
||||
/**
|
||||
* MpegEncContext.
|
||||
@ -378,6 +381,8 @@ typedef struct MpegEncContext {
|
||||
int custom_pcf;
|
||||
|
||||
/* MPEG-4 specific */
|
||||
int studio_profile;
|
||||
int dct_precision;
|
||||
///< number of bits to represent the fractional part of time (encoder only)
|
||||
int time_increment_bits;
|
||||
int last_time_base;
|
||||
@ -501,7 +506,10 @@ typedef struct MpegEncContext {
|
||||
|
||||
int16_t (*block)[64]; ///< points to one of the following blocks
|
||||
int16_t (*blocks)[12][64]; // for HQ mode we need to keep the best block
|
||||
int (*decode_mb)(struct MpegEncContext *s, int16_t block[6][64]); // used by some codecs to avoid a switch()
|
||||
int (*decode_mb)(struct MpegEncContext *s, int16_t block[12][64]); // used by some codecs to avoid a switch()
|
||||
|
||||
int32_t (*block32)[12][64];
|
||||
|
||||
#define SLICE_OK 0
|
||||
#define SLICE_ERROR -1
|
||||
#define SLICE_END -2 ///<end marker found
|
||||
@ -729,7 +737,8 @@ void ff_mpv_motion(MpegEncContext *s,
|
||||
qpel_mc_func (*qpix_op)[16]);
|
||||
|
||||
static inline void ff_update_block_index(MpegEncContext *s){
|
||||
const int block_size= 8 >> s->avctx->lowres;
|
||||
const int bytes_per_pixel = 1 + (s->avctx->bits_per_raw_sample > 8);
|
||||
const int block_size= (8*bytes_per_pixel) >> s->avctx->lowres;
|
||||
|
||||
s->block_index[0]+=2;
|
||||
s->block_index[1]+=2;
|
||||
@ -738,8 +747,8 @@ static inline void ff_update_block_index(MpegEncContext *s){
|
||||
s->block_index[4]++;
|
||||
s->block_index[5]++;
|
||||
s->dest[0]+= 2*block_size;
|
||||
s->dest[1]+= block_size;
|
||||
s->dest[2]+= block_size;
|
||||
s->dest[1]+= (2 >> s->chroma_x_shift) * block_size;
|
||||
s->dest[2]+= (2 >> s->chroma_x_shift) * block_size;
|
||||
}
|
||||
|
||||
static inline int get_bits_diff(MpegEncContext *s){
|
||||
@ -751,4 +760,13 @@ static inline int get_bits_diff(MpegEncContext *s){
|
||||
return bits - last;
|
||||
}
|
||||
|
||||
static inline int mpeg_get_qscale(MpegEncContext *s)
|
||||
{
|
||||
int qscale = get_bits(&s->gb, 5);
|
||||
if (s->q_scale_type)
|
||||
return ff_mpeg2_non_linear_qscale[qscale];
|
||||
else
|
||||
return qscale << 1;
|
||||
}
|
||||
|
||||
#endif /* AVCODEC_MPEGVIDEO_H */
|
||||
|
@ -123,6 +123,7 @@ av_cold void ff_idctdsp_init_x86(IDCTDSPContext *c, AVCodecContext *avctx,
|
||||
}
|
||||
|
||||
if (avctx->bits_per_raw_sample == 10 &&
|
||||
avctx->codec_id != AV_CODEC_ID_MPEG4 &&
|
||||
(avctx->idct_algo == FF_IDCT_AUTO ||
|
||||
avctx->idct_algo == FF_IDCT_SIMPLEAUTO ||
|
||||
avctx->idct_algo == FF_IDCT_SIMPLE)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user