#include "libavutil/imgutils.h"
#include "libavutil/opt.h"
#include "libavutil/stereo3d.h"
-#include "libavutil/timer.h"
#include "internal.h"
#include "bytestream.h"
#include "cabac.h"
#include "h264_mvpred.h"
#include "h264_ps.h"
#include "golomb.h"
-#include "hwaccel.h"
+#include "hwconfig.h"
#include "mathops.h"
#include "me_cmp.h"
#include "mpegutils.h"
h->width_from_caller = avctx->width;
h->height_from_caller = avctx->height;
- h->picture_structure = PICT_FRAME;
h->workaround_bugs = avctx->workaround_bugs;
h->flags = avctx->flags;
h->poc.prev_poc_msb = 1 << 16;
ff_h264_sei_uninit(&h->sei);
- avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
-
h->nb_slice_ctx = (avctx->active_thread_type & FF_THREAD_SLICE) ? avctx->thread_count : 1;
h->slice_ctx = av_mallocz_array(h->nb_slice_ctx, sizeof(*h->slice_ctx));
if (!h->slice_ctx) {
}
avctx->ticks_per_frame = 2;
- if (avctx->extradata_size > 0 && avctx->extradata) {
- ret = ff_h264_decode_extradata(avctx->extradata, avctx->extradata_size,
- &h->ps, &h->is_avc, &h->nal_length_size,
- avctx->err_recognition, avctx);
- if (ret < 0) {
- h264_decode_end(avctx);
- return ret;
+ if (!avctx->internal->is_copy) {
+ if (avctx->extradata_size > 0 && avctx->extradata) {
+ ret = ff_h264_decode_extradata(avctx->extradata, avctx->extradata_size,
+ &h->ps, &h->is_avc, &h->nal_length_size,
+ avctx->err_recognition, avctx);
+ if (ret < 0) {
+ int explode = avctx->err_recognition & AV_EF_EXPLODE;
+ av_log(avctx, explode ? AV_LOG_ERROR: AV_LOG_WARNING,
+ "Error decoding the extradata\n");
+ if (explode) {
+ h264_decode_end(avctx);
+ return ret;
+ }
+ ret = 0;
+ }
}
}
h->avctx->has_b_frames = h->ps.sps->num_reorder_frames;
}
- avctx->internal->allocate_progress = 1;
-
ff_h264_flush_change(h);
if (h->enable_er < 0 && (avctx->active_thread_type & FF_THREAD_SLICE))
return 0;
}
-#if HAVE_THREADS
-static int decode_init_thread_copy(AVCodecContext *avctx)
-{
- H264Context *h = avctx->priv_data;
- int ret;
-
- if (!avctx->internal->is_copy)
- return 0;
-
- memset(h, 0, sizeof(*h));
-
- ret = h264_init_context(avctx, h);
- if (ret < 0)
- return ret;
-
- h->context_initialized = 0;
-
- return 0;
-}
-#endif
-
/**
* instantaneous decoder refresh.
*/
h->poc.prev_frame_num =
h->poc.prev_frame_num_offset = 0;
h->poc.prev_poc_msb = 1<<16;
- h->poc.prev_poc_lsb = 0;
+ h->poc.prev_poc_lsb = -1;
for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++)
h->last_pocs[i] = INT_MIN;
}
h->mmco_reset = 1;
}
-/* forget old pics after a seek */
-static void flush_dpb(AVCodecContext *avctx)
+static void h264_decode_flush(AVCodecContext *avctx)
{
H264Context *h = avctx->priv_data;
int i;
h->is_avc = 1;
}
- ret = ff_h2645_packet_split(&h->pkt, buf, buf_size, avctx, h->is_avc,
- h->nal_length_size, avctx->codec_id, avctx->flags2 & AV_CODEC_FLAG2_FAST);
+ ret = ff_h2645_packet_split(&h->pkt, buf, buf_size, avctx, h->is_avc, h->nal_length_size,
+ avctx->codec_id, avctx->flags2 & AV_CODEC_FLAG2_FAST, 0);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR,
"Error splitting the input into NAL units.\n");
goto end;
}
if(!idr_cleared) {
- if (h->current_slice && (avctx->active_thread_type & FF_THREAD_SLICE)) {
- av_log(h, AV_LOG_ERROR, "invalid mixed IDR / non IDR frames cannot be decoded in slice multithreading mode\n");
- ret = AVERROR_INVALIDDATA;
- goto end;
- }
idr(h); // FIXME ensure we don't lose some frames if there is reordering
}
idr_cleared = 1;
if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
goto end;
+ // set decode_error_flags to allow users to detect concealed decoding errors
+ if ((ret < 0 || h->slice_ctx->er.error_occurred) && h->cur_pic_ptr) {
+ h->cur_pic_ptr->f->decode_error_flags |= FF_DECODE_ERROR_DECODE_SLICES;
+ }
+
ret = 0;
end:
* past end by one (callers fault) and resync_mb_y != 0
* causes problems for the first MB line, too.
*/
- if (!FIELD_PICTURE(h) && h->current_slice &&
- h->ps.sps == (const SPS*)h->ps.sps_list[h->ps.pps->sps_id]->data &&
- h->enable_er) {
+ if (!FIELD_PICTURE(h) && h->current_slice && h->enable_er) {
H264SliceContext *sl = h->slice_ctx;
int use_last_pic = h->last_pic_for_ec.f->buf[0] && !sl->ref_count[0];
#endif
NULL
},
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_EXPORTS_CROPPING,
- .flush = flush_dpb,
- .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
+ .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_EXPORTS_CROPPING |
+ FF_CODEC_CAP_ALLOCATE_PROGRESS,
+ .flush = h264_decode_flush,
.update_thread_context = ONLY_IF_THREADS_ENABLED(ff_h264_update_thread_context),
.profiles = NULL_IF_CONFIG_SMALL(ff_h264_profiles),
.priv_class = &h264_class,