Skip to content

Commit

Permalink
refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
aliakseis committed Mar 21, 2024
1 parent f2673cf commit a774faf
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 114 deletions.
4 changes: 3 additions & 1 deletion .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ IndentWidth: 4
BreakBeforeBraces: Allman
AllowShortIfStatementsOnASingleLine: false
IndentCaseLabels: false
ColumnLimit: 99
ColumnLimit: 99
IndentAccessModifiers: false
AccessModifierOffset: -4
106 changes: 106 additions & 0 deletions video/decoderiocontext.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#include "decoderiocontext.h"

extern "C"
{
#include <libavformat/avformat.h>
}


// static
int DecoderIOContext::IOReadFunc(void *data, uint8_t *buf, int buf_size)
{
auto *hctx = static_cast<DecoderIOContext*>(data);
auto len = hctx->stream->sgetn((char *)buf, buf_size);
if (len <= 0)
{
// Let FFmpeg know that we have reached EOF, or do something else
return AVERROR_EOF;
}
return static_cast<int>(len);
}

// whence: SEEK_SET, SEEK_CUR, SEEK_END (like fseek) and AVSEEK_SIZE
// static
int64_t DecoderIOContext::IOSeekFunc(void *data, int64_t pos, int whence)
{
auto *hctx = static_cast<DecoderIOContext*>(data);

if (whence == AVSEEK_SIZE)
{
// return the file size if you wish to
auto current = hctx->stream->pubseekoff(0, std::ios_base::cur, std::ios_base::in);
auto result = hctx->stream->pubseekoff(0, std::ios_base::end, std::ios_base::in);
hctx->stream->pubseekoff(current, std::ios_base::beg, std::ios_base::in);
return result;
}

std::ios_base::seekdir dir;
switch (whence)
{
case SEEK_SET:
dir = std::ios_base::beg;
break;
case SEEK_CUR:
dir = std::ios_base::cur;
break;
case SEEK_END:
dir = std::ios_base::end;
break;
default:
return -1LL;
}

return hctx->stream->pubseekoff(pos, dir);
}

DecoderIOContext::DecoderIOContext(std::unique_ptr<std::streambuf> s)
: stream(std::move(s))
{
// allocate buffer
bufferSize = 1024 * 64; // FIXME: not sure what size to use
buffer = static_cast<uint8_t*>(av_malloc(bufferSize)); // see destructor for details

// allocate the AVIOContext
ioCtx =
avio_alloc_context(buffer, bufferSize, // internal buffer and its size
0, // write flag (1=true,0=false)
(void *)this, // user data, will be passed to our callback functions
IOReadFunc,
nullptr, // no writing
IOSeekFunc);
}

DecoderIOContext::~DecoderIOContext()
{
//CHANNEL_LOG(ffmpeg_closing) << "In DecoderIOContext::~DecoderIOContext()";

// NOTE: ffmpeg messes up the buffer
// so free the buffer first then free the context
av_free(ioCtx->buffer);
ioCtx->buffer = nullptr;
av_free(ioCtx);
}

void DecoderIOContext::initAVFormatContext(AVFormatContext *pCtx)
{
pCtx->pb = ioCtx;
pCtx->flags |= AVFMT_FLAG_CUSTOM_IO;

// you can specify a format directly
// pCtx->iformat = av_find_input_format("h264");

// or read some of the file and let ffmpeg do the guessing
auto len = stream->sgetn((char *)buffer, bufferSize);
if (len <= 0)
{
return;
}
// reset to beginning of file
stream->pubseekoff(0, std::ios_base::beg, std::ios_base::in);

AVProbeData probeData = {nullptr};
probeData.buf = buffer;
probeData.buf_size = bufferSize - 1;
probeData.filename = "";
pCtx->iformat = av_probe_input_format(&probeData, 1);
}
26 changes: 26 additions & 0 deletions video/decoderiocontext.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#pragma once

#include <cstdint>
#include <memory>
#include <streambuf>

struct AVIOContext;
struct AVFormatContext;

class DecoderIOContext
{
private:
AVIOContext *ioCtx;
uint8_t *buffer; // internal buffer for ffmpeg
int bufferSize;
std::unique_ptr<std::streambuf> stream;

public:
DecoderIOContext(std::unique_ptr<std::streambuf> s);
~DecoderIOContext();

void initAVFormatContext(AVFormatContext * /*pCtx*/);

static int IOReadFunc(void *data, uint8_t *buf, int buf_size);
static int64_t IOSeekFunc(void *data, int64_t pos, int whence);
};
113 changes: 2 additions & 111 deletions video/ffmpegdecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "makeguard.h"
#include "interlockedadd.h"
#include "subtitles.h"
#include "decoderiocontext.h"

#include <boost/chrono.hpp>
#include <memory>
Expand Down Expand Up @@ -122,116 +123,6 @@ std::unique_ptr<IFrameDecoder> GetFrameDecoder(std::unique_ptr<IAudioPlayer> aud
return std::unique_ptr<IFrameDecoder>(new FFmpegDecoder(std::move(audioPlayer)));
}

// https://gist.github.com/xlphs/9895065
class FFmpegDecoder::IOContext
{
private:
AVIOContext *ioCtx;
uint8_t *buffer; // internal buffer for ffmpeg
int bufferSize;
std::unique_ptr<std::streambuf> stream;

public:
IOContext(std::unique_ptr<std::streambuf> s);
~IOContext();

void initAVFormatContext(AVFormatContext * /*pCtx*/);

static int IOReadFunc(void *data, uint8_t *buf, int buf_size);
static int64_t IOSeekFunc(void *data, int64_t pos, int whence);
};

