* commit '728d90a0c1973661a9e73da697bf4f90c9d19577':
h264: decouple h264_sei from the h264 decoder
Main changes:
- SEI decoding doesn't have access to the debug flag in the codec context so a
few logging are dropped.
- naming of quincunx_sampling_flag and frame_packing_arrangement_type are kept
as they are in FFmpeg instead of respectively quincunx_subsampling and
arrangement_type used in Libav because the former match the specifications.
- don't reset the x264 build info once read in order to fix
fate-h264-lossless (change by Hendrik)
- H264Context.has_recovery_point and deprecated
AVCodecContext.dtg_active_format are set after ff_h264_sei_decode()
based on the SEI state since ff_h264_sei_decode() doesn't have access
to H264Context anymore.
- frame_packing_arrangement_type is not checked against <= 0 in
decode_postinit() since it is always read as a positive value with
get_bits(). This fixes a -Wtype-limits warning by GCC spotted by
Michael.
Side Notes:
- tested that ffprobe on the file from ticket #3652 still returns 4
keyframes
- tested that playback from ticket #3063 still works
Merged-by: Clément Bœsch <clement@stupeflix.com>
Signed-off-by: Hendrik Leppkes <h.leppkes@gmail.com>
... | ... |
@@ -430,17 +430,17 @@ static int h264_init_context(AVCodecContext *avctx, H264Context *h) |
430 | 430 |
h->workaround_bugs = avctx->workaround_bugs; |
431 | 431 |
h->flags = avctx->flags; |
432 | 432 |
h->poc.prev_poc_msb = 1 << 16; |
433 |
- h->x264_build = -1; |
|
434 | 433 |
h->recovery_frame = -1; |
435 | 434 |
h->frame_recovered = 0; |
436 | 435 |
h->poc.prev_frame_num = -1; |
437 |
- h->sei_fpa.frame_packing_arrangement_cancel_flag = -1; |
|
436 |
+ h->sei.frame_packing.frame_packing_arrangement_cancel_flag = -1; |
|
437 |
+ h->sei.unregistered.x264_build = -1; |
|
438 | 438 |
|
439 | 439 |
h->next_outputed_poc = INT_MIN; |
440 | 440 |
for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++) |
441 | 441 |
h->last_pocs[i] = INT_MIN; |
442 | 442 |
|
443 |
- ff_h264_reset_sei(h); |
|
443 |
+ ff_h264_sei_uninit(&h->sei); |
|
444 | 444 |
|
445 | 445 |
avctx->chroma_sample_location = AVCHROMA_LOC_LEFT; |
446 | 446 |
|
... | ... |
@@ -594,7 +594,8 @@ static void decode_postinit(H264Context *h, int setup_finished) |
594 | 594 |
* decoding process if it exists. */ |
595 | 595 |
|
596 | 596 |
if (sps->pic_struct_present_flag) { |
597 |
- switch (h->sei_pic_struct) { |
|
597 |
+ H264SEIPictureTiming *pt = &h->sei.picture_timing; |
|
598 |
+ switch (pt->pic_struct) { |
|
598 | 599 |
case SEI_PIC_STRUCT_FRAME: |
599 | 600 |
break; |
600 | 601 |
case SEI_PIC_STRUCT_TOP_FIELD: |
... | ... |
@@ -624,9 +625,9 @@ static void decode_postinit(H264Context *h, int setup_finished) |
624 | 624 |
break; |
625 | 625 |
} |
626 | 626 |
|
627 |
- if ((h->sei_ct_type & 3) && |
|
628 |
- h->sei_pic_struct <= SEI_PIC_STRUCT_BOTTOM_TOP) |
|
629 |
- cur->f->interlaced_frame = (h->sei_ct_type & (1 << 1)) != 0; |
|
627 |
+ if ((pt->ct_type & 3) && |
|
628 |
+ pt->pic_struct <= SEI_PIC_STRUCT_BOTTOM_TOP) |
|
629 |
+ cur->f->interlaced_frame = (pt->ct_type & (1 << 1)) != 0; |
|
630 | 630 |
} else { |
631 | 631 |
/* Derive interlacing flag from used decoding process. */ |
632 | 632 |
cur->f->interlaced_frame = FIELD_OR_MBAFF_PICTURE(h); |
... | ... |
@@ -640,8 +641,8 @@ static void decode_postinit(H264Context *h, int setup_finished) |
640 | 640 |
if (sps->pic_struct_present_flag) { |
641 | 641 |
/* Use picture timing SEI information. Even if it is a |
642 | 642 |
* information of a past frame, better than nothing. */ |
643 |
- if (h->sei_pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM || |
|
644 |
- h->sei_pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM_TOP) |
|
643 |
+ if (h->sei.picture_timing.pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM || |
|
644 |
+ h->sei.picture_timing.pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM_TOP) |
|
645 | 645 |
cur->f->top_field_first = 1; |
646 | 646 |
else |
647 | 647 |
cur->f->top_field_first = 0; |
... | ... |
@@ -655,14 +656,14 @@ static void decode_postinit(H264Context *h, int setup_finished) |
655 | 655 |
} |
656 | 656 |
} |
657 | 657 |
|
658 |
- if (h->sei_frame_packing_present && |
|
659 |
- h->frame_packing_arrangement_type >= 0 && |
|
660 |
- h->frame_packing_arrangement_type <= 6 && |
|
661 |
- h->content_interpretation_type > 0 && |
|
662 |
- h->content_interpretation_type < 3) { |
|
658 |
+ if (h->sei.frame_packing.present && |
|
659 |
+ h->sei.frame_packing.frame_packing_arrangement_type <= 6 && |
|
660 |
+ h->sei.frame_packing.content_interpretation_type > 0 && |
|
661 |
+ h->sei.frame_packing.content_interpretation_type < 3) { |
|
662 |
+ H264SEIFramePacking *fp = &h->sei.frame_packing; |
|
663 | 663 |
AVStereo3D *stereo = av_stereo3d_create_side_data(cur->f); |
664 | 664 |
if (stereo) { |
665 |
- switch (h->frame_packing_arrangement_type) { |
|
665 |
+ switch (fp->frame_packing_arrangement_type) { |
|
666 | 666 |
case 0: |
667 | 667 |
stereo->type = AV_STEREO3D_CHECKERBOARD; |
668 | 668 |
break; |
... | ... |
@@ -673,7 +674,7 @@ static void decode_postinit(H264Context *h, int setup_finished) |
673 | 673 |
stereo->type = AV_STEREO3D_LINES; |
674 | 674 |
break; |
675 | 675 |
case 3: |
676 |
- if (h->quincunx_subsampling) |
|
676 |
+ if (fp->quincunx_sampling_flag) |
|
677 | 677 |
stereo->type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX; |
678 | 678 |
else |
679 | 679 |
stereo->type = AV_STEREO3D_SIDEBYSIDE; |
... | ... |
@@ -689,42 +690,46 @@ static void decode_postinit(H264Context *h, int setup_finished) |
689 | 689 |
break; |
690 | 690 |
} |
691 | 691 |
|
692 |
- if (h->content_interpretation_type == 2) |
|
692 |
+ if (fp->content_interpretation_type == 2) |
|
693 | 693 |
stereo->flags = AV_STEREO3D_FLAG_INVERT; |
694 | 694 |
} |
695 | 695 |
} |
696 | 696 |
|
697 |
- if (h->sei_display_orientation_present && |
|
698 |
- (h->sei_anticlockwise_rotation || h->sei_hflip || h->sei_vflip)) { |
|
699 |
- double angle = h->sei_anticlockwise_rotation * 360 / (double) (1 << 16); |
|
697 |
+ if (h->sei.display_orientation.present && |
|
698 |
+ (h->sei.display_orientation.anticlockwise_rotation || |
|
699 |
+ h->sei.display_orientation.hflip || |
|
700 |
+ h->sei.display_orientation.vflip)) { |
|
701 |
+ H264SEIDisplayOrientation *o = &h->sei.display_orientation; |
|
702 |
+ double angle = o->anticlockwise_rotation * 360 / (double) (1 << 16); |
|
700 | 703 |
AVFrameSideData *rotation = av_frame_new_side_data(cur->f, |
701 | 704 |
AV_FRAME_DATA_DISPLAYMATRIX, |
702 | 705 |
sizeof(int32_t) * 9); |
703 | 706 |
if (rotation) { |
704 | 707 |
av_display_rotation_set((int32_t *)rotation->data, angle); |
705 | 708 |
av_display_matrix_flip((int32_t *)rotation->data, |
706 |
- h->sei_hflip, h->sei_vflip); |
|
709 |
+ o->hflip, o->vflip); |
|
707 | 710 |
} |
708 | 711 |
} |
709 | 712 |
|
710 |
- if (h->sei_reguserdata_afd_present) { |
|
713 |
+ if (h->sei.afd.present) { |
|
711 | 714 |
AVFrameSideData *sd = av_frame_new_side_data(cur->f, AV_FRAME_DATA_AFD, |
712 | 715 |
sizeof(uint8_t)); |
713 | 716 |
|
714 | 717 |
if (sd) { |
715 |
- *sd->data = h->active_format_description; |
|
716 |
- h->sei_reguserdata_afd_present = 0; |
|
718 |
+ *sd->data = h->sei.afd.active_format_description; |
|
719 |
+ h->sei.afd.present = 0; |
|
717 | 720 |
} |
718 | 721 |
} |
719 | 722 |
|
720 |
- if (h->a53_caption) { |
|
723 |
+ if (h->sei.a53_caption.a53_caption) { |
|
724 |
+ H264SEIA53Caption *a53 = &h->sei.a53_caption; |
|
721 | 725 |
AVFrameSideData *sd = av_frame_new_side_data(cur->f, |
722 | 726 |
AV_FRAME_DATA_A53_CC, |
723 |
- h->a53_caption_size); |
|
727 |
+ a53->a53_caption_size); |
|
724 | 728 |
if (sd) |
725 |
- memcpy(sd->data, h->a53_caption, h->a53_caption_size); |
|
726 |
- av_freep(&h->a53_caption); |
|
727 |
- h->a53_caption_size = 0; |
|
729 |
+ memcpy(sd->data, a53->a53_caption, a53->a53_caption_size); |
|
730 |
+ av_freep(&a53->a53_caption); |
|
731 |
+ a53->a53_caption_size = 0; |
|
728 | 732 |
h->avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS; |
729 | 733 |
} |
730 | 734 |
|
... | ... |
@@ -859,7 +864,7 @@ void ff_h264_flush_change(H264Context *h) |
859 | 859 |
ff_h264_unref_picture(h, &h->last_pic_for_ec); |
860 | 860 |
|
861 | 861 |
h->first_field = 0; |
862 |
- ff_h264_reset_sei(h); |
|
862 |
+ ff_h264_sei_uninit(&h->sei); |
|
863 | 863 |
h->recovery_frame = -1; |
864 | 864 |
h->frame_recovered = 0; |
865 | 865 |
h->current_slice = 0; |
... | ... |
@@ -1005,7 +1010,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size, |
1005 | 1005 |
h->current_slice = 0; |
1006 | 1006 |
if (!h->first_field) |
1007 | 1007 |
h->cur_pic_ptr = NULL; |
1008 |
- ff_h264_reset_sei(h); |
|
1008 |
+ ff_h264_sei_uninit(&h->sei); |
|
1009 | 1009 |
} |
1010 | 1010 |
|
1011 | 1011 |
if (h->nal_length_size == 4) { |
... | ... |
@@ -1096,13 +1101,15 @@ again: |
1096 | 1096 |
if ((err = ff_h264_decode_slice_header(h, sl))) |
1097 | 1097 |
break; |
1098 | 1098 |
|
1099 |
- if (h->sei_recovery_frame_cnt >= 0) { |
|
1100 |
- if (h->poc.frame_num != h->sei_recovery_frame_cnt || sl->slice_type_nos != AV_PICTURE_TYPE_I) |
|
1099 |
+ if (h->sei.recovery_point.recovery_frame_cnt >= 0) { |
|
1100 |
+ const int sei_recovery_frame_cnt = h->sei.recovery_point.recovery_frame_cnt; |
|
1101 |
+ |
|
1102 |
+ if (h->poc.frame_num != sei_recovery_frame_cnt || sl->slice_type_nos != AV_PICTURE_TYPE_I) |
|
1101 | 1103 |
h->valid_recovery_point = 1; |
1102 | 1104 |
|
1103 | 1105 |
if ( h->recovery_frame < 0 |
1104 |
- || av_mod_uintp2(h->recovery_frame - h->poc.frame_num, h->ps.sps->log2_max_frame_num) > h->sei_recovery_frame_cnt) { |
|
1105 |
- h->recovery_frame = av_mod_uintp2(h->poc.frame_num + h->sei_recovery_frame_cnt, h->ps.sps->log2_max_frame_num); |
|
1106 |
+ || av_mod_uintp2(h->recovery_frame - h->poc.frame_num, h->ps.sps->log2_max_frame_num) > sei_recovery_frame_cnt) { |
|
1107 |
+ h->recovery_frame = av_mod_uintp2(h->poc.frame_num + sei_recovery_frame_cnt, h->ps.sps->log2_max_frame_num); |
|
1106 | 1108 |
|
1107 | 1109 |
if (!h->valid_recovery_point) |
1108 | 1110 |
h->recovery_frame = h->poc.frame_num; |
... | ... |
@@ -1167,10 +1174,15 @@ again: |
1167 | 1167 |
avpriv_request_sample(avctx, "data partitioning"); |
1168 | 1168 |
break; |
1169 | 1169 |
case NAL_SEI: |
1170 |
- h->gb = nal->gb; |
|
1171 |
- ret = ff_h264_decode_sei(h); |
|
1170 |
+ ret = ff_h264_sei_decode(&h->sei, &nal->gb, &h->ps, avctx); |
|
1171 |
+ h->has_recovery_point = h->has_recovery_point || h->sei.recovery_point.recovery_frame_cnt != -1; |
|
1172 | 1172 |
if (avctx->debug & FF_DEBUG_GREEN_MD) |
1173 |
- debug_green_metadata(&h->sei_green_metadata, h->avctx); |
|
1173 |
+ debug_green_metadata(&h->sei.green_metadata, h->avctx); |
|
1174 |
+#if FF_API_AFD |
|
1175 |
+FF_DISABLE_DEPRECATION_WARNINGS |
|
1176 |
+ h->avctx->dtg_active_format = h->sei.afd.active_format_description; |
|
1177 |
+FF_ENABLE_DEPRECATION_WARNINGS |
|
1178 |
+#endif /* FF_API_AFD */ |
|
1174 | 1179 |
if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) |
1175 | 1180 |
goto end; |
1176 | 1181 |
break; |
... | ... |
@@ -1314,7 +1326,7 @@ static int output_frame(H264Context *h, AVFrame *dst, H264Picture *srcp) |
1314 | 1314 |
if (ret < 0) |
1315 | 1315 |
return ret; |
1316 | 1316 |
|
1317 |
- av_dict_set(&dst->metadata, "stereo_mode", ff_h264_sei_stereo_mode(h), 0); |
|
1317 |
+ av_dict_set(&dst->metadata, "stereo_mode", ff_h264_sei_stereo_mode(&h->sei.frame_packing), 0); |
|
1318 | 1318 |
|
1319 | 1319 |
h->backup_width = h->avctx->width; |
1320 | 1320 |
h->backup_height = h->avctx->height; |
... | ... |
@@ -1532,8 +1544,7 @@ av_cold void ff_h264_free_context(H264Context *h) |
1532 | 1532 |
av_freep(&h->slice_ctx); |
1533 | 1533 |
h->nb_slice_ctx = 0; |
1534 | 1534 |
|
1535 |
- h->a53_caption_size = 0; |
|
1536 |
- av_freep(&h->a53_caption); |
|
1535 |
+ ff_h264_sei_uninit(&h->sei); |
|
1537 | 1536 |
|
1538 | 1537 |
for (i = 0; i < MAX_SPS_COUNT; i++) |
1539 | 1538 |
av_buffer_unref(&h->ps.sps_list[i]); |
... | ... |
@@ -35,6 +35,7 @@ |
35 | 35 |
#include "error_resilience.h" |
36 | 36 |
#include "get_bits.h" |
37 | 37 |
#include "h264_parse.h" |
38 |
+#include "h264_sei.h" |
|
38 | 39 |
#include "h2645_parse.h" |
39 | 40 |
#include "h264chroma.h" |
40 | 41 |
#include "h264dsp.h" |
... | ... |
@@ -131,48 +132,6 @@ enum { |
131 | 131 |
}; |
132 | 132 |
|
133 | 133 |
/** |
134 |
- * SEI message types |
|
135 |
- */ |
|
136 |
-typedef enum { |
|
137 |
- SEI_TYPE_BUFFERING_PERIOD = 0, ///< buffering period (H.264, D.1.1) |
|
138 |
- SEI_TYPE_PIC_TIMING = 1, ///< picture timing |
|
139 |
- SEI_TYPE_USER_DATA_REGISTERED = 4, ///< registered user data as specified by Rec. ITU-T T.35 |
|
140 |
- SEI_TYPE_USER_DATA_UNREGISTERED = 5, ///< unregistered user data |
|
141 |
- SEI_TYPE_RECOVERY_POINT = 6, ///< recovery point (frame # to decoder sync) |
|
142 |
- SEI_TYPE_FRAME_PACKING = 45, ///< frame packing arrangement |
|
143 |
- SEI_TYPE_DISPLAY_ORIENTATION = 47, ///< display orientation |
|
144 |
- SEI_TYPE_GREEN_METADATA = 56 ///< GreenMPEG information |
|
145 |
-} SEI_Type; |
|
146 |
- |
|
147 |
-/** |
|
148 |
- * pic_struct in picture timing SEI message |
|
149 |
- */ |
|
150 |
-typedef enum { |
|
151 |
- SEI_PIC_STRUCT_FRAME = 0, ///< 0: %frame |
|
152 |
- SEI_PIC_STRUCT_TOP_FIELD = 1, ///< 1: top field |
|
153 |
- SEI_PIC_STRUCT_BOTTOM_FIELD = 2, ///< 2: bottom field |
|
154 |
- SEI_PIC_STRUCT_TOP_BOTTOM = 3, ///< 3: top field, bottom field, in that order |
|
155 |
- SEI_PIC_STRUCT_BOTTOM_TOP = 4, ///< 4: bottom field, top field, in that order |
|
156 |
- SEI_PIC_STRUCT_TOP_BOTTOM_TOP = 5, ///< 5: top field, bottom field, top field repeated, in that order |
|
157 |
- SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM = 6, ///< 6: bottom field, top field, bottom field repeated, in that order |
|
158 |
- SEI_PIC_STRUCT_FRAME_DOUBLING = 7, ///< 7: %frame doubling |
|
159 |
- SEI_PIC_STRUCT_FRAME_TRIPLING = 8 ///< 8: %frame tripling |
|
160 |
-} SEI_PicStructType; |
|
161 |
- |
|
162 |
-/** |
|
163 |
- * frame_packing_arrangement types |
|
164 |
- */ |
|
165 |
-typedef enum { |
|
166 |
- SEI_FPA_TYPE_CHECKERBOARD = 0, |
|
167 |
- SEI_FPA_TYPE_INTERLEAVE_COLUMN = 1, |
|
168 |
- SEI_FPA_TYPE_INTERLEAVE_ROW = 2, |
|
169 |
- SEI_FPA_TYPE_SIDE_BY_SIDE = 3, |
|
170 |
- SEI_FPA_TYPE_TOP_BOTTOM = 4, |
|
171 |
- SEI_FPA_TYPE_INTERLEAVE_TEMPORAL = 5, |
|
172 |
- SEI_FPA_TYPE_2D = 6, |
|
173 |
-} SEI_FpaType; |
|
174 |
- |
|
175 |
-/** |
|
176 | 134 |
* Sequence parameter set |
177 | 135 |
*/ |
178 | 136 |
typedef struct SPS { |
... | ... |
@@ -281,34 +240,6 @@ typedef struct H264ParamSets { |
281 | 281 |
} H264ParamSets; |
282 | 282 |
|
283 | 283 |
/** |
284 |
- * Frame Packing Arrangement Type |
|
285 |
- */ |
|
286 |
-typedef struct FPA { |
|
287 |
- int frame_packing_arrangement_id; |
|
288 |
- int frame_packing_arrangement_cancel_flag; ///< is previous arrangement canceled, -1 if never received |
|
289 |
- SEI_FpaType frame_packing_arrangement_type; |
|
290 |
- int frame_packing_arrangement_repetition_period; |
|
291 |
- int content_interpretation_type; |
|
292 |
- int quincunx_sampling_flag; |
|
293 |
-} FPA; |
|
294 |
- |
|
295 |
-/** |
|
296 |
- * Green MetaData Information Type |
|
297 |
- */ |
|
298 |
-typedef struct H264SEIGreenMetaData { |
|
299 |
- uint8_t green_metadata_type; |
|
300 |
- uint8_t period_type; |
|
301 |
- uint16_t num_seconds; |
|
302 |
- uint16_t num_pictures; |
|
303 |
- uint8_t percent_non_zero_macroblocks; |
|
304 |
- uint8_t percent_intra_coded_macroblocks; |
|
305 |
- uint8_t percent_six_tap_filtering; |
|
306 |
- uint8_t percent_alpha_point_deblocking_instance; |
|
307 |
- uint8_t xsd_metric_type; |
|
308 |
- uint16_t xsd_metric_value; |
|
309 |
-} H264SEIGreenMetaData; |
|
310 |
- |
|
311 |
-/** |
|
312 | 284 |
* Memory management control operation opcode. |
313 | 285 |
*/ |
314 | 286 |
typedef enum MMCOOpcode { |
... | ... |
@@ -622,8 +553,6 @@ typedef struct H264Context { |
622 | 622 |
uint8_t field_scan8x8_q0[64]; |
623 | 623 |
uint8_t field_scan8x8_cavlc_q0[64]; |
624 | 624 |
|
625 |
- int x264_build; |
|
626 |
- |
|
627 | 625 |
int mb_y; |
628 | 626 |
int mb_height, mb_width; |
629 | 627 |
int mb_stride; |
... | ... |
@@ -708,11 +637,6 @@ typedef struct H264Context { |
708 | 708 |
/** @} */ |
709 | 709 |
|
710 | 710 |
/** |
711 |
- * pic_struct in picture timing SEI message |
|
712 |
- */ |
|
713 |
- SEI_PicStructType sei_pic_struct; |
|
714 |
- |
|
715 |
- /** |
|
716 | 711 |
* Complement sei_pic_struct |
717 | 712 |
* SEI_PIC_STRUCT_TOP_BOTTOM and SEI_PIC_STRUCT_BOTTOM_TOP indicate interlaced frames. |
718 | 713 |
* However, soft telecined frames may have these values. |
... | ... |
@@ -721,61 +645,10 @@ typedef struct H264Context { |
721 | 721 |
int prev_interlaced_frame; |
722 | 722 |
|
723 | 723 |
/** |
724 |
- * frame_packing_arrangment SEI message |
|
725 |
- */ |
|
726 |
- int sei_frame_packing_present; |
|
727 |
- int frame_packing_arrangement_type; |
|
728 |
- int content_interpretation_type; |
|
729 |
- int quincunx_subsampling; |
|
730 |
- |
|
731 |
- /** |
|
732 |
- * display orientation SEI message |
|
733 |
- */ |
|
734 |
- int sei_display_orientation_present; |
|
735 |
- int sei_anticlockwise_rotation; |
|
736 |
- int sei_hflip, sei_vflip; |
|
737 |
- |
|
738 |
- /** |
|
739 |
- * User data registered by Rec. ITU-T T.35 SEI |
|
740 |
- */ |
|
741 |
- int sei_reguserdata_afd_present; |
|
742 |
- uint8_t active_format_description; |
|
743 |
- int a53_caption_size; |
|
744 |
- uint8_t *a53_caption; |
|
745 |
- |
|
746 |
- /** |
|
747 |
- * Bit set of clock types for fields/frames in picture timing SEI message. |
|
748 |
- * For each found ct_type, appropriate bit is set (e.g., bit 1 for |
|
749 |
- * interlaced). |
|
750 |
- */ |
|
751 |
- int sei_ct_type; |
|
752 |
- |
|
753 |
- /** |
|
754 |
- * dpb_output_delay in picture timing SEI message, see H.264 C.2.2 |
|
755 |
- */ |
|
756 |
- int sei_dpb_output_delay; |
|
757 |
- |
|
758 |
- /** |
|
759 |
- * cpb_removal_delay in picture timing SEI message, see H.264 C.1.2 |
|
760 |
- */ |
|
761 |
- int sei_cpb_removal_delay; |
|
762 |
- |
|
763 |
- /** |
|
764 |
- * recovery_frame_cnt from SEI message |
|
765 |
- * |
|
766 |
- * Set to -1 if no recovery point SEI message found or to number of frames |
|
767 |
- * before playback synchronizes. Frames having recovery point are key |
|
768 |
- * frames. |
|
769 |
- */ |
|
770 |
- int sei_recovery_frame_cnt; |
|
771 |
- |
|
772 |
- /** |
|
773 | 724 |
* Are the SEI recovery points looking valid. |
774 | 725 |
*/ |
775 | 726 |
int valid_recovery_point; |
776 | 727 |
|
777 |
- FPA sei_fpa; |
|
778 |
- |
|
779 | 728 |
/** |
780 | 729 |
* recovery_frame is the frame_num at which the next frame should |
781 | 730 |
* be fully constructed. |
... | ... |
@@ -807,10 +680,6 @@ typedef struct H264Context { |
807 | 807 |
* slices) anymore */ |
808 | 808 |
int setup_finished; |
809 | 809 |
|
810 |
- // Timestamp stuff |
|
811 |
- int sei_buffering_period_present; ///< Buffering period SEI flag |
|
812 |
- int initial_cpb_removal_delay[32]; ///< Initial timestamps for CPBs |
|
813 |
- |
|
814 | 810 |
int cur_chroma_format_idc; |
815 | 811 |
int cur_bit_depth_luma; |
816 | 812 |
int16_t slice_row[MAX_SLICES]; ///< to detect when MAX_SLICES is too low |
... | ... |
@@ -821,6 +690,8 @@ typedef struct H264Context { |
821 | 821 |
|
822 | 822 |
int enable_er; |
823 | 823 |
|
824 |
+ H264SEIContext sei; |
|
825 |
+ |
|
824 | 826 |
AVBufferPool *qscale_table_pool; |
825 | 827 |
AVBufferPool *mb_type_pool; |
826 | 828 |
AVBufferPool *motion_val_pool; |
... | ... |
@@ -830,19 +701,11 @@ typedef struct H264Context { |
830 | 830 |
qpel_mc_func (*qpel_put)[16]; |
831 | 831 |
qpel_mc_func (*qpel_avg)[16]; |
832 | 832 |
|
833 |
- /*Green Metadata */ |
|
834 |
- H264SEIGreenMetaData sei_green_metadata; |
|
835 |
- |
|
836 | 833 |
} H264Context; |
837 | 834 |
|
838 | 835 |
extern const uint16_t ff_h264_mb_sizes[4]; |
839 | 836 |
|
840 | 837 |
/** |
841 |
- * Decode SEI |
|
842 |
- */ |
|
843 |
-int ff_h264_decode_sei(H264Context *h); |
|
844 |
- |
|
845 |
-/** |
|
846 | 838 |
* Decode SPS |
847 | 839 |
*/ |
848 | 840 |
int ff_h264_decode_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx, |
... | ... |
@@ -921,19 +784,6 @@ void ff_h264_filter_mb(const H264Context *h, H264SliceContext *sl, int mb_x, int |
921 | 921 |
uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, |
922 | 922 |
unsigned int linesize, unsigned int uvlinesize); |
923 | 923 |
|
924 |
-/** |
|
925 |
- * Reset SEI values at the beginning of the frame. |
|
926 |
- * |
|
927 |
- * @param h H.264 context. |
|
928 |
- */ |
|
929 |
-void ff_h264_reset_sei(H264Context *h); |
|
930 |
- |
|
931 |
-/** |
|
932 |
- * Get stereo_mode string from the h264 frame_packing_arrangement |
|
933 |
- * @param h H.264 context. |
|
934 |
- */ |
|
935 |
-const char* ff_h264_sei_stereo_mode(H264Context *h); |
|
936 |
- |
|
937 | 924 |
/* |
938 | 925 |
* o-o o-o |
939 | 926 |
* / / / |
... | ... |
@@ -395,7 +395,7 @@ single_col: |
395 | 395 |
(l1ref0[0] < 0 && !l1ref1[0] && |
396 | 396 |
FFABS(l1mv1[0][0]) <= 1 && |
397 | 397 |
FFABS(l1mv1[0][1]) <= 1 && |
398 |
- h->x264_build > 33U))) { |
|
398 |
+ h->sei.unregistered.x264_build > 33U))) { |
|
399 | 399 |
a = b = 0; |
400 | 400 |
if (ref[0] > 0) |
401 | 401 |
a = mv[0]; |
... | ... |
@@ -430,7 +430,7 @@ single_col: |
430 | 430 |
(l1ref0[i8] == 0 || |
431 | 431 |
(l1ref0[i8] < 0 && |
432 | 432 |
l1ref1[i8] == 0 && |
433 |
- h->x264_build > 33U))) { |
|
433 |
+ h->sei.unregistered.x264_build > 33U))) { |
|
434 | 434 |
const int16_t (*l1mv)[2] = l1ref0[i8] == 0 ? l1mv0 : l1mv1; |
435 | 435 |
if (IS_SUB_8X8(sub_mb_type)) { |
436 | 436 |
const int16_t *mv_col = l1mv[x8 * 3 + y8 * 3 * b4_stride]; |
... | ... |
@@ -636,7 +636,7 @@ static av_always_inline void hl_decode_mb_predict_luma(const H264Context *h, |
636 | 636 |
uint8_t *const ptr = dest_y + block_offset[i]; |
637 | 637 |
const int dir = sl->intra4x4_pred_mode_cache[scan8[i]]; |
638 | 638 |
if (transform_bypass && h->ps.sps->profile_idc == 244 && dir <= 1) { |
639 |
- if (h->x264_build != -1) { |
|
639 |
+ if (h->sei.unregistered.x264_build != -1) { |
|
640 | 640 |
h->hpc.pred8x8l_add[dir](ptr, sl->mb + (i * 16 + p * 256 << pixel_shift), linesize); |
641 | 641 |
} else |
642 | 642 |
h->hpc.pred8x8l_filter_add[dir](ptr, sl->mb + (i * 16 + p * 256 << pixel_shift), |
... | ... |
@@ -39,6 +39,7 @@ |
39 | 39 |
#include "get_bits.h" |
40 | 40 |
#include "golomb.h" |
41 | 41 |
#include "h264.h" |
42 |
+#include "h264_sei.h" |
|
42 | 43 |
#include "h264data.h" |
43 | 44 |
#include "internal.h" |
44 | 45 |
#include "mpegutils.h" |
... | ... |
@@ -50,6 +51,7 @@ typedef struct H264ParseContext { |
50 | 50 |
H264ParamSets ps; |
51 | 51 |
H264DSPContext h264dsp; |
52 | 52 |
H264POCContext poc; |
53 |
+ H264SEIContext sei; |
|
53 | 54 |
int got_first; |
54 | 55 |
} H264ParseContext; |
55 | 56 |
|
... | ... |
@@ -249,8 +251,8 @@ static inline int parse_nal_units(AVCodecParserContext *s, |
249 | 249 |
s->picture_structure = AV_PICTURE_STRUCTURE_UNKNOWN; |
250 | 250 |
|
251 | 251 |
h->avctx = avctx; |
252 |
- ff_h264_reset_sei(h); |
|
253 |
- h->sei_fpa.frame_packing_arrangement_cancel_flag = -1; |
|
252 |
+ ff_h264_sei_uninit(&p->sei); |
|
253 |
+ h->sei.frame_packing.frame_packing_arrangement_cancel_flag = -1; |
|
254 | 254 |
|
255 | 255 |
if (!buf_size) |
256 | 256 |
return 0; |
... | ... |
@@ -318,12 +320,7 @@ static inline int parse_nal_units(AVCodecParserContext *s, |
318 | 318 |
nal.size_bits); |
319 | 319 |
break; |
320 | 320 |
case NAL_SEI: |
321 |
- { |
|
322 |
- H264ParamSets ps = h->ps; |
|
323 |
- h->ps = p->ps; |
|
324 |
- ff_h264_decode_sei(h); |
|
325 |
- h->ps = ps; |
|
326 |
- } |
|
321 |
+ ff_h264_sei_decode(&p->sei, &nal.gb, &p->ps, avctx); |
|
327 | 322 |
break; |
328 | 323 |
case NAL_IDR_SLICE: |
329 | 324 |
s->key_frame = 1; |
... | ... |
@@ -337,7 +334,7 @@ static inline int parse_nal_units(AVCodecParserContext *s, |
337 | 337 |
get_ue_golomb_long(&nal.gb); // skip first_mb_in_slice |
338 | 338 |
slice_type = get_ue_golomb_31(&nal.gb); |
339 | 339 |
s->pict_type = ff_h264_golomb_to_pict_type[slice_type % 5]; |
340 |
- if (h->sei_recovery_frame_cnt >= 0) { |
|
340 |
+ if (p->sei.recovery_point.recovery_frame_cnt >= 0) { |
|
341 | 341 |
/* key frame, since recovery_frame_cnt is set */ |
342 | 342 |
s->key_frame = 1; |
343 | 343 |
} |
... | ... |
@@ -462,7 +459,7 @@ static inline int parse_nal_units(AVCodecParserContext *s, |
462 | 462 |
} |
463 | 463 |
|
464 | 464 |
if (sps->pic_struct_present_flag) { |
465 |
- switch (h->sei_pic_struct) { |
|
465 |
+ switch (p->sei.picture_timing.pic_struct) { |
|
466 | 466 |
case SEI_PIC_STRUCT_TOP_FIELD: |
467 | 467 |
case SEI_PIC_STRUCT_BOTTOM_FIELD: |
468 | 468 |
s->repeat_pict = 0; |
... | ... |
@@ -493,7 +490,7 @@ static inline int parse_nal_units(AVCodecParserContext *s, |
493 | 493 |
if (h->picture_structure == PICT_FRAME) { |
494 | 494 |
s->picture_structure = AV_PICTURE_STRUCTURE_FRAME; |
495 | 495 |
if (sps->pic_struct_present_flag) { |
496 |
- switch (h->sei_pic_struct) { |
|
496 |
+ switch (p->sei.picture_timing.pic_struct) { |
|
497 | 497 |
case SEI_PIC_STRUCT_TOP_BOTTOM: |
498 | 498 |
case SEI_PIC_STRUCT_TOP_BOTTOM_TOP: |
499 | 499 |
s->field_order = AV_FIELD_TT; |
... | ... |
@@ -603,10 +600,10 @@ static int h264_parse(AVCodecParserContext *s, |
603 | 603 |
|
604 | 604 |
if (avctx->framerate.num) |
605 | 605 |
avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1})); |
606 |
- if (h->sei_cpb_removal_delay >= 0) { |
|
607 |
- s->dts_sync_point = h->sei_buffering_period_present; |
|
608 |
- s->dts_ref_dts_delta = h->sei_cpb_removal_delay; |
|
609 |
- s->pts_dts_delta = h->sei_dpb_output_delay; |
|
606 |
+ if (p->sei.picture_timing.cpb_removal_delay >= 0) { |
|
607 |
+ s->dts_sync_point = p->sei.buffering_period.present; |
|
608 |
+ s->dts_ref_dts_delta = p->sei.picture_timing.cpb_removal_delay; |
|
609 |
+ s->pts_dts_delta = p->sei.picture_timing.dpb_output_delay; |
|
610 | 610 |
} else { |
611 | 611 |
s->dts_sync_point = INT_MIN; |
612 | 612 |
s->dts_ref_dts_delta = INT_MIN; |
... | ... |
@@ -669,6 +666,8 @@ static void h264_close(AVCodecParserContext *s) |
669 | 669 |
av_freep(&pc->buffer); |
670 | 670 |
ff_h264_free_context(h); |
671 | 671 |
|
672 |
+ ff_h264_sei_uninit(&p->sei); |
|
673 |
+ |
|
672 | 674 |
for (i = 0; i < FF_ARRAY_ELEMS(p->ps.sps_list); i++) |
673 | 675 |
av_buffer_unref(&p->ps.sps_list[i]); |
674 | 676 |
|
... | ... |
@@ -26,124 +26,124 @@ |
26 | 26 |
*/ |
27 | 27 |
|
28 | 28 |
#include "avcodec.h" |
29 |
+#include "get_bits.h" |
|
29 | 30 |
#include "golomb.h" |
30 | 31 |
#include "h264.h" |
32 |
+#include "h264_sei.h" |
|
31 | 33 |
#include "internal.h" |
32 | 34 |
|
33 | 35 |
static const uint8_t sei_num_clock_ts_table[9] = { |
34 | 36 |
1, 1, 1, 2, 2, 3, 3, 2, 3 |
35 | 37 |
}; |
36 | 38 |
|
37 |
-void ff_h264_reset_sei(H264Context *h) |
|
39 |
+void ff_h264_sei_uninit(H264SEIContext *h) |
|
38 | 40 |
{ |
39 |
- h->sei_recovery_frame_cnt = -1; |
|
40 |
- h->sei_dpb_output_delay = 0; |
|
41 |
- h->sei_cpb_removal_delay = -1; |
|
42 |
- h->sei_buffering_period_present = 0; |
|
43 |
- h->sei_frame_packing_present = 0; |
|
44 |
- h->sei_display_orientation_present = 0; |
|
45 |
- h->sei_reguserdata_afd_present = 0; |
|
46 |
- |
|
47 |
- h->a53_caption_size = 0; |
|
48 |
- av_freep(&h->a53_caption); |
|
41 |
+ h->recovery_point.recovery_frame_cnt = -1; |
|
42 |
+ |
|
43 |
+ h->picture_timing.dpb_output_delay = 0; |
|
44 |
+ h->picture_timing.cpb_removal_delay = -1; |
|
45 |
+ |
|
46 |
+ h->buffering_period.present = 0; |
|
47 |
+ h->frame_packing.present = 0; |
|
48 |
+ h->display_orientation.present = 0; |
|
49 |
+ h->afd.present = 0; |
|
50 |
+ |
|
51 |
+ h->a53_caption.a53_caption_size = 0; |
|
52 |
+ av_freep(&h->a53_caption.a53_caption); |
|
49 | 53 |
} |
50 | 54 |
|
51 |
-static int decode_picture_timing(H264Context *h) |
|
55 |
+static int decode_picture_timing(H264SEIPictureTiming *h, GetBitContext *gb, |
|
56 |
+ const H264ParamSets *ps, void *logctx) |
|
52 | 57 |
{ |
53 |
- const SPS *sps = h->ps.sps; |
|
54 | 58 |
int i; |
59 |
+ const SPS *sps = ps->sps; |
|
55 | 60 |
|
56 | 61 |
for (i = 0; i<MAX_SPS_COUNT; i++) |
57 |
- if ((!sps || !sps->log2_max_frame_num) && h->ps.sps_list[i]) |
|
58 |
- sps = (const SPS *)h->ps.sps_list[i]->data; |
|
62 |
+ if ((!sps || !sps->log2_max_frame_num) && ps->sps_list[i]) |
|
63 |
+ sps = (const SPS *)ps->sps_list[i]->data; |
|
59 | 64 |
|
60 | 65 |
if (!sps) { |
61 |
- av_log(h->avctx, AV_LOG_ERROR, "SPS unavailable in decode_picture_timing\n"); |
|
66 |
+ av_log(logctx, AV_LOG_ERROR, "SPS unavailable in decode_picture_timing\n"); |
|
62 | 67 |
return 0; |
63 | 68 |
} |
64 | 69 |
|
65 |
- if (sps->nal_hrd_parameters_present_flag || sps->vcl_hrd_parameters_present_flag) { |
|
66 |
- h->sei_cpb_removal_delay = get_bits_long(&h->gb, |
|
67 |
- sps->cpb_removal_delay_length); |
|
68 |
- h->sei_dpb_output_delay = get_bits_long(&h->gb, |
|
69 |
- sps->dpb_output_delay_length); |
|
70 |
+ if (sps->nal_hrd_parameters_present_flag || |
|
71 |
+ sps->vcl_hrd_parameters_present_flag) { |
|
72 |
+ h->cpb_removal_delay = get_bits_long(gb, sps->cpb_removal_delay_length); |
|
73 |
+ h->dpb_output_delay = get_bits_long(gb, sps->dpb_output_delay_length); |
|
70 | 74 |
} |
71 | 75 |
if (sps->pic_struct_present_flag) { |
72 | 76 |
unsigned int i, num_clock_ts; |
73 | 77 |
|
74 |
- h->sei_pic_struct = get_bits(&h->gb, 4); |
|
75 |
- h->sei_ct_type = 0; |
|
78 |
+ h->pic_struct = get_bits(gb, 4); |
|
79 |
+ h->ct_type = 0; |
|
76 | 80 |
|
77 |
- if (h->sei_pic_struct > SEI_PIC_STRUCT_FRAME_TRIPLING) |
|
81 |
+ if (h->pic_struct > SEI_PIC_STRUCT_FRAME_TRIPLING) |
|
78 | 82 |
return AVERROR_INVALIDDATA; |
79 | 83 |
|
80 |
- num_clock_ts = sei_num_clock_ts_table[h->sei_pic_struct]; |
|
84 |
+ num_clock_ts = sei_num_clock_ts_table[h->pic_struct]; |
|
81 | 85 |
|
82 | 86 |
for (i = 0; i < num_clock_ts; i++) { |
83 |
- if (get_bits(&h->gb, 1)) { /* clock_timestamp_flag */ |
|
87 |
+ if (get_bits(gb, 1)) { /* clock_timestamp_flag */ |
|
84 | 88 |
unsigned int full_timestamp_flag; |
85 | 89 |
|
86 |
- h->sei_ct_type |= 1 << get_bits(&h->gb, 2); |
|
87 |
- skip_bits(&h->gb, 1); /* nuit_field_based_flag */ |
|
88 |
- skip_bits(&h->gb, 5); /* counting_type */ |
|
89 |
- full_timestamp_flag = get_bits(&h->gb, 1); |
|
90 |
- skip_bits(&h->gb, 1); /* discontinuity_flag */ |
|
91 |
- skip_bits(&h->gb, 1); /* cnt_dropped_flag */ |
|
92 |
- skip_bits(&h->gb, 8); /* n_frames */ |
|
90 |
+ h->ct_type |= 1 << get_bits(gb, 2); |
|
91 |
+ skip_bits(gb, 1); /* nuit_field_based_flag */ |
|
92 |
+ skip_bits(gb, 5); /* counting_type */ |
|
93 |
+ full_timestamp_flag = get_bits(gb, 1); |
|
94 |
+ skip_bits(gb, 1); /* discontinuity_flag */ |
|
95 |
+ skip_bits(gb, 1); /* cnt_dropped_flag */ |
|
96 |
+ skip_bits(gb, 8); /* n_frames */ |
|
93 | 97 |
if (full_timestamp_flag) { |
94 |
- skip_bits(&h->gb, 6); /* seconds_value 0..59 */ |
|
95 |
- skip_bits(&h->gb, 6); /* minutes_value 0..59 */ |
|
96 |
- skip_bits(&h->gb, 5); /* hours_value 0..23 */ |
|
98 |
+ skip_bits(gb, 6); /* seconds_value 0..59 */ |
|
99 |
+ skip_bits(gb, 6); /* minutes_value 0..59 */ |
|
100 |
+ skip_bits(gb, 5); /* hours_value 0..23 */ |
|
97 | 101 |
} else { |
98 |
- if (get_bits(&h->gb, 1)) { /* seconds_flag */ |
|
99 |
- skip_bits(&h->gb, 6); /* seconds_value range 0..59 */ |
|
100 |
- if (get_bits(&h->gb, 1)) { /* minutes_flag */ |
|
101 |
- skip_bits(&h->gb, 6); /* minutes_value 0..59 */ |
|
102 |
- if (get_bits(&h->gb, 1)) /* hours_flag */ |
|
103 |
- skip_bits(&h->gb, 5); /* hours_value 0..23 */ |
|
102 |
+ if (get_bits(gb, 1)) { /* seconds_flag */ |
|
103 |
+ skip_bits(gb, 6); /* seconds_value range 0..59 */ |
|
104 |
+ if (get_bits(gb, 1)) { /* minutes_flag */ |
|
105 |
+ skip_bits(gb, 6); /* minutes_value 0..59 */ |
|
106 |
+ if (get_bits(gb, 1)) /* hours_flag */ |
|
107 |
+ skip_bits(gb, 5); /* hours_value 0..23 */ |
|
104 | 108 |
} |
105 | 109 |
} |
106 | 110 |
} |
107 | 111 |
if (sps->time_offset_length > 0) |
108 |
- skip_bits(&h->gb, |
|
112 |
+ skip_bits(gb, |
|
109 | 113 |
sps->time_offset_length); /* time_offset */ |
110 | 114 |
} |
111 | 115 |
} |
112 | 116 |
|
113 |
- if (h->avctx->debug & FF_DEBUG_PICT_INFO) |
|
114 |
- av_log(h->avctx, AV_LOG_DEBUG, "ct_type:%X pic_struct:%d\n", |
|
115 |
- h->sei_ct_type, h->sei_pic_struct); |
|
117 |
+ av_log(logctx, AV_LOG_DEBUG, "ct_type:%X pic_struct:%d\n", |
|
118 |
+ h->ct_type, h->pic_struct); |
|
116 | 119 |
} |
117 | 120 |
return 0; |
118 | 121 |
} |
119 | 122 |
|
120 |
-static int decode_registered_user_data_afd(H264Context *h, int size) |
|
123 |
+static int decode_registered_user_data_afd(H264SEIAFD *h, GetBitContext *gb, int size) |
|
121 | 124 |
{ |
122 | 125 |
int flag; |
123 | 126 |
|
124 | 127 |
if (size-- < 1) |
125 | 128 |
return AVERROR_INVALIDDATA; |
126 |
- skip_bits(&h->gb, 1); // 0 |
|
127 |
- flag = get_bits(&h->gb, 1); // active_format_flag |
|
128 |
- skip_bits(&h->gb, 6); // reserved |
|
129 |
+ skip_bits(gb, 1); // 0 |
|
130 |
+ flag = get_bits(gb, 1); // active_format_flag |
|
131 |
+ skip_bits(gb, 6); // reserved |
|
129 | 132 |
|
130 | 133 |
if (flag) { |
131 | 134 |
if (size-- < 1) |
132 | 135 |
return AVERROR_INVALIDDATA; |
133 |
- skip_bits(&h->gb, 4); // reserved |
|
134 |
- h->active_format_description = get_bits(&h->gb, 4); |
|
135 |
- h->sei_reguserdata_afd_present = 1; |
|
136 |
-#if FF_API_AFD |
|
137 |
-FF_DISABLE_DEPRECATION_WARNINGS |
|
138 |
- h->avctx->dtg_active_format = h->active_format_description; |
|
139 |
-FF_ENABLE_DEPRECATION_WARNINGS |
|
140 |
-#endif /* FF_API_AFD */ |
|
136 |
+ skip_bits(gb, 4); // reserved |
|
137 |
+ h->active_format_description = get_bits(gb, 4); |
|
138 |
+ h->present = 1; |
|
141 | 139 |
} |
142 | 140 |
|
143 | 141 |
return 0; |
144 | 142 |
} |
145 | 143 |
|
146 |
-static int decode_registered_user_data_closed_caption(H264Context *h, int size) |
|
144 |
+static int decode_registered_user_data_closed_caption(H264SEIA53Caption *h, |
|
145 |
+ GetBitContext *gb, void *logctx, |
|
146 |
+ int size) |
|
147 | 147 |
{ |
148 | 148 |
int flag; |
149 | 149 |
int user_data_type_code; |
... | ... |
@@ -152,15 +152,15 @@ static int decode_registered_user_data_closed_caption(H264Context *h, int size) |
152 | 152 |
if (size < 3) |
153 | 153 |
return AVERROR(EINVAL); |
154 | 154 |
|
155 |
- user_data_type_code = get_bits(&h->gb, 8); |
|
155 |
+ user_data_type_code = get_bits(gb, 8); |
|
156 | 156 |
if (user_data_type_code == 0x3) { |
157 |
- skip_bits(&h->gb, 1); // reserved |
|
157 |
+ skip_bits(gb, 1); // reserved |
|
158 | 158 |
|
159 |
- flag = get_bits(&h->gb, 1); // process_cc_data_flag |
|
159 |
+ flag = get_bits(gb, 1); // process_cc_data_flag |
|
160 | 160 |
if (flag) { |
161 |
- skip_bits(&h->gb, 1); // zero bit |
|
162 |
- cc_count = get_bits(&h->gb, 5); |
|
163 |
- skip_bits(&h->gb, 8); // reserved |
|
161 |
+ skip_bits(gb, 1); // zero bit |
|
162 |
+ cc_count = get_bits(gb, 5); |
|
163 |
+ skip_bits(gb, 8); // reserved |
|
164 | 164 |
size -= 2; |
165 | 165 |
|
166 | 166 |
if (cc_count && size >= cc_count * 3) { |
... | ... |
@@ -177,24 +177,25 @@ static int decode_registered_user_data_closed_caption(H264Context *h, int size) |
177 | 177 |
return ret; |
178 | 178 |
|
179 | 179 |
for (i = 0; i < cc_count; i++) { |
180 |
- h->a53_caption[h->a53_caption_size++] = get_bits(&h->gb, 8); |
|
181 |
- h->a53_caption[h->a53_caption_size++] = get_bits(&h->gb, 8); |
|
182 |
- h->a53_caption[h->a53_caption_size++] = get_bits(&h->gb, 8); |
|
180 |
+ h->a53_caption[h->a53_caption_size++] = get_bits(gb, 8); |
|
181 |
+ h->a53_caption[h->a53_caption_size++] = get_bits(gb, 8); |
|
182 |
+ h->a53_caption[h->a53_caption_size++] = get_bits(gb, 8); |
|
183 | 183 |
} |
184 | 184 |
|
185 |
- skip_bits(&h->gb, 8); // marker_bits |
|
185 |
+ skip_bits(gb, 8); // marker_bits |
|
186 | 186 |
} |
187 | 187 |
} |
188 | 188 |
} else { |
189 | 189 |
int i; |
190 | 190 |
for (i = 0; i < size - 1; i++) |
191 |
- skip_bits(&h->gb, 8); |
|
191 |
+ skip_bits(gb, 8); |
|
192 | 192 |
} |
193 | 193 |
|
194 | 194 |
return 0; |
195 | 195 |
} |
196 | 196 |
|
197 |
-static int decode_registered_user_data(H264Context *h, int size) |
|
197 |
+static int decode_registered_user_data(H264SEIContext *h, GetBitContext *gb, |
|
198 |
+ void *logctx, int size) |
|
198 | 199 |
{ |
199 | 200 |
uint32_t country_code; |
200 | 201 |
uint32_t user_identifier; |
... | ... |
@@ -203,31 +204,33 @@ static int decode_registered_user_data(H264Context *h, int size) |
203 | 203 |
return AVERROR_INVALIDDATA; |
204 | 204 |
size -= 7; |
205 | 205 |
|
206 |
- country_code = get_bits(&h->gb, 8); // itu_t_t35_country_code |
|
206 |
+ country_code = get_bits(gb, 8); // itu_t_t35_country_code |
|
207 | 207 |
if (country_code == 0xFF) { |
208 |
- skip_bits(&h->gb, 8); // itu_t_t35_country_code_extension_byte |
|
208 |
+ skip_bits(gb, 8); // itu_t_t35_country_code_extension_byte |
|
209 | 209 |
size--; |
210 | 210 |
} |
211 | 211 |
|
212 | 212 |
/* itu_t_t35_payload_byte follows */ |
213 |
- skip_bits(&h->gb, 8); // terminal provider code |
|
214 |
- skip_bits(&h->gb, 8); // terminal provider oriented code |
|
215 |
- user_identifier = get_bits_long(&h->gb, 32); |
|
213 |
+ skip_bits(gb, 8); // terminal provider code |
|
214 |
+ skip_bits(gb, 8); // terminal provider oriented code |
|
215 |
+ user_identifier = get_bits_long(gb, 32); |
|
216 | 216 |
|
217 | 217 |
switch (user_identifier) { |
218 | 218 |
case MKBETAG('D', 'T', 'G', '1'): // afd_data |
219 |
- return decode_registered_user_data_afd(h, size); |
|
219 |
+ return decode_registered_user_data_afd(&h->afd, gb, size); |
|
220 | 220 |
case MKBETAG('G', 'A', '9', '4'): // closed captions |
221 |
- return decode_registered_user_data_closed_caption(h, size); |
|
221 |
+ return decode_registered_user_data_closed_caption(&h->a53_caption, gb, |
|
222 |
+ logctx, size); |
|
222 | 223 |
default: |
223 |
- skip_bits(&h->gb, size * 8); |
|
224 |
+ skip_bits(gb, size * 8); |
|
224 | 225 |
break; |
225 | 226 |
} |
226 | 227 |
|
227 | 228 |
return 0; |
228 | 229 |
} |
229 | 230 |
|
230 |
-static int decode_unregistered_user_data(H264Context *h, int size) |
|
231 |
+static int decode_unregistered_user_data(H264SEIUnregistered *h, GetBitContext *gb, |
|
232 |
+ void *logctx, int size) |
|
231 | 233 |
{ |
232 | 234 |
uint8_t *user_data; |
233 | 235 |
int e, build, i; |
... | ... |
@@ -240,7 +243,7 @@ static int decode_unregistered_user_data(H264Context *h, int size) |
240 | 240 |
return AVERROR(ENOMEM); |
241 | 241 |
|
242 | 242 |
for (i = 0; i < size + 16; i++) |
243 |
- user_data[i] = get_bits(&h->gb, 8); |
|
243 |
+ user_data[i] = get_bits(gb, 8); |
|
244 | 244 |
|
245 | 245 |
user_data[i] = 0; |
246 | 246 |
e = sscanf(user_data + 16, "x264 - core %d", &build); |
... | ... |
@@ -250,114 +253,100 @@ static int decode_unregistered_user_data(H264Context *h, int size) |
250 | 250 |
h->x264_build = 67; |
251 | 251 |
|
252 | 252 |
if (strlen(user_data + 16) > 0) |
253 |
- av_log(h->avctx, AV_LOG_DEBUG, "user data:\"%s\"\n", user_data + 16); |
|
253 |
+ av_log(logctx, AV_LOG_DEBUG, "user data:\"%s\"\n", user_data + 16); |
|
254 | 254 |
|
255 | 255 |
av_free(user_data); |
256 | 256 |
return 0; |
257 | 257 |
} |
258 | 258 |
|
259 |
-static int decode_recovery_point(H264Context *h) |
|
259 |
+static int decode_recovery_point(H264SEIRecoveryPoint *h, GetBitContext *gb) |
|
260 | 260 |
{ |
261 |
- h->sei_recovery_frame_cnt = get_ue_golomb_long(&h->gb); |
|
261 |
+ h->recovery_frame_cnt = get_ue_golomb_long(gb); |
|
262 | 262 |
|
263 | 263 |
/* 1b exact_match_flag, |
264 | 264 |
* 1b broken_link_flag, |
265 | 265 |
* 2b changing_slice_group_idc */ |
266 |
- skip_bits(&h->gb, 4); |
|
267 |
- |
|
268 |
- if (h->avctx->debug & FF_DEBUG_PICT_INFO) |
|
269 |
- av_log(h->avctx, AV_LOG_DEBUG, "sei_recovery_frame_cnt: %d\n", h->sei_recovery_frame_cnt); |
|
270 |
- |
|
271 |
- h->has_recovery_point = 1; |
|
266 |
+ skip_bits(gb, 4); |
|
272 | 267 |
|
273 | 268 |
return 0; |
274 | 269 |
} |
275 | 270 |
|
276 |
-static int decode_buffering_period(H264Context *h) |
|
271 |
+static int decode_buffering_period(H264SEIBufferingPeriod *h, GetBitContext *gb, |
|
272 |
+ const H264ParamSets *ps, void *logctx) |
|
277 | 273 |
{ |
278 | 274 |
unsigned int sps_id; |
279 | 275 |
int sched_sel_idx; |
280 | 276 |
SPS *sps; |
281 | 277 |
|
282 |
- sps_id = get_ue_golomb_31(&h->gb); |
|
283 |
- if (sps_id > 31 || !h->ps.sps_list[sps_id]) { |
|
284 |
- av_log(h->avctx, AV_LOG_ERROR, |
|
278 |
+ sps_id = get_ue_golomb_31(gb); |
|
279 |
+ if (sps_id > 31 || !ps->sps_list[sps_id]) { |
|
280 |
+ av_log(logctx, AV_LOG_ERROR, |
|
285 | 281 |
"non-existing SPS %d referenced in buffering period\n", sps_id); |
286 | 282 |
return AVERROR_INVALIDDATA; |
287 | 283 |
} |
288 |
- sps = (SPS*)h->ps.sps_list[sps_id]->data; |
|
284 |
+ sps = (SPS*)ps->sps_list[sps_id]->data; |
|
289 | 285 |
|
290 | 286 |
// NOTE: This is really so duplicated in the standard... See H.264, D.1.1 |
291 | 287 |
if (sps->nal_hrd_parameters_present_flag) { |
292 | 288 |
for (sched_sel_idx = 0; sched_sel_idx < sps->cpb_cnt; sched_sel_idx++) { |
293 | 289 |
h->initial_cpb_removal_delay[sched_sel_idx] = |
294 |
- get_bits_long(&h->gb, sps->initial_cpb_removal_delay_length); |
|
290 |
+ get_bits_long(gb, sps->initial_cpb_removal_delay_length); |
|
295 | 291 |
// initial_cpb_removal_delay_offset |
296 |
- skip_bits(&h->gb, sps->initial_cpb_removal_delay_length); |
|
292 |
+ skip_bits(gb, sps->initial_cpb_removal_delay_length); |
|
297 | 293 |
} |
298 | 294 |
} |
299 | 295 |
if (sps->vcl_hrd_parameters_present_flag) { |
300 | 296 |
for (sched_sel_idx = 0; sched_sel_idx < sps->cpb_cnt; sched_sel_idx++) { |
301 | 297 |
h->initial_cpb_removal_delay[sched_sel_idx] = |
302 |
- get_bits_long(&h->gb, sps->initial_cpb_removal_delay_length); |
|
298 |
+ get_bits_long(gb, sps->initial_cpb_removal_delay_length); |
|
303 | 299 |
// initial_cpb_removal_delay_offset |
304 |
- skip_bits(&h->gb, sps->initial_cpb_removal_delay_length); |
|
300 |
+ skip_bits(gb, sps->initial_cpb_removal_delay_length); |
|
305 | 301 |
} |
306 | 302 |
} |
307 | 303 |
|
308 |
- h->sei_buffering_period_present = 1; |
|
304 |
+ h->present = 1; |
|
309 | 305 |
return 0; |
310 | 306 |
} |
311 | 307 |
|
312 |
-static int decode_frame_packing_arrangement(H264Context *h) |
|
308 |
+static int decode_frame_packing_arrangement(H264SEIFramePacking *h, |
|
309 |
+ GetBitContext *gb) |
|
313 | 310 |
{ |
314 |
- h->sei_fpa.frame_packing_arrangement_id = get_ue_golomb_long(&h->gb); |
|
315 |
- h->sei_fpa.frame_packing_arrangement_cancel_flag = get_bits1(&h->gb); |
|
316 |
- h->sei_frame_packing_present = !h->sei_fpa.frame_packing_arrangement_cancel_flag; |
|
317 |
- |
|
318 |
- if (h->sei_frame_packing_present) { |
|
319 |
- h->sei_fpa.frame_packing_arrangement_type = |
|
320 |
- h->frame_packing_arrangement_type = get_bits(&h->gb, 7); |
|
321 |
- h->sei_fpa.quincunx_sampling_flag = |
|
322 |
- h->quincunx_subsampling = get_bits1(&h->gb); |
|
323 |
- h->sei_fpa.content_interpretation_type = |
|
324 |
- h->content_interpretation_type = get_bits(&h->gb, 6); |
|
311 |
+ h->frame_packing_arrangement_id = get_ue_golomb_long(gb); |
|
312 |
+ h->frame_packing_arrangement_cancel_flag = get_bits1(gb); |
|
313 |
+ h->present = !h->frame_packing_arrangement_cancel_flag; |
|
314 |
+ |
|
315 |
+ if (h->present) { |
|
316 |
+ h->frame_packing_arrangement_type = get_bits(gb, 7); |
|
317 |
+ h->quincunx_sampling_flag = get_bits1(gb); |
|
318 |
+ h->content_interpretation_type = get_bits(gb, 6); |
|
325 | 319 |
|
326 | 320 |
// the following skips: spatial_flipping_flag, frame0_flipped_flag, |
327 | 321 |
// field_views_flag, current_frame_is_frame0_flag, |
328 | 322 |
// frame0_self_contained_flag, frame1_self_contained_flag |
329 |
- skip_bits(&h->gb, 6); |
|
323 |
+ skip_bits(gb, 6); |
|
330 | 324 |
|
331 |
- if (!h->quincunx_subsampling && h->frame_packing_arrangement_type != 5) |
|
332 |
- skip_bits(&h->gb, 16); // frame[01]_grid_position_[xy] |
|
333 |
- skip_bits(&h->gb, 8); // frame_packing_arrangement_reserved_byte |
|
334 |
- h->sei_fpa.frame_packing_arrangement_repetition_period = get_ue_golomb_long(&h->gb); |
|
325 |
+ if (!h->quincunx_sampling_flag && h->frame_packing_arrangement_type != 5) |
|
326 |
+ skip_bits(gb, 16); // frame[01]_grid_position_[xy] |
|
327 |
+ skip_bits(gb, 8); // frame_packing_arrangement_reserved_byte |
|
328 |
+ h->frame_packing_arrangement_repetition_period = get_ue_golomb_long(gb); |
|
335 | 329 |
} |
336 |
- skip_bits1(&h->gb); // frame_packing_arrangement_extension_flag |
|
337 |
- |
|
338 |
- if (h->avctx->debug & FF_DEBUG_PICT_INFO) |
|
339 |
- av_log(h->avctx, AV_LOG_DEBUG, "SEI FPA %d %d %d %d %d %d\n", |
|
340 |
- h->sei_fpa.frame_packing_arrangement_id, |
|
341 |
- h->sei_fpa.frame_packing_arrangement_cancel_flag, |
|
342 |
- h->sei_fpa.frame_packing_arrangement_type, |
|
343 |
- h->sei_fpa.quincunx_sampling_flag, |
|
344 |
- h->sei_fpa.content_interpretation_type, |
|
345 |
- h->sei_fpa.frame_packing_arrangement_repetition_period); |
|
330 |
+ skip_bits1(gb); // frame_packing_arrangement_extension_flag |
|
346 | 331 |
|
347 | 332 |
return 0; |
348 | 333 |
} |
349 | 334 |
|
350 |
-static int decode_display_orientation(H264Context *h) |
|
335 |
+static int decode_display_orientation(H264SEIDisplayOrientation *h, |
|
336 |
+ GetBitContext *gb) |
|
351 | 337 |
{ |
352 |
- h->sei_display_orientation_present = !get_bits1(&h->gb); |
|
338 |
+ h->present = !get_bits1(gb); |
|
353 | 339 |
|
354 |
- if (h->sei_display_orientation_present) { |
|
355 |
- h->sei_hflip = get_bits1(&h->gb); // hor_flip |
|
356 |
- h->sei_vflip = get_bits1(&h->gb); // ver_flip |
|
340 |
+ if (h->present) { |
|
341 |
+ h->hflip = get_bits1(gb); // hor_flip |
|
342 |
+ h->vflip = get_bits1(gb); // ver_flip |
|
357 | 343 |
|
358 |
- h->sei_anticlockwise_rotation = get_bits(&h->gb, 16); |
|
359 |
- get_ue_golomb_long(&h->gb); // display_orientation_repetition_period |
|
360 |
- skip_bits1(&h->gb); // display_orientation_extension_flag |
|
344 |
+ h->anticlockwise_rotation = get_bits(gb, 16); |
|
345 |
+ get_ue_golomb_long(gb); // display_orientation_repetition_period |
|
346 |
+ skip_bits1(gb); // display_orientation_extension_flag |
|
361 | 347 |
} |
362 | 348 |
|
363 | 349 |
return 0; |
... | ... |
@@ -388,107 +377,105 @@ static int decode_green_metadata(H264SEIGreenMetaData *h, GetBitContext *gb) |
388 | 388 |
return 0; |
389 | 389 |
} |
390 | 390 |
|
391 |
-int ff_h264_decode_sei(H264Context *h) |
|
391 |
+int ff_h264_sei_decode(H264SEIContext *h, GetBitContext *gb, |
|
392 |
+ const H264ParamSets *ps, void *logctx) |
|
392 | 393 |
{ |
393 |
- while (get_bits_left(&h->gb) > 16 && show_bits(&h->gb, 16)) { |
|
394 |
+ while (get_bits_left(gb) > 16 && show_bits(gb, 16)) { |
|
394 | 395 |
int type = 0; |
395 | 396 |
unsigned size = 0; |
396 | 397 |
unsigned next; |
397 | 398 |
int ret = 0; |
398 | 399 |
|
399 | 400 |
do { |
400 |
- if (get_bits_left(&h->gb) < 8) |
|
401 |
+ if (get_bits_left(gb) < 8) |
|
401 | 402 |
return AVERROR_INVALIDDATA; |
402 |
- type += show_bits(&h->gb, 8); |
|
403 |
- } while (get_bits(&h->gb, 8) == 255); |
|
403 |
+ type += show_bits(gb, 8); |
|
404 |
+ } while (get_bits(gb, 8) == 255); |
|
404 | 405 |
|
405 | 406 |
do { |
406 |
- if (get_bits_left(&h->gb) < 8) |
|
407 |
+ if (get_bits_left(gb) < 8) |
|
407 | 408 |
return AVERROR_INVALIDDATA; |
408 |
- size += show_bits(&h->gb, 8); |
|
409 |
- } while (get_bits(&h->gb, 8) == 255); |
|
410 |
- |
|
411 |
- if (h->avctx->debug&FF_DEBUG_STARTCODE) |
|
412 |
- av_log(h->avctx, AV_LOG_DEBUG, "SEI %d len:%d\n", type, size); |
|
409 |
+ size += show_bits(gb, 8); |
|
410 |
+ } while (get_bits(gb, 8) == 255); |
|
413 | 411 |
|
414 |
- if (size > get_bits_left(&h->gb) / 8) { |
|
415 |
- av_log(h->avctx, AV_LOG_ERROR, "SEI type %d size %d truncated at %d\n", |
|
416 |
- type, 8*size, get_bits_left(&h->gb)); |
|
412 |
+ if (size > get_bits_left(gb) / 8) { |
|
413 |
+ av_log(logctx, AV_LOG_ERROR, "SEI type %d size %d truncated at %d\n", |
|
414 |
+ type, 8*size, get_bits_left(gb)); |
|
417 | 415 |
return AVERROR_INVALIDDATA; |
418 | 416 |
} |
419 |
- next = get_bits_count(&h->gb) + 8 * size; |
|
417 |
+ next = get_bits_count(gb) + 8 * size; |
|
420 | 418 |
|
421 | 419 |
switch (type) { |
422 | 420 |
case SEI_TYPE_PIC_TIMING: // Picture timing SEI |
423 |
- ret = decode_picture_timing(h); |
|
421 |
+ ret = decode_picture_timing(&h->picture_timing, gb, ps, logctx); |
|
424 | 422 |
break; |
425 | 423 |
case SEI_TYPE_USER_DATA_REGISTERED: |
426 |
- ret = decode_registered_user_data(h, size); |
|
424 |
+ ret = decode_registered_user_data(h, gb, logctx, size); |
|
427 | 425 |
break; |
428 | 426 |
case SEI_TYPE_USER_DATA_UNREGISTERED: |
429 |
- ret = decode_unregistered_user_data(h, size); |
|
427 |
+ ret = decode_unregistered_user_data(&h->unregistered, gb, logctx, size); |
|
430 | 428 |
break; |
431 | 429 |
case SEI_TYPE_RECOVERY_POINT: |
432 |
- ret = decode_recovery_point(h); |
|
430 |
+ ret = decode_recovery_point(&h->recovery_point, gb); |
|
433 | 431 |
break; |
434 | 432 |
case SEI_TYPE_BUFFERING_PERIOD: |
435 |
- ret = decode_buffering_period(h); |
|
433 |
+ ret = decode_buffering_period(&h->buffering_period, gb, ps, logctx); |
|
436 | 434 |
break; |
437 | 435 |
case SEI_TYPE_FRAME_PACKING: |
438 |
- ret = decode_frame_packing_arrangement(h); |
|
436 |
+ ret = decode_frame_packing_arrangement(&h->frame_packing, gb); |
|
439 | 437 |
break; |
440 | 438 |
case SEI_TYPE_DISPLAY_ORIENTATION: |
441 |
- ret = decode_display_orientation(h); |
|
439 |
+ ret = decode_display_orientation(&h->display_orientation, gb); |
|
442 | 440 |
break; |
443 | 441 |
case SEI_TYPE_GREEN_METADATA: |
444 |
- ret = decode_green_metadata(&h->sei_green_metadata, &h->gb); |
|
442 |
+ ret = decode_green_metadata(&h->green_metadata, gb); |
|
445 | 443 |
break; |
446 | 444 |
default: |
447 |
- av_log(h->avctx, AV_LOG_DEBUG, "unknown SEI type %d\n", type); |
|
445 |
+ av_log(logctx, AV_LOG_DEBUG, "unknown SEI type %d\n", type); |
|
448 | 446 |
} |
449 | 447 |
if (ret < 0) |
450 | 448 |
return ret; |
451 | 449 |
|
452 |
- skip_bits_long(&h->gb, next - get_bits_count(&h->gb)); |
|
450 |
+ skip_bits_long(gb, next - get_bits_count(gb)); |
|
453 | 451 |
|
454 | 452 |
// FIXME check bits here |
455 |
- align_get_bits(&h->gb); |
|
453 |
+ align_get_bits(gb); |
|
456 | 454 |
} |
457 | 455 |
|
458 | 456 |
return 0; |
459 | 457 |
} |
460 | 458 |
|
461 |
-const char* ff_h264_sei_stereo_mode(H264Context *h) |
|
459 |
+const char *ff_h264_sei_stereo_mode(const H264SEIFramePacking *h) |
|
462 | 460 |
{ |
463 |
- if (h->sei_fpa.frame_packing_arrangement_cancel_flag == 0) { |
|
464 |
- switch (h->sei_fpa.frame_packing_arrangement_type) { |
|
461 |
+ if (h->frame_packing_arrangement_cancel_flag == 0) { |
|
462 |
+ switch (h->frame_packing_arrangement_type) { |
|
465 | 463 |
case SEI_FPA_TYPE_CHECKERBOARD: |
466 |
- if (h->sei_fpa.content_interpretation_type == 2) |
|
464 |
+ if (h->content_interpretation_type == 2) |
|
467 | 465 |
return "checkerboard_rl"; |
468 | 466 |
else |
469 | 467 |
return "checkerboard_lr"; |
470 | 468 |
case SEI_FPA_TYPE_INTERLEAVE_COLUMN: |
471 |
- if (h->sei_fpa.content_interpretation_type == 2) |
|
469 |
+ if (h->content_interpretation_type == 2) |
|
472 | 470 |
return "col_interleaved_rl"; |
473 | 471 |
else |
474 | 472 |
return "col_interleaved_lr"; |
475 | 473 |
case SEI_FPA_TYPE_INTERLEAVE_ROW: |
476 |
- if (h->sei_fpa.content_interpretation_type == 2) |
|
474 |
+ if (h->content_interpretation_type == 2) |
|
477 | 475 |
return "row_interleaved_rl"; |
478 | 476 |
else |
479 | 477 |
return "row_interleaved_lr"; |
480 | 478 |
case SEI_FPA_TYPE_SIDE_BY_SIDE: |
481 |
- if (h->sei_fpa.content_interpretation_type == 2) |
|
479 |
+ if (h->content_interpretation_type == 2) |
|
482 | 480 |
return "right_left"; |
483 | 481 |
else |
484 | 482 |
return "left_right"; |
485 | 483 |
case SEI_FPA_TYPE_TOP_BOTTOM: |
486 |
- if (h->sei_fpa.content_interpretation_type == 2) |
|
484 |
+ if (h->content_interpretation_type == 2) |
|
487 | 485 |
return "bottom_top"; |
488 | 486 |
else |
489 | 487 |
return "top_bottom"; |
490 | 488 |
case SEI_FPA_TYPE_INTERLEAVE_TEMPORAL: |
491 |
- if (h->sei_fpa.content_interpretation_type == 2) |
|
489 |
+ if (h->content_interpretation_type == 2) |
|
492 | 490 |
return "block_rl"; |
493 | 491 |
else |
494 | 492 |
return "block_lr"; |
... | ... |
@@ -496,7 +483,7 @@ const char* ff_h264_sei_stereo_mode(H264Context *h) |
496 | 496 |
default: |
497 | 497 |
return "mono"; |
498 | 498 |
} |
499 |
- } else if (h->sei_fpa.frame_packing_arrangement_cancel_flag == 1) { |
|
499 |
+ } else if (h->frame_packing_arrangement_cancel_flag == 1) { |
|
500 | 500 |
return "mono"; |
501 | 501 |
} else { |
502 | 502 |
return NULL; |
503 | 503 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,173 @@ |
0 |
+/* |
|
1 |
+ * This file is part of FFmpeg. |
|
2 |
+ * |
|
3 |
+ * FFmpeg is free software; you can redistribute it and/or |
|
4 |
+ * modify it under the terms of the GNU Lesser General Public |
|
5 |
+ * License as published by the Free Software Foundation; either |
|
6 |
+ * version 2.1 of the License, or (at your option) any later version. |
|
7 |
+ * |
|
8 |
+ * FFmpeg is distributed in the hope that it will be useful, |
|
9 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
11 |
+ * Lesser General Public License for more details. |
|
12 |
+ * |
|
13 |
+ * You should have received a copy of the GNU Lesser General Public |
|
14 |
+ * License along with FFmpeg; if not, write to the Free Software |
|
15 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
16 |
+ */ |
|
17 |
+ |
|
18 |
+#ifndef AVCODEC_H264_SEI_H |
|
19 |
+#define AVCODEC_H264_SEI_H |
|
20 |
+ |
|
21 |
+#include "get_bits.h" |
|
22 |
+ |
|
23 |
+/** |
|
24 |
+ * SEI message types |
|
25 |
+ */ |
|
26 |
+typedef enum { |
|
27 |
+ SEI_TYPE_BUFFERING_PERIOD = 0, ///< buffering period (H.264, D.1.1) |
|
28 |
+ SEI_TYPE_PIC_TIMING = 1, ///< picture timing |
|
29 |
+ SEI_TYPE_USER_DATA_REGISTERED = 4, ///< registered user data as specified by Rec. ITU-T T.35 |
|
30 |
+ SEI_TYPE_USER_DATA_UNREGISTERED = 5, ///< unregistered user data |
|
31 |
+ SEI_TYPE_RECOVERY_POINT = 6, ///< recovery point (frame # to decoder sync) |
|
32 |
+ SEI_TYPE_FRAME_PACKING = 45, ///< frame packing arrangement |
|
33 |
+ SEI_TYPE_DISPLAY_ORIENTATION = 47, ///< display orientation |
|
34 |
+ SEI_TYPE_GREEN_METADATA = 56 ///< GreenMPEG information |
|
35 |
+} SEI_Type; |
|
36 |
+ |
|
37 |
+/** |
|
38 |
+ * pic_struct in picture timing SEI message |
|
39 |
+ */ |
|
40 |
+typedef enum { |
|
41 |
+ SEI_PIC_STRUCT_FRAME = 0, ///< 0: %frame |
|
42 |
+ SEI_PIC_STRUCT_TOP_FIELD = 1, ///< 1: top field |
|
43 |
+ SEI_PIC_STRUCT_BOTTOM_FIELD = 2, ///< 2: bottom field |
|
44 |
+ SEI_PIC_STRUCT_TOP_BOTTOM = 3, ///< 3: top field, bottom field, in that order |
|
45 |
+ SEI_PIC_STRUCT_BOTTOM_TOP = 4, ///< 4: bottom field, top field, in that order |
|
46 |
+ SEI_PIC_STRUCT_TOP_BOTTOM_TOP = 5, ///< 5: top field, bottom field, top field repeated, in that order |
|
47 |
+ SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM = 6, ///< 6: bottom field, top field, bottom field repeated, in that order |
|
48 |
+ SEI_PIC_STRUCT_FRAME_DOUBLING = 7, ///< 7: %frame doubling |
|
49 |
+ SEI_PIC_STRUCT_FRAME_TRIPLING = 8 ///< 8: %frame tripling |
|
50 |
+} SEI_PicStructType; |
|
51 |
+ |
|
52 |
+/** |
|
53 |
+ * frame_packing_arrangement types |
|
54 |
+ */ |
|
55 |
+typedef enum { |
|
56 |
+ SEI_FPA_TYPE_CHECKERBOARD = 0, |
|
57 |
+ SEI_FPA_TYPE_INTERLEAVE_COLUMN = 1, |
|
58 |
+ SEI_FPA_TYPE_INTERLEAVE_ROW = 2, |
|
59 |
+ SEI_FPA_TYPE_SIDE_BY_SIDE = 3, |
|
60 |
+ SEI_FPA_TYPE_TOP_BOTTOM = 4, |
|
61 |
+ SEI_FPA_TYPE_INTERLEAVE_TEMPORAL = 5, |
|
62 |
+ SEI_FPA_TYPE_2D = 6, |
|
63 |
+} SEI_FpaType; |
|
64 |
+ |
|
65 |
+typedef struct H264SEIPictureTiming { |
|
66 |
+ SEI_PicStructType pic_struct; |
|
67 |
+ |
|
68 |
+ /** |
|
69 |
+ * Bit set of clock types for fields/frames in picture timing SEI message. |
|
70 |
+ * For each found ct_type, appropriate bit is set (e.g., bit 1 for |
|
71 |
+ * interlaced). |
|
72 |
+ */ |
|
73 |
+ int ct_type; |
|
74 |
+ |
|
75 |
+ /** |
|
76 |
+ * dpb_output_delay in picture timing SEI message, see H.264 C.2.2 |
|
77 |
+ */ |
|
78 |
+ int dpb_output_delay; |
|
79 |
+ |
|
80 |
+ /** |
|
81 |
+ * cpb_removal_delay in picture timing SEI message, see H.264 C.1.2 |
|
82 |
+ */ |
|
83 |
+ int cpb_removal_delay; |
|
84 |
+} H264SEIPictureTiming; |
|
85 |
+ |
|
86 |
+typedef struct H264SEIAFD { |
|
87 |
+ int present; |
|
88 |
+ uint8_t active_format_description; |
|
89 |
+} H264SEIAFD; |
|
90 |
+ |
|
91 |
+typedef struct H264SEIA53Caption { |
|
92 |
+ int a53_caption_size; |
|
93 |
+ uint8_t *a53_caption; |
|
94 |
+} H264SEIA53Caption; |
|
95 |
+ |
|
96 |
+typedef struct H264SEIUnregistered { |
|
97 |
+ int x264_build; |
|
98 |
+} H264SEIUnregistered; |
|
99 |
+ |
|
100 |
+typedef struct H264SEIRecoveryPoint { |
|
101 |
+ /** |
|
102 |
+ * recovery_frame_cnt |
|
103 |
+ * |
|
104 |
+ * Set to -1 if no recovery point SEI message found or to number of frames |
|
105 |
+ * before playback synchronizes. Frames having recovery point are key |
|
106 |
+ * frames. |
|
107 |
+ */ |
|
108 |
+ int recovery_frame_cnt; |
|
109 |
+} H264SEIRecoveryPoint; |
|
110 |
+ |
|
111 |
+typedef struct H264SEIBufferingPeriod { |
|
112 |
+ int present; ///< Buffering period SEI flag |
|
113 |
+ int initial_cpb_removal_delay[32]; ///< Initial timestamps for CPBs |
|
114 |
+} H264SEIBufferingPeriod; |
|
115 |
+ |
|
116 |
+typedef struct H264SEIFramePacking { |
|
117 |
+ int present; |
|
118 |
+ int frame_packing_arrangement_id; |
|
119 |
+ int frame_packing_arrangement_cancel_flag; ///< is previous arrangement canceled, -1 if never received |
|
120 |
+ SEI_FpaType frame_packing_arrangement_type; |
|
121 |
+ int frame_packing_arrangement_repetition_period; |
|
122 |
+ int content_interpretation_type; |
|
123 |
+ int quincunx_sampling_flag; |
|
124 |
+} H264SEIFramePacking; |
|
125 |
+ |
|
126 |
+typedef struct H264SEIDisplayOrientation { |
|
127 |
+ int present; |
|
128 |
+ int anticlockwise_rotation; |
|
129 |
+ int hflip, vflip; |
|
130 |
+} H264SEIDisplayOrientation; |
|
131 |
+ |
|
132 |
+typedef struct H264SEIGreenMetaData { |
|
133 |
+ uint8_t green_metadata_type; |
|
134 |
+ uint8_t period_type; |
|
135 |
+ uint16_t num_seconds; |
|
136 |
+ uint16_t num_pictures; |
|
137 |
+ uint8_t percent_non_zero_macroblocks; |
|
138 |
+ uint8_t percent_intra_coded_macroblocks; |
|
139 |
+ uint8_t percent_six_tap_filtering; |
|
140 |
+ uint8_t percent_alpha_point_deblocking_instance; |
|
141 |
+ uint8_t xsd_metric_type; |
|
142 |
+ uint16_t xsd_metric_value; |
|
143 |
+} H264SEIGreenMetaData; |
|
144 |
+ |
|
145 |
+typedef struct H264SEIContext { |
|
146 |
+ H264SEIPictureTiming picture_timing; |
|
147 |
+ H264SEIAFD afd; |
|
148 |
+ H264SEIA53Caption a53_caption; |
|
149 |
+ H264SEIUnregistered unregistered; |
|
150 |
+ H264SEIRecoveryPoint recovery_point; |
|
151 |
+ H264SEIBufferingPeriod buffering_period; |
|
152 |
+ H264SEIFramePacking frame_packing; |
|
153 |
+ H264SEIDisplayOrientation display_orientation; |
|
154 |
+ H264SEIGreenMetaData green_metadata; |
|
155 |
+} H264SEIContext; |
|
156 |
+ |
|
157 |
+struct H264ParamSets; |
|
158 |
+ |
|
159 |
+int ff_h264_sei_decode(H264SEIContext *h, GetBitContext *gb, |
|
160 |
+ const struct H264ParamSets *ps, void *logctx); |
|
161 |
+ |
|
162 |
+/** |
|
163 |
+ * Reset SEI values at the beginning of the frame. |
|
164 |
+ */ |
|
165 |
+void ff_h264_sei_uninit(H264SEIContext *h); |
|
166 |
+ |
|
167 |
+/** |
|
168 |
+ * Get stereo_mode string from the h264 frame_packing_arrangement |
|
169 |
+ */ |
|
170 |
+const char *ff_h264_sei_stereo_mode(const H264SEIFramePacking *h); |
|
171 |
+ |
|
172 |
+#endif /* AVCODEC_H264_SEI_H */ |
... | ... |
@@ -418,7 +418,7 @@ int ff_h264_update_thread_context(AVCodecContext *dst, |
418 | 418 |
// extradata/NAL handling |
419 | 419 |
h->is_avc = h1->is_avc; |
420 | 420 |
h->nal_length_size = h1->nal_length_size; |
421 |
- h->x264_build = h1->x264_build; |
|
421 |
+ h->sei.unregistered.x264_build = h1->sei.unregistered.x264_build; |
|
422 | 422 |
|
423 | 423 |
// POC timing |
424 | 424 |
copy_fields(h, h1, poc, current_slice); |
... | ... |
@@ -486,7 +486,7 @@ static int h264_frame_start(H264Context *h) |
486 | 486 |
pic->mmco_reset = 0; |
487 | 487 |
pic->recovered = 0; |
488 | 488 |
pic->invalid_gap = 0; |
489 |
- pic->sei_recovery_frame_cnt = h->sei_recovery_frame_cnt; |
|
489 |
+ pic->sei_recovery_frame_cnt = h->sei.recovery_point.recovery_frame_cnt; |
|
490 | 490 |
|
491 | 491 |
if ((ret = alloc_picture(h, pic)) < 0) |
492 | 492 |
return ret; |
... | ... |
@@ -913,7 +913,7 @@ static int h264_slice_header_init(H264Context *h) |
913 | 913 |
|
914 | 914 |
if (sps->timing_info_present_flag) { |
915 | 915 |
int64_t den = sps->time_scale; |
916 |
- if (h->x264_build < 44U) |
|
916 |
+ if (h->sei.unregistered.x264_build < 44U) |
|
917 | 917 |
den *= 2; |
918 | 918 |
av_reduce(&h->avctx->framerate.den, &h->avctx->framerate.num, |
919 | 919 |
sps->num_units_in_tick * h->avctx->ticks_per_frame, den, 1 << 30); |
... | ... |
@@ -1126,7 +1126,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) |
1126 | 1126 |
(h->avctx->skip_frame >= AVDISCARD_NONREF && !h->nal_ref_idc) || |
1127 | 1127 |
(h->avctx->skip_frame >= AVDISCARD_BIDIR && sl->slice_type_nos == AV_PICTURE_TYPE_B) || |
1128 | 1128 |
(h->avctx->skip_frame >= AVDISCARD_NONINTRA && sl->slice_type_nos != AV_PICTURE_TYPE_I) || |
1129 |
- (h->avctx->skip_frame >= AVDISCARD_NONKEY && h->nal_unit_type != NAL_IDR_SLICE && h->sei_recovery_frame_cnt < 0) || |
|
1129 |
+ (h->avctx->skip_frame >= AVDISCARD_NONKEY && h->nal_unit_type != NAL_IDR_SLICE && h->sei.recovery_point.recovery_frame_cnt < 0) || |
|
1130 | 1130 |
h->avctx->skip_frame >= AVDISCARD_ALL) { |
1131 | 1131 |
return SLICE_SKIPED; |
1132 | 1132 |
} |