Ticket #1079: get-frame-timing.patch

File get-frame-timing.patch, 12.3 KB (added by danielk, 20 years ago)

Shows timing differences between scaling image as YUV vs. RGB

  • libs/libmythtv/NuppelVideoPlayer.h

     
    1414#include "recordingprofile.h"
    1515#include "videooutbase.h"
    1616#include "tv_play.h"
     17#include "yuv2rgb.h"
    1718
    1819extern "C" {
    1920#include "filter.h"
     
    213214    void DiscardVideoFrames(bool next_frame_keyframe);
    214215    void DrawSlice(VideoFrame *frame, int x, int y, int w, int h);
    215216
     217    // Preview Image stuff
     218    const QImage &GetARGBFrame(const QSize &size);
     219    const unsigned char *GetScaledFrame(QSize &size);
     220    void ShutdownYUVResize(void);
     221
    216222    // Reinit
    217223    void    ReinitOSD(void);
    218224    void    ReinitVideo(void);
     
    493499    NuppelVideoPlayer *setpipplayer;
    494500    bool needsetpipplayer;
    495501
     502    // Preview window support
     503    bool                argb_need_copy;
     504    unsigned char      *argb_buf;
     505    QSize               argb_size;
     506    QImage              argb_scaled_img;
     507
     508    yuv2rgb_fun         conv_yuv2rgba;
     509
     510    bool                yuv_need_copy;
     511    unsigned char      *yuv_frame_scaled;
     512    QSize               yuv_size_scaled;
     513    QSize               yuv_size_unscaled;
     514    ImgReSampleContext *yuv_scaler;
     515
     516    QMutex              argb_lock;
     517
    496518    // Filters
    497519    QMutex   videofiltersLock;
    498520    QString  videoFilterList;
  • libs/libmythtv/NuppelVideoPlayer.cpp

     
    126126      audio_samplerate(44100),      audio_stretchfactor(1.0f),
    127127      // Picture-in-Picture
    128128      pipplayer(NULL), setpipplayer(NULL), needsetpipplayer(false),
     129      // Preview window support
     130      argb_need_copy(false), argb_buf(NULL), argb_size(0,0),
    129131      // Filters
    130       videoFilterList(""),
     132    videoFilterList(""),
    131133      postfilt_width(0),            postfilt_height(0),
    132134      videoFilters(NULL),           FiltMan(new FilterManager()),
    133135      // Commercial filtering
     
    185187    bool valid = false;
    186188    uint tmp = mypage.toInt(&valid, 16);
    187189    ttPageNum = (valid) ? tmp : ttPageNum;
     190
     191    conv_yuv2rgba     = yuv2rgb_init_mmx(32, MODE_RGB);
     192    yuv_need_copy     = false;
     193    yuv_frame_scaled  = NULL;
     194    yuv_size_scaled   = QSize(0,0);
     195    yuv_size_unscaled = QSize(0,0);
     196    yuv_scaler        = NULL;
    188197}
    189198
    190199NuppelVideoPlayer::~NuppelVideoPlayer(void)
     
    10541063        vidExitLock.unlock();
    10551064}
    10561065
     1066void NuppelVideoPlayer::ShutdownYUVResize(void)
     1067{
     1068    if (yuv_frame_scaled)
     1069        delete [] yuv_frame_scaled;
     1070    if (yuv_scaler)
     1071        img_resample_close(yuv_scaler);
     1072
     1073    yuv_frame_scaled  = NULL;
     1074    yuv_scaler        = NULL;
     1075    yuv_size_unscaled = QSize(0,0);
     1076    yuv_size_scaled   = QSize(0,0);
     1077}
     1078
     1079const unsigned char *NuppelVideoPlayer::GetScaledFrame(QSize &size)
     1080{
     1081    size = QSize(size.width() & ~0x1, size.height() & ~0x1);
     1082
     1083    QSize vsize = QSize(video_width, video_height);
     1084    if ((vsize != yuv_size_unscaled) || (size != yuv_size_scaled))
     1085    {
     1086        ShutdownYUVResize();
     1087
     1088        uint sz = size.width() * size.height() * 3 / 2;
     1089        yuv_frame_scaled = new unsigned char[sz + 128];
     1090
     1091        yuv_size_unscaled = vsize;
     1092        yuv_size_scaled   = size;
     1093
     1094        yuv_scaler = img_resample_init(
     1095            size.width(), size.height(), vsize.width(), vsize.height());
     1096    }
     1097
     1098    argb_lock.lock();
     1099    yuv_need_copy = true;
     1100
     1101    while (yuv_need_copy)
     1102    {
     1103        argb_lock.unlock();
     1104        usleep(5000);
     1105        argb_lock.lock();
     1106    }
     1107    argb_lock.unlock();
     1108
     1109    return yuv_frame_scaled;
     1110}
     1111
     1112#if 0
     1113const QImage &NuppelVideoPlayer::GetARGBFrame(const QSize &size)
     1114{
     1115    argb_lock.lock();
     1116    argb_need_copy = true;
     1117
     1118    while (argb_need_copy)
     1119    {
     1120        argb_lock.unlock();
     1121        usleep(5000);
     1122        argb_lock.lock();
     1123    }
     1124    argb_lock.unlock();
     1125
     1126    MythTimer timer;
     1127    timer.start();
     1128    QImage img(argb_buf, argb_size.width(), argb_size.height(),
     1129               32, NULL, 65536 * 65536, QImage::LittleEndian);
     1130    argb_scaled_img = img.scale(size.width(), size.height());
     1131    cerr<<timer.elapsed()<<"s";
     1132
     1133    return argb_scaled_img;
     1134}
     1135#else
     1136const QImage &NuppelVideoPlayer::GetARGBFrame(const QSize &Xsize)
     1137{
     1138    QSize size = Xsize;
     1139
     1140    unsigned char *yuv_buf = (unsigned char*) GetScaledFrame(size);
     1141    if (argb_size != size)
     1142    {
     1143        if (argb_buf)
     1144            delete [] argb_buf;
     1145        argb_buf = new unsigned char[size.width() * size.height() * 4];
     1146        argb_size = QSize(size.width(), size.height());
     1147    }
     1148
     1149    MythTimer timer;
     1150    timer.start();
     1151    uint w = argb_size.width(), h = argb_size.height();
     1152    conv_yuv2rgba(argb_buf,
     1153                  yuv_buf, yuv_buf + (w * h), yuv_buf + (w * h * 5 / 4),
     1154                  w, h, w * 4, w, w / 2, 0);
     1155
     1156    argb_scaled_img = QImage(argb_buf, argb_size.width(), argb_size.height(),
     1157                             32, NULL, 65536 * 65536, QImage::LittleEndian);
     1158    cerr<<timer.elapsed()<<"c";
     1159
     1160    return argb_scaled_img;
     1161}
     1162#endif
     1163
    10571164void NuppelVideoPlayer::EmbedInWidget(WId wid, int x, int y, int w, int h)
    10581165{
    10591166    if (videoOutput)
     
    17751882
    17761883    VideoFrame *frame = videoOutput->GetLastShownFrame();
    17771884
     1885    if (argb_need_copy)
     1886    {
     1887        QMutexLocker locker(&argb_lock);
     1888        MythTimer timer;
     1889        timer.start();
     1890        if ((argb_size.width()  != video_width) ||
     1891            (argb_size.height() != video_height))
     1892        {
     1893            if (argb_buf)
     1894                delete [] argb_buf;
     1895            argb_buf = new unsigned char[video_width * video_height * 4];
     1896            argb_size = QSize(video_width, video_height);
     1897        }
     1898        unsigned char *yuv_buf = frame->buf;
     1899        uint w = video_width, h = video_height;
     1900        conv_yuv2rgba(argb_buf,
     1901                      yuv_buf, yuv_buf + (w * h), yuv_buf + (w * h * 5 / 4),
     1902                      w, h, w * 4, w, w / 2, 0);
     1903        argb_need_copy = false;
     1904        cerr<<timer.elapsed()<<"c";
     1905    }
     1906
     1907    if (yuv_need_copy)
     1908    {
     1909        QMutexLocker locker(&argb_lock);
     1910        MythTimer timer;
     1911        timer.start();
     1912        AVPicture img_out, img_in;
     1913        avpicture_fill(&img_out, yuv_frame_scaled, PIX_FMT_YUV420P,
     1914                       yuv_size_scaled.width(), yuv_size_scaled.height());
     1915        avpicture_fill(&img_in, frame->buf, PIX_FMT_YUV420P,
     1916                       yuv_size_unscaled.width(), yuv_size_unscaled.height());
     1917
     1918        img_resample(yuv_scaler, &img_out, &img_in);
     1919        yuv_need_copy = false;
     1920        cerr<<timer.elapsed()<<"s";
     1921    }
     1922
    17781923    if (subtitlesOn)
    17791924    {
    17801925        ShowText();
  • libs/libmythtv/videoout_null.cpp

     
    66#include "videoout_null.h"
    77
    88const int kNumBuffers = 31;
    9 const int kNeedFreeFrames = 1;
     9const int kNeedFreeFrames = 2;
    1010const int kPrebufferFramesNormal = 12;
    1111const int kPrebufferFramesSmall = 4;
    1212const int kKeepPrebuffer = 2;
  • libs/libmythtv/tv_rec.cpp

     
    12121212        if (curRecording)
    12131213            curRecording->UpdateInUseMark();
    12141214
     1215        // Check for the end of the current program..
    12151216        if (GetState() == kState_WatchingLiveTV)
    12161217        {
    1217             bool enable_livetv_ui = false;
    1218             if (pseudoLiveTVRecording &&
    1219                 (QDateTime::currentDateTime() > recordEndTime ||
    1220                  HasFlags(kFlagFinishRecording)))
    1221             {
     1218#define LIVETV_END (now >= curRecording->endts)
     1219// use the following instead to test ringbuffer switching
     1220//#define LIVETV_END (now >= curRecording->recstartts.addSecs(60))
     1221
     1222            QDateTime now   = QDateTime::currentDateTime();
     1223            bool has_finish = HasFlags(kFlagFinishRecording);
     1224            bool has_rec    = pseudoLiveTVRecording;
     1225            bool rec_soon   = pendingRecording;
     1226            bool enable_ui  = true;
     1227
     1228            if (has_rec && (has_finish || (now > recordEndTime)))
    12221229                SetPseudoLiveTVRecording(NULL);
    1223                 enable_livetv_ui = true;
    1224             }
    1225             else if (curRecording &&
    1226                      !pseudoLiveTVRecording && !pendingRecording)
     1230            else if (!has_rec && !rec_soon && curRecording && LIVETV_END)
     1231                SwitchLiveTVRingBuffer();
     1232            else
     1233                enable_ui = false;
     1234
     1235            if (enable_ui)
    12271236            {
    1228 //#define TESTING_RING_BUFFER_SWITCHING
    1229 #ifdef TESTING_RING_BUFFER_SWITCHING
    1230                 if ((QDateTime::currentDateTime() >=
    1231                      curRecording->recstartts.addSecs(60)))
    1232 #else
    1233                 if ((QDateTime::currentDateTime() >= curRecording->endts))
    1234 #endif
    1235                 {
    1236                     CheckForRecGroupChange();
    1237                     if (pseudoLiveTVRecording)
    1238                     {
    1239                         // If the last recording was flagged for keeping
    1240                         // in the frontend, then add the recording rule
    1241                         // so that transcode, commfrag, etc can be run.
    1242                         recordEndTime =
    1243                             GetRecordEndTime(pseudoLiveTVRecording);
    1244                         NotifySchedulerOfRecording(curRecording);
    1245                     }
    1246                     else
    1247                     {
    1248                         SwitchLiveTVRingBuffer();
    1249                         enable_livetv_ui = true;
    1250                     }
    1251                 }
    1252             }
    1253             if (enable_livetv_ui)
    1254             {
    12551237                VERBOSE(VB_IMPORTANT, LOC + "Enabling Full LiveTV UI.");
    12561238                QString message = QString("LIVETV_WATCH %1 0").arg(cardid);
    12571239                MythEvent me(message);
  • libs/libmythtv/videobuffers.cpp

     
    1010#include "videoout_xv.h" // for xvmc stuff
    1111#endif
    1212
    13 #define DEBUG_FRAME_LOCKS 0
     13#define DEBUG_FRAME_LOCKS 1
    1414
    1515#define TRY_LOCK_SPINS                 100
    1616#define TRY_LOCK_SPINS_BEFORE_WARNING   10
  • programs/mythfrontend/playbackbox.cpp

     
    867867            state = kStopped;
    868868    }
    869869
    870     /* if we are playing and nvp is running, then grab a new video frame */
    871870    if ((state == kPlaying) && nvp->IsPlaying() && !playingSomething)
    872871    {
    873         int w = 0, h = 0;
    874         VideoFrame *frame = nvp->GetCurrentFrame(w, h);
    875 
    876         if (w == 0 || h == 0 || !frame || !(frame->buf))
    877         {
    878             nvp->ReleaseCurrentFrame(frame);
    879             return;
    880         }
    881 
    882         unsigned char *yuv_buf = frame->buf;
    883         if (conv_rgba_size.width() != w || conv_rgba_size.height() != h)
    884         {
    885             if (conv_rgba_buf)
    886                 delete [] conv_rgba_buf;
    887             conv_rgba_buf = new unsigned char[w * h * 4];
    888             conv_rgba_size = QSize(w, h);
    889         }
    890 
    891         conv_yuv2rgba(conv_rgba_buf,
    892                       yuv_buf, yuv_buf + (w * h), yuv_buf + (w * h * 5 / 4),
    893                       w, h, w * 4, w, w / 2, 0);
    894 
    895         nvp->ReleaseCurrentFrame(frame);
    896 
    897         QImage img(conv_rgba_buf, w, h, 32, NULL, 65536 * 65536,
    898                    QImage::LittleEndian);
    899         img = img.scale(videoRect.width(), videoRect.height());
    900 
    901         p->drawImage(videoRect.x(), videoRect.y(), img);
     872        const QImage &frame = nvp->GetARGBFrame(videoRect.size());
     873        p->drawImage(videoRect.x(), videoRect.y(), frame);
    902874    }
    903875
    904876    /* have we timed out waiting for nvp to start? */
  • programs/mythfrontend/playbackbox.h

     
    349349
    350350    mutable QMutex previewGeneratorLock;
    351351    QMap<QString, PreviewGenerator*> previewGenerator;
     352
     353
     354    QMutex xxx;
    352355};
    353356
    354357#endif