aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2016-05-17 14:51:01 +0200
committerAnton Khirnov <anton@khirnov.net>2016-06-21 11:08:03 +0200
commit8d36932c8d33f93ce1afdd5c1f402e7b6655d5ae (patch)
tree1dcac4e0ac5f6a10cfdaf4bb8d896d4a4e8a1045
parentb25cd7540e7cba9868edc13817c0ce1ddef90ffc (diff)
downloadffmpeg-8d36932c8d33f93ce1afdd5c1f402e7b6655d5ae.tar.gz
h264: move the block starting a new field out of slice_header_parse()
There is no bitstream parsing in that block and messing with decoder-global state is not something that belongs into header parsing. Nothing else in this function depends on the value of current_slice, except for two validity checks. Those checks are also moved out of slice_header_parse().
-rw-r--r--libavcodec/h264_slice.c68
1 files changed, 33 insertions, 35 deletions
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index 17608b455a..c43a0beca0 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -1177,21 +1177,6 @@ static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl,
sl->first_mb_addr = get_ue_golomb(&sl->gb);
- if (sl->first_mb_addr == 0) { // FIXME better field boundary detection
- if (h->current_slice && h->cur_pic_ptr && FIELD_PICTURE(h)) {
- ff_h264_field_end(h, sl, 1);
- }
-
- h->current_slice = 0;
- if (!h->first_field) {
- if (h->cur_pic_ptr && !h->droppable) {
- ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,
- h->picture_structure == PICT_BOTTOM_FIELD);
- }
- h->cur_pic_ptr = NULL;
- }
- }
-
slice_type = get_ue_golomb_31(&sl->gb);
if (slice_type > 9) {
av_log(h->avctx, AV_LOG_ERROR,
@@ -1226,11 +1211,6 @@ static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl,
sl->pps_id);
return AVERROR_INVALIDDATA;
}
- if (h->current_slice > 0 &&
- h->ps.pps != (const PPS*)h->ps.pps_list[sl->pps_id]->data) {
- av_log(h->avctx, AV_LOG_ERROR, "PPS changed between slices\n");
- return AVERROR_INVALIDDATA;
- }
pps = (const PPS*)h->ps.pps_list[sl->pps_id]->data;
if (!h->ps.sps_list[pps->sps_id]) {
@@ -1265,21 +1245,6 @@ static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl,
sl->picture_structure = picture_structure;
sl->mb_field_decoding_flag = picture_structure != PICT_FRAME;
- if (h->current_slice != 0) {
- if (h->picture_structure != picture_structure ||
- h->droppable != droppable) {
- av_log(h->avctx, AV_LOG_ERROR,
- "Changing field mode (%d -> %d) between slices is not allowed\n",
- h->picture_structure, picture_structure);
- return AVERROR_INVALIDDATA;
- } else if (!h->cur_pic_ptr) {
- av_log(h->avctx, AV_LOG_ERROR,
- "unset cur_pic_ptr on slice %d\n",
- h->current_slice + 1);
- return AVERROR_INVALIDDATA;
- }
- }
-
if (picture_structure == PICT_FRAME) {
h->curr_pic_num = h->poc.frame_num;
h->max_pic_num = 1 << sps->log2_max_frame_num;
@@ -1430,10 +1395,43 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl,
if (ret < 0)
return ret;
+ if (sl->first_mb_addr == 0) { // FIXME better field boundary detection
+ if (h->current_slice && h->cur_pic_ptr && FIELD_PICTURE(h)) {
+ ff_h264_field_end(h, sl, 1);
+ }
+
+ h->current_slice = 0;
+ if (!h->first_field) {
+ if (h->cur_pic_ptr && !h->droppable) {
+ ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,
+ h->picture_structure == PICT_BOTTOM_FIELD);
+ }
+ h->cur_pic_ptr = NULL;
+ }
+ }
+
if (h->current_slice == 0) {
ret = h264_field_start(h, sl, nal);
if (ret < 0)
return ret;
+ } else {
+ if (h->ps.pps != (const PPS*)h->ps.pps_list[sl->pps_id]->data) {
+ av_log(h->avctx, AV_LOG_ERROR, "PPS changed between slices\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (h->picture_structure != sl->picture_structure ||
+ h->droppable != (nal->ref_idc == 0)) {
+ av_log(h->avctx, AV_LOG_ERROR,
+ "Changing field mode (%d -> %d) between slices is not allowed\n",
+ h->picture_structure, sl->picture_structure);
+ return AVERROR_INVALIDDATA;
+ } else if (!h->cur_pic_ptr) {
+ av_log(h->avctx, AV_LOG_ERROR,
+ "unset cur_pic_ptr on slice %d\n",
+ h->current_slice + 1);
+ return AVERROR_INVALIDDATA;
+ }
}
assert(h->mb_num == h->mb_width * h->mb_height);