add export mp4 test
This commit is contained in:
@@ -77,8 +77,8 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>true</LinkIncremental>
|
||||||
<IncludePath>libs\glm;libs\glew-2.0.0\include;libs\stb;libs\tinyxml2;libs\yoga;libs\curl-win\include;libs\jpeg;libs\wacom;libs\bugtrap-client\include;libs\poly2tri\poly2tri;libs\base64;libs\sqlite3;libs\openvr\headers;libs\nanort;libs\hash-library;libs\fmt\include;libs\glad\include;$(IncludePath)</IncludePath>
|
<IncludePath>libs\glm;libs\glew-2.0.0\include;libs\stb;libs\tinyxml2;libs\yoga;libs\curl-win\include;libs\jpeg;libs\wacom;libs\bugtrap-client\include;libs\poly2tri\poly2tri;libs\base64;libs\sqlite3;libs\openvr\headers;libs\nanort;libs\hash-library;libs\fmt\include;libs\glad\include;libs\openh264\include;libs\mp4v2\include;$(IncludePath)</IncludePath>
|
||||||
<LibraryPath>libs\curl-win\lib\dll-$(Configuration)-$(PlatformShortName);libs\glew-2.0.0\lib\Release\$(Platform);libs\bugtrap-client\lib;libs\openvr\lib\win64;$(LibraryPath)</LibraryPath>
|
<LibraryPath>libs\curl-win\lib\dll-$(Configuration)-$(PlatformShortName);libs\glew-2.0.0\lib\Release\$(Platform);libs\bugtrap-client\lib;libs\openvr\lib\win64;libs\openh264\lib;libs\mp4v2\lib\win;$(LibraryPath)</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
@@ -87,8 +87,8 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<IncludePath>libs\glm;libs\glew-2.0.0\include;libs\stb;libs\tinyxml2;libs\yoga;libs\curl-win\include;libs\jpeg;libs\wacom;libs\bugtrap-client\include;libs\poly2tri\poly2tri;libs\base64;libs\sqlite3;libs\openvr\headers;libs\nanort;libs\hash-library;libs\fmt\include;libs\glad\include;$(IncludePath)</IncludePath>
|
<IncludePath>libs\glm;libs\glew-2.0.0\include;libs\stb;libs\tinyxml2;libs\yoga;libs\curl-win\include;libs\jpeg;libs\wacom;libs\bugtrap-client\include;libs\poly2tri\poly2tri;libs\base64;libs\sqlite3;libs\openvr\headers;libs\nanort;libs\hash-library;libs\fmt\include;libs\glad\include;libs\openh264\include;libs\mp4v2\include;$(IncludePath)</IncludePath>
|
||||||
<LibraryPath>libs\curl-win\lib\dll-$(Configuration)-$(PlatformShortName);libs\glew-2.0.0\lib\Release\$(Platform);libs\bugtrap-client\lib;libs\openvr\lib\win64;$(LibraryPath)</LibraryPath>
|
<LibraryPath>libs\curl-win\lib\dll-$(Configuration)-$(PlatformShortName);libs\glew-2.0.0\lib\Release\$(Platform);libs\bugtrap-client\lib;libs\openvr\lib\win64;libs\openh264\lib;libs\mp4v2\lib\win;$(LibraryPath)</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
|
|||||||
@@ -249,6 +249,10 @@
|
|||||||
<icon icon="pencil" width="20"/>
|
<icon icon="pencil" width="20"/>
|
||||||
<text id="menu-label" text="Start SonarPen" margin="0 0 0 5"/>
|
<text id="menu-label" text="Start SonarPen" margin="0 0 0 5"/>
|
||||||
</button-custom>
|
</button-custom>
|
||||||
|
<button-custom id="mp4test" height="40" align="center" color=".2" pad="0 0 0 10" dir="row">
|
||||||
|
<icon icon="pencil" width="20"/>
|
||||||
|
<text id="menu-label" text="Test MP4 Export" margin="0 0 0 5"/>
|
||||||
|
</button-custom>
|
||||||
</popup-menu>
|
</popup-menu>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
||||||
|
|||||||
@@ -255,6 +255,7 @@ public:
|
|||||||
void dialog_resize();
|
void dialog_resize();
|
||||||
void dialog_preset_download();
|
void dialog_preset_download();
|
||||||
void dialog_ppbr_export();
|
void dialog_ppbr_export();
|
||||||
|
void dialog_export_mp4();
|
||||||
|
|
||||||
void cloud_upload();
|
void cloud_upload();
|
||||||
void cloud_upload_all();
|
void cloud_upload_all();
|
||||||
|
|||||||
@@ -10,6 +10,10 @@
|
|||||||
#include "node_usermanual.h"
|
#include "node_usermanual.h"
|
||||||
#include "node_dialog_export_ppbr.h"
|
#include "node_dialog_export_ppbr.h"
|
||||||
|
|
||||||
|
#include <codec_api.h>
|
||||||
|
#define MP4V2_NO_STDINT_DEFS
|
||||||
|
#include <mp4v2/mp4v2.h>
|
||||||
|
|
||||||
#ifdef __QUEST__
|
#ifdef __QUEST__
|
||||||
#include "oculus_vr.h"
|
#include "oculus_vr.h"
|
||||||
#elif __WEB__
|
#elif __WEB__
|
||||||
@@ -641,3 +645,177 @@ void App::dialog_ppbr_export()
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void App::dialog_export_mp4()
|
||||||
|
{
|
||||||
|
std::thread([this] {
|
||||||
|
const int video_width = 1024;
|
||||||
|
const int video_height = 512;
|
||||||
|
const int video_frames = 500;
|
||||||
|
|
||||||
|
auto pb = show_progress("Export MP4", video_frames);
|
||||||
|
|
||||||
|
ISVCEncoder* encoder;
|
||||||
|
int rv = WelsCreateSVCEncoder(&encoder);
|
||||||
|
|
||||||
|
//SEncParamBase param;
|
||||||
|
//memset(¶m, 0, sizeof(SEncParamBase));
|
||||||
|
//param.iUsageType = EUsageType::CAMERA_VIDEO_REAL_TIME; //from EUsageType enum
|
||||||
|
//param.fMaxFrameRate = 25;
|
||||||
|
//param.iPicWidth = 400;
|
||||||
|
//param.iPicHeight = 400;
|
||||||
|
//param.iTargetBitrate = 5000000;
|
||||||
|
//param.iRCMode = RC_TIMESTAMP_MODE;
|
||||||
|
//encoder->Initialize(¶m);
|
||||||
|
|
||||||
|
//Encoder params
|
||||||
|
SEncParamExt param;
|
||||||
|
encoder->GetDefaultParams(¶m);
|
||||||
|
param.iUsageType = CAMERA_VIDEO_REAL_TIME;
|
||||||
|
param.fMaxFrameRate = 25.f;
|
||||||
|
param.iLtrMarkPeriod = 75;
|
||||||
|
param.iPicWidth = 1024;
|
||||||
|
param.iPicHeight = 512;
|
||||||
|
param.iTargetBitrate = 1000 << 10;
|
||||||
|
param.bEnableDenoise = false;
|
||||||
|
param.iSpatialLayerNum = 1;
|
||||||
|
param.bUseLoadBalancing = false;
|
||||||
|
param.bEnableSceneChangeDetect = false;
|
||||||
|
param.bEnableBackgroundDetection = false;
|
||||||
|
param.bEnableAdaptiveQuant = false;
|
||||||
|
param.bEnableFrameSkip = false;
|
||||||
|
param.iMultipleThreadIdc = 0;
|
||||||
|
//param.uiIntraPeriod = 10;
|
||||||
|
|
||||||
|
for (int i = 0; i < param.iSpatialLayerNum; i++)
|
||||||
|
{
|
||||||
|
param.sSpatialLayers[i].iVideoWidth = param.iPicWidth >> (param.iSpatialLayerNum - 1 - i);
|
||||||
|
param.sSpatialLayers[i].iVideoHeight = param.iPicHeight >> (param.iSpatialLayerNum - 1 - i);
|
||||||
|
param.sSpatialLayers[i].fFrameRate = 25.f;
|
||||||
|
param.sSpatialLayers[i].iSpatialBitrate = param.iTargetBitrate;
|
||||||
|
param.sSpatialLayers[i].uiProfileIdc = PRO_BASELINE;
|
||||||
|
param.sSpatialLayers[i].uiLevelIdc = LEVEL_4_2;
|
||||||
|
param.sSpatialLayers[i].iDLayerQp = 42;
|
||||||
|
|
||||||
|
//SSliceArgument sliceArg;
|
||||||
|
//sliceArg.uiSliceMode = SM_FIXEDSLCNUM_SLICE;
|
||||||
|
//sliceArg.uiSliceNum = 0;
|
||||||
|
//param.sSpatialLayers[i].sSliceArgument = sliceArg;
|
||||||
|
}
|
||||||
|
|
||||||
|
param.uiMaxNalSize = 1500;
|
||||||
|
param.iTargetBitrate *= param.iSpatialLayerNum;
|
||||||
|
encoder->InitializeExt(¶m);
|
||||||
|
|
||||||
|
|
||||||
|
int trace_level = WELS_LOG_ERROR;
|
||||||
|
encoder->SetOption(ENCODER_OPTION_TRACE_LEVEL, &trace_level);
|
||||||
|
int videoFormat = videoFormatI420;
|
||||||
|
encoder->SetOption(ENCODER_OPTION_DATAFORMAT, &videoFormat);
|
||||||
|
|
||||||
|
int frameSize = param.iPicWidth * param.iPicHeight * 3 / 2;
|
||||||
|
std::vector<uint8_t> buf(frameSize);
|
||||||
|
|
||||||
|
SFrameBSInfo info;
|
||||||
|
memset(&info, 0, sizeof(SFrameBSInfo));
|
||||||
|
SSourcePicture pic;
|
||||||
|
memset(&pic, 0, sizeof(SSourcePicture));
|
||||||
|
pic.iPicWidth = param.iPicWidth;
|
||||||
|
pic.iPicHeight = param.iPicHeight;
|
||||||
|
pic.iColorFormat = videoFormatI420;
|
||||||
|
pic.iStride[0] = pic.iPicWidth;
|
||||||
|
pic.iStride[1] = pic.iStride[2] = pic.iPicWidth >> 1;
|
||||||
|
pic.pData[0] = buf.data();
|
||||||
|
pic.pData[1] = pic.pData[0] + (param.iPicWidth * param.iPicHeight);
|
||||||
|
pic.pData[2] = pic.pData[1] + (param.iPicWidth * param.iPicHeight >> 2);
|
||||||
|
|
||||||
|
std::string mp4_path = data_path + "/out.mp4";
|
||||||
|
|
||||||
|
MP4FileHandle mp4 = MP4Create(mp4_path.c_str());
|
||||||
|
MP4TrackId mp4_track = -1;
|
||||||
|
MP4SetTimeScale(mp4, 90000);
|
||||||
|
|
||||||
|
const int frames = 500;
|
||||||
|
//std::ofstream f("out.h264", std::ios::binary);
|
||||||
|
for (int num = 0; num < frames; num++)
|
||||||
|
{
|
||||||
|
pb->increment();
|
||||||
|
printf("encoding %.2f%%\r", (float)num / (float)(frames - 1) * 100.f);
|
||||||
|
|
||||||
|
float value = sinf((float)num / (float)frames * 10.f);
|
||||||
|
for (int y = 0; y < param.iPicHeight; y++)
|
||||||
|
for (int x = 0; x < param.iPicWidth; x++)
|
||||||
|
buf[y * param.iPicWidth + x] = (((y + num / 4) / 10) % 2) * (255.f * value);
|
||||||
|
|
||||||
|
//prepare input data
|
||||||
|
rv = encoder->EncodeFrame(&pic, &info);
|
||||||
|
//pic.uiTimeStamp += (1.f/25.f) * 1000.f;
|
||||||
|
//assert (rv == cmResultSuccess);
|
||||||
|
if (info.eFrameType != videoFrameTypeSkip)
|
||||||
|
{
|
||||||
|
//output bitstream handling
|
||||||
|
for (int layer = 0; layer < info.iLayerNum; layer++)
|
||||||
|
{
|
||||||
|
size_t bs_size = 0;
|
||||||
|
for (int nal = 0; nal < info.sLayerInfo[layer].iNalCount; nal++)
|
||||||
|
{
|
||||||
|
std::array<uint8_t, 5> nalu_bytes;
|
||||||
|
for (int i = 0; i < nalu_bytes.size(); i++)
|
||||||
|
nalu_bytes[i] = info.sLayerInfo[layer].pBsBuf[bs_size + i];
|
||||||
|
if (nalu_bytes[4] == 0x67) // SPS
|
||||||
|
{
|
||||||
|
uint8_t avc_profile = info.sLayerInfo[layer].pBsBuf[bs_size + 5];
|
||||||
|
uint8_t avc_profile_compat = info.sLayerInfo[layer].pBsBuf[bs_size + 6];
|
||||||
|
uint8_t avc_level = info.sLayerInfo[layer].pBsBuf[bs_size + 7];
|
||||||
|
if (mp4_track == -1)
|
||||||
|
{
|
||||||
|
mp4_track = MP4AddH264VideoTrack(mp4, 90000, 90000 / 25,
|
||||||
|
param.iPicWidth, param.iPicHeight,
|
||||||
|
avc_profile, avc_profile_compat, avc_level, 3);
|
||||||
|
MP4SetVideoProfileLevel(mp4, 1);
|
||||||
|
}
|
||||||
|
MP4AddH264SequenceParameterSet(mp4, mp4_track, info.sLayerInfo[layer].pBsBuf + bs_size + 4,
|
||||||
|
info.sLayerInfo[layer].pNalLengthInByte[nal] - 4);
|
||||||
|
}
|
||||||
|
else if (nalu_bytes[4] == 0x68) // PPS
|
||||||
|
{
|
||||||
|
MP4AddH264PictureParameterSet(mp4, mp4_track, info.sLayerInfo[layer].pBsBuf + bs_size + 4,
|
||||||
|
info.sLayerInfo[layer].pNalLengthInByte[nal] - 4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int nalu_sz = info.sLayerInfo[layer].pNalLengthInByte[nal];
|
||||||
|
uint8_t* data = info.sLayerInfo[layer].pBsBuf + bs_size;
|
||||||
|
data[0] = (nalu_sz - 4) >> 24;
|
||||||
|
data[1] = (nalu_sz - 4) >> 16;
|
||||||
|
data[2] = (nalu_sz - 4) >> 8;
|
||||||
|
data[3] = (nalu_sz - 4) & 0xff;
|
||||||
|
bool sync = false;
|
||||||
|
if (nalu_bytes[4] == 0x65) // I-frame
|
||||||
|
sync = true;
|
||||||
|
else // 0x61 P-frame
|
||||||
|
sync = false;
|
||||||
|
MP4WriteSample(mp4, mp4_track, data, nalu_sz, MP4_INVALID_DURATION, 0, sync);
|
||||||
|
}
|
||||||
|
//printf("nalu %x\n", nalu_bytes[4]);
|
||||||
|
bs_size += info.sLayerInfo[layer].pNalLengthInByte[nal];
|
||||||
|
}
|
||||||
|
//f.write((const char*)info.sLayerInfo[layer].pBsBuf, bs_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//f.close();
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
MP4Close(mp4);
|
||||||
|
|
||||||
|
if (encoder)
|
||||||
|
{
|
||||||
|
encoder->Uninitialize();
|
||||||
|
WelsDestroySVCEncoder(encoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
pb->destroy();
|
||||||
|
}).detach();
|
||||||
|
}
|
||||||
@@ -1037,6 +1037,12 @@ void App::init_menu_tools()
|
|||||||
popup_exp->destroy();
|
popup_exp->destroy();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
popup_exp->find<NodeButtonCustom>("mp4test")->on_click = [this, popup_exp](Node*) {
|
||||||
|
dialog_export_mp4();
|
||||||
|
popup_exp->mouse_release();
|
||||||
|
popup_exp->destroy();
|
||||||
|
};
|
||||||
|
|
||||||
#if __IOS__
|
#if __IOS__
|
||||||
popup_exp->find<NodeButtonCustom>("sonarpen")->on_click = [this, popup_exp](Node*) {
|
popup_exp->find<NodeButtonCustom>("sonarpen")->on_click = [this, popup_exp](Node*) {
|
||||||
[ios_app sonarpen_start];
|
[ios_app sonarpen_start];
|
||||||
|
|||||||
@@ -21,4 +21,6 @@
|
|||||||
#pragma comment(lib, "Shlwapi.lib")
|
#pragma comment(lib, "Shlwapi.lib")
|
||||||
//#pragma comment(lib, "Shcore.lib")
|
//#pragma comment(lib, "Shcore.lib")
|
||||||
#pragma comment(lib, "openvr_api.lib")
|
#pragma comment(lib, "openvr_api.lib")
|
||||||
|
#pragma comment(lib, "openh264-2.0.0-win64.lib")
|
||||||
|
#pragma comment(lib, "libmp4v2.lib")
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|||||||
Reference in New Issue
Block a user