Signed-off-by: Vittorio Giovara <vittorio.giovara@gmail.com>tags/n2.3
| @@ -25,6 +25,7 @@ | |||||
| #include "libavutil/attributes.h" | #include "libavutil/attributes.h" | ||||
| #include "libavutil/common.h" | #include "libavutil/common.h" | ||||
| #include "libavutil/display.h" | |||||
| #include "libavutil/internal.h" | #include "libavutil/internal.h" | ||||
| #include "libavutil/md5.h" | #include "libavutil/md5.h" | ||||
| #include "libavutil/opt.h" | #include "libavutil/opt.h" | ||||
| @@ -2457,6 +2458,20 @@ static int set_side_data(HEVCContext *s) | |||||
| stereo->flags = AV_STEREO3D_FLAG_INVERT; | stereo->flags = AV_STEREO3D_FLAG_INVERT; | ||||
| } | } | ||||
| if (s->sei_display_orientation_present && | |||||
| (s->sei_anticlockwise_rotation || s->sei_hflip || s->sei_vflip)) { | |||||
| double angle = s->sei_anticlockwise_rotation * 360 / (double) (1 << 16); | |||||
| AVFrameSideData *rotation = av_frame_new_side_data(out, | |||||
| AV_FRAME_DATA_DISPLAYMATRIX, | |||||
| sizeof(int32_t) * 9); | |||||
| if (!rotation) | |||||
| return AVERROR(ENOMEM); | |||||
| av_display_rotation_set((int32_t *)rotation->data, angle); | |||||
| av_display_matrix_flip((int32_t *)rotation->data, | |||||
| s->sei_vflip, s->sei_hflip); | |||||
| } | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -859,6 +859,11 @@ typedef struct HEVCContext { | |||||
| int frame_packing_arrangement_type; | int frame_packing_arrangement_type; | ||||
| int content_interpretation_type; | int content_interpretation_type; | ||||
| int quincunx_subsampling; | int quincunx_subsampling; | ||||
| /** display orientation */ | |||||
| int sei_display_orientation_present; | |||||
| int sei_anticlockwise_rotation; | |||||
| int sei_hflip, sei_vflip; | |||||
| } HEVCContext; | } HEVCContext; | ||||
| int ff_hevc_decode_short_term_rps(HEVCContext *s, ShortTermRPS *rps, | int ff_hevc_decode_short_term_rps(HEVCContext *s, ShortTermRPS *rps, | ||||
| @@ -71,6 +71,21 @@ static void decode_nal_sei_frame_packing_arrangement(HEVCContext *s) | |||||
| skip_bits1(gb); // upsampled_aspect_ratio_flag | skip_bits1(gb); // upsampled_aspect_ratio_flag | ||||
| } | } | ||||
| static void decode_nal_sei_display_orientation(HEVCContext *s) | |||||
| { | |||||
| GetBitContext *gb = &s->HEVClc.gb; | |||||
| s->sei_display_orientation_present = !get_bits1(gb); | |||||
| if (s->sei_display_orientation_present) { | |||||
| s->sei_hflip = get_bits1(gb); // hor_flip | |||||
| s->sei_vflip = get_bits1(gb); // ver_flip | |||||
| s->sei_anticlockwise_rotation = get_bits(gb, 16); | |||||
| skip_bits1(gb); // display_orientation_persistence_flag | |||||
| } | |||||
| } | |||||
| static int decode_nal_sei_message(HEVCContext *s) | static int decode_nal_sei_message(HEVCContext *s) | ||||
| { | { | ||||
| GetBitContext *gb = &s->HEVClc.gb; | GetBitContext *gb = &s->HEVClc.gb; | ||||
| @@ -94,6 +109,8 @@ static int decode_nal_sei_message(HEVCContext *s) | |||||
| decode_nal_sei_decoded_picture_hash(s); | decode_nal_sei_decoded_picture_hash(s); | ||||
| else if (payload_type == 45) | else if (payload_type == 45) | ||||
| decode_nal_sei_frame_packing_arrangement(s); | decode_nal_sei_frame_packing_arrangement(s); | ||||
| else if (payload_type == 47) | |||||
| decode_nal_sei_display_orientation(s); | |||||
| else { | else { | ||||
| av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", payload_type); | av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", payload_type); | ||||
| skip_bits(gb, 8 * payload_size); | skip_bits(gb, 8 * payload_size); | ||||