History

Merge commit '61f168ae348f94f39e7afc6971654455a5de0e4d'

* commit '61f168ae348f94f39e7afc6971654455a5de0e4d': h264: factor out setting the parameter sets for a frame Michael's changes on top of the merge undo parts of the original diff that are not factorization: "The call point is left where it was before. Such a change should be in a separate commit and has multiple issues, one being null pointer dereferences the other is that some safety checks would become conditional. I tried to split the PPS init between the new and old functions similarly to the SPS code."

Clément Bœsch committed 10 years ago

Commit f512e4a2 parents 0f2654c 61f168a2 files · +138 −125Browse files

Unified · Split

2 files
  1. libavcodec/h264.h +2 −0
  2. libavcodec/h264_slice.c +136 −125
libavcodec/h264.h+2−0
@@ -413,6 +413,8 @@ typedef struct H264SliceContext { · 412 unmodified lines
413413 } ref_modifications[2][32];
414414 int nb_ref_modifications[2];
415415
416+ unsigned int pps_id;
417+
416418 const uint8_t *intra_pcm_ptr;
417419 int16_t *dc_val_base;
418420
libavcodec/h264_slice.c+136−125
@@ -1004,6 +1004,125 @@ static enum AVPixelFormat non_j_pixfmt(enum AVPixelFormat a) · 1003 unmodified lines
10041004 }
10051005 }
10061006
1007+static int h264_init_ps(H264Context *h, const H264SliceContext *sl, int first_slice)
1008+{
1009+ const SPS *sps;
1010+ int needs_reinit = 0, must_reinit, ret;
1011+
1012+ if (first_slice) {
1013+ av_buffer_unref(&h->ps.pps_ref);
1014+ h->ps.pps = NULL;
1015+ h->ps.pps_ref = av_buffer_ref(h->ps.pps_list[sl->pps_id]);
1016+ if (!h->ps.pps_ref)
1017+ return AVERROR(ENOMEM);
1018+ h->ps.pps = (const PPS*)h->ps.pps_ref->data;
1019+ }
1020+
1021+ if (h->ps.sps != (const SPS*)h->ps.sps_list[h->ps.pps->sps_id]->data) {
1022+ av_buffer_unref(&h->ps.sps_ref);
1023+ h->ps.sps = NULL;
1024+ h->ps.sps_ref = av_buffer_ref(h->ps.sps_list[h->ps.pps->sps_id]);
1025+ if (!h->ps.sps_ref)
1026+ return AVERROR(ENOMEM);
1027+ h->ps.sps = (const SPS*)h->ps.sps_ref->data;
1028+
1029+ if (h->mb_width != h->ps.sps->mb_width ||
1030+ h->mb_height != h->ps.sps->mb_height * (2 - h->ps.sps->frame_mbs_only_flag) ||
1031+ h->cur_bit_depth_luma != h->ps.sps->bit_depth_luma ||
1032+ h->cur_chroma_format_idc != h->ps.sps->chroma_format_idc
1033+ )
1034+ needs_reinit = 1;
1035+
1036+ if (h->bit_depth_luma != h->ps.sps->bit_depth_luma ||
1037+ h->chroma_format_idc != h->ps.sps->chroma_format_idc)
1038+ needs_reinit = 1;
1039+ }
1040+ sps = h->ps.sps;
1041+
1042+ must_reinit = (h->context_initialized &&
1043+ ( 16*sps->mb_width != h->avctx->coded_width
1044+ || 16*sps->mb_height * (2 - sps->frame_mbs_only_flag) != h->avctx->coded_height
1045+ || h->cur_bit_depth_luma != sps->bit_depth_luma
1046+ || h->cur_chroma_format_idc != sps->chroma_format_idc
1047+ || h->mb_width != sps->mb_width
1048+ || h->mb_height != sps->mb_height * (2 - sps->frame_mbs_only_flag)
1049+ ));
1050+ if (h->avctx->pix_fmt == AV_PIX_FMT_NONE
1051+ || (non_j_pixfmt(h->avctx->pix_fmt) != non_j_pixfmt(get_pixel_format(h, 0))))
1052+ must_reinit = 1;
1053+
1054+ if (first_slice && av_cmp_q(sps->sar, h->avctx->sample_aspect_ratio))
1055+ must_reinit = 1;
1056+
1057+ if (!h->setup_finished) {
1058+ h->avctx->profile = ff_h264_get_profile(sps);
1059+ h->avctx->level = sps->level_idc;
1060+ h->avctx->refs = sps->ref_frame_count;
1061+
1062+ h->mb_width = sps->mb_width;
1063+ h->mb_height = sps->mb_height * (2 - sps->frame_mbs_only_flag);
1064+ h->mb_num = h->mb_width * h->mb_height;
1065+ h->mb_stride = h->mb_width + 1;
1066+
1067+ h->b_stride = h->mb_width * 4;
1068+
1069+ h->chroma_y_shift = sps->chroma_format_idc <= 1; // 400 uses yuv420p
1070+
1071+ h->width = 16 * h->mb_width;
1072+ h->height = 16 * h->mb_height;
1073+
1074+ ret = init_dimensions(h);
1075+ if (ret < 0)
1076+ return ret;
1077+
1078+ if (sps->video_signal_type_present_flag) {
1079+ h->avctx->color_range = sps->full_range > 0 ? AVCOL_RANGE_JPEG
1080+ : AVCOL_RANGE_MPEG;
1081+ if (sps->colour_description_present_flag) {
1082+ if (h->avctx->colorspace != sps->colorspace)
1083+ needs_reinit = 1;
1084+ h->avctx->color_primaries = sps->color_primaries;
1085+ h->avctx->color_trc = sps->color_trc;
1086+ h->avctx->colorspace = sps->colorspace;
1087+ }
1088+ }
1089+ }
1090+
1091+ if (!h->context_initialized || must_reinit || needs_reinit) {
1092+ int flush_changes = h->context_initialized;
1093+ h->context_initialized = 0;
1094+ if (sl != h->slice_ctx) {
1095+ av_log(h->avctx, AV_LOG_ERROR,
1096+ "changing width %d -> %d / height %d -> %d on "
1097+ "slice %d\n",
1098+ h->width, h->avctx->coded_width,
1099+ h->height, h->avctx->coded_height,
1100+ h->current_slice + 1);
1101+ return AVERROR_INVALIDDATA;
1102+ }
1103+
1104+ av_assert1(first_slice);
1105+
1106+ if (flush_changes)
1107+ ff_h264_flush_change(h);
1108+
1109+ if ((ret = get_pixel_format(h, 1)) < 0)
1110+ return ret;
1111+ h->avctx->pix_fmt = ret;
1112+
1113+ av_log(h->avctx, AV_LOG_VERBOSE, "Reinit context to %dx%d, "
1114+ "pix_fmt: %s\n", h->width, h->height, av_get_pix_fmt_name(h->avctx->pix_fmt));
1115+
1116+ if ((ret = h264_slice_header_init(h)) < 0) {
1117+ av_log(h->avctx, AV_LOG_ERROR,
1118+ "h264_slice_header_init() failed\n");
1119+ return ret;
1120+ }
1121+ }
1122+
1123+ return 0;
1124+}
1125+
10071126 /* This function is called right after decoding the slice header for a first
10081127 * slice in a field (or a frame). It decides whether we are decoding a new frame
10091128 * or a second field in a pair and does the necessary setup.
@@ -1011,10 +1130,12 @@ static enum AVPixelFormat non_j_pixfmt(enum AVPixelFormat a) · 1 unmodified line
10111130 static int h264_field_start(H264Context *h, const H264SliceContext *sl)
10121131 {
10131132 int i;
1014− const SPS *sps = h->ps.sps;
1133+ const SPS *sps;
10151134
10161135 int last_pic_structure, last_pic_droppable, ret;
10171136
1137+ sps = h->ps.sps;
1138+
10181139 last_pic_droppable = h->droppable;
10191140 last_pic_structure = h->picture_structure;
10201141 h->droppable = (h->nal_ref_idc == 0);
@@ -1205,11 +1326,8 @@ static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl) · 184 unmodified lines
12051326 {
12061327 const SPS *sps;
12071328 const PPS *pps;
1208− unsigned int pps_id;
12091329 int ret;
12101330 unsigned int slice_type, tmp, i;
1211− int must_reinit;
1212− int needs_reinit = 0;
12131331 int field_pic_flag, bottom_field_flag;
12141332 int first_slice = sl == h->slice_ctx && !h->current_slice;
12151333 int frame_num, droppable, picture_structure;
@@ -1299,152 +1417,45 @@ static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl) · 83 unmodified lines
12991417 }
13001418 }
13011419
1302− pps_id = get_ue_golomb(&sl->gb);
1303− if (pps_id >= MAX_PPS_COUNT) {
1304− av_log(h->avctx, AV_LOG_ERROR, "pps_id %u out of range\n", pps_id);
1420+ sl->pps_id = get_ue_golomb(&sl->gb);
1421+ if (sl->pps_id >= MAX_PPS_COUNT) {
1422+ av_log(h->avctx, AV_LOG_ERROR, "pps_id %u out of range\n", sl->pps_id);
13051423 return AVERROR_INVALIDDATA;
13061424 }
1307− if (!h->ps.pps_list[pps_id]) {
1425+ if (!h->ps.pps_list[sl->pps_id]) {
13081426 av_log(h->avctx, AV_LOG_ERROR,
13091427 "non-existing PPS %u referenced\n",
1310− pps_id);
1428+ sl->pps_id);
13111429 return AVERROR_INVALIDDATA;
13121430 }
13131431
1314− pps = (const PPS*)h->ps.pps_list[pps_id]->data;
1432+ pps = (const PPS*)h->ps.pps_list[sl->pps_id]->data;
13151433
13161434 if (!h->ps.sps_list[pps->sps_id]) {
13171435 av_log(h->avctx, AV_LOG_ERROR,
1318− "non-existing SPS %u referenced\n",
1319− pps->sps_id);
1436+ "non-existing SPS %u referenced\n", pps->sps_id);
13201437 return AVERROR_INVALIDDATA;
13211438 }
1322−
1323− if (first_slice) {
1324− av_buffer_unref(&h->ps.pps_ref);
1325− h->ps.pps = NULL;
1326− h->ps.pps_ref = av_buffer_ref(h->ps.pps_list[pps_id]);
1327− if (!h->ps.pps_ref)
1328− return AVERROR(ENOMEM);
1329− h->ps.pps = (const PPS*)h->ps.pps_ref->data;
1330− } else {
1439+ if (!first_slice) {
13311440 if (h->ps.pps->sps_id != pps->sps_id ||
13321441 h->ps.pps->transform_8x8_mode != pps->transform_8x8_mode /*||
13331442 (h->setup_finished && h->ps.pps != pps)*/) {
13341443 av_log(h->avctx, AV_LOG_ERROR, "PPS changed between slices\n");
13351444 return AVERROR_INVALIDDATA;
13361445 }
1337− }
1338−
1339− if (h->ps.sps != (const SPS*)h->ps.sps_list[h->ps.pps->sps_id]->data) {
1340− if (!first_slice) {
1446+ if (h->ps.sps != (const SPS*)h->ps.sps_list[h->ps.pps->sps_id]->data) {
13411447 av_log(h->avctx, AV_LOG_ERROR,
13421448 "SPS changed in the middle of the frame\n");
13431449 return AVERROR_INVALIDDATA;
13441450 }
1345−
1346− av_buffer_unref(&h->ps.sps_ref);
1347− h->ps.sps = NULL;
1348− h->ps.sps_ref = av_buffer_ref(h->ps.sps_list[h->ps.pps->sps_id]);
1349− if (!h->ps.sps_ref)
1350− return AVERROR(ENOMEM);
1351− h->ps.sps = (const SPS*)h->ps.sps_ref->data;
1352−
1353− if (h->mb_width != h->ps.sps->mb_width ||
1354− h->mb_height != h->ps.sps->mb_height * (2 - h->ps.sps->frame_mbs_only_flag) ||
1355− h->cur_bit_depth_luma != h->ps.sps->bit_depth_luma ||
1356− h->cur_chroma_format_idc != h->ps.sps->chroma_format_idc
1357− )
1358− needs_reinit = 1;
1359−
1360− if (h->bit_depth_luma != h->ps.sps->bit_depth_luma ||
1361− h->chroma_format_idc != h->ps.sps->chroma_format_idc)
1362− needs_reinit = 1;
13631451 }
13641452
1365− pps = h->ps.pps;
1366− sps = h->ps.sps;
1367−
1368− must_reinit = (h->context_initialized &&
1369− ( 16*sps->mb_width != h->avctx->coded_width
1370− || 16*sps->mb_height * (2 - sps->frame_mbs_only_flag) != h->avctx->coded_height
1371− || h->cur_bit_depth_luma != sps->bit_depth_luma
1372− || h->cur_chroma_format_idc != sps->chroma_format_idc
1373− || h->mb_width != sps->mb_width
1374− || h->mb_height != sps->mb_height * (2 - sps->frame_mbs_only_flag)
1375− ));
1376− if (h->avctx->pix_fmt == AV_PIX_FMT_NONE
1377− || (non_j_pixfmt(h->avctx->pix_fmt) != non_j_pixfmt(get_pixel_format(h, 0))))
1378− must_reinit = 1;
1379−
1380− if (first_slice && av_cmp_q(sps->sar, h->avctx->sample_aspect_ratio))
1381− must_reinit = 1;
1382−
1383− if (!h->setup_finished) {
1384− h->avctx->profile = ff_h264_get_profile(sps);
1385− h->avctx->level = sps->level_idc;
1386− h->avctx->refs = sps->ref_frame_count;
1387−
1388− h->mb_width = sps->mb_width;
1389− h->mb_height = sps->mb_height * (2 - sps->frame_mbs_only_flag);
1390− h->mb_num = h->mb_width * h->mb_height;
1391− h->mb_stride = h->mb_width + 1;
1392−
1393− h->b_stride = h->mb_width * 4;
1394−
1395− h->chroma_y_shift = sps->chroma_format_idc <= 1; // 400 uses yuv420p
1396−
1397− h->width = 16 * h->mb_width;
1398− h->height = 16 * h->mb_height;
1399−
1400− ret = init_dimensions(h);
1401− if (ret < 0)
1402− return ret;
1403−
1404− if (sps->video_signal_type_present_flag) {
1405− h->avctx->color_range = sps->full_range > 0 ? AVCOL_RANGE_JPEG
1406− : AVCOL_RANGE_MPEG;
1407− if (sps->colour_description_present_flag) {
1408− if (h->avctx->colorspace != sps->colorspace)
1409− needs_reinit = 1;
1410− h->avctx->color_primaries = sps->color_primaries;
1411− h->avctx->color_trc = sps->color_trc;
1412− h->avctx->colorspace = sps->colorspace;
1413− }
1414− }
1415− }
1416−
1417− if (!h->context_initialized || must_reinit || needs_reinit) {
1418− int flush_changes = h->context_initialized;
1419− h->context_initialized = 0;
1420− if (sl != h->slice_ctx) {
1421− av_log(h->avctx, AV_LOG_ERROR,
1422− "changing width %d -> %d / height %d -> %d on "
1423− "slice %d\n",
1424− h->width, h->avctx->coded_width,
1425− h->height, h->avctx->coded_height,
1426− h->current_slice + 1);
1427− return AVERROR_INVALIDDATA;
1428− }
1429−
1430− av_assert1(first_slice);
1431−
1432− if(flush_changes)
1433− ff_h264_flush_change(h);
1434−
1435− if ((ret = get_pixel_format(h, 1)) < 0)
1436− return ret;
1437− h->avctx->pix_fmt = ret;
1438−
1439− av_log(h->avctx, AV_LOG_VERBOSE, "Reinit context to %dx%d, "
1440− "pix_fmt: %s\n", h->width, h->height, av_get_pix_fmt_name(h->avctx->pix_fmt));
1453+ // TODO: should probably be moved to h264_field_start()
1454+ ret = h264_init_ps(h, sl, first_slice);
1455+ if (ret < 0)
1456+ return ret;
14411457
1442− if ((ret = h264_slice_header_init(h)) < 0) {
1443− av_log(h->avctx, AV_LOG_ERROR,
1444− "h264_slice_header_init() failed\n");
1445− return ret;
1446− }
1447− }
1458+ sps = (const SPS*)h->ps.sps_list[pps->sps_id]->data;
14481459
14491460 frame_num = get_bits(&sl->gb, sps->log2_max_frame_num);
14501461 if (!first_slice) {

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t