Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixes #9861. Rotate upside-down iPhone videos.

Thanks to David Badia for the patch (slightly modified to eliminate
compiler warnings and conform to coding standards).

This has been tested under the Slim and VDPAU Normal playback profiles.

Signed-off-by: Jim Stichnoth <jstichnoth@mythtv.org>
  • Loading branch information...
commit 60cf735196cf267226dd8f7ec937a82fb5f8d4b3 1 parent 04715f6
dbadia dbadia authored stichnot committed
1  mythtv/filters/filters.pro
View
@@ -6,6 +6,7 @@ TEMPLATE = subdirs
# Directories
SUBDIRS += invert linearblend denoise3d quickdnr kerneldeint crop force
SUBDIRS += adjust onefield bobdeint ivtc greedyhdeint yadif fieldorder
+SUBDIRS += vflip
contains(CONFIG_POSTPROC, yes): SUBDIRS += postprocess
6 mythtv/libs/libmythtv/avformatdecoder.cpp
View
@@ -70,6 +70,7 @@ extern "C" {
#include "libavformat/avio.h"
#include "libavformat/internal.h"
#include "libswscale/swscale.h"
+#include "libavformat/isom.h"
#include "ivtv_myth.h"
}
@@ -1314,6 +1315,11 @@ void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc,
}
}
+ AVDictionaryEntry *metatag =
+ av_dict_get(stream->metadata, "rotate", NULL, 0);
+ if (metatag && metatag->value && QString("180") == metatag->value)
+ video_inverted = true;
+
if (CODEC_IS_VDPAU(codec))
{
enc->get_buffer = get_avf_buffer_vdpau;
1  mythtv/libs/libmythtv/decoderbase.cpp
View
@@ -44,6 +44,7 @@ DecoderBase::DecoderBase(MythPlayer *parent, const ProgramInfo &pginfo)
getrawframes(false), getrawvideo(false),
errored(false), waitingForChange(false), readAdjust(0),
justAfterChange(false),
+ video_inverted(false),
decodeAllSubtitles(false),
// language preference
languagePreference(iso639_get_language_key_list())
2  mythtv/libs/libmythtv/decoderbase.h
View
@@ -216,6 +216,7 @@ class DecoderBase
void SaveTotalDuration(void);
void ResetTotalDuration(void) { totalDuration = 0; }
void SaveTotalFrames(void);
+ bool GetVideoInverted(void) const { return video_inverted; }
protected:
virtual int AutoSelectTrack(uint type);
@@ -286,6 +287,7 @@ class DecoderBase
bool waitingForChange;
long long readAdjust;
bool justAfterChange;
+ bool video_inverted;
// Audio/Subtitle/EIA-608/EIA-708 stream selection
bool decodeAllSubtitles;
7 mythtv/libs/libmythtv/mythplayer.cpp
View
@@ -500,6 +500,9 @@ bool MythPlayer::InitVideo(void)
if (embedding && pipState == kPIPOff)
videoOutput->EmbedInWidget(embedRect);
+ if (decoder && decoder->GetVideoInverted())
+ videoOutput->SetVideoFlip();
+
InitFilters();
return true;
@@ -1049,6 +1052,10 @@ void MythPlayer::InitFilters(void)
if (!videoFiltersOverride.isEmpty())
filters = videoFiltersOverride;
+ AvFormatDecoder *afd = dynamic_cast<AvFormatDecoder *>(decoder);
+ if (afd && afd->GetVideoInverted() && !filters.contains("vflip"))
+ filters += ",vflip";
+
filters.detach();
videofiltersLock.lock();
10 mythtv/libs/libmythtv/videoout_vdpau.cpp
View
@@ -1309,3 +1309,13 @@ QStringList VideoOutputVDPAU::GetVisualiserList(void)
return VideoVisual::GetVisualiserList(m_render->Type());
return VideoOutput::GetVisualiserList();
}
+
+void VideoOutputVDPAU::SetVideoFlip(void)
+{
+ if (!m_render)
+ {
+ LOG(VB_PLAYBACK, LOG_ERR, QString("SetVideoFlip failed."));
+ return;
+ }
+ m_render->SetVideoFlip();
+}
1  mythtv/libs/libmythtv/videoout_vdpau.h
View
@@ -71,6 +71,7 @@ class VideoOutputVDPAU : public VideoOutput
{ return VideoOutput::SetupVisualisation(audio, m_render, name); }
virtual QStringList GetVisualiserList(void);
virtual void ClearDummyFrame(VideoFrame* frame);
+ virtual void SetVideoFlip(void);
private:
virtual bool hasFullScreenOSD(void) const { return true; }
3  mythtv/libs/libmythtv/videooutbase.h
View
@@ -230,6 +230,9 @@ class VideoOutput
/// \brief check if video underscan/overscan is allowed
bool IsVideoScalingAllowed(void) const;
+ /// \brief Tells the player to flip the video frames for proper display
+ virtual void SetVideoFlip(void) { };
+
/// \brief returns QRect of PIP based on PIPLocation
virtual QRect GetPIPRect(PIPLocation location,
MythPlayer *pipplayer = NULL,
21 mythtv/libs/libmythui/mythrender_vdpau.cpp
View
@@ -273,6 +273,7 @@ MythRenderVDPAU::MythRenderVDPAU()
m_render_lock(QMutex::Recursive), m_decode_lock(QMutex::Recursive),
m_display(NULL), m_window(0), m_device(0), m_surface(0),
m_flipQueue(0), m_flipTarget(0), m_flipReady(false), m_colorKey(0),
+ m_flipFrames(false),
vdp_get_proc_address(NULL), vdp_get_error_string(NULL)
{
LOCK_ALL
@@ -1105,16 +1106,26 @@ bool MythRenderVDPAU::MixAndRend(uint id, VdpVideoMixerPictureStructure field,
outRect.y0 = dst.top();
outRect.x1 = dst.left() + dst.width();
outRect.y1 = dst.top() + dst.height();
- srcRect.x0 = src.left();
- srcRect.y0 = src.top();
- srcRect.x1 = src.left() + src.width();
- srcRect.y1 = src.top() + src.height();
+ if (m_flipFrames)
+ {
+ // flip the image
+ srcRect.x0 = src.left() + src.width();
+ srcRect.y0 = src.top() + src.height();
+ srcRect.x1 = src.left();
+ srcRect.y1 = src.top();
+ }
+ else
+ {
+ srcRect.x0 = src.left();
+ srcRect.y0 = src.top();
+ srcRect.x1 = src.left() + src.width();
+ srcRect.y1 = src.top() + src.height();
+ }
outRectVid.x0 = dst_vid.left();
outRectVid.y0 = dst_vid.top();
outRectVid.x1 = dst_vid.left() + dst_vid.width();
outRectVid.y1 = dst_vid.top() + dst_vid.height();
-
vdp_st = vdp_video_mixer_render(mixer, VDP_INVALID_HANDLE,
NULL, field, deint ? 2 : 0,
deint ? past_surfaces : NULL,
2  mythtv/libs/libmythui/mythrender_vdpau.h
View
@@ -135,6 +135,7 @@ class MUI_PUBLIC MythRenderVDPAU : public MythRender
void ChangeVideoSurfaceOwner(uint id);
void Decode(uint id, struct vdpau_render_state *render);
+ void SetVideoFlip(void) { m_flipFrames = true; }
private:
virtual ~MythRenderVDPAU();
@@ -180,6 +181,7 @@ class MUI_PUBLIC MythRenderVDPAU : public MythRender
VdpPresentationQueueTarget m_flipTarget;
bool m_flipReady;
uint m_colorKey;
+ bool m_flipFrames;
QVector<uint> m_surfaces;
QHash<uint, VDPAUOutputSurface> m_outputSurfaces;
Please sign in to comment.
Something went wrong with that request. Please try again.