Skip to content

Commit

Permalink
Handle video flip and rotate metadata in ffms2
Browse files Browse the repository at this point in the history
  • Loading branch information
wangqr authored and tgoyne committed Sep 23, 2019
1 parent 57ee580 commit 6d4dd60
Showing 1 changed file with 56 additions and 0 deletions.
56 changes: 56 additions & 0 deletions src/video_provider_ffmpegsource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,17 @@ class FFmpegSourceVideoProvider final : public VideoProvider, FFmpegSourceProvid
}

int GetFrameCount() const override { return VideoInfo->NumFrames; }

#if FFMS_VERSION >= ((2 << 24) | (24 << 16) | (0 << 8) | 0)
int GetWidth() const override { return (VideoInfo->Rotation % 180 == 90 || VideoInfo->Rotation % 180 == -90) ? Height : Width; }
int GetHeight() const override { return (VideoInfo->Rotation % 180 == 90 || VideoInfo->Rotation % 180 == -90) ? Width : Height; }
double GetDAR() const override { return (VideoInfo->Rotation % 180 == 90 || VideoInfo->Rotation % 180 == -90) ? 1 / DAR : DAR; }
#else
int GetWidth() const override { return Width; }
int GetHeight() const override { return Height; }
double GetDAR() const override { return DAR; }
#endif

agi::vfr::Framerate GetFPS() const override { return Timecodes; }
std::string GetColorSpace() const override { return ColorSpace; }
std::string GetRealColorSpace() const override { return RealColorSpace; }
Expand Down Expand Up @@ -318,6 +326,54 @@ void FFmpegSourceVideoProvider::GetFrame(int n, VideoFrame &out) {
out.width = Width;
out.height = Height;
out.pitch = frame->Linesize[0];
#if FFMS_VERSION >= ((2 << 24) | (31 << 16) | (0 << 8) | 0)
// Handle flip
if (VideoInfo->Flip > 0)
for (int x = 0; x < Height; ++x)
for (int y = 0; y < Width / 2; ++y)
for (int ch = 0; ch < 4; ++ch)
std::swap(out.data[frame->Linesize[0] * x + 4 * y + ch], out.data[frame->Linesize[0] * x + 4 * (Width - 1 - y) + ch]);

else if (VideoInfo->Flip < 0)
for (int x = 0; x < Height / 2; ++x)
for (int y = 0; y < Width; ++y)
for (int ch = 0; ch < 4; ++ch)
std::swap(out.data[frame->Linesize[0] * x + 4 * y + ch], out.data[frame->Linesize[0] * (Height - 1 - x) + 4 * y + ch]);
#endif
#if FFMS_VERSION >= ((2 << 24) | (24 << 16) | (0 << 8) | 0)
// Handle rotation
if (VideoInfo->Rotation % 360 == 180 || VideoInfo->Rotation % 360 == -180) {
std::vector<unsigned char> data(std::move(out.data));
out.data.resize(Width * Height * 4);
for (int x = 0; x < Height; ++x)
for (int y = 0; y < Width; ++y)
for (int ch = 0; ch < 4; ++ch)
out.data[4 * (Width * x + y) + ch] = data[frame->Linesize[0] * (Height - 1 - x) + 4 * (Width - 1 - y) + ch];
out.pitch = 4 * Width;
}
else if (VideoInfo->Rotation % 180 == 90 || VideoInfo->Rotation % 360 == -270) {
std::vector<unsigned char> data(std::move(out.data));
out.data.resize(Width * Height * 4);
for (int x = 0; x < Width; ++x)
for (int y = 0; y < Height; ++y)
for (int ch = 0; ch < 4; ++ch)
out.data[4 * (Height * x + y) + ch] = data[frame->Linesize[0] * y + 4 * (Width - 1 - x) + ch];
out.width = Height;
out.height = Width;
out.pitch = 4 * Height;
}
else if (VideoInfo->Rotation % 180 == 270 || VideoInfo->Rotation % 360 == -90) {
std::vector<unsigned char> data(std::move(out.data));
out.data.resize(Width * Height * 4);
for (int x = 0; x < Width; ++x)
for (int y = 0; y < Height; ++y)
for (int ch = 0; ch < 4; ++ch)
out.data[4 * (Height * x + y) + ch] = data[frame->Linesize[0] * (Height - 1 - y) + 4 * x + ch];
out.width = Height;
out.height = Width;
out.pitch = 4 * Height;
}
#endif
}
}

Expand Down

0 comments on commit 6d4dd60

Please sign in to comment.