#include "rtp-ext.h" #include #include #include #include #include #include // https://www.arib.or.jp/english/html/overview/doc/STD-T63V12_00/5_Appendix/Rel13/26/26114-d30.pdf /* 7.4.5 Coordination of Video Orientation Coordination of Video Orientation consists in signalling of the current orientation of the image captured on the sender side to the receiver for appropriate rendering and displaying. When CVO is succesfully negotiated it shall be signalled by the MTSI client. The signalling of the CVO uses RTP Header Extensions as specified in IETF RFC 5285 [95]. The one-byte form of the header should be used. CVO information for a 2 bit granularity of Rotation (corresponding to urn:3gpp:video-orientation) is carried as a byte formatted as follows: 0 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ID | len=0 |0 0 0 0 C F R R| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Bit# 7 6 5 4 3 2 1 0(LSB) Definition 0 0 0 0 C F R1 R0 With the following definitions: C = Camera: indicates the direction of the camera used for this video stream. It can be used by the MTSI client in receiver to e.g. display the received video differently depending on the source camera. 0: Front-facing camera, facing the user. If camera direction is unknown by the sending MTSI client in the terminal then this is the default value used. 1: Back-facing camera, facing away from the user. F = Flip: indicates a horizontal (left-right flip) mirror operation on the video as sent on the link. 0: No flip operation. If the sending MTSI client in terminal does not know if a horizontal mirror operation is necessary, then this is the default value used. 1: Horizontal flip operation R1, R0 = Rotation: indicates the rotation of the video as transmitted on the link. The receiver should rotate the video to compensate that rotation. E.g. a 90กใ Counter Clockwise rotation should be compensated by the receiver with a 90กใ Clockwise rotation prior to displaying. Table 7.2: Rotation signalling for 2 bit granularity R1 R0 Rotation of the video as sent on the link Rotation on the receiver before display 0 0 0กใ rotation None 0 1 90กใ Counter Clockwise (CCW) rotation or 90กใ CW rotation 270กใ Clockwise (CW) rotation 1 0 180กใ CCW rotation or 180กใ CW rotation 180กใ CW rotation 1 1 270กใ CCW rotation or 90กใ CW rotation 90กใ CCW rotation CVO information for a higher granularity of Rotation (corresponding to urn:3GPP:video-orientation:6) is carried as a byte formatted as follows: Bit# 7 6 5 4 3 2 1 0(LSB) Definition R5 R4 R3 R2 C F R1 R0 where C and F are as defined above and the bits R5,R4,R3,R2,R1,R0 represent the Rotation, which indicates the rotation of the video as transmitted on the link. Table 7.3 describes the rotation to be applied by the receiver based on the rotation bits. Table 7.3: Rotation signalling for 6 bit granularity R1 R0 R5 R4 R3 R2 Rotation of the video as Rotation on the receiver sent on the link before display 0 0 0 0 0 0 0กใ rotation None 0 0 0 0 0 1 (360/64)กใ Counter Clockwise (360/64)กใ CW rotation (CCW) rotation 0 0 0 0 1 0 (2*360/64)กใ CCW rotation (2*360/64)กใ CW rotation . . . . . . . . . . . . . . . . . . . . . . . . 1 1 1 1 1 0 (62*360/64)กใ CCW rotation (2*360/64)กใ CCW rotation 1 1 1 1 1 1 (63*360/64)กใ CCW rotation (360/64)กใ CCW rotation */ int rtp_ext_video_orientation_parse(const uint8_t* data, int bytes, struct rtp_ext_video_orientation_t *ext) { assert(1 == bytes); if (bytes < 1) return -1; ext->camera = (data[0] >> 3) & 0x01; ext->flip = (data[0] >> 2) & 0x01; ext->rotaion = (data[0] & 0x03) * 90; return 0; } int rtp_ext_video_orientation_write(uint8_t* data, int bytes, const struct rtp_ext_video_orientation_t* ext) { if (bytes < 1) return -1; data[0] = ext->camera ? 0x04 : 0; data[0] |= ext->flip ? 0x03 : 0; data[0] |= (ext->rotaion / 90) & 0x03; return 1; }