Commit 78265fcf authored by Michael Niedermayer's avatar Michael Niedermayer

Merge commit '28096e0a'

* commit '28096e0a':
  h264: wait for initial complete frame before outputing frames

Conflicts:
	doc/APIchanges
	libavcodec/h264.c
	libavcodec/mpegvideo.h
	libavutil/frame.h
	libavutil/version.h

See: a64b028a (as well as various later commits)
Merged-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parents 2acc525d 28096e0a
......@@ -15,6 +15,9 @@ libavutil: 2012-10-22
API changes, most recent first:
2013-08-xx - xxxxxxx - lavu 52.17.0 - avframe.h
Add AVFrame.flags and AV_FRAME_FLAG_CORRUPT.
2013-10-27 - xxxxxxx - lavc 55.39.100 - avcodec.h
Add CODEC_CAP_DELAY support to avcodec_decode_subtitle2.
......
......@@ -692,6 +692,7 @@ typedef struct RcOverride{
#define CODEC_FLAG_UNALIGNED 0x0001
#define CODEC_FLAG_QSCALE 0x0002 ///< Use fixed qscale.
#define CODEC_FLAG_4MV 0x0004 ///< 4 MV per MB allowed / advanced prediction for H.263.
#define CODEC_FLAG_OUTPUT_CORRUPT 0x0008 ///< Output even those frames that might be corrupted
#define CODEC_FLAG_QPEL 0x0010 ///< Use qpel MC.
#define CODEC_FLAG_GMC 0x0020 ///< Use GMC.
#define CODEC_FLAG_MV0 0x0040 ///< Always try a MB with MV=<0,0>.
......
......@@ -361,10 +361,10 @@ static int ref_picture(H264Context *h, Picture *dst, Picture *src)
dst->field_picture = src->field_picture;
dst->needs_realloc = src->needs_realloc;
dst->reference = src->reference;
dst->sync = src->sync;
dst->crop = src->crop;
dst->crop_left = src->crop_left;
dst->crop_top = src->crop_top;
dst->recovered = src->recovered;
return 0;
fail:
......@@ -1902,7 +1902,7 @@ static int decode_update_thread_context(AVCodecContext *dst,
copy_picture_range(h->delayed_pic, h1->delayed_pic,
MAX_DELAYED_PIC_COUNT + 2, h, h1);
h->sync = h1->sync;
h->frame_recovered = h1->frame_recovered;
if (context_reinitialized)
h264_set_parameter_from_sps(h);
......@@ -1919,6 +1919,8 @@ static int decode_update_thread_context(AVCodecContext *dst,
h->prev_frame_num = h->frame_num;
h->outputed_poc = h->next_outputed_poc;
h->recovery_frame = h1->recovery_frame;
return err;
}
......@@ -1959,12 +1961,12 @@ static int h264_frame_start(H264Context *h)
* See decode_nal_units().
*/
pic->f.key_frame = 0;
pic->sync = 0;
pic->mmco_reset = 0;
pic->recovered = 0;
if ((ret = alloc_picture(h, pic)) < 0)
return ret;
if(!h->sync && !h->avctx->hwaccel &&
if(!h->frame_recovered && !h->avctx->hwaccel &&
!(h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU))
avpriv_color_frame(&pic->f, c);
......@@ -2189,8 +2191,15 @@ static void decode_postinit(H264Context *h, int setup_finished)
av_log(h->avctx, AV_LOG_DEBUG, "no picture %s\n", out_of_order ? "ooo" : "");
}
if (h->next_output_pic && h->next_output_pic->sync) {
h->sync |= 2;
if (h->next_output_pic) {
if (h->next_output_pic->recovered) {
// We have reached an recovery point and all frames after it in
// display order are "recovered".
h->frame_recovered |= FRAME_RECOVERED_SEI;
}
#if 0
h->next_output_pic->recovered |= !!(h->frame_recovered & FRAME_RECOVERED_SEI);
#endif
}
if (setup_finished && !h->avctx->hwaccel)
......@@ -2781,8 +2790,8 @@ static void flush_change(H264Context *h)
memset(h->default_ref_list[0], 0, sizeof(h->default_ref_list[0]));
memset(h->default_ref_list[1], 0, sizeof(h->default_ref_list[1]));
ff_h264_reset_sei(h);
h->recovery_frame= -1;
h->sync= 0;
h->recovery_frame = -1;
h->frame_recovered = 0;
h->list_count = 0;
h->current_slice = 0;
h->mmco_reset = 1;
......@@ -4844,8 +4853,8 @@ again:
if ( h->sei_recovery_frame_cnt >= 0
&& ( h->recovery_frame<0
|| ((h->recovery_frame - h->frame_num) & ((1 << h->sps.log2_max_frame_num)-1)) > h->sei_recovery_frame_cnt)) {
h->recovery_frame = (h->frame_num + h->sei_recovery_frame_cnt) %
(1 << h->sps.log2_max_frame_num);
h->recovery_frame = (h->frame_num + h->sei_recovery_frame_cnt) &
((1 << h->sps.log2_max_frame_num) - 1);
if (!h->valid_recovery_point)
h->recovery_frame = h->frame_num;
......@@ -4854,14 +4863,22 @@ again:
h->cur_pic_ptr->f.key_frame |=
(hx->nal_unit_type == NAL_IDR_SLICE);
if (h->recovery_frame == h->frame_num) {
h->cur_pic_ptr->sync |= 1;
h->recovery_frame = -1;
if (hx->nal_unit_type == NAL_IDR_SLICE ||
h->recovery_frame == h->frame_num) {
h->recovery_frame = -1;
h->cur_pic_ptr->recovered = 1;
}
h->sync |= !!h->cur_pic_ptr->f.key_frame;
h->sync |= 3*!!(avctx->flags2 & CODEC_FLAG2_SHOW_ALL);
h->cur_pic_ptr->sync |= h->sync;
// If we have an IDR, all frames after it in decoded order are
// "recovered".
if (hx->nal_unit_type == NAL_IDR_SLICE)
h->frame_recovered |= FRAME_RECOVERED_IDR;
h->frame_recovered |= 3*!!(avctx->flags2 & CODEC_FLAG2_SHOW_ALL);
h->frame_recovered |= 3*!!(avctx->flags & CODEC_FLAG_OUTPUT_CORRUPT);
#if 1
h->cur_pic_ptr->recovered |= h->frame_recovered;
#else
h->cur_pic_ptr->recovered |= !!(h->frame_recovered & FRAME_RECOVERED_IDR);
#endif
if (h->current_slice == 1) {
if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS))
......@@ -5135,7 +5152,15 @@ not_extra:
/* Wait for second field. */
*got_frame = 0;
if (h->next_output_pic && (h->next_output_pic->sync || h->sync>1)) {
#if 1
if (h->next_output_pic && (h->next_output_pic->recovered || h->frame_recovered>1)) {
#else
if (h->next_output_pic && (
h->next_output_pic->recovered)) {
#endif
if (!h->next_output_pic->recovered)
h->next_output_pic->f.flags |= AV_FRAME_FLAG_CORRUPT;
ret = output_frame(h, pict, h->next_output_pic);
if (ret < 0)
return ret;
......
......@@ -641,6 +641,14 @@ typedef struct H264Context {
* frames.
*/
int sei_recovery_frame_cnt;
/**
* Are the SEI recovery points looking valid.
*/
int valid_recovery_point;
FPA sei_fpa;
/**
* recovery_frame is the frame_num at which the next frame should
* be fully constructed.
......@@ -649,12 +657,18 @@ typedef struct H264Context {
*/
int recovery_frame;
/**
* Are the SEI recovery points looking valid.
*/
int valid_recovery_point;
/**
* We have seen an IDR, so all the following frames in coded order are correctly
* decodable.
*/
#define FRAME_RECOVERED_IDR (1 << 0)
/**
* Sufficient number of frames have been decoded since a SEI recovery point,
* so all the following frames in presentation order are correct.
*/
#define FRAME_RECOVERED_SEI (1 << 1)
FPA sei_fpa;
int frame_recovered; ///< Initial frame has been completely recovered
int luma_weight_flag[2]; ///< 7.4.3.2 luma_weight_lX_flag
int chroma_weight_flag[2]; ///< 7.4.3.2 chroma_weight_lX_flag
......@@ -668,8 +682,6 @@ typedef struct H264Context {
int16_t slice_row[MAX_SLICES]; ///< to detect when MAX_SLICES is too low
int sync; ///< did we had a keyframe or recovery point
uint8_t parse_history[4];
int parse_history_count;
int parse_last_mb;
......
......@@ -733,9 +733,9 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count)
print_long_term(h);
if(err >= 0 && h->long_ref_count==0 && h->short_ref_count<=2 && h->pps.ref_count[0]<=2 + (h->picture_structure != PICT_FRAME) && h->cur_pic_ptr->f.pict_type == AV_PICTURE_TYPE_I){
h->cur_pic_ptr->sync |= 1;
h->cur_pic_ptr->recovered |= 1;
if(!h->avctx->has_b_frames)
h->sync = 2;
h->frame_recovered = 2;
}
return (h->avctx->err_recognition & AV_EF_EXPLODE) ? err : 0;
......
......@@ -167,7 +167,6 @@ typedef struct Picture{
int ref_count[2][2]; ///< number of entries in ref_poc (FIXME need per slice)
int mbaff; ///< h264 1 -> MBAFF frame 0-> not MBAFF
int field_picture; ///< whether or not the picture was encoded in separate fields
int sync; ///< has been decoded after a keyframe
int mb_var_sum; ///< sum of MB variance for current frame
int mc_mb_var_sum; ///< motion compensated MB variance for current frame
......@@ -177,6 +176,7 @@ typedef struct Picture{
int reference;
int shared;
int recovered; ///< Picture at IDR or recovery point + recovery count
int crop;
int crop_left;
......
......@@ -70,6 +70,7 @@ static const AVOption avcodec_options[] = {
{"aic", "H.263 advanced intra coding / MPEG-4 AC prediction", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_AC_PRED }, INT_MIN, INT_MAX, V|E, "flags"},
{"ilme", "interlaced motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_INTERLACED_ME }, INT_MIN, INT_MAX, V|E, "flags"},
{"cgop", "closed GOP", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_CLOSED_GOP }, INT_MIN, INT_MAX, V|E, "flags"},
{"output_corrupt", "Output even potentially corrupted frames", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_OUTPUT_CORRUPT }, INT_MIN, INT_MAX, V|D, "flags"},
{"fast", "allow non-spec-compliant speedup tricks", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_FAST }, INT_MIN, INT_MAX, V|E, "flags2"},
{"noout", "skip bitstream encoding", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_NO_OUTPUT }, INT_MIN, INT_MAX, V|E, "flags2"},
{"ignorecrop", "ignore cropping information from sps", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_IGNORE_CROP }, INT_MIN, INT_MAX, V|D, "flags2"},
......
......@@ -386,6 +386,16 @@ typedef struct AVFrame {
AVFrameSideData **side_data;
int nb_side_data;
/**
* The frame data may be corrupted, e.g. due to decoding errors.
*/
#define AV_FRAME_FLAG_CORRUPT (1 << 0)
/**
* Frame flags, a combination of AV_FRAME_FLAG_*
*/
int flags;
/**
* frame timestamp estimated using various heuristics, in stream time base
* Code outside libavcodec should access this field using:
......
......@@ -75,7 +75,7 @@
*/
#define LIBAVUTIL_VERSION_MAJOR 52
#define LIBAVUTIL_VERSION_MINOR 48
#define LIBAVUTIL_VERSION_MINOR 49
#define LIBAVUTIL_VERSION_MICRO 100
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment