最簡單的讓IjkPlayer自動旋轉帶有rotation視訊的方法
阿新 • • 發佈:2018-12-25
問題
在專案裡面我們使用了ijkplayer0.8.8版本去播放網路視訊,發現有一些視訊播放時被拉伸了。如下圖:
把視訊抓下來查明原因,發現是視訊metadata裡面帶了rotation資訊,而視訊的寬高被調換了。
解決方法
官方的解決方法是給一個ROTATION_CHANGE的回撥給上層,然後上層去把View做旋轉。這樣實在是太麻煩。我但是很奇怪的是ijkplayer本身是基於ffplay做的,而ffplay本身是支援這一類視訊的旋轉播放的。看了一下ijkplayer的程式碼,在ff_play.c裡面發現如下程式碼:
if (ffp->autorotate) {
double theta = get_rotation(is->video_st);
if (fabs(theta - 90) < 1.0) {
INSERT_FILT("transpose", "clock");
} else if (fabs(theta - 180) < 1.0) {
INSERT_FILT("hflip", NULL);
INSERT_FILT("vflip", NULL);
} else if (fabs(theta - 270) < 1.0) {
INSERT_FILT("transpose" , "cclock");
} else if (fabs(theta) > 1.0) {
char rotate_buf[64];
snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
INSERT_FILT("rotate", rotate_buf);
}
}
原來ffplay本身確實有手動做過transpose的邏輯,但是這個邏輯在ijkplayer裡面並沒有生效,在ijkmedia/ijkplayer/config.h
CONFIG_AVFILTER
選項被關閉了。於是把這個選項開啟之後重新編譯,視訊的播放終於自動旋轉了。需要注意的是如果ffmpeg選項裡面沒有開啟avfilter,則需要先去編譯開啟avfilter的ffmpeg到專案中才行。 總結
本來我一開始是準備在渲染的部分去對MVP做矩陣旋轉。這樣基本不會增加任何的CPU消耗,不過修改成本比較高一些,而且需要自己維護,考慮到這一類視訊本身很少,所以這個成本也就忽略了。