做音视频RTSP或RTMP直播播放器的时候,不免会遇到这样的诉求,实时播放或快照的时候,由于前端摄像头安装角度不一定是正向,导致播放或快照的时候,视频view显示的画面是呈90° 180°甚至270°旋转的。
以Android平台为例,视频view显示的话,处理比较方便,我们之前有设计相关的顺时针旋转接口:
/*** 设置顺时针旋转, 注意除了0度之外, 其他角度都会额外消耗性能** @param handle: return value from SmartPlayerOpen()** @param degress: 当前支持 0度,90度, 180度, 270度 旋转** @return {0} if successful*/public native int SmartPlayerSetRotation(long handle, int degress);
此外,还设计了水平反转和垂直反转解接口:
/*** 设置视频垂直反转** @param handle: return value from SmartPlayerOpen()** @param is_flip: 0: 不反转, 1: 反转** @return {0} if successful*/public native int SmartPlayerSetFlipVertical(long handle, int is_flip);/*** 设置视频水平反转** @param handle: return value from SmartPlayerOpen()** @param is_flip: 0: 不反转, 1: 反转** @return {0} if successful*/public native int SmartPlayerSetFlipHorizontal(long handle, int is_flip);
如果需要把快照数据按照设定角度旋转,通常的做法,可以在解码后的yuv数据先做旋转,然后再做argb的转换,也可以转成argb后,针对argb旋转即可,旋转后的数据,再做png编码写入文件即可,以Libyuv为例(数据在jni层处理):
如果需要旋转yuv数据,可用的接口如下:
// Rotate I420 frame.
LIBYUV_API
int I420Rotate(const uint8_t* src_y,int src_stride_y,const uint8_t* src_u,int src_stride_u,const uint8_t* src_v,int src_stride_v,uint8_t* dst_y,int dst_stride_y,uint8_t* dst_u,int dst_stride_u,uint8_t* dst_v,int dst_stride_v,int width,int height,enum RotationMode mode);
如果是ARGB数据:
// Rotate ARGB frame
LIBYUV_API
int ARGBRotate(const uint8_t* src_argb,int src_stride_argb,uint8_t* dst_argb,int dst_stride_argb,int src_width,int src_height,enum RotationMode mode);
其中,RotationMode枚举定义如下:
// Supported rotation.
typedef enum RotationMode {kRotate0 = 0, // No rotation.kRotate90 = 90, // Rotate 90 degrees clockwise.kRotate180 = 180, // Rotate 180 degrees.kRotate270 = 270, // Rotate 270 degrees clockwise.// Deprecated.kRotateNone = 0,kRotateClockwise = 90,kRotateCounterClockwise = 270,
} RotationModeEnum;
这块技术难度不大,有这块技术需求的开发者,可酌情参考。