Ticket #6824: 6824-v1.patch

File 6824-v1.patch, 15.0 KB (added by danielk, 15 years ago)

Proof of concept patch

  • libs/libmythtv/NuppelVideoPlayer.cpp

     
    12561256            SetDecoder(new AvFormatDecoder(this, *player_ctx->playingInfo,
    12571257                                           using_null_videoout,
    12581258                                           allow_libmpeg2,
    1259                                            no_hardware_decoders));
     1259                                           no_hardware_decoders,
     1260                                           player_ctx->GetSpecialDecode()));
    12601261        }
    12611262        player_ctx->UnlockPlayingInfo(__FILE__, __LINE__);
    12621263        if (GetDecoder())
  • libs/libmythtv/avformatdecoder.cpp

     
    7575                             int *nblks, int *sfreq);
    7676static int encode_frame(bool dts, unsigned char* data, int len,
    7777                        short *samples, int &samples_size);
     78static QSize get_video_dim(const AVCodecContext &ctx)
     79{
     80    return QSize(ctx.width >> ctx.lowres, ctx.height >> ctx.lowres);
     81}
     82static float get_aspect(const AVCodecContext &ctx)
     83{
     84    float aspect_ratio = 0.0f;
    7885
     86    if (ctx.sample_aspect_ratio.num && ctx.height)
     87    {
     88        aspect_ratio = av_q2d(ctx.sample_aspect_ratio) * (float) ctx.width;
     89        aspect_ratio /= (float) ctx.height;
     90    }
     91
     92    if (aspect_ratio <= 0.0f || aspect_ratio > 6.0f)
     93    {
     94        if (ctx.height)
     95            aspect_ratio = (float)ctx.width / (float)ctx.height;
     96        else
     97            aspect_ratio = 4.0f / 3.0f;
     98    }
     99
     100    return aspect_ratio;
     101}
     102
    79103int get_avf_buffer_xvmc(struct AVCodecContext *c, AVFrame *pic);
    80104int get_avf_buffer(struct AVCodecContext *c, AVFrame *pic);
    81105void release_avf_buffer(struct AVCodecContext *c, AVFrame *pic);
     
    432456                                 const ProgramInfo &pginfo,
    433457                                 bool use_null_videoout,
    434458                                 bool allow_libmpeg2,
    435                                  bool no_hardware_decode)
     459                                 bool no_hardware_decode,
     460                                 AVSpecialDecode special_decoding)
    436461    : DecoderBase(parent, pginfo),
    437462      d(new AvFormatDecoderPrivate(allow_libmpeg2)),
    438463      is_db_ignored(gContext->IsDatabaseIgnored()),
     
    450475      using_null_videoout(use_null_videoout),
    451476      video_codec_id(kCodec_NONE),
    452477      no_hardware_decoders(no_hardware_decode),
     478      special_decode(special_decoding),
    453479      maxkeyframedist(-1),
    454480      // Closed Caption & Teletext decoders
    455481      ccd608(new CC608Decoder(parent)),
     
    490516    cc608_build_parity_table(cc608_parity_table);
    491517
    492518    no_dts_hack = false;
     519
     520    int x = gContext->GetNumSetting("CommFlagFast", 0);
     521    if (x)
     522        special_decode = (AVSpecialDecode) x;
     523    VERBOSE(VB_IMPORTANT, "commflagging_speedups: " << special_decode);
    493524}
    494525
    495526AvFormatDecoder::~AvFormatDecoder()
     
    11731204            <<") type ("<<codec_type_string(enc->codec_type)
    11741205            <<").");
    11751206
    1176     float aspect_ratio = 0.0;
    1177 
    11781207    if (ringBuffer->isDVD())
    11791208        directrendering = false;
    11801209
    1181     if (selectedStream)
    1182     {
    1183         fps = normalized_fps(stream, enc);
    1184 
    1185         if (enc->sample_aspect_ratio.num == 0)
    1186             aspect_ratio = 0.0f;
    1187         else
    1188             aspect_ratio = av_q2d(enc->sample_aspect_ratio) *
    1189                 enc->width / enc->height;
    1190 
    1191         if (aspect_ratio <= 0.0f || aspect_ratio > 6.0f)
    1192             aspect_ratio = (float)enc->width / (float)enc->height;
    1193 
    1194         current_width = enc->width;
    1195         current_height = enc->height;
    1196         current_aspect = aspect_ratio;
    1197     }
    1198 
    11991210    enc->opaque = (void *)this;
    12001211    enc->get_buffer = avcodec_default_get_buffer;
    12011212    enc->release_buffer = avcodec_default_release_buffer;
     
    12641275            directrendering = true;
    12651276    }
    12661277
     1278    if (special_decode)
     1279    {
     1280        if (special_decode & kAVSpecialDecode_SingleThreaded)
     1281            enc->thread_count = 1;
     1282
     1283        enc->flags |= CODEC_FLAG2_FAST;
     1284
     1285        if ((CODEC_ID_MPEG2VIDEO == codec->id) ||
     1286            (CODEC_ID_MPEG1VIDEO == codec->id))
     1287        {
     1288            if (special_decode & kAVSpecialDecode_FewBlocks)
     1289            {
     1290                uint total_blocks = (enc->height+15) / 16;
     1291                enc->skip_top     = (total_blocks+3) / 4;
     1292                enc->skip_bottom  = (total_blocks+3) / 4;
     1293            }
     1294
     1295            if (special_decode & kAVSpecialDecode_LowRes)
     1296                enc->lowres = 2; // 1 = 1/2 size, 2 = 1/4 size
     1297        }
     1298        else if (CODEC_ID_H264 == codec->id)
     1299        {
     1300            if (special_decode & kAVSpecialDecode_NoLoopFilter)
     1301            {
     1302                enc->flags &= ~CODEC_FLAG_LOOP_FILTER;
     1303                enc->skip_loop_filter = AVDISCARD_ALL;
     1304            }
     1305        }
     1306
     1307        if (special_decode & kAVSpecialDecode_NoDecode)
     1308        {
     1309            enc->skip_idct = AVDISCARD_ALL;
     1310        }
     1311    }
     1312
    12671313    if (selectedStream)
    12681314    {
    1269         uint width  = enc->width;
    1270         uint height = enc->height;
     1315        fps = normalized_fps(stream, enc);
     1316        QSize dim    = get_video_dim(*enc);
     1317        int   width  = current_width  = dim.width();
     1318        int   height = current_height = dim.height();
     1319        float aspect = current_aspect = get_aspect(*enc);
    12711320
    1272         if (width == 0 && height == 0)
     1321        if (!width || !height)
    12731322        {
    12741323            VERBOSE(VB_PLAYBACK, LOC + "InitVideoCodec "
    12751324                    "invalid dimensions, resetting decoder.");
    1276             width = 640;
     1325            width  = 640;
    12771326            height = 480;
    1278             fps = 29.97;
    1279             aspect_ratio = 4.0 / 3;
     1327            fps    = 29.97f;
     1328            aspect = 4.0f / 3.0f;
    12801329        }
    12811330
    12821331        GetNVP()->SetVideoParams(width, height, fps,
    1283                                  keyframedist, aspect_ratio, kScan_Detect,
     1332                                 keyframedist, aspect, kScan_Detect,
    12841333                                 dvd_video_codec_changed);
    12851334    }
    12861335}
     
    16101659                d->DestroyMPEG2();
    16111660                m_h264_parser->Reset();
    16121661
    1613                 uint width  = max(enc->width, 16);
    1614                 uint height = max(enc->height, 16);
     1662                QSize dim = get_video_dim(*enc);
     1663                uint width  = max(dim.width(),  16);
     1664                uint height = max(dim.height(), 16);
    16151665                QString dec = "ffmpeg";
    16161666                uint thread_count = 1;
    16171667
     
    25642614            SequenceHeader *seq = reinterpret_cast<SequenceHeader*>(
    25652615                const_cast<uint8_t*>(bufptr));
    25662616
    2567             uint  width  = seq->width();
    2568             uint  height = seq->height();
     2617            uint  width  = seq->width()  >> context->lowres;
     2618            uint  height = seq->height() >> context->lowres;
    25692619            float aspect = seq->aspect(context->sub_id == 1);
    25702620            float seqFPS = seq->fps();
    25712621
    2572             bool changed = (seqFPS > fps+0.01) || (seqFPS < fps-0.01);
     2622            bool changed = (seqFPS > fps+0.01f) || (seqFPS < fps-0.01f);
    25732623            changed |= (width  != (uint)current_width );
    25742624            changed |= (height != (uint)current_height);
    25752625            changed |= fabs(aspect - current_aspect) > eps;
     
    25932643
    25942644                // fps debugging info
    25952645                float avFPS = normalized_fps(stream, context);
    2596                 if ((seqFPS > avFPS+0.01) || (seqFPS < avFPS-0.01))
     2646                if ((seqFPS > avFPS+0.01f) || (seqFPS < avFPS-0.01f))
    25972647                {
    25982648                    VERBOSE(VB_PLAYBACK, LOC +
    25992649                            QString("avFPS(%1) != seqFPS(%2)")
     
    26322682            || m_h264_parser->FieldType() == H264Parser::FIELD_BOTTOM)
    26332683            continue;
    26342684
    2635         float aspect_ratio;
    2636         if (context->sample_aspect_ratio.num == 0)
    2637             aspect_ratio = 0.0f;
    2638         else
    2639             aspect_ratio = av_q2d(context->sample_aspect_ratio) *
    2640                 context->width / context->height;
    2641 
    2642         if (aspect_ratio <= 0.0f || aspect_ratio > 6.0f)
    2643             aspect_ratio = (float)context->width / context->height;
    2644 
    2645         uint  width  = context->width;
    2646         uint  height = context->height;
     2685        float aspect_ratio = get_aspect(*context);
     2686        QSize dim    = get_video_dim(*context);
     2687        uint  width  = dim.width();
     2688        uint  height = dim.height();
    26472689        float seqFPS = normalized_fps(stream, context);
    26482690
    2649         bool changed = (seqFPS > fps+0.01) || (seqFPS < fps-0.01);
     2691        bool changed = (seqFPS > fps+0.01f) || (seqFPS < fps-0.01f);
    26502692        changed |= (width  != (uint)current_width );
    26512693        changed |= (height != (uint)current_height);
    26522694        changed |= fabs(aspect_ratio - current_aspect) > eps;
     
    26682710
    26692711            // fps debugging info
    26702712            float avFPS = normalized_fps(stream, context);
    2671             if ((seqFPS > avFPS+0.01) || (seqFPS < avFPS-0.01))
     2713            if ((seqFPS > avFPS+0.01f) || (seqFPS < avFPS-0.01f))
    26722714            {
    26732715                VERBOSE(VB_PLAYBACK, LOC +
    26742716                        QString("avFPS(%1) != seqFPS(%2)")
     
    34203462
    34213463            if (!d->HasMPEG2Dec())
    34223464            {
    3423                 int current_width = curstream->codec->width;
     3465                int current_width = curstream->codec->width; // TODO CHECKME
    34243466                int video_width = GetNVP()->GetVideoSize().width();
    34253467                if (dvd_xvmc_enabled && GetNVP() && GetNVP()->getVideoOutput())
    34263468                {
     
    39283970                        tmppicture.linesize[1] = picframe->pitches[1];
    39293971                        tmppicture.linesize[2] = picframe->pitches[2];
    39303972
     3973                        QSize dim = get_video_dim(*context);
    39313974                        myth_sws_img_convert(
    39323975                            &tmppicture, PIX_FMT_YUV420P,
    3933                                     (AVPicture *)&mpa_pic,
    3934                                     context->pix_fmt,
    3935                                     context->width,
    3936                                     context->height);
     3976                            (AVPicture *)&mpa_pic,
     3977                            context->pix_fmt,
     3978                            dim.width(), dim.height());
    39373979
    39383980                        if (xf)
    39393981                        {
  • libs/libmythtv/playercontext.cpp

     
    3535PlayerContext::PlayerContext(const QString &inUseID) :
    3636    recUsage(inUseID), nvp(NULL), nvpUnsafe(false), recorder(NULL),
    3737    tvchain(NULL), buffer(NULL), playingInfo(NULL),
     38    playingLen(0), specialDecode(kAVSpecialDecode_None),
    3839    nohardwaredecoders(false),
    3940    decoding(false), last_cardid(-1), last_framerate(30.0f),
    4041    // Fast forward state
  • libs/libmythtv/videoouttypes.h

     
    114114    kVisibility_Embedded,
    115115} WindowVisibility;
    116116
     117typedef enum AVSpecialDecode
     118{
     119    kAVSpecialDecode_None           = 0x00,
     120    kAVSpecialDecode_LowRes         = 0x01,
     121    kAVSpecialDecode_SingleThreaded = 0x02,
     122    kAVSpecialDecode_FewBlocks      = 0x04,
     123    kAVSpecialDecode_NoLoopFilter   = 0x08,
     124    kAVSpecialDecode_NoDecode       = 0x10,
     125} AVSpecialDecode;
     126
    117127class DisplayInfo
    118128{
    119129  public:
  • libs/libmythtv/playercontext.h

     
    9797    void SetPIPState(PIPState change) { pipState = change; }
    9898    void SetNVPChangingBuffers(bool val) { nvpUnsafe = val; }
    9999    void SetNoHardwareDecoders(void) { nohardwaredecoders = true; }
     100    void SetSpecialDecode(AVSpecialDecode sp) { specialDecode = sp; }
    100101
    101102    // Gets
    102103    QRect    GetStandAlonePIPRect(void);
     
    108109    QString  GetFilters(const QString &baseFilters) const;
    109110    QString  GetPlayMessage(void) const;
    110111    TVState  GetState(void) const;
     112    AVSpecialDecode GetSpecialDecode(void) const { return specialDecode; }
    111113
    112114    // Boolean Gets
    113115    bool IsPIPSupported(void) const;
     
    144146    RingBuffer         *buffer;
    145147    ProgramInfo        *playingInfo; ///< Currently playing info
    146148    long long           playingLen;  ///< Initial CalculateLength()
     149    AVSpecialDecode     specialDecode;
    147150    bool                nohardwaredecoders; // < Disable use of VDPAU decoding
    148151    bool                decoding;    ///< Video decoder thread started
    149152    pthread_t           decode;      ///< Video decoder thread
  • libs/libmythtv/avformatdecoder.h

     
    11#ifndef AVFORMATDECODER_H_
    22#define AVFORMATDECODER_H_
    33
    4 #include <qstring.h>
    5 #include <qmap.h>
     4#include <QString>
     5#include <QMap>
    66#include <QList>
    77
    88#include "programinfo.h"
     
    7777  public:
    7878    AvFormatDecoder(NuppelVideoPlayer *parent, const ProgramInfo &pginfo,
    7979                    bool use_null_video_out, bool allow_libmpeg2 = true,
    80                     bool no_hardware_decode = false);
     80                    bool no_hardware_decode = false,
     81                    AVSpecialDecode av_special_decode = kAVSpecialDecode_None);
    8182   ~AvFormatDecoder();
    8283
    8384    void CloseCodecs();
     
    241242    bool using_null_videoout;
    242243    MythCodecID video_codec_id;
    243244    bool no_hardware_decoders;
     245    AVSpecialDecode special_decode;
    244246
    245247    int maxkeyframedist;
    246248
  • programs/mythcommflag/main.cpp

     
    138138    NuppelVideoPlayer *nvp = new NuppelVideoPlayer();
    139139
    140140    PlayerContext *ctx = new PlayerContext("seektable rebuilder");
     141    ctx->SetSpecialDecode(kAVSpecialDecode_NoDecode);
    141142    ctx->SetPlayingInfo(program_info);
    142143    ctx->SetRingBuffer(tmprbuf);
    143144    ctx->SetNVP(nvp);
     
    696697    NuppelVideoPlayer *nvp = new NuppelVideoPlayer();
    697698
    698699    PlayerContext *ctx = new PlayerContext("flagger");
     700
     701    AVSpecialDecode sp = (AVSpecialDecode)
     702        (kAVSpecialDecode_LowRes         |
     703         kAVSpecialDecode_SingleThreaded |
     704         kAVSpecialDecode_NoLoopFilter);
     705
     706#if 0 /* blank detector needs to be only sample center for this optimization. */
     707    if ((COMM_DETECT_BLANKS  == commDetectMethod) ||
     708        (COMM_DETECT_2_BLANK == commDetectMethod))
     709    {
     710        sp = (AVSpecialDecode) (sp | kAVSpecialDecode_FewBlocks);
     711    }
     712#endif
     713
     714    ctx->SetSpecialDecode(sp);
     715
    699716    ctx->SetPlayingInfo(program_info);
    700717    ctx->SetRingBuffer(tmprbuf);
    701718    ctx->SetNVP(nvp);