Ticket #6824: 6824-v2.patch

File 6824-v2.patch, 17.3 KB (added by beirdo, 14 years ago)
  • mythtv/libs/libmythtv/NuppelVideoPlayer.cpp

    From 728d6d42596d83f3fc8236f710ec1db7a2154d9f Mon Sep 17 00:00:00 2001
    From: Gavin Hurlbut <gjhurlbu@gmail.com>
    Date: Wed, 28 Jul 2010 18:08:07 -0700
    Subject: [PATCH] Modified version of 6824-v1.patch from #6824
    
    ---
     mythtv/libs/libmythtv/NuppelVideoPlayer.cpp |    3 +-
     mythtv/libs/libmythtv/avformatdecoder.cpp   |  146 +++++++++++++++++----------
     mythtv/libs/libmythtv/avformatdecoder.h     |    5 +-
     mythtv/libs/libmythtv/playercontext.cpp     |    3 +-
     mythtv/libs/libmythtv/playercontext.h       |    3 +
     mythtv/libs/libmythtv/videoouttypes.h       |   10 ++
     mythtv/programs/mythcommflag/main.cpp       |   17 +++
     7 files changed, 131 insertions(+), 56 deletions(-)
    
    diff --git a/mythtv/libs/libmythtv/NuppelVideoPlayer.cpp b/mythtv/libs/libmythtv/NuppelVideoPlayer.cpp
    index cfcda58..dd500ca 100644
    a b int NuppelVideoPlayer::OpenFile(uint retries, bool allow_libmpeg2) 
    942942                          (player_ctx->IsPBP() && !player_ctx->IsPrimaryPBP());
    943943            SetDecoder(new AvFormatDecoder(this, *player_ctx->playingInfo,
    944944                                           using_null_videoout,
    945                                            allow_libmpeg2, noaccel));
     945                                           allow_libmpeg2, noaccel,
     946                                           player_ctx->GetSpecialDecode()));
    946947        }
    947948        player_ctx->UnlockPlayingInfo(__FILE__, __LINE__);
    948949        if (GetDecoder())
  • mythtv/libs/libmythtv/avformatdecoder.cpp

    diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp
    index b99aba6..92413ce 100644
    a b static int dts_decode_header(uint8_t *indata_ptr, int *rate, 
    8484                             int *nblks, int *sfreq);
    8585static int encode_frame(bool dts, unsigned char* data, int len,
    8686                        short *samples, int &samples_size);
     87static QSize get_video_dim(const AVCodecContext &ctx)
     88{
     89    return QSize(ctx.width >> ctx.lowres, ctx.height >> ctx.lowres);
     90}
     91static float get_aspect(const AVCodecContext &ctx)
     92{
     93    float aspect_ratio = 0.0f;
     94
     95    if (ctx.sample_aspect_ratio.num && ctx.height)
     96    {
     97        aspect_ratio = av_q2d(ctx.sample_aspect_ratio) * (float) ctx.width;
     98        aspect_ratio /= (float) ctx.height;
     99    }
     100
     101    if (aspect_ratio <= 0.0f || aspect_ratio > 6.0f)
     102    {
     103        if (ctx.height)
     104            aspect_ratio = (float)ctx.width / (float)ctx.height;
     105        else
     106            aspect_ratio = 4.0f / 3.0f;
     107    }
     108
     109    return aspect_ratio;
     110}
    87111
    88112int get_avf_buffer_xvmc(struct AVCodecContext *c, AVFrame *pic);
    89113int get_avf_buffer(struct AVCodecContext *c, AVFrame *pic);
    AvFormatDecoder::AvFormatDecoder(NuppelVideoPlayer *parent, 
    476500                                 const ProgramInfo &pginfo,
    477501                                 bool use_null_videoout,
    478502                                 bool allow_libmpeg2,
    479                                  bool no_hardware_decode)
     503                                 bool no_hardware_decode,
     504                                 AVSpecialDecode special_decoding)
    480505    : DecoderBase(parent, pginfo),
    481506      d(new AvFormatDecoderPrivate(allow_libmpeg2)),
    482507      is_db_ignored(gCoreContext->IsDatabaseIgnored()),
    AvFormatDecoder::AvFormatDecoder(NuppelVideoPlayer *parent, 
    495520      using_null_videoout(use_null_videoout),
    496521      video_codec_id(kCodec_NONE),
    497522      no_hardware_decoders(no_hardware_decode),
     523      special_decode(special_decoding),
    498524      maxkeyframedist(-1),
    499525      // Closed Caption & Teletext decoders
    500526      ccd608(new CC608Decoder(parent->GetCC608Reader())),
    AvFormatDecoder::AvFormatDecoder(NuppelVideoPlayer *parent, 
    536562        CC708Window::forceWhiteOnBlackText = true;
    537563
    538564    no_dts_hack = false;
     565
     566    int x = gContext->GetNumSetting("CommFlagFast", 0);
     567    if (x)
     568        special_decode = (AVSpecialDecode) x;
     569    VERBOSE(VB_IMPORTANT, "commflagging_speedups: " << special_decode);
    539570}
    540571
    541572AvFormatDecoder::~AvFormatDecoder()
    void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc, 
    13851416            <<") type ("<<codec_type_string(enc->codec_type)
    13861417            <<").");
    13871418
    1388     float aspect_ratio = 0.0;
    1389 
    13901419    if (ringBuffer && ringBuffer->isDVD())
    13911420        directrendering = false;
    13921421
    1393     if (selectedStream)
    1394     {
    1395         fps = normalized_fps(stream, enc);
    1396 
    1397         if (enc->sample_aspect_ratio.num)
    1398             aspect_ratio = av_q2d(enc->sample_aspect_ratio);
    1399         else if (stream->sample_aspect_ratio.num)
    1400             aspect_ratio = av_q2d(stream->sample_aspect_ratio);
    1401         else
    1402             aspect_ratio = 1.0f;
    1403 
    1404         if (aspect_ratio <= 0.0f || aspect_ratio > 6.0f)
    1405             aspect_ratio = 1.0f;
    1406 
    1407         aspect_ratio *= (float)enc->width / (float)enc->height;
    1408 
    1409         current_width  = enc->width;
    1410         current_height = enc->height;
    1411         current_aspect = aspect_ratio;
    1412     }
    1413 
    14141422    enc->opaque = (void *)this;
    14151423    enc->get_buffer = get_avf_buffer;
    14161424    enc->release_buffer = release_avf_buffer;
    void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc, 
    14821490                .arg(codec_id_string(enc->codec_id)));
    14831491    }
    14841492
     1493    if (special_decode)
     1494    {
     1495        if (special_decode & kAVSpecialDecode_SingleThreaded)
     1496            enc->thread_count = 1;
     1497
     1498        enc->flags |= CODEC_FLAG2_FAST;
     1499
     1500        if ((CODEC_ID_MPEG2VIDEO == codec->id) ||
     1501            (CODEC_ID_MPEG1VIDEO == codec->id))
     1502        {
     1503            if (special_decode & kAVSpecialDecode_FewBlocks)
     1504            {
     1505                uint total_blocks = (enc->height+15) / 16;
     1506                enc->skip_top     = (total_blocks+3) / 4;
     1507                enc->skip_bottom  = (total_blocks+3) / 4;
     1508            }
     1509
     1510            if (special_decode & kAVSpecialDecode_LowRes)
     1511                enc->lowres = 2; // 1 = 1/2 size, 2 = 1/4 size
     1512        }
     1513        else if (CODEC_ID_H264 == codec->id)
     1514        {
     1515            if (special_decode & kAVSpecialDecode_NoLoopFilter)
     1516            {
     1517                enc->flags &= ~CODEC_FLAG_LOOP_FILTER;
     1518                enc->skip_loop_filter = AVDISCARD_ALL;
     1519            }
     1520        }
     1521
     1522        if (special_decode & kAVSpecialDecode_NoDecode)
     1523        {
     1524            enc->skip_idct = AVDISCARD_ALL;
     1525        }
     1526    }
     1527
    14851528    if (selectedStream)
    14861529    {
    1487         uint width  = enc->width;
    1488         uint height = enc->height;
     1530        fps = normalized_fps(stream, enc);
     1531        QSize dim    = get_video_dim(*enc);
     1532        int   width  = current_width  = dim.width();
     1533        int   height = current_height = dim.height();
     1534        float aspect = current_aspect = get_aspect(*enc);
    14891535
    1490         if (width == 0 && height == 0)
     1536        if (!width || !height)
    14911537        {
    14921538            VERBOSE(VB_PLAYBACK, LOC + "InitVideoCodec "
    14931539                    "invalid dimensions, resetting decoder.");
    1494             width = 640;
     1540            width  = 640;
    14951541            height = 480;
    1496             fps = 29.97;
    1497             aspect_ratio = 4.0 / 3;
     1542            fps    = 29.97f;
     1543            aspect = 4.0f / 3.0f;
    14981544        }
    14991545
    15001546        GetNVP()->SetVideoParams(width, height, fps,
    1501                                  keyframedist, aspect_ratio, kScan_Detect,
     1547                                 keyframedist, aspect, kScan_Detect,
    15021548                                 dvd_video_codec_changed);
    15031549        if (LCD *lcd = LCD::Get())
    15041550        {
    int AvFormatDecoder::ScanStreams(bool novideo) 
    19111957                d->DestroyMPEG2();
    19121958                m_h264_parser->Reset();
    19131959
    1914                 uint width  = max(enc->width, 16);
    1915                 uint height = max(enc->height, 16);
     1960                QSize dim = get_video_dim(*enc);
     1961                uint width  = max(dim.width(),  16);
     1962                uint height = max(dim.height(), 16);
    19161963                QString dec = "ffmpeg";
    19171964                uint thread_count = 1;
    19181965
    void AvFormatDecoder::MpegPreProcessPkt(AVStream *stream, AVPacket *pkt) 
    29222969            SequenceHeader *seq = reinterpret_cast<SequenceHeader*>(
    29232970                const_cast<uint8_t*>(bufptr));
    29242971
    2925             uint  width  = seq->width();
    2926             uint  height = seq->height();
     2972            uint  width  = seq->width()  >> context->lowres;
     2973            uint  height = seq->height() >> context->lowres;
    29272974            float aspect = seq->aspect(context->sub_id == 1);
    29282975            float seqFPS = seq->fps();
    29292976
    2930             bool changed = (seqFPS > fps+0.01) || (seqFPS < fps-0.01);
     2977            bool changed = (seqFPS > fps+0.01f) || (seqFPS < fps-0.01f);
    29312978            changed |= (width  != (uint)current_width );
    29322979            changed |= (height != (uint)current_height);
    29332980            changed |= fabs(aspect - current_aspect) > eps;
    void AvFormatDecoder::MpegPreProcessPkt(AVStream *stream, AVPacket *pkt) 
    29512998
    29522999                // fps debugging info
    29533000                float avFPS = normalized_fps(stream, context);
    2954                 if ((seqFPS > avFPS+0.01) || (seqFPS < avFPS-0.01))
     3001                if ((seqFPS > avFPS+0.01f) || (seqFPS < avFPS-0.01f))
    29553002                {
    29563003                    VERBOSE(VB_PLAYBACK, LOC +
    29573004                            QString("avFPS(%1) != seqFPS(%2)")
    bool AvFormatDecoder::H264PreProcessPkt(AVStream *stream, AVPacket *pkt) 
    30253072            continue;
    30263073        }
    30273074
    3028         float aspect_ratio;
    3029         if (context->sample_aspect_ratio.num == 0)
    3030             aspect_ratio = 0.0f;
    3031         else
    3032             aspect_ratio = av_q2d(context->sample_aspect_ratio) *
    3033                 context->width / context->height;
    3034 
    3035         if (aspect_ratio <= 0.0f || aspect_ratio > 6.0f)
    3036             aspect_ratio = (float)context->width / context->height;
    3037 
    3038         uint  width  = context->width;
    3039         uint  height = context->height;
     3075        float aspect_ratio = get_aspect(*context);
     3076        QSize dim    = get_video_dim(*context);
     3077        uint  width  = dim.width();
     3078        uint  height = dim.height();
    30403079        float seqFPS = normalized_fps(stream, context);
    30413080
    3042         bool changed = (seqFPS > fps+0.01) || (seqFPS < fps-0.01);
     3081        bool changed = (seqFPS > fps+0.01f) || (seqFPS < fps-0.01f);
    30433082        changed |= (width  != (uint)current_width );
    30443083        changed |= (height != (uint)current_height);
    30453084        changed |= fabs(aspect_ratio - current_aspect) > eps;
    bool AvFormatDecoder::H264PreProcessPkt(AVStream *stream, AVPacket *pkt) 
    30613100
    30623101            // fps debugging info
    30633102            float avFPS = normalized_fps(stream, context);
    3064             if ((seqFPS > avFPS+0.01) || (seqFPS < avFPS-0.01))
     3103            if ((seqFPS > avFPS+0.01f) || (seqFPS < avFPS-0.01f))
    30653104            {
    30663105                VERBOSE(VB_PLAYBACK, LOC +
    30673106                        QString("avFPS(%1) != seqFPS(%2)")
    bool AvFormatDecoder::ProcessVideoPacket(AVStream *curstream, AVPacket *pkt) 
    32003239        tmppicture.linesize[1] = picframe->pitches[1];
    32013240        tmppicture.linesize[2] = picframe->pitches[2];
    32023241
     3242        QSize dim = get_video_dim(*context);
    32033243        sws_ctx = sws_getCachedContext(sws_ctx, context->width,
    32043244                                       context->height, context->pix_fmt,
    32053245                                       context->width, context->height,
    bool AvFormatDecoder::ProcessVideoPacket(AVStream *curstream, AVPacket *pkt) 
    32103250            VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to allocate sws context");
    32113251            return false;
    32123252        }
    3213         sws_scale(sws_ctx, mpa_pic.data, mpa_pic.linesize, 0, context->height,
     3253        sws_scale(sws_ctx, mpa_pic.data, mpa_pic.linesize, 0, dim.height(),
    32143254                  tmppicture.data, tmppicture.linesize);
    32153255
    32163256
    bool AvFormatDecoder::GetFrame(DecodeType decodetype) 
    43804420
    43814421            if (!d->HasMPEG2Dec())
    43824422            {
    4383                 int current_width = curstream->codec->width;
     4423                int current_width = curstream->codec->width; // TODO CHECKME
    43844424                int video_width = GetNVP()->GetVideoSize().width();
    43854425                if (dvd_xvmc_enabled && GetNVP() && GetNVP()->getVideoOutput())
    43864426                {
  • mythtv/libs/libmythtv/avformatdecoder.h

    diff --git a/mythtv/libs/libmythtv/avformatdecoder.h b/mythtv/libs/libmythtv/avformatdecoder.h
    index a7454d2..04774d5 100644
    a b  
    22#define AVFORMATDECODER_H_
    33
    44#include <QString>
     5#include <QMap>
    56#include <QList>
    67
    78#include "programinfo.h"
    class AvFormatDecoder : public DecoderBase 
    7980    static void GetDecoders(render_opts &opts);
    8081    AvFormatDecoder(NuppelVideoPlayer *parent, const ProgramInfo &pginfo,
    8182                    bool use_null_video_out, bool allow_libmpeg2 = true,
    82                     bool no_hardware_decode = false);
     83                    bool no_hardware_decode = false,
     84                    AVSpecialDecode av_special_decode = kAVSpecialDecode_None);
    8385   ~AvFormatDecoder();
    8486
    8587    void CloseCodecs();
    class AvFormatDecoder : public DecoderBase 
    264266    bool using_null_videoout;
    265267    MythCodecID video_codec_id;
    266268    bool no_hardware_decoders;
     269    AVSpecialDecode special_decode;
    267270
    268271    int maxkeyframedist;
    269272
  • mythtv/libs/libmythtv/playercontext.cpp

    diff --git a/mythtv/libs/libmythtv/playercontext.cpp b/mythtv/libs/libmythtv/playercontext.cpp
    index a102568..46d8ca8 100644
    a b void PlayerThread::run(void) 
    3737PlayerContext::PlayerContext(const QString &inUseID) :
    3838    recUsage(inUseID), nvp(NULL), nvpUnsafe(false), recorder(NULL),
    3939    tvchain(NULL), buffer(NULL), playingInfo(NULL),
    40     playingLen(0), nohardwaredecoders(false), last_cardid(-1), last_framerate(30.0f),
     40    playingLen(0), specialDecode(kAVSpecialDecode_None),
     41    nohardwaredecoders(false), last_cardid(-1), last_framerate(30.0f),
    4142    // Fast forward state
    4243    ff_rew_state(0), ff_rew_index(0), ff_rew_speed(0),
    4344    // Other state
  • mythtv/libs/libmythtv/playercontext.h

    diff --git a/mythtv/libs/libmythtv/playercontext.h b/mythtv/libs/libmythtv/playercontext.h
    index 2b0e518..756d4bd 100644
    a b class MPUBLIC PlayerContext 
    119119    void SetPIPState(PIPState change) { pipState = change; }
    120120    void SetNVPChangingBuffers(bool val) { nvpUnsafe = val; }
    121121    void SetNoHardwareDecoders(void) { nohardwaredecoders = true; }
     122    void SetSpecialDecode(AVSpecialDecode sp) { specialDecode = sp; }
    122123
    123124    // Gets
    124125    QRect    GetStandAlonePIPRect(void);
    class MPUBLIC PlayerContext 
    131132    QString  GetPlayMessage(void) const;
    132133    TVState  GetState(void) const;
    133134    bool     GetPlayingInfoMap(InfoMap &infoMap) const;
     135    AVSpecialDecode GetSpecialDecode(void) const { return specialDecode; }
    134136
    135137    // Boolean Gets
    136138    bool IsPIPSupported(void) const;
    class MPUBLIC PlayerContext 
    169171    RingBuffer         *buffer;
    170172    ProgramInfo        *playingInfo; ///< Currently playing info
    171173    long long           playingLen;  ///< Initial CalculateLength()
     174    AVSpecialDecode     specialDecode;
    172175    bool                nohardwaredecoders; // < Disable use of VDPAU decoding
    173176    int                 last_cardid; ///< CardID of current/last recorder
    174177    float               last_framerate; ///< Estimated framerate from recorder
  • mythtv/libs/libmythtv/videoouttypes.h

    diff --git a/mythtv/libs/libmythtv/videoouttypes.h b/mythtv/libs/libmythtv/videoouttypes.h
    index 37b9517..b3401a3 100644
    a b typedef enum VideoErrorState 
    109109    kError_Switch_Renderer = 0x04, // Current renderer is not preferred choice
    110110} VideoErrorState;
    111111
     112typedef enum AVSpecialDecode
     113{
     114    kAVSpecialDecode_None           = 0x00,
     115    kAVSpecialDecode_LowRes         = 0x01,
     116    kAVSpecialDecode_SingleThreaded = 0x02,
     117    kAVSpecialDecode_FewBlocks      = 0x04,
     118    kAVSpecialDecode_NoLoopFilter   = 0x08,
     119    kAVSpecialDecode_NoDecode       = 0x10,
     120} AVSpecialDecode;
     121
    112122inline bool is_interlaced(FrameScanType scan)
    113123{
    114124    return (kScan_Interlaced == scan) || (kScan_Intr2ndField == scan);
  • mythtv/programs/mythcommflag/main.cpp

    diff --git a/mythtv/programs/mythcommflag/main.cpp b/mythtv/programs/mythcommflag/main.cpp
    index 1d745cd..a24600a 100644
    a b int BuildVideoMarkup(ProgramInfo *program_info, bool useDB) 
    172172
    173173    MythCommFlagPlayer *cfp = new MythCommFlagPlayer();
    174174    PlayerContext *ctx = new PlayerContext("seektable rebuilder");
     175    ctx->SetSpecialDecode(kAVSpecialDecode_NoDecode);
    175176    ctx->SetPlayingInfo(program_info);
    176177    ctx->SetRingBuffer(tmprbuf);
    177178    ctx->SetNVP(cfp);
    int FlagCommercials( 
    756757    MythCommFlagPlayer *cfp = new MythCommFlagPlayer();
    757758
    758759    PlayerContext *ctx = new PlayerContext(kFlaggerInUseID);
     760
     761    AVSpecialDecode sp = (AVSpecialDecode)
     762        (kAVSpecialDecode_LowRes         |
     763         kAVSpecialDecode_SingleThreaded |
     764         kAVSpecialDecode_NoLoopFilter);
     765
     766#if 0 /* blank detector needs to be only sample center for this optimization. */
     767    if ((COMM_DETECT_BLANKS  == commDetectMethod) ||
     768        (COMM_DETECT_2_BLANK == commDetectMethod))
     769    {
     770        sp = (AVSpecialDecode) (sp | kAVSpecialDecode_FewBlocks);
     771    }
     772#endif
     773
     774    ctx->SetSpecialDecode(sp);
     775
    759776    ctx->SetPlayingInfo(program_info);
    760777    ctx->SetRingBuffer(tmprbuf);
    761778    ctx->SetNVP(cfp);