// static
int FFmpegDecoder::IOContext::IOReadFunc(void *data, uint8_t *buf, int buf_size)
{
auto *hctx = static_cast<IOContext *>(data);
auto len = hctx->stream->sgetn((char*)buf, buf_size);
if (len <= 0)
{
// Let FFmpeg know that we have reached EOF, or do something else
return AVERROR_EOF;
}
return static_cast<int>(len);
}

// whence: SEEK_SET, SEEK_CUR, SEEK_END (like fseek) and AVSEEK_SIZE
// static
int64_t FFmpegDecoder::IOContext::IOSeekFunc(void *data, int64_t pos, int whence)
{
auto *hctx = static_cast<IOContext *>(data);

if (whence == AVSEEK_SIZE)
{
// return the file size if you wish to
auto current = hctx->stream->pubseekoff(0, std::ios_base::cur, std::ios_base::in);
auto result = hctx->stream->pubseekoff(0, std::ios_base::end, std::ios_base::in);
hctx->stream->pubseekoff(current, std::ios_base::beg, std::ios_base::in);
return result;
}

std::ios_base::seekdir dir;
switch (whence)
{
case SEEK_SET: dir = std::ios_base::beg; break;
case SEEK_CUR: dir = std::ios_base::cur; break;
case SEEK_END: dir = std::ios_base::end; break;
default: return -1LL;
}

return hctx->stream->pubseekoff(pos, dir);
}

FFmpegDecoder::IOContext::IOContext(std::unique_ptr<std::streambuf> s)
: stream(std::move(s))
{
// allocate buffer
bufferSize = 1024 * 64; // FIXME: not sure what size to use
buffer = static_cast<uint8_t *>(av_malloc(bufferSize)); // see destructor for details

// allocate the AVIOContext
ioCtx =
avio_alloc_context(buffer, bufferSize, // internal buffer and its size
0, // write flag (1=true,0=false)
(void *)this, // user data, will be passed to our callback functions
IOReadFunc,
nullptr, // no writing
IOSeekFunc);
}

FFmpegDecoder::IOContext::~IOContext()
{
CHANNEL_LOG(ffmpeg_closing) << "In IOContext::~IOContext()";

// NOTE: ffmpeg messes up the buffer
// so free the buffer first then free the context
av_free(ioCtx->buffer);
ioCtx->buffer = nullptr;
av_free(ioCtx);
}

void FFmpegDecoder::IOContext::initAVFormatContext(AVFormatContext *pCtx)
{
pCtx->pb = ioCtx;
pCtx->flags |= AVFMT_FLAG_CUSTOM_IO;

// you can specify a format directly
// pCtx->iformat = av_find_input_format("h264");

// or read some of the file and let ffmpeg do the guessing
auto len = stream->sgetn((char*)buffer, bufferSize);
if (len <= 0) {
return;
}
// reset to beginning of file
stream->pubseekoff(0, std::ios_base::beg, std::ios_base::in);

AVProbeData probeData = { nullptr };
probeData.buf = buffer;
probeData.buf_size = bufferSize - 1;
probeData.filename = "";
pCtx->iformat = av_probe_input_format(&probeData, 1);
}

//////////////////////////////////////////////////////////////////////////////

FFmpegDecoder::FFmpegDecoder(std::unique_ptr<IAudioPlayer> audioPlayer)
Expand Down Expand Up @@ -460,7 +351,7 @@ bool FFmpegDecoder::openStream(std::unique_ptr<std::streambuf> stream)
{
close();

auto ioCtx = std::make_unique<IOContext>(std::move(stream));
auto ioCtx = std::make_unique<DecoderIOContext>(std::move(stream));

auto formatContext = avformat_alloc_context();

Expand Down
6 changes: 4 additions & 2 deletions video/ffmpegdecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ struct RendezVousData
boost::condition_variable cond;
};

class DecoderIOContext;


// Inspired by http://dranger.com/ffmpeg/ffmpeg.html

class FFmpegDecoder final : public IFrameDecoder, public IAudioPlayerCallback
Expand Down Expand Up @@ -147,7 +150,6 @@ class FFmpegDecoder final : public IFrameDecoder, public IAudioPlayerCallback
void setImageConversionFunc(ImageConversionFunc func) override;

private:
class IOContext;
struct VideoParseContext;

// Threads
Expand Down Expand Up @@ -312,7 +314,7 @@ class FFmpegDecoder final : public IFrameDecoder, public IAudioPlayerCallback

std::vector<int> m_audioIndices;

std::unique_ptr<IOContext> m_ioCtx;
std::unique_ptr<DecoderIOContext> m_ioCtx;

boost::atomic<boost::chrono::high_resolution_clock::duration> m_referenceTime;

Expand Down
2 changes: 2 additions & 0 deletions video/video.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="audioparserunnable.cpp" />
<ClCompile Include="decoderiocontext.cpp" />
<ClCompile Include="displayrunnable.cpp" />
<ClCompile Include="ffmpegdecoder.cpp" />
<ClCompile Include="ffmpeg_dxva2.cpp" />
Expand All @@ -145,6 +146,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="audioplayer.h" />
<ClInclude Include="decoderiocontext.h" />
<ClInclude Include="ffmpegdecoder.h" />
<ClInclude Include="ffmpeg_dxva2.h" />
<ClInclude Include="fqueue.h" />
Expand Down
6 changes: 6 additions & 0 deletions video/video.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
<ClCompile Include="subtitles.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="decoderiocontext.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="audioplayer.h">
Expand Down Expand Up @@ -68,6 +71,9 @@
<ClInclude Include="subtitles.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="decoderiocontext.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
</ItemGroup>
Expand Down

0 comments on commit a774faf

Please sign in to comment.