Skip to content

Commit 624a0ad

Browse files
vasn1kzlatinski
authored andcommitted
Add Duck IVF parsing support to the elementary stream.
Signed-off-by: Vassili Nikolaev (NVIDIA) <vnikolaev@nvidia.com>
1 parent 445200d commit 624a0ad

File tree

1 file changed

+78
-5
lines changed

1 file changed

+78
-5
lines changed

vk_video_decoder/libs/VkDecoderUtils/ElementaryStream.cpp

Lines changed: 78 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
#include <fstream>
1919
#include "mio/mio.hpp"
2020
#include "VkDecoderUtils/VideoStreamDemuxer.h"
21+
#define DKIF_FRAME_CONTAINER_HEADER_SIZE 12
22+
#define DKIF_HEADER_MAGIC *((const uint32_t*)"DKIF")
23+
#define DKIF_FILE_HEADER_SIZE 32
24+
#define USE_SIMPLE_MALLOC 1
2125

2226
class ElementaryStream : public VideoStreamDemuxer {
2327

@@ -32,11 +36,38 @@ class ElementaryStream : public VideoStreamDemuxer {
3236
, m_height(defaultHeight)
3337
, m_bitDepth(defaultBitDepth)
3438
, m_videoCodecType(forceParserType)
39+
#ifndef USE_SIMPLE_MALLOC
3540
, m_inputVideoStreamMmap()
41+
#endif
3642
, m_pBitstreamData(nullptr)
3743
, m_bitstreamDataSize(0)
3844
, m_bytesRead(0) {
3945

46+
#ifdef USE_SIMPLE_MALLOC
47+
FILE* handle = fopen(pFilePath, "rb");
48+
if (handle == nullptr) {
49+
printf("Failed to open video file %s\n", pFilePath);
50+
m_bitstreamDataSize = 0;
51+
m_pBitstreamData = nullptr;
52+
return;
53+
}
54+
55+
fseek(handle, 0, SEEK_END);
56+
size_t size = ftell(handle);
57+
uint8_t* data = (uint8_t*)malloc(size);
58+
59+
if (data == nullptr) {
60+
printf("Failed to allocate memory for video file: %i\n", (uint32_t)size);
61+
m_bitstreamDataSize = 0;
62+
return;
63+
}
64+
65+
m_bitstreamDataSize = size;
66+
fseek(handle, 0, SEEK_SET);
67+
fread(data, 1, size, handle);
68+
m_pBitstreamData = data;
69+
fclose(handle);
70+
#else
4071
std::error_code error;
4172
m_inputVideoStreamMmap.map(pFilePath, 0, mio::map_entire_file, error);
4273
if (error) {
@@ -46,6 +77,14 @@ class ElementaryStream : public VideoStreamDemuxer {
4677
m_bitstreamDataSize = m_inputVideoStreamMmap.mapped_length();
4778

4879
m_pBitstreamData = m_inputVideoStreamMmap.data();
80+
#endif
81+
if (m_videoCodecType == VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR) {
82+
// Assume Duck IVF. DKIF.
83+
assert(*(const uint32_t*)m_pBitstreamData == DKIF_HEADER_MAGIC);
84+
const uint32_t firstFrameOffset = (DKIF_FILE_HEADER_SIZE + DKIF_FRAME_CONTAINER_HEADER_SIZE);
85+
m_pBitstreamData += firstFrameOffset;
86+
m_bitstreamDataSize -= firstFrameOffset;
87+
}
4988
}
5089

5190
ElementaryStream(const uint8_t *pInput, const size_t,
@@ -54,11 +93,19 @@ class ElementaryStream : public VideoStreamDemuxer {
5493
, m_height(144)
5594
, m_bitDepth(8)
5695
, m_videoCodecType(codecType)
96+
#ifndef USE_SIMPLE_MALLOC
5797
, m_inputVideoStreamMmap()
98+
#endif
5899
, m_pBitstreamData(pInput)
59100
, m_bitstreamDataSize(0)
60-
, m_bytesRead(0) {
61-
101+
, m_bytesRead(0)
102+
{
103+
if (m_videoCodecType == VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR) {
104+
// Assume Duck IVF. DKIF.
105+
assert(*(const uint32_t*)pInput == DKIF_HEADER_MAGIC);
106+
const uint32_t firstFrameOffset = (DKIF_FILE_HEADER_SIZE + DKIF_FRAME_CONTAINER_HEADER_SIZE);
107+
m_pBitstreamData += firstFrameOffset;
108+
}
62109
}
63110

64111
int32_t Initialize() { return 0; }
@@ -83,7 +130,11 @@ class ElementaryStream : public VideoStreamDemuxer {
83130
}
84131

85132
virtual ~ElementaryStream() {
133+
#ifdef USE_SIMPLE_MALLOC
134+
135+
#else
86136
m_inputVideoStreamMmap.unmap();
137+
#endif
87138
}
88139

89140
virtual bool IsStreamDemuxerEnabled() const { return false; }
@@ -135,7 +186,17 @@ class ElementaryStream : public VideoStreamDemuxer {
135186
}
136187
virtual uint32_t GetProfileIdc() const
137188
{
138-
return STD_VIDEO_H264_PROFILE_IDC_MAIN;
189+
switch (m_videoCodecType) {
190+
case VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR:
191+
return STD_VIDEO_H264_PROFILE_IDC_MAIN;
192+
case VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR:
193+
return STD_VIDEO_H265_PROFILE_IDC_MAIN;
194+
case VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR:
195+
return STD_VIDEO_AV1_PROFILE_MAIN;
196+
default:
197+
assert(0);
198+
}
199+
return (uint32_t)(-1);
139200
}
140201

141202
virtual int32_t GetWidth() const { return m_width; }
@@ -150,8 +211,18 @@ class ElementaryStream : public VideoStreamDemuxer {
150211
assert(m_pBitstreamData != nullptr);
151212

152213
// Compute and return the pointer to data at new offset.
153-
*ppVideo = (m_pBitstreamData + offset);
154-
return m_bitstreamDataSize - offset;
214+
if (m_videoCodecType == VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR) {
215+
*ppVideo = (m_pBitstreamData + offset);
216+
uint32_t dataSize = *(const uint32_t*)(*ppVideo - DKIF_FRAME_CONTAINER_HEADER_SIZE);
217+
if ((m_bitstreamDataSize - (offset + dataSize)) == 0) {
218+
return dataSize;
219+
}
220+
221+
return dataSize + DKIF_FRAME_CONTAINER_HEADER_SIZE;
222+
} else {
223+
*ppVideo = (m_pBitstreamData + offset);
224+
return m_bitstreamDataSize - offset;
225+
}
155226
}
156227

157228
virtual void DumpStreamParameters() const {
@@ -160,7 +231,9 @@ class ElementaryStream : public VideoStreamDemuxer {
160231
private:
161232
int32_t m_width, m_height, m_bitDepth;
162233
VkVideoCodecOperationFlagBitsKHR m_videoCodecType;
234+
#ifndef USE_SIMPLE_MALLOC
163235
mio::basic_mmap<mio::access_mode::read, uint8_t> m_inputVideoStreamMmap;
236+
#endif
164237
const uint8_t* m_pBitstreamData;
165238
VkDeviceSize m_bitstreamDataSize;
166239
VkDeviceSize m_bytesRead;

0 commit comments

Comments
 (0)