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.mzph.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;留着记号了