Ticket #3326: 3326-dvb-radio-v1.patch

File 3326-dvb-radio-v1.patch, 8.7 KB (added by danielk, 13 years ago)

Proof of concept patch for fixing DVB Radio in multirec branch

  • libs/libmythtv/avformatdecoder.cpp

     
    2424#include "cc708decoder.h"
    2525#include "interactivetv.h"
    2626#include "DVDRingBuffer.h"
     27#include "audiooutputbase.h"
    2728
    2829#ifdef USING_XVMC
    2930#include "videoout_xv.h"
     
    26812682    }
    26822683}
    26832684
     2685// documented in decoderbase.h
    26842686bool AvFormatDecoder::GetFrame(int onlyvideo)
    26852687{
    26862688    AVPacket *pkt = NULL;
     
    27042706
    27052707    bool skipaudio = (lastvpts == 0);
    27062708
     2709    bool has_video = true;
     2710    if (ic->cur_pmt_sect)
     2711    {
     2712        const PESPacket pes = PESPacket::ViewData(ic->cur_pmt_sect);
     2713        const PSIPTable psip(pes);
     2714        const ProgramMapTable pmt(psip);
     2715
     2716        has_video = false;
     2717        for (uint i = 0; i < pmt.StreamCount(); i++)
     2718        {
     2719            // MythTV remaps OpenCable Video to normal video during recording
     2720            // so "dvb" is the safest choice for system info type, since this
     2721            // will ignore other uses of the same stream id in DVB countries.
     2722            has_video |= pmt.IsVideo(i, "dvb");
     2723        }
     2724    }
     2725
     2726    //cerr<<"GetFrame("<<onlyvideo<<") has_video: "<<has_video;
     2727
     2728    if (!has_video && (onlyvideo >= 0))
     2729    {
     2730        VideoFrame *frame = GetNVP()->GetNextVideoFrame(true);
     2731        if (frame)
     2732        {
     2733            clear(frame, GUID_YV12_PLANAR);
     2734            unsigned int ysize  = frame->width * frame->height;
     2735            for (uint i = 0; i < ysize; i++)
     2736            {
     2737                *(frame->buf + frame->offsets[0] + i) =
     2738                    (framesPlayed+i) & 0xff;
     2739            }
     2740
     2741            frame->interlaced_frame = 0; // not interlaced
     2742            frame->top_field_first  = 1; // top field first
     2743            frame->repeat_pict      = 0; // not a repeated picture
     2744            frame->frameNumber = framesPlayed;
     2745
     2746            GetNVP()->ReleaseNextVideoFrame(frame, lastvpts);
     2747
     2748            if (GetNVP()->getVideoOutput())
     2749            {
     2750                GetNVP()->getVideoOutput()->DeLimboFrame(frame);
     2751                if (!GetNVP()->getVideoOutput()->EnoughPrebufferedFrames())
     2752                    allowedquit = true;
     2753            }
     2754
     2755            decoded_video_frame = frame;
     2756            gotvideo = 1;
     2757            framesPlayed++;
     2758        }
     2759        onlyvideo = -1;
     2760        skipaudio = false;
     2761    }
     2762
     2763    uint deadmancounter = 0;
     2764
    27072765    while (!allowedquit)
    27082766    {
    2709         if ((onlyvideo == 0) &&
     2767        //cerr<<".";
     2768        if ((onlyvideo == 0) && has_video &&
    27102769            ((currentTrack[kTrackTypeAudio] < 0) ||
    27112770             (selectedTrack[kTrackTypeAudio].av_stream_index < 0)))
    27122771        {
    27132772            // disable audio request if there are no audio streams anymore
     2773            cerr<<"disabling audio";
    27142774            onlyvideo = 1;
    27152775        }
    27162776
     
    27802840                //cout << "behind: " << lastapts << " " << lastvpts << endl;
    27812841                storevideoframes = true;
    27822842            }
    2783             else
     2843            else if (onlyvideo >= 0)
    27842844            {
     2845                //cerr<<"got video -- set allowedquit"<<endl;
    27852846                allowedquit = true;
    27862847                continue;
    27872848            }
     
    30133074            {
    30143075                case CODEC_TYPE_AUDIO:
    30153076                {
     3077                    deadmancounter++;
     3078
    30163079                    bool reselectAudioTrack = false;
    30173080
    30183081                    // detect switches between stereo and dual languages
     
    30563119                        lastapts = (long long)(av_q2d(curstream->time_base) *
    30573120                                               pkt->pts * 1000);
    30583121
    3059                     if (onlyvideo != 0 || (pkt->stream_index != audIdx))
     3122                    if ((onlyvideo > 0) || (pkt->stream_index != audIdx))
    30603123                    {
    30613124                        ptr += len;
    30623125                        len = 0;
     
    31423205                    GetNVP()->AddAudioData((char *)audioSamples, data_size,
    31433206                                           temppts);
    31443207
     3208                    AudioOutputBase *audio = dynamic_cast<AudioOutputBase*>
     3209                        (GetNVP()->getAudioOutput());
     3210
     3211                    if ((onlyvideo < 0) &&
     3212                        (!audio ||
     3213                         ((audio->getBufferedOnSoundcard() == 0) ||
     3214                          (audio->getSpaceOnSoundcard() <
     3215                           audio->getBufferedOnSoundcard()))))
     3216                    {
     3217                        allowedquit = (onlyvideo < 0);
     3218                        //if (onlyvideo < 0)
     3219                        //    cerr<<"audio -- set allowedquit"<<endl;
     3220                    }
     3221
     3222                    if ((onlyvideo < 0) && deadmancounter > 10)
     3223                    {
     3224                        cerr<<"BUG: dead man counter triggered"<<endl;
     3225                        allowedquit = true;
     3226                    }
     3227
    31453228                    if (ringBuffer->InDVDMenuOrStillFrame())
    31463229                        allowedquit = true;
    31473230
     
    33953478    if (pkt)
    33963479        delete pkt;
    33973480
     3481    //cerr<<endl;
    33983482    return true;
    33993483}
    34003484
  • libs/libmythtv/decoderbase.h

     
    7070    virtual void SetDisablePassThrough(bool disable) { (void)disable; }
    7171
    7272    virtual void setWatchingRecording(bool mode);
     73    /// Decode a frame of video/audio. If onlyvideo is +1,
     74    /// decodes the video portion, if it is -1 only decodes
     75    /// the audio portion, if it is 0 it decodes audio and video
    7376    virtual bool GetFrame(int onlyvideo) = 0;
    7477    NuppelVideoPlayer *GetNVP() { return m_parent; }
    7578   
  • libs/libmythtv/libmythtv.pro

     
    1414INCLUDEPATH += ../libmythlivemedia/groupsock/include
    1515INCLUDEPATH += ../libmythlivemedia/liveMedia/include
    1616INCLUDEPATH += ../libmythlivemedia/UsageEnvironment/include
     17INCLUDEPATH += ../libmythsoundtouch
    1718
    1819DEPENDPATH  += ../libmyth ../libavcodec ../libavformat ../libavutil
    1920DEPENDPATH  += ../libmythmpeg2 ../libmythdvdnav
  • libs/libmythtv/hdhrrecorder.cpp

     
    273273        if (tspacket.HasPayload())
    274274        {
    275275            const unsigned int lpid = tspacket.PID();
     276
     277            if ((GetStreamData()->VideoPIDSingleProgram() == 0xffffffff) &&
     278                _wait_for_keyframe_option)
     279            {
     280                _wait_for_keyframe_option = false;
     281            }
     282
    276283            // Pass or reject frames based on PID, and parse info from them
    277284            if (lpid == GetStreamData()->VideoPIDSingleProgram())
    278285            {
  • libs/libmythtv/mpeg/mpegstreamdata.cpp

     
    1515#include "atscstreamdata.h"
    1616#include "atsctables.h"
    1717
     18#define DEBUG_MPEG_RADIO // uncomment to strip video streams from TS stream
     19
    1820void init_sections(sections_t &sect, uint last_section)
    1921{
    2022    static const unsigned char init_bits[8] =
     
    554556            audioPIDs.push_back(pid);
    555557        }
    556558
     559#ifdef DEBUG_MPEG_RADIO
    557560        if (is_video)
     561            continue;
     562#endif // DEBUG_MPEG_RADIO
     563
     564        if (is_video)
    558565        {
    559566            video_cnt++;
    560567            videoPIDs.push_back(pid);
  • libs/libmythtv/avformatdecoder.h

     
    9494                 char testbuf[kDecoderProbeBufferSize],
    9595                 int testbufsize = kDecoderProbeBufferSize);
    9696
    97     /// Decode a frame of video/audio. If onlyvideo is set,
    98     /// just decode the video portion.
    9997    bool GetFrame(int onlyvideo);
    10098
    10199    bool isLastFrameKey(void) { return false; }
  • libs/libmyth/audiooutputbase.h

     
    7777    virtual bool OpenDevice(void) = 0;
    7878    virtual void CloseDevice(void) = 0;
    7979    virtual void WriteAudio(unsigned char *aubuf, int size) = 0;
     80  public:
    8081    virtual int getSpaceOnSoundcard(void) = 0;
    8182    virtual int getBufferedOnSoundcard(void) = 0;
    8283    virtual int GetVolumeChannel(int channel) = 0; // Returns 0-100