Signed-off-by: Vittorio Giovara <vittorio.giovara@gmail.com>tags/n2.3
| @@ -26,6 +26,7 @@ | |||||
| */ | */ | ||||
| #include "libavutil/avassert.h" | #include "libavutil/avassert.h" | ||||
| #include "libavutil/display.h" | |||||
| #include "libavutil/imgutils.h" | #include "libavutil/imgutils.h" | ||||
| #include "libavutil/stereo3d.h" | #include "libavutil/stereo3d.h" | ||||
| #include "libavutil/timer.h" | #include "libavutil/timer.h" | ||||
| @@ -822,6 +823,20 @@ static void decode_postinit(H264Context *h, int setup_finished) | |||||
| stereo->flags = AV_STEREO3D_FLAG_INVERT; | stereo->flags = AV_STEREO3D_FLAG_INVERT; | ||||
| } | } | ||||
| if (h->sei_display_orientation_present && | |||||
| (h->sei_anticlockwise_rotation || h->sei_hflip || h->sei_vflip)) { | |||||
| double angle = h->sei_anticlockwise_rotation * 360 / (double) (1 << 16); | |||||
| AVFrameSideData *rotation = av_frame_new_side_data(&cur->f, | |||||
| AV_FRAME_DATA_DISPLAYMATRIX, | |||||
| sizeof(int32_t) * 9); | |||||
| if (!rotation) | |||||
| return; | |||||
| av_display_rotation_set((int32_t *)rotation->data, angle); | |||||
| av_display_matrix_flip((int32_t *)rotation->data, | |||||
| h->sei_vflip, h->sei_hflip); | |||||
| } | |||||
| // FIXME do something with unavailable reference frames | // FIXME do something with unavailable reference frames | ||||
| /* Sort B-frames into display order */ | /* Sort B-frames into display order */ | ||||
| @@ -132,6 +132,7 @@ typedef enum { | |||||
| SEI_TYPE_USER_DATA_UNREGISTERED = 5, ///< unregistered user data | SEI_TYPE_USER_DATA_UNREGISTERED = 5, ///< unregistered user data | ||||
| SEI_TYPE_RECOVERY_POINT = 6, ///< recovery point (frame # to decoder sync) | SEI_TYPE_RECOVERY_POINT = 6, ///< recovery point (frame # to decoder sync) | ||||
| SEI_TYPE_FRAME_PACKING = 45, ///< frame packing arrangement | SEI_TYPE_FRAME_PACKING = 45, ///< frame packing arrangement | ||||
| SEI_TYPE_DISPLAY_ORIENTATION = 47, ///< display orientation | |||||
| } SEI_Type; | } SEI_Type; | ||||
| /** | /** | ||||
| @@ -633,6 +634,13 @@ typedef struct H264Context { | |||||
| int content_interpretation_type; | int content_interpretation_type; | ||||
| int quincunx_subsampling; | int quincunx_subsampling; | ||||
| /** | |||||
| * display orientation SEI message | |||||
| */ | |||||
| int sei_display_orientation_present; | |||||
| int sei_anticlockwise_rotation; | |||||
| int sei_hflip, sei_vflip; | |||||
| /** | /** | ||||
| * Bit set of clock types for fields/frames in picture timing SEI message. | * Bit set of clock types for fields/frames in picture timing SEI message. | ||||
| * For each found ct_type, appropriate bit is set (e.g., bit 1 for | * For each found ct_type, appropriate bit is set (e.g., bit 1 for | ||||
| @@ -41,6 +41,7 @@ void ff_h264_reset_sei(H264Context *h) | |||||
| h->sei_cpb_removal_delay = -1; | h->sei_cpb_removal_delay = -1; | ||||
| h->sei_buffering_period_present = 0; | h->sei_buffering_period_present = 0; | ||||
| h->sei_frame_packing_present = 0; | h->sei_frame_packing_present = 0; | ||||
| h->sei_display_orientation_present = 0; | |||||
| } | } | ||||
| static int decode_picture_timing(H264Context *h) | static int decode_picture_timing(H264Context *h) | ||||
| @@ -199,6 +200,22 @@ static int decode_frame_packing_arrangement(H264Context *h) | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| static int decode_display_orientation(H264Context *h) | |||||
| { | |||||
| h->sei_display_orientation_present = !get_bits1(&h->gb); | |||||
| if (h->sei_display_orientation_present) { | |||||
| h->sei_hflip = get_bits1(&h->gb); // hor_flip | |||||
| h->sei_vflip = get_bits1(&h->gb); // ver_flip | |||||
| h->sei_anticlockwise_rotation = get_bits(&h->gb, 16); | |||||
| get_ue_golomb(&h->gb); // display_orientation_repetition_period | |||||
| skip_bits1(&h->gb); // display_orientation_extension_flag | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| int ff_h264_decode_sei(H264Context *h) | int ff_h264_decode_sei(H264Context *h) | ||||
| { | { | ||||
| while (get_bits_left(&h->gb) > 16) { | while (get_bits_left(&h->gb) > 16) { | ||||
| @@ -246,6 +263,11 @@ int ff_h264_decode_sei(H264Context *h) | |||||
| if (ret < 0) | if (ret < 0) | ||||
| return ret; | return ret; | ||||
| break; | break; | ||||
| case SEI_TYPE_DISPLAY_ORIENTATION: | |||||
| ret = decode_display_orientation(h); | |||||
| if (ret < 0) | |||||
| return ret; | |||||
| break; | |||||
| default: | default: | ||||
| av_log(h->avctx, AV_LOG_DEBUG, "unknown SEI type %d\n", type); | av_log(h->avctx, AV_LOG_DEBUG, "unknown SEI type %d\n", type); | ||||
| skip_bits(&h->gb, 8 * size); | skip_bits(&h->gb, 8 * size); | ||||