*/
#include "libavutil/imgutils.h"
+#include "libavutil/opt.h"
#include "internal.h"
#include "dsputil.h"
#include "avcodec.h"
static const enum PixelFormat hwaccel_pixfmt_list_h264_jpeg_420[] = {
PIX_FMT_DXVA2_VLD,
PIX_FMT_VAAPI_VLD,
+ PIX_FMT_VDA_VLD,
PIX_FMT_YUVJ420P,
PIX_FMT_NONE
};
av_cold int ff_h264_decode_init(AVCodecContext *avctx){
H264Context *h= avctx->priv_data;
MpegEncContext * const s = &h->s;
+ int i;
MPV_decode_defaults(s);
h->thread_context[0] = h;
h->outputed_poc = h->next_outputed_poc = INT_MIN;
+ for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++)
+ h->last_pocs[i] = INT_MIN;
h->prev_poc_msb= 1<<16;
h->x264_build = -1;
ff_h264_reset_sei(h);
if(h->sps.bitstream_restriction_flag && s->avctx->has_b_frames >= h->sps.num_reorder_frames)
{ }
- else if((out_of_order && pics-1 == s->avctx->has_b_frames && s->avctx->has_b_frames < MAX_DELAYED_PIC_COUNT)
- || (s->low_delay &&
- ((h->next_outputed_poc != INT_MIN && out->poc > h->next_outputed_poc + 2)
- || cur->f.pict_type == AV_PICTURE_TYPE_B)))
- {
+ else if (out_of_order && pics-1 == s->avctx->has_b_frames &&
+ s->avctx->has_b_frames < MAX_DELAYED_PIC_COUNT) {
+ int cnt = 0, invalid = 0;
+ for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++) {
+ cnt += out->poc < h->last_pocs[i];
+ invalid += h->last_pocs[i] == INT_MIN;
+ }
+ if (invalid + cnt < MAX_DELAYED_PIC_COUNT) {
+ s->avctx->has_b_frames = FFMAX(s->avctx->has_b_frames, cnt);
+ } else if (cnt) {
+ for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++)
+ h->last_pocs[i] = INT_MIN;
+ }
+ s->low_delay = 0;
+ } else if (s->low_delay &&
+ ((h->next_outputed_poc != INT_MIN && out->poc > h->next_outputed_poc + 2) ||
+ cur->f.pict_type == AV_PICTURE_TYPE_B)) {
s->low_delay = 0;
s->avctx->has_b_frames++;
}
for(i=out_idx; h->delayed_pic[i]; i++)
h->delayed_pic[i] = h->delayed_pic[i+1];
}
+ memmove(h->last_pocs, &h->last_pocs[1], sizeof(*h->last_pocs) * (MAX_DELAYED_PIC_COUNT - 1));
+ h->last_pocs[MAX_DELAYED_PIC_COUNT - 1] = out->poc;
if(!out_of_order && pics > s->avctx->has_b_frames){
h->next_output_pic = out;
if (out_idx == 0 && h->delayed_pic[0] && (h->delayed_pic[0]->f.key_frame || h->delayed_pic[0]->mmco_reset)) {
static const uint8_t dc_mapping[16] = { 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};
for(i = 0; i < 16; i++)
- dctcoef_set(h->mb+p*256, pixel_shift, dc_mapping[i], dctcoef_get(h->mb_luma_dc[p], pixel_shift, i));
+ dctcoef_set(h->mb+(p*256 << pixel_shift), pixel_shift, dc_mapping[i], dctcoef_get(h->mb_luma_dc[p], pixel_shift, i));
}
}
}else
}
if (chroma422) {
for(i=j*16+4; i<j*16+8; i++){
- if(h->non_zero_count_cache[ scan8[i] ] || dctcoef_get(h->mb, pixel_shift, i*16))
+ if(h->non_zero_count_cache[ scan8[i+4] ] || dctcoef_get(h->mb, pixel_shift, i*16))
idct_add (dest[j-1] + block_offset[i+4], h->mb + (i*16 << pixel_shift), uvlinesize);
}
}
s->chroma_y_shift = h->sps.chroma_format_idc <= 1; // 400 uses yuv420p
- s->width = 16*s->mb_width - (2>>CHROMA444)*FFMIN(h->sps.crop_right, (8<<CHROMA444)-1);
- if(h->sps.frame_mbs_only_flag)
- s->height= 16*s->mb_height - (1<<s->chroma_y_shift)*FFMIN(h->sps.crop_bottom, (16>>s->chroma_y_shift)-1);
- else
- s->height= 16*s->mb_height - (2<<s->chroma_y_shift)*FFMIN(h->sps.crop_bottom, (16>>s->chroma_y_shift)-1);
+ s->width = 16*s->mb_width;
+ s->height= 16*s->mb_height;
if (s->context_initialized
- && ( s->width != s->avctx->width || s->height != s->avctx->height
+ && ( s->width != s->avctx->coded_width || s->height != s->avctx->coded_height
|| s->avctx->bits_per_raw_sample != h->sps.bit_depth_luma
|| h->cur_chroma_format_idc != h->sps.chroma_format_idc
|| av_cmp_q(h->sps.sar, s->avctx->sample_aspect_ratio))) {
av_log(h->s.avctx, AV_LOG_ERROR, "Cannot (re-)initialize context during parallel decoding.\n");
return -1;
}
-
avcodec_set_dimensions(s->avctx, s->width, s->height);
+ s->avctx->width -= (2>>CHROMA444)*FFMIN(h->sps.crop_right, (8<<CHROMA444)-1);
+ s->avctx->height -= (1<<s->chroma_y_shift)*FFMIN(h->sps.crop_bottom, (16>>s->chroma_y_shift)-1) * (2 - h->sps.frame_mbs_only_flag);
s->avctx->sample_aspect_ratio= h->sps.sar;
av_assert0(s->avctx->sample_aspect_ratio.den);
{ FF_PROFILE_UNKNOWN },
};
+static const AVOption h264_options[] = {
+ {"is_avc", "is avc", offsetof(H264Context, is_avc), FF_OPT_TYPE_INT, {.dbl = 0}, 0, 1, 0},
+ {"nal_length_size", "nal_length_size", offsetof(H264Context, nal_length_size), FF_OPT_TYPE_INT, {.dbl = 0}, 0, 4, 0},
+ {NULL}
+};
+
+static const AVClass h264_class = {
+ "H264 Decoder",
+ av_default_item_name,
+ h264_options,
+ LIBAVUTIL_VERSION_INT,
+};
+
+static const AVClass h264_vdpau_class = {
+ "H264 VDPAU Decoder",
+ av_default_item_name,
+ h264_options,
+ LIBAVUTIL_VERSION_INT,
+};
+
AVCodec ff_h264_decoder = {
.name = "h264",
.type = AVMEDIA_TYPE_VIDEO,
.init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
.update_thread_context = ONLY_IF_THREADS_ENABLED(decode_update_thread_context),
.profiles = NULL_IF_CONFIG_SMALL(profiles),
+ .priv_class = &h264_class,
};
#if CONFIG_H264_VDPAU_DECODER
.long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (VDPAU acceleration)"),
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_VDPAU_H264, PIX_FMT_NONE},
.profiles = NULL_IF_CONFIG_SMALL(profiles),
+ .priv_class = &h264_vdpau_class,
};
#endif