From 897c8c72872b67127740e5daa1355922f581d3ca Mon Sep 17 00:00:00 2001 From: wang-bin Date: Thu, 14 Mar 2013 21:38:06 +0800 Subject: [PATCH 1/7] add osd --- src/AVPlayer.cpp | 19 +++++++++ src/Filter.cpp | 37 ++++++++++++++++ src/OSDFilter.cpp | 65 ++++++++++++++++++++++++++++ src/OSDFilterQPainter.cpp | 78 ++++++++++++++++++++++++++++++++++ src/QtAV/AVPlayer.h | 4 ++ src/QtAV/Filter.h | 52 +++++++++++++++++++++++ src/QtAV/OSDFilter.h | 35 +++++++++++++++ src/QtAV/OSDFilterQPainter.h | 37 ++++++++++++++++ src/QtAV/VideoThread.h | 2 + src/QtAV/private/Filter_p.h | 38 +++++++++++++++++ src/QtAV/private/OSDFilter_p.h | 48 +++++++++++++++++++++ src/VideoThread.cpp | 27 ++++++++++-- src/libQtAV.pro | 11 ++++- 13 files changed, 448 insertions(+), 5 deletions(-) create mode 100644 src/Filter.cpp create mode 100644 src/OSDFilter.cpp create mode 100644 src/OSDFilterQPainter.cpp create mode 100644 src/QtAV/Filter.h create mode 100644 src/QtAV/OSDFilter.h create mode 100644 src/QtAV/OSDFilterQPainter.h create mode 100644 src/QtAV/private/Filter_p.h create mode 100644 src/QtAV/private/OSDFilter_p.h diff --git a/src/AVPlayer.cpp b/src/AVPlayer.cpp index d7a7b5340..9f7086589 100644 --- a/src/AVPlayer.cpp +++ b/src/AVPlayer.cpp @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -54,6 +55,7 @@ namespace QtAV { AVPlayer::AVPlayer(QObject *parent) : QObject(parent),loaded(false),capture_dir("capture"),_renderer(0),_audio(0) ,event_filter(0),video_capture(0) + , osd(0) { qDebug("%s", aboutQtAV().toUtf8().constData()); /* @@ -90,6 +92,7 @@ AVPlayer::AVPlayer(QObject *parent) : setPlayerEventFilter(new EventFilter(this)); setVideoCapture(new VideoCapture()); + setOSDFilter(new OSDFilterQPainter()); } AVPlayer::~AVPlayer() @@ -231,6 +234,19 @@ bool AVPlayer::captureVideo() return true; } +OSDFilter* AVPlayer::setOSDFilter(OSDFilter *osd) +{ + OSDFilter *old = osd; + this->osd = osd; + video_thread->setOSDFilter(osd); + return old; +} + +OSDFilter* AVPlayer::osdFilter() +{ + return osd; +} + bool AVPlayer::play(const QString& path) { setFile(path); @@ -339,6 +355,9 @@ void AVPlayer::play() Q_ASSERT(clock != 0); clock->reset(); + if (osd) { + osd->setTotalTime(duration()); + } if (aCodecCtx) { qDebug("Starting audio thread..."); audio_thread->start(QThread::HighestPriority); diff --git a/src/Filter.cpp b/src/Filter.cpp new file mode 100644 index 000000000..9836f94a3 --- /dev/null +++ b/src/Filter.cpp @@ -0,0 +1,37 @@ +/****************************************************************************** + QtAV: Media play library based on Qt and FFmpeg + Copyright (C) 2013 Wang Bin + +* This file is part of QtAV + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +******************************************************************************/ + +#include "QtAV/Filter.h" +#include "private/Filter_p.h" + +namespace QtAV { + +Filter::Filter(FilterPrivate &d) + :DPTR_INIT(&d) +{ + +} + +Filter::~Filter() +{ +} + +} //namespace QtAV diff --git a/src/OSDFilter.cpp b/src/OSDFilter.cpp new file mode 100644 index 000000000..296a75db8 --- /dev/null +++ b/src/OSDFilter.cpp @@ -0,0 +1,65 @@ +#include "QtAV/OSDFilter.h" +#include "private/OSDFilter_p.h" + +namespace QtAV { + +OSDFilter::OSDFilter(OSDFilterPrivate &d): + Filter(d) +{ +} + +OSDFilter::~OSDFilter() +{ +} + +void OSDFilter::setShowType(ShowType type) +{ + DPTR_D(OSDFilter); + d.show_type = type; +} + +OSDFilter::ShowType OSDFilter::showType() const +{ + return d_func().show_type; +} + +void OSDFilter::useNextShowType() +{ + DPTR_D(OSDFilter); + if (d.show_type == ShowNone) { + d.show_type = (ShowType)1; + return; + } + if (d.show_type + 1 == ShowNone) { + d.show_type = ShowNone; + return; + } + d.show_type = (ShowType)(d.show_type << 1); +} + +bool OSDFilter::hasShowType(ShowType t) const +{ + DPTR_D(const OSDFilter); + return (t&d.show_type) == t; +} + +void OSDFilter::setCurrentTime(int currentSeconds) +{ + DPTR_D(OSDFilter); + d.sec_current = currentSeconds; +} + +void OSDFilter::setTotalTime(int totalSeconds) +{ + DPTR_D(OSDFilter); + d.sec_total = totalSeconds; +} + +void OSDFilter::setImageSize(int width, int height) +{ + DPTR_D(OSDFilter); + d.width = width; + d.height = height; +} + +} //namespace QtAV diff --git a/src/OSDFilterQPainter.cpp b/src/OSDFilterQPainter.cpp new file mode 100644 index 000000000..ffd136fcf --- /dev/null +++ b/src/OSDFilterQPainter.cpp @@ -0,0 +1,78 @@ +/****************************************************************************** + QtAV: Media play library based on Qt and FFmpeg + Copyright (C) 2013 Wang Bin + +* This file is part of QtAV + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +******************************************************************************/ + +#include "QtAV/OSDFilterQPainter.h" +#include "private/OSDFilter_p.h" +#include +#include + +namespace QtAV { + +class OSDFilterQPainterPrivate : public OSDFilterPrivate +{ + +}; + +OSDFilterQPainter::OSDFilterQPainter(): + OSDFilter(*new OSDFilterQPainterPrivate()) +{ +} + +void OSDFilterQPainter::process(QByteArray &data) +{ + DPTR_D(OSDFilterQPainter); + if (d.sec_current < 0 || d.sec_total < 0) + return; + QString text; + if (hasShowType(ShowCurrentTime) || hasShowType(ShowCurrentAndTotalTime)) { + int h = d.sec_current/3600; + int m = (d.sec_current%3600)/60; + int s = d.sec_current%60; + text += QString("%1:%2:%3").arg(h, 2, 10, QChar('0')).arg(m, 2, 10, QChar('0')).arg(s, 2, 10, QChar('0')); + if (hasShowType(ShowCurrentAndTotalTime)) + text += " / "; + } + if (hasShowType(ShowCurrentAndTotalTime)) { + int h = d.sec_total/3600; + int m = (d.sec_total%3600)/60; + int s = d.sec_total%60; + text += QString("%1:%2:%3").arg(h, 2, 10, QChar('0')).arg(m, 2, 10, QChar('0')).arg(s, 2, 10, QChar('0')); + } + if (hasShowType(ShowRemainTime)) { + int h = (d.sec_total-d.sec_current)/3600; + int m = ((d.sec_total-d.sec_current)%3600)/60; + int s = (d.sec_total-d.sec_current)%60; + text += QString(" -%1:%2:%3").arg(h, 2, 10, QChar('0')).arg(m, 2, 10, QChar('0')).arg(s, 2, 10, QChar('0')); + } + if (hasShowType(ShowPercent) && d.sec_total > 0) + text += QString::number(qreal(d.sec_current)/qreal(d.sec_total)*100.0) + "%"; + + QImage image((uchar*)data.data(), d.width, d.height, QImage::Format_RGB32); + QPainter painter(&image); + QFont f; + f.setBold(true); + f.setPixelSize(26); + painter.setFont(f); + painter.setPen(Qt::white); + painter.drawText(60, 60, text); +} + +} //namespace QtAV diff --git a/src/QtAV/AVPlayer.h b/src/QtAV/AVPlayer.h index 46c1d971b..b98c9d065 100644 --- a/src/QtAV/AVPlayer.h +++ b/src/QtAV/AVPlayer.h @@ -36,6 +36,7 @@ class VideoRenderer; class AVClock; class AVDemuxThread; class VideoCapture; +class OSDFilter; class Q_EXPORT AVPlayer : public QObject { Q_OBJECT @@ -61,6 +62,8 @@ class Q_EXPORT AVPlayer : public QObject void setCaptureName(const QString& name);//TODO: remove. base name void setCaptureSaveDir(const QString& dir); //TODO: remove bool captureVideo(); + OSDFilter* setOSDFilter(OSDFilter* osd); + OSDFilter* osdFilter(); bool play(const QString& path); bool isPlaying() const; bool isPaused() const; @@ -111,6 +114,7 @@ protected slots: //tODO: (un)register api QObject *event_filter; VideoCapture *video_capture; + OSDFilter *osd; }; } //namespace QtAV diff --git a/src/QtAV/Filter.h b/src/QtAV/Filter.h new file mode 100644 index 000000000..af7aa3c0c --- /dev/null +++ b/src/QtAV/Filter.h @@ -0,0 +1,52 @@ +/****************************************************************************** + QtAV: Media play library based on Qt and FFmpeg + Copyright (C) 2013 Wang Bin + +* This file is part of QtAV + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +******************************************************************************/ + +#ifndef QTAV_FILTER_H +#define QTAV_FILTER_H + +#include + +class QByteArray; +namespace QtAV { + +class FilterPrivate; +class Q_EXPORT Filter +{ + DPTR_DECLARE_PRIVATE(Filter) +public: + virtual ~Filter() = 0; + + //TODO: parameter FrameContext +protected: + /* + * If the filter is in AVThread, it's safe to operate on ref. + */ + virtual void process(QByteArray& data) = 0; + Filter(FilterPrivate& d); + + friend class AVThread; + friend class VideoThread; + DPTR_DECLARE(Filter) +}; + +} //namespace QtAV + +#endif // QTAV_FILTER_H diff --git a/src/QtAV/OSDFilter.h b/src/QtAV/OSDFilter.h new file mode 100644 index 000000000..4066e33f5 --- /dev/null +++ b/src/QtAV/OSDFilter.h @@ -0,0 +1,35 @@ +#ifndef QTAV_OSDFILTER_H +#define QTAV_OSDFILTER_H + +#include + +namespace QtAV { + +class OSDFilterPrivate; +class OSDFilter : public Filter +{ + DPTR_DECLARE_PRIVATE(OSDFilter) +public: + enum ShowType { + ShowCurrentTime = 1, + ShowCurrentAndTotalTime = 1<<1, + ShowRemainTime = 1<<2, + ShowPercent = 1<<3, + ShowNone + }; + + virtual ~OSDFilter(); + void setShowType(ShowType type); + ShowType showType() const; + void useNextShowType(); + bool hasShowType(ShowType t) const; + void setCurrentTime(int currentSeconds); + void setTotalTime(int totalSeconds); + void setImageSize(int width, int height); //TODO: move to VideoFrameContext +protected: + OSDFilter(OSDFilterPrivate& d); +}; + +} //namespace QtAV + +#endif // QTAV_OSDFILTER_H diff --git a/src/QtAV/OSDFilterQPainter.h b/src/QtAV/OSDFilterQPainter.h new file mode 100644 index 000000000..a1fec8aa6 --- /dev/null +++ b/src/QtAV/OSDFilterQPainter.h @@ -0,0 +1,37 @@ +/****************************************************************************** + QtAV: Media play library based on Qt and FFmpeg + Copyright (C) 2013 Wang Bin + +* This file is part of QtAV + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +******************************************************************************/ + +#ifndef QTAV_OSDFILTERQPAINTER_H +#define QTAV_OSDFILTERQPAINTER_H + +#include + +namespace QtAV { + +class OSDFilterQPainter : public OSDFilter +{ +public: + OSDFilterQPainter(); + virtual void process(QByteArray &data); +}; + +} //namespace QtAV +#endif // QTAV_OSDFILTERQPAINTER_H diff --git a/src/QtAV/VideoThread.h b/src/QtAV/VideoThread.h index 16894cf18..78b122a6d 100644 --- a/src/QtAV/VideoThread.h +++ b/src/QtAV/VideoThread.h @@ -29,6 +29,7 @@ namespace QtAV { class ImageConverter; +class OSDFilter; class VideoCapture; class VideoThreadPrivate; class VideoThread : public AVThread @@ -42,6 +43,7 @@ class VideoThread : public AVThread ImageConverter* imageConverter() const; double currentPts() const; VideoCapture *setVideoCapture(VideoCapture* cap); //ensure thread safe + OSDFilter *setOSDFilter(OSDFilter* osd); protected: virtual void run(); }; diff --git a/src/QtAV/private/Filter_p.h b/src/QtAV/private/Filter_p.h new file mode 100644 index 000000000..8ceb40dac --- /dev/null +++ b/src/QtAV/private/Filter_p.h @@ -0,0 +1,38 @@ +/****************************************************************************** + QtAV: Media play library based on Qt and FFmpeg + Copyright (C) 2013 Wang Bin + +* This file is part of QtAV + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +******************************************************************************/ + +#ifndef QTAV_FILTER_P_H +#define QTAV_FILTER_P_H + +#include + +namespace QtAV { + +class Filter; +class FilterPrivate : public DPtrPrivate +{ +public: + virtual ~FilterPrivate() {} +}; + +} //namespace QtAV + +#endif // QTAV_FILTER_P_H diff --git a/src/QtAV/private/OSDFilter_p.h b/src/QtAV/private/OSDFilter_p.h new file mode 100644 index 000000000..4692a5590 --- /dev/null +++ b/src/QtAV/private/OSDFilter_p.h @@ -0,0 +1,48 @@ +/****************************************************************************** + QtAV: Media play library based on Qt and FFmpeg + Copyright (C) 2013 Wang Bin + +* This file is part of QtAV + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +******************************************************************************/ + +#ifndef QTAV_OSDFILTER_P_H +#define QTAV_OSDFILTER_P_H + +#include "Filter_p.h" +#include "QtAV/OSDFilter.h" + +namespace QtAV { + +class OSDFilterPrivate : public FilterPrivate +{ +public: + OSDFilterPrivate(): + show_type(OSDFilter::ShowCurrentAndTotalTime) + , width(0) + , height(0) + , sec_current(0) + , sec_total(0) + { + } + virtual ~OSDFilterPrivate() {} + OSDFilter::ShowType show_type; + int width, height; + int sec_current, sec_total; +}; + +} //namespace QtAV +#endif // QTAV_OSDFILTER_P_H diff --git a/src/VideoThread.cpp b/src/VideoThread.cpp index 5d00f8534..5777976fe 100644 --- a/src/VideoThread.cpp +++ b/src/VideoThread.cpp @@ -28,17 +28,23 @@ #include #include #include +#include namespace QtAV { class VideoThreadPrivate : public AVThreadPrivate { public: - VideoThreadPrivate():conv(0),capture(0){} + VideoThreadPrivate(): + conv(0) + , capture(0) + , osd(0) + {} ImageConverter *conv; double pts; //current decoded pts. for capture //QImage image; //use QByteArray? Then must allocate a picture in ImageConverter, see VideoDecoder VideoCapture *capture; + OSDFilter *osd; }; VideoThread::VideoThread(QObject *parent) : @@ -73,7 +79,16 @@ VideoCapture* VideoThread::setVideoCapture(VideoCapture *cap) d.capture = cap; return old; } - +//it may be called in main thread usually, but is being used in video thread, +OSDFilter* VideoThread::setOSDFilter(OSDFilter *osd) +{ + qDebug("setOSDFilter %p", osd); + DPTR_D(VideoThread); + QMutexLocker locker(&d.mutex); + OSDFilter *old = d.osd; + d.osd = osd; + return old; +} //TODO: if output is null or dummy, the use duration to wait void VideoThread::run() { @@ -153,8 +168,14 @@ void VideoThread::run() d.conv->setInSize(d.renderer_width, d.renderer_height); if (!d.conv->convert(d.decoded_data.constData(), d.image.bits())) { }*/ + QByteArray data = dec->data(); + if (d.osd) { + d.osd->setImageSize(dec->width(), dec->height()); + d.osd->setCurrentTime(pkt.pts); + d.osd->process(data); + } if (vo_ok) { - vo->writeData(dec->data()); + vo->writeData(data); } } //use the last size first then update the last size so that decoder(converter) can update output size diff --git a/src/libQtAV.pro b/src/libQtAV.pro index ac9c05e36..dc73d03a1 100644 --- a/src/libQtAV.pro +++ b/src/libQtAV.pro @@ -14,7 +14,7 @@ preparePaths($$OUT_PWD/../out) win32 { RC_FILE = $${PROJECTROOT}/res/QtAV.rc -#no depends for rc file by default, even if rc includes a header +#no depends for rc file by default, even if rc includes a header. Makefile target use '/' as default, so not works iwth win cmd rc.target = $$clean_path($$RC_FILE) #rc obj depends on clean path target rc.depends = $$PWD/QtAV/version.h #why use multiple rule failed? i.e. add a rule without command @@ -91,12 +91,15 @@ SOURCES += \ AVDemuxer.cpp \ AVDemuxThread.cpp \ EventFilter.cpp \ + Filter.cpp \ GLWidgetRenderer.cpp \ GraphicsItemRenderer.cpp \ ImageConverter.cpp \ ImageConverterFF.cpp \ ImageConverterIPP.cpp \ QPainterRenderer.cpp \ + OSDFilter.cpp \ + OSDFilterQPainter.cpp \ Packet.cpp \ AVPlayer.cpp \ VideoCapture.cpp \ @@ -120,8 +123,10 @@ HEADERS += \ QtAV/private/AVThread_p.h \ QtAV/private/AVDecoder_p.h \ QtAV/private/AVOutput_p.h \ + QtAV/private/Filter_p.h \ QtAV/private/GraphicsItemRenderer_p.h \ QtAV/private/ImageConverter_p.h \ + QtAV/private/OSDFilter_p.h \ QtAV/private/VideoRenderer_p.h \ QtAV/private/QPainterRenderer_p.h \ QtAV/private/WidgetRenderer_p.h \ @@ -131,10 +136,13 @@ HEADERS += \ QtAV/AVDemuxer.h \ QtAV/AVDemuxThread.h \ QtAV/BlockingQueue.h \ + QtAV/Filter.h \ QtAV/GLWidgetRenderer.h \ QtAV/GraphicsItemRenderer.h \ QtAV/ImageConverter.h \ QtAV/QPainterRenderer.h \ + QtAV/OSDFilter.h \ + QtAV/OSDFilterQPainter.h \ QtAV/Packet.h \ QtAV/AVPlayer.h \ QtAV/VideoCapture.h \ @@ -150,4 +158,3 @@ HEADERS += \ QtAV/FactoryDefine.h \ QtAV/ImageConverterTypes.h \ QtAV/version.h - From 3378c3195f22303641d590fe6bae89811a7429c7 Mon Sep 17 00:00:00 2001 From: wang-bin Date: Thu, 14 Mar 2013 22:12:38 +0800 Subject: [PATCH 2/7] return if no osd etc. --- TODO.txt | 2 ++ src/OSDFilterQPainter.cpp | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/TODO.txt b/TODO.txt index 19f40b5eb..ce3742429 100644 --- a/TODO.txt +++ b/TODO.txt @@ -11,6 +11,8 @@ network stream avio pause network TODO: +Filter framework: use FrameContext instead of QByteArray. + type.h QtAV_Compat.h=>pch external clock diff --git a/src/OSDFilterQPainter.cpp b/src/OSDFilterQPainter.cpp index ffd136fcf..1d0855bb6 100644 --- a/src/OSDFilterQPainter.cpp +++ b/src/OSDFilterQPainter.cpp @@ -39,9 +39,10 @@ OSDFilterQPainter::OSDFilterQPainter(): void OSDFilterQPainter::process(QByteArray &data) { DPTR_D(OSDFilterQPainter); - if (d.sec_current < 0 || d.sec_total < 0) + if (d.show_type == ShowNone || d.sec_current < 0 || d.sec_total < 0) return; QString text; + //TODO: calculation move to a function if (hasShowType(ShowCurrentTime) || hasShowType(ShowCurrentAndTotalTime)) { int h = d.sec_current/3600; int m = (d.sec_current%3600)/60; @@ -63,7 +64,7 @@ void OSDFilterQPainter::process(QByteArray &data) text += QString(" -%1:%2:%3").arg(h, 2, 10, QChar('0')).arg(m, 2, 10, QChar('0')).arg(s, 2, 10, QChar('0')); } if (hasShowType(ShowPercent) && d.sec_total > 0) - text += QString::number(qreal(d.sec_current)/qreal(d.sec_total)*100.0) + "%"; + text += QString::number(qreal(d.sec_current)/qreal(d.sec_total)*100, 'f', 1) + "%"; QImage image((uchar*)data.data(), d.width, d.height, QImage::Format_RGB32); QPainter painter(&image); From 0cbae901b231547288f3927750e251cb897c326d Mon Sep 17 00:00:00 2001 From: wang-bin Date: Thu, 14 Mar 2013 22:17:50 +0800 Subject: [PATCH 3/7] shortcut change: O is OSD, Ctrl+O is open a file --- README.md | 4 +++- src/EventFilter.cpp | 19 ++++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 3297b4643..6d4aab6f1 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ QtAV can meet your most demands - Seek, pause/resume - Video capture +- OSD - Aspect ratio - Transform video using GraphicsItemRenderer. (rotate, shear, etc) - Playing frame by frame (currently support forward playing) @@ -98,11 +99,12 @@ For more detail to using QtAV, see the wiki [Use QtAV In Your Project](https://g Default Shortcuts ----------------- +- Ctrl+O: open a file - Space: pause/continue - F: fullscreen on/off - T: stays on top on/off - N: show next frame. Continue the playing by pressing "Space" -- O: open a file +- O: OSD - P: replay - S: stop - R: switch aspect ratio diff --git a/src/EventFilter.cpp b/src/EventFilter.cpp index 727ecfad8..f2e2dd621 100644 --- a/src/EventFilter.cpp +++ b/src/EventFilter.cpp @@ -34,6 +34,7 @@ #include #include #include +#include namespace QtAV { @@ -81,7 +82,8 @@ void EventFilter::help() "

" + tr("F: fullscreen on/off\n") + "

" "

" + tr("T: stays on top on/off\n") + "

" "

" + tr("N: show next frame. Continue the playing by pressing 'Space'\n") + "

" - "

" + tr("O: open a file\n") + "

" + "

" + tr("Ctrl+O: open a file\n") + "

" + "

" + tr("O: OSD\n") + "

" "

" + tr("P: replay\n") + "

" "

" + tr("S: stop\n") + "

" "

" + tr("R: switch aspect ratio") + "

" @@ -112,7 +114,8 @@ bool EventFilter::eventFilter(QObject *watched, QEvent *event) return false; break; case QEvent::KeyPress: { - int key = static_cast(event)->key(); + QKeyEvent *key_event = static_cast(event); + int key = key_event->key(); switch (key) { case Qt::Key_C: //capture player->captureVideo(); @@ -166,9 +169,15 @@ bool EventFilter::eventFilter(QObject *watched, QEvent *event) qDebug("vol = %.3f", player->audio()->volume()); } break; - case Qt::Key_O: - //TODO: emit a signal so we can use custome dialogs? - openLocalFile(); + case Qt::Key_O: { + Qt::KeyboardModifiers m = key_event->modifiers(); + if (m == Qt::ControlModifier) { + //TODO: emit a signal so we can use custome dialogs? + openLocalFile(); + } else/* if (m == Qt::NoModifier) */{ + player->osdFilter()->useNextShowType(); + } + } break; case Qt::Key_Left: qDebug("<-"); From d80216506deb30c13849fc0881f26bd737af28b9 Mon Sep 17 00:00:00 2001 From: wang-bin Date: Thu, 14 Mar 2013 22:23:28 +0800 Subject: [PATCH 4/7] translations --- i18n/QtAV_zh_CN.qm | Bin 2076 -> 2154 bytes i18n/QtAV_zh_CN.ts | 67 ++++++++++++++++++++++++++------------------- 2 files changed, 39 insertions(+), 28 deletions(-) diff --git a/i18n/QtAV_zh_CN.qm b/i18n/QtAV_zh_CN.qm index d2a32bbdf185c70aa289ac244f83eb948606e913..297f68fcdad91fd74fb50fa7f3b8ab2933fea641 100644 GIT binary patch delta 324 zcmbOu@Je8UNc{~4hL|1(26lf2mNy0r49pP>tZDlg7+5M9+@~F3U|_6dShMyO0|VPS zhK(0NbR6TCV_Xaj4Ao3W-KBu)9GIh4-va7uV_kgZ6i}RjP0H#%Q2ZgAnE=pSR%x~a zk#B(fJkN1pThTF zD;`M8WdeOwvGG*~lZFI?GeZeO5kn4xHiJKd6@x-ja6Ch5yWcksu!Dhwh;vC%j`rm5 oELxj`n7bI|cp&P4WH5sZTot>&m4bh;3)ke2OwyYbS${JD0FG);qW}N^ delta 268 zcmaDQFh^j5Nc{x{hL|1(26j#cmNy0r49si{tZDlg7+8!M+@~F3U|_6dShMyO0|Q$I z!^VpsT7vP*F)juMhHB=h)wh7^O<1@DegWxstc$Ol0*W)RNm<YvSKCIB>-iL6P(P~>r_t#upt6&kIf-8w7{VD>aITL4YGl2~B`(qrq=UGU+q4)Mn09mB z<=X|MQ+TXauL2solPB>b8_+=yc&avM0o5(w`JZD2w78Pj*Z?TcD986-D;}s`E)(b* wqm7?3m^QCr?qZY{VDM+KVo*p5j%P@1_xr}c#Q}CDkl>%(#H_VBpY=Br0D|L05dZ)H diff --git a/i18n/QtAV_zh_CN.ts b/i18n/QtAV_zh_CN.ts index b0ade2a8f..c88d8b382 100644 --- a/i18n/QtAV_zh_CN.ts +++ b/i18n/QtAV_zh_CN.ts @@ -4,20 +4,20 @@ QObject - + A media playing library base on Qt and FFmpeg. 基于 Qt 和 FFmpeg 的音视频播放库. - + Distributed under the terms of LGPLv2.1 or later. - + Shanghai University, Shanghai, China 上海大学,中国上海 @@ -27,143 +27,154 @@ QtAV::EventFilter - + Open a video 打开视频 - + Open an url 打开 url - + Url - + About QtAV 关于 QtAV - - + + Ctrl+O: open a file + + Ctrl+O: 打开文件 + + + + O: OSD + + O: OSD + + + + Help 帮助 - + Drag and drop a file to player 拖放文件到播放器 - + Shortcut: 快捷键: - + Space: pause/continue 空格: 暂停/继续 - + F: fullscreen on/off F: 全屏开关 - + T: stays on top on/off T: 窗口置顶开关 - + N: show next frame. Continue the playing by pressing 'Space' N: 播放下一帧 - O: open a file - O: 打开文件 + O: 打开文件 - + P: replay P: 重新播放 - + S: stop S: 停止播放 - + R: switch aspect ratio R: 切换显示比例 - + M: mute on/off M: 静音开关 - + C: capture video C: 视频截图 - + Up/Down: volume +/- 光标上下: 音量增减 - + ->/<-: seek forward/backward 光标左右: 快退 快进 - + Open 打开 - + Open Url 打开 Url - + About 关于 - + About Qt 关于 Qt From 5e6841a7988f9dbf0e18b831ade43a5e61c5761a Mon Sep 17 00:00:00 2001 From: wang-bin Date: Thu, 14 Mar 2013 22:31:39 +0800 Subject: [PATCH 5/7] TODO: renderer on vo to fix osd position. other filters as well --- TODO.txt | 2 +- src/OSDFilterQPainter.cpp | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/TODO.txt b/TODO.txt index ce3742429..a6cc6a8f8 100644 --- a/TODO.txt +++ b/TODO.txt @@ -11,7 +11,7 @@ network stream avio pause network TODO: -Filter framework: use FrameContext instead of QByteArray. +Filter framework: use FrameContext instead of QByteArray. Render on vo or image type.h QtAV_Compat.h=>pch diff --git a/src/OSDFilterQPainter.cpp b/src/OSDFilterQPainter.cpp index 1d0855bb6..4074c83d4 100644 --- a/src/OSDFilterQPainter.cpp +++ b/src/OSDFilterQPainter.cpp @@ -24,6 +24,10 @@ #include #include +/* TODO: + * Render on VideoRenderer directly to fix the position + */ + namespace QtAV { class OSDFilterQPainterPrivate : public OSDFilterPrivate @@ -73,7 +77,7 @@ void OSDFilterQPainter::process(QByteArray &data) f.setPixelSize(26); painter.setFont(f); painter.setPen(Qt::white); - painter.drawText(60, 60, text); + painter.drawText(32, 32, text); } } //namespace QtAV From ec0121d5937eb81140a3476b88f2f2a318d74710 Mon Sep 17 00:00:00 2001 From: wang-bin Date: Fri, 15 Mar 2013 01:28:59 +0800 Subject: [PATCH 6/7] always lock in convertData() to make sure image data is safe TODO: for QPainterRenderer without lock like before, crashes if an image is in OSDFilter::process(), why? why crashes when resizing without lock? In QPainterRenderer::convertData(), why image can be constructed from data but not d.data? why d.data = data is required? --- src/GraphicsItemRenderer.cpp | 8 ++------ src/QPainterRenderer.cpp | 18 +++++++++--------- src/WidgetRenderer.cpp | 9 +++------ 3 files changed, 14 insertions(+), 21 deletions(-) diff --git a/src/GraphicsItemRenderer.cpp b/src/GraphicsItemRenderer.cpp index 312b067af..41b68ff62 100644 --- a/src/GraphicsItemRenderer.cpp +++ b/src/GraphicsItemRenderer.cpp @@ -70,9 +70,8 @@ void GraphicsItemRenderer::paint(QPainter *painter, const QStyleOptionGraphicsIt Q_UNUSED(option); Q_UNUSED(widget); DPTR_D(GraphicsItemRenderer); - if (!d.scale_in_renderer) { - d.img_mutex.lock(); - } + QMutexLocker locker(&d.img_mutex); + Q_UNUSED(locker); //fill background color only when the displayed frame rect not equas to renderer's if (d.out_rect != boundingRect()) { painter->fillRect(boundingRect(), QColor(0, 0, 0)); @@ -88,9 +87,6 @@ void GraphicsItemRenderer::paint(QPainter *painter, const QStyleOptionGraphicsIt } else { painter->drawImage(d.out_rect, d.image); } - if (!d.scale_in_renderer) { - d.img_mutex.unlock(); - } } //GraphicsWidget will lose focus forever if focus out. Why? diff --git a/src/QPainterRenderer.cpp b/src/QPainterRenderer.cpp index b38febfa6..41695bb59 100644 --- a/src/QPainterRenderer.cpp +++ b/src/QPainterRenderer.cpp @@ -62,26 +62,26 @@ void QPainterRenderer::convertData(const QByteArray &data) * But if we use the fixed original frame size, the data address and size always the same, so we can * avoid the lock and use the ref data directly and safely */ - if (!d.scale_in_renderer) { + //if (!d.scale_in_renderer) { /*if lock is required, do not use locker in if() scope, it will unlock outside the scope*/ - d.img_mutex.lock(); - d.data = data; + QMutexLocker locker(&d.img_mutex); + Q_UNUSED(locker); + d.data = data; //TODO: why need this line? Then use data.data() is OK? If use d.data.data() it will eat more cpu, why? //qDebug("data address = %p, %p", data.data(), d.data.data()); #if QT_VERSION >= QT_VERSION_CHECK(4, 0, 0) - d.image = QImage((uchar*)d.data.data(), d.src_width, d.src_height, QImage::Format_RGB32); + d.image = QImage((uchar*)data.data(), d.src_width, d.src_height, QImage::Format_RGB32); #else - d.image = QImage((uchar*)d.data.data(), d.src_width, d.src_height, 16, NULL, 0, QImage::IgnoreEndian); + d.image = QImage((uchar*)data.data(), d.src_width, d.src_height, 16, NULL, 0, QImage::IgnoreEndian); #endif - d.img_mutex.unlock(); - } else { + //} else { //qDebug("data address = %p", data.data()); //Format_RGB32 is fast. see document #if QT_VERSION >= QT_VERSION_CHECK(4, 0, 0) - d.image = QImage((uchar*)data.data(), d.src_width, d.src_height, QImage::Format_RGB32); + //d.image = QImage((uchar*)data.data(), d.src_width, d.src_height, QImage::Format_RGB32); #else d.image = QImage((uchar*)data.data(), d.src_width, d.src_height, 16, NULL, 0, QImage::IgnoreEndian); #endif - } + //} } } //namespace QtAV diff --git a/src/WidgetRenderer.cpp b/src/WidgetRenderer.cpp index 4fbb67574..690763530 100644 --- a/src/WidgetRenderer.cpp +++ b/src/WidgetRenderer.cpp @@ -118,9 +118,8 @@ void WidgetRenderer::mouseDoubleClickEvent(QMouseEvent *) void WidgetRenderer::paintEvent(QPaintEvent *) { DPTR_D(WidgetRenderer); - if (!d.scale_in_renderer) { - d.img_mutex.lock(); - } + QMutexLocker locker(&d.img_mutex); + Q_UNUSED(locker); QPainter p(this); //fill background color only when the displayed frame rect not equas to renderer's if (d.out_rect != rect()) { @@ -142,9 +141,7 @@ void WidgetRenderer::paintEvent(QPaintEvent *) //what's the difference? //p.drawImage(QPoint(), image.scaled(d.renderer_width, d.renderer_height)); } - if (!d.scale_in_renderer) { - d.img_mutex.unlock(); - } + } } //namespace QtAV From b02267475a361f0140c93e69cc023f436f015c6f Mon Sep 17 00:00:00 2001 From: wang-bin Date: Fri, 15 Mar 2013 10:59:52 +0800 Subject: [PATCH 7/7] Optimize time calculation --- src/OSDFilter.cpp | 1 + src/OSDFilterQPainter.cpp | 29 ++++++++++++++--------------- src/QtAV/private/OSDFilter_p.h | 10 ++++++++++ 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/OSDFilter.cpp b/src/OSDFilter.cpp index 296a75db8..40e0ddd82 100644 --- a/src/OSDFilter.cpp +++ b/src/OSDFilter.cpp @@ -53,6 +53,7 @@ void OSDFilter::setTotalTime(int totalSeconds) { DPTR_D(OSDFilter); d.sec_total = totalSeconds; + d.computeTime(totalSeconds, &d.total_hour, &d.total_min, &d.total_sec); } void OSDFilter::setImageSize(int width, int height) diff --git a/src/OSDFilterQPainter.cpp b/src/OSDFilterQPainter.cpp index 4074c83d4..b476e9272 100644 --- a/src/OSDFilterQPainter.cpp +++ b/src/OSDFilterQPainter.cpp @@ -32,7 +32,14 @@ namespace QtAV { class OSDFilterQPainterPrivate : public OSDFilterPrivate { +public: + OSDFilterQPainterPrivate() + { + font.setBold(true); + font.setPixelSize(26); + } + QFont font; }; OSDFilterQPainter::OSDFilterQPainter(): @@ -48,34 +55,26 @@ void OSDFilterQPainter::process(QByteArray &data) QString text; //TODO: calculation move to a function if (hasShowType(ShowCurrentTime) || hasShowType(ShowCurrentAndTotalTime)) { - int h = d.sec_current/3600; - int m = (d.sec_current%3600)/60; - int s = d.sec_current%60; + int h, m, s; + d.computeTime(d.sec_current, &h, &m, &s); text += QString("%1:%2:%3").arg(h, 2, 10, QChar('0')).arg(m, 2, 10, QChar('0')).arg(s, 2, 10, QChar('0')); if (hasShowType(ShowCurrentAndTotalTime)) text += " / "; } if (hasShowType(ShowCurrentAndTotalTime)) { - int h = d.sec_total/3600; - int m = (d.sec_total%3600)/60; - int s = d.sec_total%60; - text += QString("%1:%2:%3").arg(h, 2, 10, QChar('0')).arg(m, 2, 10, QChar('0')).arg(s, 2, 10, QChar('0')); + text += QString("%1:%2:%3").arg(d.total_hour, 2, 10, QChar('0')).arg(d.total_min, 2, 10, QChar('0')).arg(d.total_sec, 2, 10, QChar('0')); } if (hasShowType(ShowRemainTime)) { - int h = (d.sec_total-d.sec_current)/3600; - int m = ((d.sec_total-d.sec_current)%3600)/60; - int s = (d.sec_total-d.sec_current)%60; + int h, m, s; + d.computeTime(d.sec_total-d.sec_current, &h, &m, &s); text += QString(" -%1:%2:%3").arg(h, 2, 10, QChar('0')).arg(m, 2, 10, QChar('0')).arg(s, 2, 10, QChar('0')); } if (hasShowType(ShowPercent) && d.sec_total > 0) text += QString::number(qreal(d.sec_current)/qreal(d.sec_total)*100, 'f', 1) + "%"; - QImage image((uchar*)data.data(), d.width, d.height, QImage::Format_RGB32); QPainter painter(&image); - QFont f; - f.setBold(true); - f.setPixelSize(26); - painter.setFont(f); + //painter.setRenderHint(QPainter::TextAntialiasing); + painter.setFont(d.font); painter.setPen(Qt::white); painter.drawText(32, 32, text); } diff --git a/src/QtAV/private/OSDFilter_p.h b/src/QtAV/private/OSDFilter_p.h index 4692a5590..88846773c 100644 --- a/src/QtAV/private/OSDFilter_p.h +++ b/src/QtAV/private/OSDFilter_p.h @@ -36,12 +36,22 @@ class OSDFilterPrivate : public FilterPrivate , height(0) , sec_current(0) , sec_total(0) + , total_hour(0) + , total_min(0) + , total_sec(0) { } virtual ~OSDFilterPrivate() {} + void computeTime(int seconds, int *hour, int *min, int *sec) { + *hour = seconds/3600; + *min = (seconds%3600)/60; + *sec = seconds%60; + } + OSDFilter::ShowType show_type; int width, height; int sec_current, sec_total; + int total_hour, total_min, total_sec; }; } //namespace QtAV