ffmpeg解码视频帧旋转角度
常见视频,有部分视频带有角度的,在ffmpeg视频流在获取AVFormatContext信息是可以获取角度信息,通过这个角度在播放器会进行旋转,不然你播放视频有角度视频
获取旋转角度
在这个格式上下文AVFormatContext *pFormatCtx 可以获取相应的信息,下面获取视频角度方法封装
int WlFFmpeg::getRotate(){
AVDictionaryEntry *tag = NULL;
int m_Rotate=0;
tag = av_dict_get(pFormatCtx->metadata, "rotate", tag, 0);
if (tag==NULL)
{
if(LOG_DEBUG)
{
LOGE("==========tag is null");
}
m_Rotate = 0;
}
else
{
int angle = atoi(tag->value);
if(LOG_DEBUG)
{
LOGE("===========angle==:%d",angle);
}
angle %= 360;
if (angle == 90)
{
m_Rotate = 90;
}
else if (angle == 180)
{
m_Rotate = 180;
}
else if (angle == 270)
{
m_Rotate = 270;
}
else
{
m_Rotate = 270;
}
}
return m_Rotate;
}
视频角度旋转方法90、180、270
手动AVFrame进行旋转存储数据
/**
* 逆时针旋转90
* @param src
* @param des
*/
void WlVideo::frame_rotate_90(AVFrame *src, AVFrame *des) {
int n = 0;
int hw = src->width >> 1;
int hh = src->height >> 1;
int size = src->width * src->height;
int hsize = size >> 2;
int pos = 0;
//copy y
for (int j = 0; j < src->width; j++) {
pos = size;
for (int i = src->height - 1; i >= 0; i--) {
pos -= src->width;
des->data[0][n++] = src->data[0][pos + j];
}
}
//copy uv
n = 0;
for (int j = 0; j < hw; j++) {
pos = hsize;
for (int i = hh - 1; i >= 0; i--) {
pos -= hw;
des->data[1][n] = src->data[1][pos + j];
des->data[2][n] = src->data[2][pos + j];
n++;
}
}
des->linesize[0] = src->height;
des->linesize[1] = src->height >> 1;
des->linesize[2] = src->height >> 1;
des->height = src->width;
des->width = src->height;
}
void WlVideo::frame_rotate_180(AVFrame *src, AVFrame *des) {
int n = 0, i = 0, j = 0;
int hw = src->width >> 1;
int hh = src->height >> 1;
int pos = src->width * src->height;
for (i = 0; i < src->height; i++) {
pos -= src->width;
for (int j = 0; j < src->width; j++) {
des->data[0][n++] = src->data[0][pos + j];
}
}
n = 0;
pos = src->width * src->height >> 2;
for (i = 0; i < hh; i++) {
pos -= hw;
for (int j = 0; j < hw; j++) {
des->data[1][n] = src->data[1][pos + j];
des->data[2][n] = src->data[2][pos + j];
n++;
}
}
des->linesize[0] = src->width;
des->linesize[1] = src->width >> 1;
des->linesize[2] = src->width >> 1;
des->width = src->width;
des->height = src->height;
des->format = src->format;
des->pts = src->pts;
des->pkt_pts = src->pkt_pts;
des->pkt_dts = src->pkt_dts;
des->key_frame = src->key_frame;
}
void WlVideo::frame_rotate_270(AVFrame *src, AVFrame *des) {
int n = 0, i = 0, j = 0;
int hw = src->width >> 1;
int hh = src->height >> 1;
int pos = 0;
for (i = src->width - 1; i >= 0; i--) {
pos = 0;
for (j = 0; j < src->height; j++) {
des->data[0][n++] = src->data[0][pos + i];
pos += src->width;
}
}
n = 0;
for (i = hw - 1; i >= 0; i--) {
pos = 0;
for (j = 0; j < hh; j++) {
des->data[1][n] = src->data[1][pos + i];
des->data[2][n] = src->data[2][pos + i];
pos += hw;
n++;
}
}
des->linesize[0] = src->height;
des->linesize[1] = src->height >> 1;
des->linesize[2] = src->height >> 1;
des->width = src->height;
des->height = src->width;
des->format = src->format;
des->pts = src->pts;
des->pkt_pts = src->pkt_pts;
des->pkt_dts = src->pkt_dts;
des->key_frame = src->key_frame;
}