|
|
|
@ -25,6 +25,7 @@ |
|
|
|
|
* @author Michael Niedermayer <michaelni@gmx.at> |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
#include "libavutil/avassert.h" |
|
|
|
|
#include "libavutil/imgutils.h" |
|
|
|
|
#include "internal.h" |
|
|
|
|
#include "cabac.h" |
|
|
|
@ -43,7 +44,6 @@ |
|
|
|
|
#include "svq3.h" |
|
|
|
|
#include "thread.h" |
|
|
|
|
#include "vdpau_internal.h" |
|
|
|
|
#include "libavutil/avassert.h" |
|
|
|
|
|
|
|
|
|
// #undef NDEBUG
|
|
|
|
|
#include <assert.h> |
|
|
|
@ -213,7 +213,6 @@ static int ref_picture(H264Context *h, Picture *dst, Picture *src) |
|
|
|
|
if (ret < 0) |
|
|
|
|
goto fail; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dst->qscale_table_buf = av_buffer_ref(src->qscale_table_buf); |
|
|
|
|
dst->mb_type_buf = av_buffer_ref(src->mb_type_buf); |
|
|
|
|
if (!dst->qscale_table_buf || !dst->mb_type_buf) |
|
|
|
@ -259,7 +258,6 @@ fail: |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int alloc_scratch_buffers(H264Context *h, int linesize) |
|
|
|
|
{ |
|
|
|
|
int alloc_size = FFALIGN(FFABS(linesize) + 32, 32); |
|
|
|
@ -510,12 +508,14 @@ const uint8_t *ff_h264_decode_nal(H264Context *h, const uint8_t *src, |
|
|
|
|
} \
|
|
|
|
|
break; \
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if HAVE_FAST_UNALIGNED |
|
|
|
|
#define FIND_FIRST_ZERO \ |
|
|
|
|
if (i > 0 && !src[i]) \
|
|
|
|
|
i--; \
|
|
|
|
|
while (src[i]) \
|
|
|
|
|
i++ |
|
|
|
|
|
|
|
|
|
#if HAVE_FAST_64BIT |
|
|
|
|
for (i = 0; i + 1 < length; i += 9) { |
|
|
|
|
if (!((~AV_RN64A(src + i) & |
|
|
|
@ -583,8 +583,8 @@ const uint8_t *ff_h264_decode_nal(H264Context *h, const uint8_t *src, |
|
|
|
|
} |
|
|
|
|
while (si < length) |
|
|
|
|
dst[di++] = src[si++]; |
|
|
|
|
nsc: |
|
|
|
|
|
|
|
|
|
nsc: |
|
|
|
|
memset(dst + di, 0, FF_INPUT_BUFFER_PADDING_SIZE); |
|
|
|
|
|
|
|
|
|
*dst_length = di; |
|
|
|
@ -2338,7 +2338,8 @@ static av_always_inline void hl_decode_mb_predict_luma(H264Context *h, |
|
|
|
|
0 * 16, 1 * 16, 4 * 16, 5 * 16, |
|
|
|
|
2 * 16, 3 * 16, 6 * 16, 7 * 16, |
|
|
|
|
8 * 16, 9 * 16, 12 * 16, 13 * 16, |
|
|
|
|
10 * 16, 11 * 16, 14 * 16, 15 * 16 }; |
|
|
|
|
10 * 16, 11 * 16, 14 * 16, 15 * 16 |
|
|
|
|
}; |
|
|
|
|
for (i = 0; i < 16; i++) |
|
|
|
|
dctcoef_set(h->mb + (p * 256 << pixel_shift), |
|
|
|
|
pixel_shift, dc_mapping[i], |
|
|
|
@ -2438,7 +2439,8 @@ void ff_h264_hl_decode_mb(H264Context *h) |
|
|
|
|
{ |
|
|
|
|
const int mb_xy = h->mb_xy; |
|
|
|
|
const int mb_type = h->cur_pic.mb_type[mb_xy]; |
|
|
|
|
int is_complex = CONFIG_SMALL || h->is_complex || IS_INTRA_PCM(mb_type) || h->qscale == 0; |
|
|
|
|
int is_complex = CONFIG_SMALL || h->is_complex || |
|
|
|
|
IS_INTRA_PCM(mb_type) || h->qscale == 0; |
|
|
|
|
|
|
|
|
|
if (CHROMA444(h)) { |
|
|
|
|
if (is_complex || h->pixel_shift) |
|
|
|
@ -2654,9 +2656,11 @@ int ff_init_poc(H264Context *h, int pic_field_poc[2], int *pic_poc) |
|
|
|
|
if (h->sps.poc_type == 0) { |
|
|
|
|
const int max_poc_lsb = 1 << h->sps.log2_max_poc_lsb; |
|
|
|
|
|
|
|
|
|
if (h->poc_lsb < h->prev_poc_lsb && h->prev_poc_lsb - h->poc_lsb >= max_poc_lsb / 2) |
|
|
|
|
if (h->poc_lsb < h->prev_poc_lsb && |
|
|
|
|
h->prev_poc_lsb - h->poc_lsb >= max_poc_lsb / 2) |
|
|
|
|
h->poc_msb = h->prev_poc_msb + max_poc_lsb; |
|
|
|
|
else if (h->poc_lsb > h->prev_poc_lsb && h->prev_poc_lsb - h->poc_lsb < -max_poc_lsb / 2) |
|
|
|
|
else if (h->poc_lsb > h->prev_poc_lsb && |
|
|
|
|
h->prev_poc_lsb - h->poc_lsb < -max_poc_lsb / 2) |
|
|
|
|
h->poc_msb = h->prev_poc_msb - max_poc_lsb; |
|
|
|
|
else |
|
|
|
|
h->poc_msb = h->prev_poc_msb; |
|
|
|
@ -3250,7 +3254,6 @@ static int decode_slice_header(H264Context *h, H264Context *h0) |
|
|
|
|
(h->width != h->avctx->coded_width || |
|
|
|
|
h->height != h->avctx->coded_height || |
|
|
|
|
needs_reinit)) { |
|
|
|
|
|
|
|
|
|
if (h != h0) { |
|
|
|
|
av_log(h->avctx, AV_LOG_ERROR, "changing width/height on " |
|
|
|
|
"slice %d\n", h0->current_slice + 1); |
|
|
|
@ -3417,17 +3420,22 @@ static int decode_slice_header(H264Context *h, H264Context *h0) |
|
|
|
|
if (ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index) < 0 && |
|
|
|
|
(h->avctx->err_recognition & AV_EF_EXPLODE)) |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
/* Error concealment: if a ref is missing, copy the previous ref in its place.
|
|
|
|
|
* FIXME: avoiding a memcpy would be nice, but ref handling makes many assumptions |
|
|
|
|
* about there being no actual duplicates. |
|
|
|
|
* FIXME: this doesn't copy padding for out-of-frame motion vectors. Given we're |
|
|
|
|
* concealing a lost frame, this probably isn't noticeable by comparison, but it should |
|
|
|
|
* be fixed. */ |
|
|
|
|
/* Error concealment: If a ref is missing, copy the previous ref
|
|
|
|
|
* in its place. |
|
|
|
|
* FIXME: Avoiding a memcpy would be nice, but ref handling makes |
|
|
|
|
* many assumptions about there being no actual duplicates. |
|
|
|
|
* FIXME: This does not copy padding for out-of-frame motion |
|
|
|
|
* vectors. Given we are concealing a lost frame, this probably |
|
|
|
|
* is not noticeable by comparison, but it should be fixed. */ |
|
|
|
|
if (h->short_ref_count) { |
|
|
|
|
if (prev) { |
|
|
|
|
av_image_copy(h->short_ref[0]->f.data, h->short_ref[0]->f.linesize, |
|
|
|
|
(const uint8_t **)prev->f.data, prev->f.linesize, |
|
|
|
|
h->avctx->pix_fmt, h->mb_width * 16, h->mb_height * 16); |
|
|
|
|
av_image_copy(h->short_ref[0]->f.data, |
|
|
|
|
h->short_ref[0]->f.linesize, |
|
|
|
|
(const uint8_t **)prev->f.data, |
|
|
|
|
prev->f.linesize, |
|
|
|
|
h->avctx->pix_fmt, |
|
|
|
|
h->mb_width * 16, |
|
|
|
|
h->mb_height * 16); |
|
|
|
|
h->short_ref[0]->poc = prev->poc + 2; |
|
|
|
|
} |
|
|
|
|
h->short_ref[0]->frame_num = h->prev_frame_num; |
|
|
|
@ -3486,7 +3494,8 @@ static int decode_slice_header(H264Context *h, H264Context *h0) |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
h->resync_mb_x = h->mb_x = first_mb_in_slice % h->mb_width; |
|
|
|
|
h->resync_mb_y = h->mb_y = (first_mb_in_slice / h->mb_width) << FIELD_OR_MBAFF_PICTURE(h); |
|
|
|
|
h->resync_mb_y = h->mb_y = (first_mb_in_slice / h->mb_width) << |
|
|
|
|
FIELD_OR_MBAFF_PICTURE(h); |
|
|
|
|
if (h->picture_structure == PICT_BOTTOM_FIELD) |
|
|
|
|
h->resync_mb_y = h->mb_y = h->mb_y + 1; |
|
|
|
|
assert(h->mb_y < h->mb_height); |
|
|
|
@ -3550,7 +3559,6 @@ static int decode_slice_header(H264Context *h, H264Context *h0) |
|
|
|
|
h->ref_count[0] = h->ref_count[1] = 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
max_refs = h->picture_structure == PICT_FRAME ? 16 : 32; |
|
|
|
|
|
|
|
|
|
if (h->ref_count[0] > max_refs || h->ref_count[1] > max_refs) { |
|
|
|
@ -3707,7 +3715,8 @@ static int decode_slice_header(H264Context *h, H264Context *h0) |
|
|
|
|
int *ref2frm = h->ref2frm[h->slice_num & (MAX_SLICES - 1)][j]; |
|
|
|
|
for (i = 0; i < 16; i++) { |
|
|
|
|
id_list[i] = 60; |
|
|
|
|
if (j < h->list_count && i < h->ref_count[j] && h->ref_list[j][i].f.buf[0]) { |
|
|
|
|
if (j < h->list_count && i < h->ref_count[j] && |
|
|
|
|
h->ref_list[j][i].f.buf[0]) { |
|
|
|
|
int k; |
|
|
|
|
AVBuffer *buf = h->ref_list[j][i].f.buf[0]->buffer; |
|
|
|
|
for (k = 0; k < h->short_ref_count; k++) |
|
|
|
@ -3726,8 +3735,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0) |
|
|
|
|
ref2frm[0] = |
|
|
|
|
ref2frm[1] = -1; |
|
|
|
|
for (i = 0; i < 16; i++) |
|
|
|
|
ref2frm[i + 2] = 4 * id_list[i] + |
|
|
|
|
(h->ref_list[j][i].reference & 3); |
|
|
|
|
ref2frm[i + 2] = 4 * id_list[i] + (h->ref_list[j][i].reference & 3); |
|
|
|
|
ref2frm[18 + 0] = |
|
|
|
|
ref2frm[18 + 1] = -1; |
|
|
|
|
for (i = 16; i < 48; i++) |
|
|
|
@ -4330,6 +4338,8 @@ static int execute_decode_slices(H264Context *h, int context_count) |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static const uint8_t start_code[] = { 0x00, 0x00, 0x01 }; |
|
|
|
|
|
|
|
|
|
static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size, |
|
|
|
|
int parse_extradata) |
|
|
|
|
{ |
|
|
|
@ -4514,11 +4524,11 @@ again: |
|
|
|
|
return -1; |
|
|
|
|
} else if (CONFIG_H264_VDPAU_DECODER && |
|
|
|
|
h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) { |
|
|
|
|
static const uint8_t start_code[] = { |
|
|
|
|
0x00, 0x00, 0x01 }; |
|
|
|
|
ff_vdpau_add_data_chunk(h->cur_pic_ptr->f.data[0], start_code, |
|
|
|
|
ff_vdpau_add_data_chunk(h->cur_pic_ptr->f.data[0], |
|
|
|
|
start_code, |
|
|
|
|
sizeof(start_code)); |
|
|
|
|
ff_vdpau_add_data_chunk(h->cur_pic_ptr->f.data[0], &buf[buf_index - consumed], |
|
|
|
|
ff_vdpau_add_data_chunk(h->cur_pic_ptr->f.data[0], |
|
|
|
|
&buf[buf_index - consumed], |
|
|
|
|
consumed); |
|
|
|
|
} else |
|
|
|
|
context_count++; |
|
|
|
|