~ubuntu-branches/ubuntu/lucid/mythtv/lucid

« back to all changes in this revision

Viewing changes to libs/libmythtv/NuppelVideoPlayer.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Dave Walker (Daviey), Jamie Bennett, Mario Limonciello, Dave Walker (Daviey)
  • Date: 2010-03-23 19:32:33 UTC
  • mfrom: (1.1.49 upstream)
  • Revision ID: james.westby@ubuntu.com-20100323193233-5sv9djoxtlmwt3ca
Tags: 0.23.0+fixes23789-0ubuntu1
[ Jamie Bennett ]
* Fix FTBFS on armel (LP: #537714)

[ Mario Limonciello ]
* mythtv-{common,backend}.{config,templates,postinst}: (LP: #483748)
  - Simplify debconf questions by avoiding showing the generated pw
  - Don't warn about mythtv group.
  - Don't notify about running mythtv-setup.  This is optional (but
    of course encouraged!)
* Set version to include a "+" delimitter.
* Restore libfaad-dev dependency. (LP: #546552)

[ Dave Walker (Daviey) ]
* New snapshot (r23789), based from 0.23-fixes.
* debian/control:
  - mythtv-frontend set to Conflict with mythflix, as it's dropped
    upstream. (LP: #544521)
  - Remove unnecessary and potentially problematic use of Pre-Depends.
  - Set the debug package to Priority extra.
  - Change *-perl Section's from libs to perl
  - add ${shlibs:Depends} for mythtv-common Depends field
  - Minor spelling fix.
  - Fixes the long description for one of the packages, ensuring the
    description doesn't exceed 80 characters.
  - Vcs-* set to -fixes, rather than -trunk.
* debian/rules:
  - Use debconf-updatepo to update translations when required
  - Ensure license files are not included in the binary packages, except 
    for debian/copyright.
  - Fixes the permissions of certain files in the packaging.
* debian/copyright:
  - updated to reflect that mythtv is GPL-2 only.
  - inserted better licence statement and Copyright reference.
* debian/mythtv-*.templates
  - Simplified strings; removed verbosity and improved readability.
* Prevent the maintainer scripts from failing in case any questions 
  can't be displayed.
* Added holding debian/mythtv-frontend.config, mainly to appease lintian.
* debian/mythtv-frontend.menu: Changed section to Applications/Graphics.
* debian/mythtv-backend.postinst: Load debconf libraries.
* debian/source.lintian-overrides: Removes the unecessary override of the 
  binNMU warnings.
* Fix perl binding installation.

Show diffs side-by-side

added added

removed removed

Lines of Context:
211
211
      audio_paused(false),
212
212
      repeat_delay(0),
213
213
      // Audio warping stuff
214
 
      usevideotimebase(false),
215
214
      warpfactor(1.0f),             warpfactor_avg(1.0f),
216
 
      warplbuff(NULL),              warprbuff(NULL),
217
 
      warpbuffsize(0),
218
215
      // Time Code stuff
219
216
      prevtc(0),                    prevrp(0),
220
217
      tc_avcheck_framecounter(0),   tc_diff_estimate(0),
503
500
    audio_lock.lock();
504
501
    if (audioOutput && unpauseaudio)
505
502
        audio_paused = false;
506
 
    
 
503
 
507
504
    audio_lock.unlock();
508
505
    if (player_ctx->buffer)
509
506
        player_ctx->buffer->Unpause();
537
534
void NuppelVideoPlayer::PauseVideo(bool wait)
538
535
{
539
536
    QMutexLocker locker(&pauseUnpauseLock);
540
 
    
 
537
 
541
538
    if (wait)
542
539
        video_actually_paused = false;
543
540
    pausevideo = true;
544
 
    
 
541
 
545
542
    for (uint i = 0; wait && !video_actually_paused; i++)
546
543
    {
547
544
        videoThreadPaused.wait(&pauseUnpauseLock, 250);
1144
1141
    isDummy = true;
1145
1142
 
1146
1143
    float displayAspect =
1147
 
        gContext->GetFloatSettingOnHost("XineramaMonitorAspectRatio", 
 
1144
        gContext->GetFloatSettingOnHost("XineramaMonitorAspectRatio",
1148
1145
                                        gContext->GetHostName(), 1.3333);
1149
1146
 
1150
1147
    if (!videoOutput)
2258
2255
 
2259
2256
/// Max amount the warpfactor can change in 1 frame.
2260
2257
#define MAXWARPDIFF 0.0005f
2261
 
/// How much dwe multiply the warp by when storing it in an integer.
2262
 
#define WARPMULTIPLIER 1000000000
2263
2258
/// How long to average the warp over.
2264
2259
#define WARPAVLEN (video_frame_rate * 600)
2265
2260
/** How much we allow the warp to deviate from 1.0 (normal speed). */
2320
2315
 
2321
2316
    repeat_delay = 0;
2322
2317
 
2323
 
    if (usevideotimebase)
2324
 
    {
2325
 
        warpfactor_avg = gContext->GetNumSetting("WarpFactor", 0);
2326
 
        if (warpfactor_avg)
2327
 
            warpfactor_avg /= WARPMULTIPLIER;
2328
 
        else
2329
 
            warpfactor_avg = 1;
2330
 
        // Reset the warpfactor if it's obviously bogus
2331
 
        if (warpfactor_avg < (1 - WARPCLIP))
2332
 
            warpfactor_avg = 1;
2333
 
        if (warpfactor_avg > (1 + (WARPCLIP * 2)) )
2334
 
            warpfactor_avg = 1;
2335
 
 
2336
 
        warpfactor = warpfactor_avg;
2337
 
    }
2338
 
 
2339
2318
    refreshrate = videoOutput ? videoOutput->GetDisplayInfo().rate : 0;
2340
2319
    if (refreshrate <= 0)
2341
2320
        refreshrate = frame_interval;
2343
2322
 
2344
2323
    if (!using_null_videoout)
2345
2324
    {
2346
 
        if (usevideotimebase)
2347
 
            VERBOSE(VB_PLAYBACK, "Using video as timebase");
2348
 
        else
2349
 
            VERBOSE(VB_PLAYBACK, "Using audio as timebase");
2350
 
 
2351
2325
        QString timing_type = videosync->getName();
2352
2326
 
2353
2327
        QString msg = QString("Video timing method: %1").arg(timing_type);
2573
2547
            if (avsync_delay > 2000000 && player_ctx->buffer->isDVD())
2574
2548
                avsync_delay = 90000;
2575
2549
            avsync_avg = (avsync_delay + (avsync_avg * 3)) / 4;
2576
 
            if (!usevideotimebase)
 
2550
 
 
2551
            /* If the audio time codes and video diverge, shift
 
2552
               the video by one interlaced field (1/2 frame) */
 
2553
            if (!lastsync)
2577
2554
            {
2578
 
                /* If the audio time codes and video diverge, shift
2579
 
                   the video by one interlaced field (1/2 frame) */
2580
 
 
2581
 
                if (!lastsync)
2582
 
                {
2583
 
                    if (avsync_avg > frame_interval * 3 / 2)
2584
 
                    {
2585
 
                        avsync_adjustment = refreshrate;
2586
 
                        lastsync = true;
2587
 
                    }
2588
 
                    else if (avsync_avg < 0 - frame_interval * 3 / 2)
2589
 
                    {
2590
 
                        avsync_adjustment = -refreshrate;
2591
 
                        lastsync = true;
2592
 
                    }
2593
 
                }
2594
 
                else
2595
 
                    lastsync = false;
 
2555
                if (avsync_avg > frame_interval * 3 / 2)
 
2556
                {
 
2557
                    avsync_adjustment = refreshrate;
 
2558
                    lastsync = true;
 
2559
                }
 
2560
                else if (avsync_avg < 0 - frame_interval * 3 / 2)
 
2561
                {
 
2562
                    avsync_adjustment = -refreshrate;
 
2563
                    lastsync = true;
 
2564
                }
2596
2565
            }
 
2566
            else
 
2567
                lastsync = false;
2597
2568
        }
2598
2569
        else
2599
2570
        {
2600
2571
            avsync_avg = 0;
2601
2572
            avsync_oldavg = 0;
2602
2573
        }
2603
 
    } 
 
2574
    }
2604
2575
    else
2605
2576
        audio_lock.unlock();
2606
2577
}
2607
2578
 
2608
 
void NuppelVideoPlayer::ShutdownAVSync(void)
2609
 
{
2610
 
    if (usevideotimebase)
2611
 
    {
2612
 
        gContext->SaveSetting("WarpFactor",
2613
 
            (int)(warpfactor_avg * WARPMULTIPLIER));
2614
 
 
2615
 
        if (warplbuff)
2616
 
        {
2617
 
            free(warplbuff);
2618
 
            warplbuff = NULL;
2619
 
        }
2620
 
 
2621
 
        if (warprbuff)
2622
 
        {
2623
 
            free(warprbuff);
2624
 
            warprbuff = NULL;
2625
 
        }
2626
 
        warpbuffsize = 0;
2627
 
    }
2628
 
}
2629
 
 
2630
2579
void NuppelVideoPlayer::DisplayPauseFrame(void)
2631
2580
{
2632
2581
    if (!video_actually_paused)
2920
2869
    refreshrate = 0;
2921
2870
    lastsync = false;
2922
2871
 
2923
 
    usevideotimebase = gContext->GetNumSetting("UseVideoTimebase", 0);
2924
 
 
2925
2872
    if (VERBOSE_LEVEL_CHECK(VB_PLAYBACK))
2926
2873
        output_jmeter = new Jitterometer("video_output", 100);
2927
2874
    else
3056
3003
        delete videoOutput;
3057
3004
        videoOutput = NULL;
3058
3005
    }
3059
 
 
3060
 
    ShutdownAVSync();
3061
3006
}
3062
3007
 
3063
3008
void *NuppelVideoPlayer::kickoffOutputVideoLoop(void *player)
4063
4008
        audioOutput->Drain();
4064
4009
    }
4065
4010
 
4066
 
    // If there is no warping, just send it to the audioOutput.
4067
 
    if (!usevideotimebase)
4068
 
    {
4069
 
        if (!audioOutput->AddSamples(buffer, samples, timecode))
4070
 
            VERBOSE(VB_PLAYBACK, "NVP::AddAudioData():p1: "
4071
 
                    "Audio buffer overflow, audio data lost!");
4072
 
        return;
4073
 
    }
4074
 
 
4075
 
    // If we need warping, do it...
4076
 
    int newsamples = (int)(samples / warpfactor);
4077
 
    int newlen     = newsamples * samplesize;
4078
 
 
4079
 
    // We resize the buffers if they aren't big enough
4080
 
    if ((warpbuffsize < newlen) || (!warplbuff))
4081
 
    {
4082
 
        warplbuff = (short int*) realloc(warplbuff, newlen);
4083
 
        warprbuff = (short int*) realloc(warprbuff, newlen);
4084
 
        warpbuffsize = newlen;
4085
 
    }
4086
 
 
4087
 
    // Resample...
4088
 
    float incount  = 0.0f;
4089
 
    int   outcount = 0;
4090
 
    while ((incount < samples) && (outcount < newsamples))
4091
 
    {
4092
 
        char *out_ptr = ((char*)warplbuff) + (outcount * samplesize);
4093
 
        char *in_ptr  = buffer + (((int)incount) * samplesize);
4094
 
        memcpy(out_ptr, in_ptr, samplesize);
4095
 
 
4096
 
        outcount += 1;
4097
 
        incount  += warpfactor;
4098
 
    }
4099
 
    samples = outcount;
4100
 
 
4101
 
    // Send new warped audio to audioOutput
4102
 
    if (!audioOutput->AddSamples((char*)warplbuff, samples, timecode))
4103
 
        VERBOSE(VB_PLAYBACK,"NVP::AddAudioData():p2: "
 
4011
    if (!audioOutput->AddSamples(buffer, samples, timecode))
 
4012
        VERBOSE(VB_PLAYBACK, "NVP::AddAudioData():p1: "
4104
4013
                "Audio buffer overflow, audio data lost!");
 
4014
    return;
4105
4015
}
4106
4016
 
4107
4017
/** \fn NuppelVideoPlayer::AddAudioData(short int*,short int*,int,long long)
4122
4032
    if (!audioOutput)
4123
4033
        return;
4124
4034
 
4125
 
    // If there is no warping, just send it to the audioOutput.
4126
 
    if (!usevideotimebase)
4127
 
    {
4128
 
        buffers[0] = (char*) lbuffer;
4129
 
        buffers[1] = (char*) rbuffer;
4130
 
        if (!audioOutput->AddSamples(buffers, samples, timecode))
4131
 
            VERBOSE(VB_PLAYBACK, "NVP::AddAudioData():p3: "
4132
 
                    "Audio buffer overflow, audio data lost!");
4133
 
        return;
4134
 
    }
4135
 
 
4136
 
    // If we need warping, do it...
4137
 
    int samplesize = sizeof(short int);
4138
 
    int newsamples = (int)(samples / warpfactor);
4139
 
    int newlen     = newsamples * samplesize;
4140
 
 
4141
 
    // We resize the buffers if they aren't big enough
4142
 
    if ((warpbuffsize < newlen) || (!warplbuff) || (!warprbuff))
4143
 
    {
4144
 
        warplbuff = (short int*) realloc(warplbuff, newlen);
4145
 
        warprbuff = (short int*) realloc(warprbuff, newlen);
4146
 
        warpbuffsize = newlen;
4147
 
    }
4148
 
 
4149
 
    // Resample...
4150
 
    float incount  = 0.0f;
4151
 
    int   outcount = 0;
4152
 
    while ((incount < samples) && (outcount < newsamples))
4153
 
    {
4154
 
        warplbuff[outcount] = lbuffer[(uint)round(incount)];
4155
 
        warprbuff[outcount] = rbuffer[(uint)round(incount)];
4156
 
 
4157
 
        outcount += 1;
4158
 
        incount  += warpfactor;
4159
 
    }
4160
 
    samples = outcount;
4161
 
 
4162
 
    // Send new warped audio to audioOutput
4163
 
    buffers[0] = (char*) warplbuff;
4164
 
    buffers[1] = (char*) warprbuff;
 
4035
    buffers[0] = (char*) lbuffer;
 
4036
    buffers[1] = (char*) rbuffer;
4165
4037
    if (!audioOutput->AddSamples(buffers, samples, timecode))
4166
 
        VERBOSE(VB_PLAYBACK, "NVP::AddAudioData():p4: "
 
4038
        VERBOSE(VB_PLAYBACK, "NVP::AddAudioData():p2: "
4167
4039
                "Audio buffer overflow, audio data lost!");
 
4040
    return;
4168
4041
}
4169
4042
 
4170
4043
/**
6871
6744
        if (decoder)
6872
6745
        {
6873
6746
            msg = decoder->GetTrackDesc(type, GetTrack(type));
6874
 
            
 
6747
 
6875
6748
            if (player_ctx->buffer->isDVD())
6876
6749
                player_ctx->buffer->DVD()->SetTrack(type, trackNo);
6877
6750
        }
7329
7202
    }
7330
7203
    else
7331
7204
    {
7332
 
        // BEGIN HACK
7333
 
        // Like frame based subtitles this can get out of sync after
7334
 
        // transcoding, using the raw timecode doesn't work either
7335
 
        // with DTV broadcasts where the timecode isn't zero on the
7336
 
        // first frame, and may roll over during the broadcast.
7337
 
        playPos = (uint64_t)
7338
 
            ((currentFrame->frameNumber / video_frame_rate) * 1000);
7339
 
        // END HACK
 
7205
        // Use timecodes for time based SRT subtitles. Feeding this into
 
7206
        // NormalizeVideoTimecode() should adjust for non-zero start times
 
7207
        // and wraps. For MPEG, wraps will occur just once every 26.5 hours
 
7208
        // and other formats less frequently so this should be sufficient.
 
7209
        // Note: timecodes should now always be valid even in the case
 
7210
        // when a frame doesn't have a valid timestamp. If an exception is
 
7211
        // found where this is not true then we need to use the frameNumber
 
7212
        // when timecode is not defined by uncommenting the following lines.
 
7213
        //if (currentFrame->timecode == 0)
 
7214
        //    playPos = (uint64_t)
 
7215
        //        ((currentFrame->frameNumber / video_frame_rate) * 1000);
 
7216
        //else
 
7217
        playPos = GetDecoder()->NormalizeVideoTimecode(currentFrame->timecode);
7340
7218
    }
7341
7219
 
7342
7220
    if (!textSubtitles.HasSubtitleChanged(playPos))
7602
7480
{
7603
7481
    if (!player_ctx->buffer->isDVD())
7604
7482
        return false;
7605
 
    
 
7483
 
7606
7484
    textDisplayMode = kDisplayNone;
7607
7485
    bool ret = player_ctx->buffer->DVD()->GoToMenu(str);
7608
 
    
 
7486
 
7609
7487
    if (!ret)
7610
7488
    {
7611
7489
        if (osd)
7613
7491
        VERBOSE(VB_GENERAL, "No DVD Menu available.");
7614
7492
        return false;
7615
7493
    }
7616
 
    
 
7494
 
7617
7495
    return true;
7618
7496
}
7619
7497
 
7804
7682
    {
7805
7683
        int i = window_id;
7806
7684
        {
7807
 
            CC708Window &win = GetCCWin(service_num, i);
7808
 
 
7809
7685
#if 0
7810
7686
            if ((1<<i) & CC708DelayedDeletes[service_num&63])
7811
7687
            {
7821
7697
                        .arg(service_num).arg(i).arg(txt));
7822
7698
            }
7823
7699
#endif
7824
 
 
7825
 
            win.exists = false;
7826
 
            if (win.text)
7827
 
            {
7828
 
                delete [] win.text;
7829
 
                win.text = NULL;
7830
 
            }
7831
 
 
7832
7700
            CC708DelayedDeletes[service_num&63] &= ~(1<<i);
7833
7701
            if (GetOSD())
7834
7702
                GetOSD()->CC708Updated();
7862
7730
{
7863
7731
    VERBOSE(VB_VBI, LOC + QString("DeleteWindows(%1, 0x%2)")
7864
7732
            .arg(service_num).arg(window_map,0,16));
7865
 
 
 
7733
    for (uint i=0; i<8; i++)
 
7734
        if ((1<<i) & window_map)
 
7735
            GetCCWin(service_num, i).Clear();
7866
7736
    CC708DelayedDeletes[service_num&63] |= window_map;
7867
7737
}
7868
7738
 
8091
7961
    if (!(textDisplayMode & kDisplayCC708))
8092
7962
        return;
8093
7963
 
8094
 
    for (uint i = 0; i < (uint)len; i++)
8095
 
        GetCCWin(service_num).AddChar(QChar(unicode_string[i]));
 
7964
    {
 
7965
        CC708Window &win = GetCCWin(service_num);
 
7966
        QMutexLocker locker(&win.lock);
 
7967
        for (uint i = 0; i < (uint)len; i++)
 
7968
            win.AddChar(QChar(unicode_string[i]));
 
7969
    }
8096
7970
 
8097
7971
    if (GetOSD())
8098
7972
        GetOSD()->CC708Updated();