WebM VP8 SDK Usage/關于WebM VP8 SDK的用法

WebM是Google提出的新的網絡視頻格式,本質上是個MKV的殼,封裝VPX中的VP8視頻流與Vorbis OGG音頻流。目前Firefox、Opera、Chrome都能直接打開WebM視頻文件而無需其他任何亂七八糟的插件。我個人倒是很喜歡WebM的OGG音頻,雖然在低比特率下不如AAC,不過依舊勝過MP3太多了。

最近接手了一個項目,將Showcase中的Flash視頻導出替換為WebM視頻導出,著實蛋疼了一把,因為ffmpeg這個破玩意的最新二進制版本雖然集成了VPX,不過由于許可證等等原因,商業軟件不好直接使用。一氣之下我直接用Google提供的WebM SDK搞定從序列幀到視頻的輸出,完全擺脫ffmpeg。

對于WebM SDK我了找到的三個問題:

  • 依舊沒有內建RGB24到YV12的轉換,不得不手動來。
  • SDK提供的simple_encoder產生出的IVF依舊無法播放。
  • 如果構造了一個YV12格式的vpx_image_t對象,這個對象無法重復使用,產生的視頻有錯。

下面是我的WebMEnc編碼器主文件的代碼,不明白的WebM SDK如何使用的朋友可以學習一下。JPEG、TIFF、PNG的讀取使用了FreeImage。

完整的代碼在Ortholab的SVN里有。

可執行二進制程序可以在這里下載。

