+ ff_h264_init_poc(h->cur_pic_ptr->field_poc, &h->cur_pic_ptr->poc,
+ h->ps.sps, &h->poc, h->picture_structure, nal->ref_idc);
+
+ memcpy(h->mmco, sl->mmco, sl->nb_mmco * sizeof(*h->mmco));
+ h->nb_mmco = sl->nb_mmco;
+ h->explicit_ref_marking = sl->explicit_ref_marking;
+
+ h->picture_idr = nal->type == H264_NAL_IDR_SLICE;
+
+ if (h->sei.recovery_point.recovery_frame_cnt >= 0 && h->recovery_frame < 0) {
+ h->recovery_frame = (h->poc.frame_num + h->sei.recovery_point.recovery_frame_cnt) &
+ ((1 << h->ps.sps->log2_max_frame_num) - 1);
+ }
+
+ h->cur_pic_ptr->f->key_frame |= (nal->type == H264_NAL_IDR_SLICE) ||
+ (h->sei.recovery_point.recovery_frame_cnt >= 0);
+
+ if (nal->type == H264_NAL_IDR_SLICE || h->recovery_frame == h->poc.frame_num) {
+ h->recovery_frame = -1;
+ h->cur_pic_ptr->recovered = 1;
+ }
+ // If we have an IDR, all frames after it in decoded order are
+ // "recovered".
+ if (nal->type == H264_NAL_IDR_SLICE)
+ h->frame_recovered |= FRAME_RECOVERED_IDR;
+ h->cur_pic_ptr->recovered |= !!(h->frame_recovered & FRAME_RECOVERED_IDR);
+
+ /* Set the frame properties/side data. Only done for the second field in
+ * field coded frames, since some SEI information is present for each field
+ * and is merged by the SEI parsing code. */
+ if (!FIELD_PICTURE(h) || !h->first_field) {
+ ret = h264_export_frame_props(h);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (h->avctx->hwaccel) {
+ ret = h->avctx->hwaccel->start_frame(h->avctx, NULL, 0);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int h264_slice_header_parse(H264SliceContext *sl, const H2645NAL *nal,
+ const H264ParamSets *ps, AVCodecContext *avctx)
+{
+ const SPS *sps;
+ const PPS *pps;
+ int ret;
+ unsigned int slice_type, tmp, i;
+ int field_pic_flag, bottom_field_flag;
+ int droppable, picture_structure;
+
+ sl->first_mb_addr = get_ue_golomb(&sl->gb);
+
+ slice_type = get_ue_golomb_31(&sl->gb);
+ if (slice_type > 9) {
+ av_log(avctx, AV_LOG_ERROR,
+ "slice type %d too large at %d\n",
+ slice_type, sl->first_mb_addr);
+ return AVERROR_INVALIDDATA;
+ }
+ if (slice_type > 4) {
+ slice_type -= 5;
+ sl->slice_type_fixed = 1;
+ } else
+ sl->slice_type_fixed = 0;
+
+ slice_type = ff_h264_golomb_to_pict_type[slice_type];
+ sl->slice_type = slice_type;
+ sl->slice_type_nos = slice_type & 3;
+
+ if (nal->type == H264_NAL_IDR_SLICE &&
+ sl->slice_type_nos != AV_PICTURE_TYPE_I) {
+ av_log(avctx, AV_LOG_ERROR, "A non-intra slice in an IDR NAL unit.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ sl->pps_id = get_ue_golomb(&sl->gb);
+ if (sl->pps_id >= MAX_PPS_COUNT) {
+ av_log(avctx, AV_LOG_ERROR, "pps_id %u out of range\n", sl->pps_id);
+ return AVERROR_INVALIDDATA;
+ }
+ if (!ps->pps_list[sl->pps_id]) {
+ av_log(avctx, AV_LOG_ERROR,
+ "non-existing PPS %u referenced\n",
+ sl->pps_id);
+ return AVERROR_INVALIDDATA;
+ }
+ pps = (const PPS*)ps->pps_list[sl->pps_id]->data;
+
+ if (!ps->sps_list[pps->sps_id]) {
+ av_log(avctx, AV_LOG_ERROR,
+ "non-existing SPS %u referenced\n", pps->sps_id);
+ return AVERROR_INVALIDDATA;
+ }
+ sps = (const SPS*)ps->sps_list[pps->sps_id]->data;
+
+ sl->frame_num = get_bits(&sl->gb, sps->log2_max_frame_num);
+
+ sl->mb_mbaff = 0;
+
+ droppable = nal->ref_idc == 0;
+ if (sps->frame_mbs_only_flag) {
+ picture_structure = PICT_FRAME;
+ } else {
+ field_pic_flag = get_bits1(&sl->gb);
+ if (field_pic_flag) {
+ bottom_field_flag = get_bits1(&sl->gb);
+ picture_structure = PICT_TOP_FIELD + bottom_field_flag;