// Copyright (c) 2011 Bo Zhou<Bo.Schwarzstein@gmail.com>
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//		http://www.apache.org/licenses/LICENSE-2.0 
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.#include <stdio.h>
#include <stdlib.h>#include <FreeImage.h>#include <vpx/vpx_codec.h>
#include <vpx/vpx_encoder.h>
#include <vpx/vpx_image.h>
#include <vpx/vpx_version.h>#include <vpx/vp8cx.h>#include "EbmlWriter.h"#define rgbtoy(b, g, r, y) \
y=(unsigned char)(((int)(30*r) + (int)(59*g) + (int)(11*b))/100)#define rgbtoyuv(b, g, r, y, u, v) \
rgbtoy(b, g, r, y); \
u=(unsigned char)(((int)(-17*r) - (int)(33*g) + (int)(50*b)+12800)/100); \
v=(unsigned char)(((int)(50*r) - (int)(42*g) - (int)(8*b)+12800)/100)#if defined(_MSC_VER)
/* MSVS doesn't define off_t, and uses _f{seek,tell}i64 */
#define fseeko _fseeki64
#define ftello _ftelli64
#endifvoid rgb2YUV420P(vpx_image_t *rgbImage, vpx_image_t *yv12Image)
{unsigned int width = rgbImage->w;unsigned int height = rgbImage->h;unsigned int planeSize = width * height;unsigned int halfWidth = width >> 1;unsigned char* yPlane = yv12Image->img_data;unsigned char* uPlane = yPlane + planeSize;unsigned char* vPlane = uPlane + (planeSize >> 2);static const int rgbIncrement = 3;unsigned char* rgb = rgbImage->img_data;for (unsigned int y = 0; y < height; ++ y){unsigned char* yLine = yPlane + (y * width);unsigned char* uLine = uPlane + ((y >> 1) * halfWidth);unsigned char* vLine = vPlane + ((y >> 1) * halfWidth);for (unsigned int x = 0; x < width; x += 2){rgbtoyuv(rgb[2], rgb[1], rgb[0], *yLine, *uLine, *vLine);rgb += rgbIncrement;yLine++;rgbtoyuv(rgb[2], rgb[1], rgb[0], *yLine, *uLine, *vLine);rgb += rgbIncrement;yLine++;uLine++;vLine++;}}
}bool readImage(char *filename, int frameNumber, vpx_image_t **pRGBImage, vpx_image_t **pYV12Image)
{// Load image.//char path[512];sprintf(path, filename, frameNumber);FREE_IMAGE_FORMAT format = FIF_UNKNOWN;format = FreeImage_GetFIFFromFilename(filename);if ( (format == FIF_UNKNOWN) ||((format != FIF_JPEG) &&(format != FIF_TIFF) &&(format != FIF_PNG)) ){return false;}FIBITMAP* dib = FreeImage_Load(format, path);if (dib == NULL){return false;}unsigned w = FreeImage_GetWidth(dib);unsigned h = FreeImage_GetHeight(dib);if (*pRGBImage == NULL){*pRGBImage = vpx_img_alloc(NULL, VPX_IMG_FMT_RGB24, w, h, 1);}if (*pYV12Image == NULL){*pYV12Image = vpx_img_alloc(NULL, VPX_IMG_FMT_YV12, w, h, 1);}memcpy((*pRGBImage)->img_data, FreeImage_GetBits(dib), w * h * 3);rgb2YUV420P(*pRGBImage, *pYV12Image);vpx_img_flip(*pYV12Image);FreeImage_Unload(dib);return true;
}int main(int argc, char* argv[])
{if (argc != 4){printf("  Usage: WebMEnc <filename> <bit-rates> <output file>\nExample: WebMEnc frame.%%.5d.jpg 512 frame.webm\n");return EXIT_FAILURE;}#ifdef FREEIMAGE_LIBFreeImage_Initialise();
#endif// Initialize VPX codec.//vpx_codec_ctx_t vpxContext;vpx_codec_enc_cfg_t vpxConfig;if (vpx_codec_enc_config_default(vpx_codec_vp8_cx(), &vpxConfig, 0) != VPX_CODEC_OK){return EXIT_FAILURE;}// Try to load the first frame to initialize width and height.//vpx_image_t *rgbImage = NULL, *yv12Image = NULL;if (readImage(argv[1], 0, &rgbImage, &yv12Image) == false){return EXIT_FAILURE;}vpxConfig.g_h = yv12Image->h;vpxConfig.g_w = yv12Image->w;vpxConfig.rc_target_bitrate = atoi(argv[2]);vpxConfig.g_threads = 2;// Prepare the output .webm file.//EbmlGlobal ebml;memset(&ebml, 0, sizeof(EbmlGlobal));ebml.last_pts_ms = -1;ebml.stream = fopen(argv[3], "wb");if (ebml.stream == NULL){return EXIT_FAILURE;}vpx_rational ebmlFPS = vpxConfig.g_timebase;struct vpx_rational arg_framerate = {30, 1};Ebml_WriteWebMFileHeader(&ebml, &vpxConfig, &arg_framerate);if (vpx_codec_enc_init(&vpxContext, vpx_codec_vp8_cx(), &vpxConfig, 0) != VPX_CODEC_OK){return EXIT_FAILURE;}// Reading image file sequence, encoding to .WebM file.//int frameNumber = 0;while(readImage(argv[1], frameNumber, &rgbImage, &yv12Image)){vpx_codec_err_t vpxError = vpx_codec_encode(&vpxContext, yv12Image, frameNumber, 33, 0, 0);if (vpxError != VPX_CODEC_OK){return EXIT_FAILURE;}vpx_codec_iter_t iter = NULL;const vpx_codec_cx_pkt_t *packet;while( (packet = vpx_codec_get_cx_data(&vpxContext, &iter)) ){Ebml_WriteWebMBlock(&ebml, &vpxConfig, packet);}frameNumber ++;printf("Processed %d frames.\r", frameNumber);vpx_img_free(yv12Image);yv12Image = NULL;}Ebml_WriteWebMFileFooter(&ebml, 0);fclose(ebml.stream);vpx_codec_destroy(&vpxContext);#ifdef FREEIMAGE_LIBFreeImage_DeInitialise();
#endifreturn EXIT_SUCCESS;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/388666.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/388666.shtml
英文地址,請注明出處:http://en.pswp.cn/news/388666.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數據分析師 需求分析師_是什么讓分析師出色?

數據分析師 需求分析師重點 (Top highlight)Before we dissect the nature of analytical excellence, let’s start with a quick summary of three common misconceptions about analytics from Part 1:在剖析卓越分析的本質之前&#xff0c;讓我們從第1部分中對分析的三種常…

JQuery發起ajax請求,并在頁面動態的添加元素

頁面html代碼&#xff1a; <li><div class"coll-tit"><span class"coll-icon"><iclass"sysfont coll-default"></i>全域旅游目的地</span></div><div class"coll-panel"><div c…

arcgis鏡像圖形工具,ArcGis圖形編輯

一、編輯工具條介紹二、草圖工具介紹Sketch Tool&#xff1a;使用草圖工具來創建點要素或是線或面要素的節點。雙擊或是F2鍵結束草圖狀態&#xff0c;轉化為要素。Intersection Tool&#xff1a;使用相交工具在兩個線要素相交(或延長相交)的地方創建一個節點。如圖&#xff1a;…

MAYA插件入門

我們知道&#xff0c; MAYA 是一個基于結點的插件式軟件架構&#xff0c;這種開放式的軟件架構是非常優秀的&#xff0c;它可以讓用戶非常方便地在其基礎上開發一些自已想要的插件&#xff0c;從而實現一些特殊的功能或效果。 在MAYA上開發自已的插件&#xff0c;你有3種選擇&a…

(原創) 如何使用C++/CLI讀/寫jpg檔? (.NET) (C++/CLI) (GDI+) (C/C++) (Image Processing)

Abstract因為Computer Vision的作業&#xff0c;之前都是用C# GDI寫&#xff0c;但這次的作業要做Grayscale Dilation&#xff0c;想用STL的Generic Algorithm寫&#xff0c;但C Standard Library并無法讀取jpg檔&#xff0c;用其它Library又比較麻煩&#xff0c;所以又回頭想…

貓眼電影評論_電影的人群意見和評論家的意見一樣好嗎?

貓眼電影評論Ryan Bellgardt’s 2018 movie, The Jurassic Games, tells the story of ten death row inmates who must compete for survival in a virtual reality game where they not only fight each other but must also fight dinosaurs which can kill them both in th…

128.Two Sum

題目&#xff1a; Given an array of integers, return indices of the two numbers such that they add up to a specific target. 給定一個整數數組&#xff0c;返回兩個數字的索引&#xff0c;使它們相加到特定目標。 You may assume that each input would have exactly on…

php獲取錯誤信息函數,關于php:如何獲取mail()函數的錯誤消息?

我一直在使用PHP mail()函數。如果郵件由于任何原因未發送&#xff0c;我想回顯錯誤消息。 我該怎么做&#xff1f;就像是$this_mail mail(exampleexample.com, My Subject, $message);if($this_mail) echo sent!;else echo error_message;謝謝&#xff01;當mail()返回false時…

關于夏季及雷雨天氣的MODEM、路由器使用注意事項

每年夏季是雷雨多發季節&#xff0c;容易出現家用電腦因而雷擊造成電腦硬件的損壞和通訊故障&#xff0c;為了避免這種情況的的發生&#xff0c;保護您的財產不受損失&#xff08;一般雷擊照成損壞的設備是沒得保修的&#xff09;&#xff0c;建議您繼續閱讀下面內容&#xff1…

創建Console應用程序,粘貼一下代碼,創建E://MyWebServerRoot//目錄,作為虛擬目錄,親自測試通過,

創建Console應用程序&#xff0c;粘貼一下代碼&#xff0c;創建E://MyWebServerRoot//目錄&#xff0c;作為虛擬目錄&#xff0c;親自測試通過&#xff0c; 有一個想法&#xff0c;調用ASP.DLL解析ASP&#xff0c;可是始終沒有找到資料&#xff0c;有待于研究&#xff0c;還有…

c#對文件的讀寫

最近需要對一個文件進行數量的分割&#xff0c;因為數據量龐大&#xff0c;所以就想到了通過寫程序來處理。將代碼貼出來以備以后使用。 //讀取文件的內容 放置于StringBuilder 中 StreamReader sr new StreamReader(path, Encoding.Default); String line; StringBuilder sb …

php表格tr,jQuery+ajax實現動態添加表格tr td功能示例

本文實例講述了jQueryajax實現動態添加表格tr td功能。分享給大家供大家參考&#xff0c;具體如下&#xff1a;功能&#xff1a;ajax獲取后臺返回數據給table動態添加tr/tdhtml部分&#xff1a;ajax部分&#xff1a;var year $(#year).val();//下拉框數據var province $(#prov…

maya的簡單使用

1、導出obj類型文件window - settings preferences - plug- in Manager objExport.mllfile - export selection就有OBJ選項了窗口-設置/首選項- 插件管理 objExport.mll文件-導出當前選擇2、合并元素在文件下面的下拉框&#xff0c;選擇多邊形。按住shift鍵&…

ai前沿公司_美術是AI的下一個前沿嗎?

ai前沿公司In 1950, Alan Turing developed the Turing Test as a test of a machine’s ability to display human-like intelligent behavior. In his prolific paper, he posed the following questions:1950年&#xff0c;阿蘭圖靈開發的圖靈測試作為一臺機器的顯示類似人類…

查看修改swap空間大小

查看swap 空間大小(總計)&#xff1a; # free -m 默認單位為k, -m 單位為M   total used free shared buffers cached  Mem: 377 180 197 0 19 110  -/ buffers/ca…

關于WKWebView高度的問題的解決

關于WKWebView高度的問題的解決 IOS端嵌入網頁的方式有兩種UIWebView和WKWebView。其中WKWebView的性能要高些;WKWebView的使用也相對簡單 WKWebView在加載完成后&#xff0c;在相應的代理里面獲取其內容高度&#xff0c;大多數網上的方法在獲取高度是會出現一定的問題&#xf…

測試nignx php請求并發數,nginx 優化(突破十萬并發)

一般來說nginx 配置文件中對優化比較有作用的為以下幾項&#xff1a;worker_processes 8;nginx 進程數&#xff0c;建議按照cpu 數目來指定&#xff0c;一般為它的倍數。worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;為每個進…

多米諾骨牌v.1MEL語言

// // //Script Name:多米諾骨牌v.1 //Author:瘋狂小豬 //Last Updated: 2011.10.5 //Email:wzybwj163.com // //---------------------------------------------------------------------------- //-----------------------------------------------------------------…

THINKPHP3.2視頻教程

http://edu.51cto.com/lesson/id-24504.html lunix視頻教程 http://bbs.lampbrother.net/read-htm-tid-161465.html TP資料http://pan.baidu.com/s/1dDCLFRr#path%252Fthink 微信開發&#xff0c;任務吧&#xff0c;留著記號了