Ticket #7659: audioprops.patch

File audioprops.patch, 18.7 KB (added by doug@…, 11 years ago)
  • libs/libmythtv/nuppeldecoder.cpp

     
    13231323    return true;
    13241324}
    13251325
     1326int NuppelDecoder::GetAudioProperties(void)
     1327{
     1328    VERBOSE(VB_AUDIO, LOC + QString("Getting Nuppel Audio Props"));
     1329     
     1330    if (!mpa_audctx)
     1331    {
     1332        VERBOSE(VB_AUDIO, LOC + QString("No Audio Context, ignoring audio props"));
     1333        return -1;
     1334    }
     1335
     1336    int props = GetAudioPropertiesFromContext(mpa_audctx);
     1337
     1338    // no way to find AUD_HARDHEAR so ignore
     1339    // DH: I don't know what AUD_VISUALIMPAIR is so ignore
     1340
     1341    return props;
     1342}
     1343
    13261344void NuppelDecoder::SeekReset(long long newKey, uint skipFrames,
    13271345                              bool doFlush, bool discardFrames)
    13281346{
  • libs/libmythtv/NuppelVideoPlayer.cpp

     
    79147914    osdtheme = themename; osdtheme.detach();
    79157915}
    79167916
     7917int NuppelVideoPlayer::GetAudioProperties(void)
     7918{
     7919    using_null_videoout = true;
     7920
     7921    VERBOSE(VB_AUDIO, LOC + "opening file for audio props");
     7922    if (OpenFile(false, 0, false) < 0)
     7923    {
     7924        VERBOSE(VB_IMPORTANT, LOC_ERR + "Could not open file for audio props.");
     7925        return NULL;
     7926    }
     7927
     7928    VERBOSE(VB_AUDIO, LOC + "Getting decoder for audio props");
     7929    if (GetDecoder())
     7930    {
     7931        VERBOSE(VB_AUDIO, QString("Found decoder, getting audio props"));
     7932        return GetDecoder()->GetAudioProperties();
     7933    }
     7934
     7935    VERBOSE(VB_IMPORTANT, QString("Found no decoder for audio props"));
     7936    return -1;
     7937}
     7938
    79177939// EIA-708 caption support -- end
    79187940
    79197941static unsigned dbg_ident(const NuppelVideoPlayer *nvp)
  • libs/libmythtv/audiopropsgenerator.cpp

     
     1// MythTV headers
     2#include "RingBuffer.h"
     3#include "NuppelVideoPlayer.h"
     4#include "audiopropsgenerator.h"
     5#include "tv_rec.h"
     6#include "playercontext.h"
     7#include "mythverbose.h"
     8
     9#define LOC QString("Audio Props: ")
     10#define LOC_ERR QString("Audio Props Error: ")
     11#define LOC_WARN QString("Audio Props Warning: ")
     12
     13/** \class AudioPropsGenerator
     14 *  \brief This class updates the Audio Properties of a recording.
     15 *
     16 *   The usage is simple: First, pass a ProgramInfo whose pathname points
     17 *   to a local or remote recording to the constructor. Then call either
     18 *   Start(void) or Run(void) to update the audio props.
     19 *
     20 *   Start(void) will create a thread that processes the request.
     21 *
     22 *   Run(void) will process the request in the current thread,
     23 *
     24 *   The AudioPropsGenerator will send Qt signals when the update is ready
     25 *   and when the thread finishes running if Start(void) was called.
     26 */
     27
     28/**
     29 *  \brief Constructor
     30 *
     31 *  \param pginfo     ProgramInfo for the reording we want to generate audio props for
     32 */
     33AudioPropsGenerator::AudioPropsGenerator(const ProgramInfo *pginfo)
     34    : programInfo(*pginfo)
     35{
     36    VERBOSE(VB_AUDIO, LOC + QString("Constructing Audio Props Generator"));
     37}
     38
     39AudioPropsGenerator::~AudioPropsGenerator()
     40{
     41    VERBOSE(VB_AUDIO, LOC + QString("Deconstructing Audio Props Generator"));
     42
     43    audioPropsLock.lock();
     44    emit audioPropsThreadDone(&programInfo);
     45    audioPropsLock.unlock();
     46    disconnectSafe();
     47}
     48
     49void AudioPropsGenerator::AttachSignals(QObject *obj)
     50{
     51    QMutexLocker locker(&audioPropsLock);
     52    qRegisterMetaType<bool>("bool &");
     53    connect(this, SIGNAL(audioPropsThreadDone(const QString&,bool&)),
     54            obj,  SLOT(  audioPropsThreadDone(const QString&,bool&)),
     55            Qt::DirectConnection);
     56    connect(this, SIGNAL(audioPropsReady(const ProgramInfo*)),
     57            obj,  SLOT(  audioPropsReady(const ProgramInfo*)),
     58            Qt::DirectConnection);
     59}
     60
     61/** \fn AudioProps::disconnectSafe(void)
     62 *  \brief disconnects signals while holding audioPropsLock, ensuring that
     63 *         no one will receive a signal from this class after this call.
     64 */
     65void AudioPropsGenerator::disconnectSafe(void)
     66{
     67    QMutexLocker locker(&audioPropsLock);
     68    QObject::disconnect(this, NULL, NULL, NULL);
     69}
     70
     71/** \fn AudioProps::Start(void)
     72 *  \brief This call starts a thread that will update the audio props
     73 */
     74void AudioPropsGenerator::Start(void)
     75{
     76    pthread_create(&audioPropsThread, NULL, AudioPropsRun, this);
     77    // detach, so we don't have to join thread to free thread local mem.
     78    pthread_detach(audioPropsThread);
     79}
     80
     81bool AudioPropsGenerator::Run(void)
     82{
     83    bool ok = UpdateAudioProps();
     84
     85    if (ok)
     86    {
     87        QMutexLocker locker(&audioPropsLock);
     88        emit audioPropsReady(&programInfo);
     89    }
     90
     91    return ok;
     92}
     93
     94void *AudioPropsGenerator::AudioPropsRun(void *param)
     95{
     96    // Lower scheduling priority, to avoid problems with recordings.
     97    if (setpriority(PRIO_PROCESS, 0, 9))
     98        VERBOSE(VB_IMPORTANT, LOC + "Setting priority failed." + ENO);
     99    AudioPropsGenerator *gen = (AudioPropsGenerator*) param;
     100    gen->Run();
     101    gen->deleteLater();
     102    return NULL;
     103}
     104
     105bool AudioPropsGenerator::UpdateAudioProps(void)
     106{
     107
     108    VERBOSE(VB_AUDIO, LOC + QString("Starting Audio Inspection"));
     109    PlayerContext *ctx = new PlayerContext(kAudioInspectorInUseID);
     110
     111    VERBOSE(VB_AUDIO, LOC + QString("Using file: %1").arg(programInfo.pathname));
     112    RingBuffer *rbuf = new RingBuffer(programInfo.pathname, false, false, 0);
     113
     114    VERBOSE(VB_AUDIO, LOC + QString("Setting player"));
     115    ctx->SetRingBuffer(rbuf);
     116    ctx->SetPlayingInfo(&programInfo);
     117    ctx->SetNVP(new NuppelVideoPlayer());
     118    ctx->nvp->SetPlayerInfo(NULL, NULL, true, ctx);
     119
     120    VERBOSE(VB_AUDIO, LOC + QString("Getting audio props"));
     121    int audioprops  = ctx->nvp->GetAudioProperties();
     122
     123    VERBOSE(VB_AUDIO, LOC + QString("Got audio props"));
     124    bool updated = audioprops >= 0;
     125
     126    if (!updated)
     127        VERBOSE(VB_IMPORTANT, LOC + QString("NOT Saving audio props for %1").arg(programInfo.title));
     128    else
     129    {
     130        VERBOSE(VB_IMPORTANT, LOC + QString("Saving audio props (%1) for %2").arg(audioprops).arg(programInfo.title));
     131        programInfo.SaveAudioProps(audioprops);
     132    }
     133
     134    return updated;
     135}
     136
     137/* vim: set expandtab tabstop=4 shiftwidth=4: */
  • libs/libmythtv/decoderbase.h

     
    147147
    148148    virtual QString GetXDS(const QString&) const { return QString::null; }
    149149
     150    virtual int GetAudioProperties(void) = 0;
     151
     152    int GetAudioPropertiesFromContext(AVCodecContext *context);
     153
    150154    // MHEG/MHI stuff
    151155    virtual bool SetAudioByComponentTag(int) { return false; }
    152156    virtual bool SetVideoByComponentTag(int) { return false; }
  • libs/libmythtv/avformatdecoder.cpp

     
    18591859                VERBOSE(VB_GENERAL, LOC + QString("codec %1 has %2 channels")
    18601860                        .arg(codec_id_string(enc->codec_id))
    18611861                        .arg(enc->channels));
    1862 
    18631862#if 0
    18641863                // HACK MULTICHANNEL DTS passthru disabled for multichannel,
    18651864                // dont know how to handle this
     
    43834382    return passthru;
    43844383}
    43854384
     4385// returns the AudioProperties for the current data
     4386int AvFormatDecoder::GetAudioProperties(void)
     4387{
     4388    VERBOSE(VB_AUDIO, LOC + QString("Getting AFD Audio Props"));
     4389
     4390    if (!ic)
     4391    {
     4392        VERBOSE(VB_IMPORTANT, LOC + QString("No FormatContext, ignoring audio props"));
     4393        return -1;
     4394    }
     4395   
     4396    int props = 0;
     4397
     4398    // first try to find audio properties form the audio tracks
     4399    sinfo_vec_t::iterator it = tracks[kTrackTypeAudio].begin();
     4400    for (; it != tracks[kTrackTypeAudio].end(); ++it)
     4401    // for (uint i = 0; i < ic->nb_streams; i++)
     4402    {
     4403        //AVStream *stream = ic->streams[i];
     4404        AVStream *stream = ic->streams[it->av_stream_index];
     4405        int i = it->av_stream_index;
     4406
     4407        VERBOSE(VB_AUDIO, LOC + QString("Inspecting Audio Stream id #%1 ").arg(i));
     4408
     4409        // make sure there's a stream
     4410        if (!stream)
     4411        {
     4412             VERBOSE(VB_IMPORTANT, LOC + QString("No Stream for Stream id #%1").arg(i));
     4413             continue;
     4414        }
     4415
     4416        AVCodecContext *codec = stream->codec;
     4417
     4418        // mmake sure there's a codec
     4419        if (!codec)
     4420        {
     4421             VERBOSE(VB_IMPORTANT, LOC + QString("No Codec for Stream id #%1").arg(i));
     4422             continue;
     4423        }
     4424
     4425        props |= GetAudioPropertiesFromContext(codec);
     4426    }
     4427
     4428    // if there are any of these assume hard hearing
     4429    int track_count = kTrackTypeCount;
     4430    if (
     4431         (track_count >= kTrackTypeSubtitle         && tracks[kTrackTypeSubtitle].size() > 0)         ||
     4432         (track_count >= kTrackTypeCC608            && tracks[kTrackTypeCC608].size() > 0)            ||
     4433         (track_count >= kTrackTypeCC708            && tracks[kTrackTypeCC708].size() > 0)            ||
     4434         (track_count >= kTrackTypeTeletextCaptions && tracks[kTrackTypeTeletextCaptions].size() > 0) ||
     4435         (track_count >= kTrackTypeTeletextMenu     && tracks[kTrackTypeTeletextMenu].size() > 0)     ||
     4436         (track_count >= kTrackTypeTextSubtitle     && tracks[kTrackTypeTextSubtitle].size() > 0)     
     4437        )
     4438    {
     4439            VERBOSE(VB_AUDIO, LOC + QString("Found HARDHEARING Track"));
     4440            props |= AUD_HARDHEAR;
     4441    }
     4442
     4443    // DH: I don't know what AUD_VISUALIMPAIR is, so ignore it
     4444
     4445    return props;
     4446}
     4447
    43864448/** \fn AvFormatDecoder::SetupAudioStream(void)
    43874449 *  \brief Reinitializes audio if it needs to be reinitialized.
    43884450 *
     
    44244486    if (info == audioIn)
    44254487        return false; // no change
    44264488
    4427     VERBOSE(VB_AUDIO, LOC + "Initializing audio parms from " +
     4489    VERBOSE(VB_AUDIO, LOC + "Initializing audio params from " +
    44284490            QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1));
    44294491
    44304492    audioOut = audioIn = info;
  • libs/libmythtv/libmythtv.pro

     
    151151HEADERS += viewschdiff.h            livetvchain.h
    152152HEADERS += playgroup.h
    153153HEADERS += channelsettings.h        previewgenerator.h
     154HEADERS += audiopropsgenerator.h
    154155HEADERS += transporteditor.h        listingsources.h
    155156HEADERS += myth_imgconvert.h
    156157HEADERS += channelgroup.h           channelgroupsettings.h
     
    173174SOURCES += viewschdiff.cpp
    174175SOURCES += livetvchain.cpp          playgroup.cpp
    175176SOURCES += channelsettings.cpp      previewgenerator.cpp
     177SOURCES += audiopropsgenerator.cpp
    176178SOURCES += transporteditor.cpp
    177179SOURCES += channelgroup.cpp         channelgroupsettings.cpp
    178180SOURCES += myth_imgconvert.cpp
  • libs/libmythtv/nuppeldecoder.h

     
    5252    QString GetCodecDecoderName(void) const { return "nuppel"; }
    5353    MythCodecID GetVideoCodecID(void) const;
    5454
     55    int GetAudioProperties(void);
     56
    5557  private:
    5658    inline bool ReadFileheader(struct rtfileheader *fileheader);
    5759    inline bool ReadFrameheader(struct rtframeheader *frameheader);
  • libs/libmythtv/NuppelVideoPlayer.h

     
    211211    QString   GetXDS(const QString &key) const;
    212212    bool      GetAudioBufferStatus(uint &fill, uint &total) const;
    213213    PIPLocation GetNextPIPLocation(void) const;
     214    int       GetAudioProperties(void);
    214215
    215216    // Bool Gets
    216217    bool    GetRawAudioState(void) const;
  • libs/libmythtv/decoderbase.cpp

     
    886886    return currentTrack[type];
    887887}
    888888
     889/** \fn DecoderBase::GetAudioPropertiesFromContext(AVCodecContext *context)
     890 *  \brief Get Audio Properties Enum from context object
     891 *
     892 *  \return int with bitwise properties, -1 otherwise
     893 */
     894int DecoderBase::GetAudioPropertiesFromContext(AVCodecContext *context)
     895{
     896    int props = 0;
     897    // mmake sure there's a context
     898    if (!context)
     899    {
     900        VERBOSE(VB_IMPORTANT, LOC + QString("No context; ignoring audio props"));
     901        return -1;
     902    }
     903
     904    // use the channel_layout to approximate the data sound type
     905    // we can't use channels because it gets overwritten in AutoSelectAudioTrack
     906    int channel_layout = context->channel_layout;
     907
     908    VERBOSE(VB_AUDIO, LOC + QString("Channel Layout: %1").arg(channel_layout));
     909
     910    // assume DOLBY
     911    if (    (channel_layout & CH_LAYOUT_5POINT1) == CH_LAYOUT_5POINT1 )
     912    {
     913        VERBOSE(VB_AUDIO, LOC + QString("Found DOLBY"));
     914        props |= AUD_DOLBY;
     915    }
     916
     917    // assume SURROUND
     918    else if ( (channel_layout & CH_LAYOUT_SURROUND) == CH_LAYOUT_SURROUND)
     919    {
     920        VERBOSE(VB_AUDIO, LOC + QString("Found SURROUND"));
     921        props |= AUD_SURROUND;
     922    }
     923
     924    // assume stereo
     925    else if ( (channel_layout & CH_LAYOUT_STEREO) == CH_LAYOUT_STEREO )
     926    {
     927        VERBOSE(VB_AUDIO, LOC + QString("Found STEREO"));
     928        props |= AUD_STEREO;
     929    }
     930
     931    // assume mono
     932    else if ((channel_layout & CH_LAYOUT_MONO) == CH_LAYOUT_MONO)
     933    {
     934        VERBOSE(VB_AUDIO, LOC + QString("Found MONO"));
     935        props |= AUD_MONO;
     936    }
     937   
     938    // otherwise unknown
     939    else
     940    {
     941        VERBOSE(VB_AUDIO, LOC + QString("Found UNKNOWN"));
     942        props |= AUD_UNKNOWN;
     943    }
     944
     945    return props;
     946}
     947
    889948StreamInfo DecoderBase::GetTrackInfo(uint type, uint trackNo) const
    890949{
    891950    QMutexLocker locker(avcodeclock);
     
    915974    return true;
    916975}
    917976
     977
     978
    918979/** \fn DecoderBase::AutoSelectTrack(uint)
    919980 *  \brief Select best track.
    920981 *
  • libs/libmythtv/avformatdecoder.h

     
    200200    bool GenerateDummyVideoFrame(void);
    201201    bool HasVideo(const AVFormatContext *ic);
    202202
     203    virtual int GetAudioProperties(void);
     204
    203205  private:
    204206    class AvFormatDecoderPrivate *d;
    205207
  • libs/libmythtv/tv_rec.cpp

     
    3030#include "eitscanner.h"
    3131#include "RingBuffer.h"
    3232#include "previewgenerator.h"
     33#include "audiopropsgenerator.h"
    3334#include "storagegroup.h"
    3435#include "remoteutil.h"
    3536#include "tvremoteutil.h"
     
    11201151        if (!killFile)
    11211152        {
    11221153            (new PreviewGenerator(curRecording, PreviewGenerator::kLocal))->Start();
     1154            (new AudioPropsGenerator(curRecording))->Start();
    11231155
    11241156            if (!tvchain)
    11251157            {
  • libs/libmythtv/audiopropsgenerator.h

     
     1// -*- Mode: c++ -*-
     2#ifndef AUDIOPROPS_GENERATOR_H_
     3#define AUDIOPROPS_GENERATOR_H_
     4
     5#include <pthread.h>
     6
     7#include <QMutex>
     8#include <QString>
     9
     10#include "programinfo.h"
     11
     12class MPUBLIC AudioPropsGenerator : public QObject
     13{
     14    Q_OBJECT
     15
     16  public:
     17    AudioPropsGenerator(const ProgramInfo *pginfo);
     18
     19    void Start(void);
     20    bool Run(void);
     21
     22  signals:
     23    void audioPropsThreadDone(const ProgramInfo*);
     24    void audioPropsReady(const ProgramInfo*);
     25
     26  protected:
     27    virtual ~AudioPropsGenerator();
     28    bool UpdateAudioProps(void);
     29    void disconnectSafe(void);
     30    void AttachSignals(QObject *);
     31    static void *AudioPropsRun(void*);
     32
     33  protected:
     34    QMutex             audioPropsLock;
     35    pthread_t          audioPropsThread;
     36    ProgramInfo        programInfo;
     37};
     38
     39#endif //AUDIOPROPS_GENERATOR_H_
  • libs/libmythtv/dummydecoder.h

     
    3030    virtual MythCodecID GetVideoCodecID(void) const { return kCodec_NONE; }
    3131
    3232    virtual bool SyncPositionMap(void) { return false; }
     33
     34    virtual int GetAudioProperties(void) { return -1; }
    3335};
    3436
    3537#endif
  • libs/libmyth/programinfo.h

     
    1616#include "mythdbcon.h"
    1717
    1818MPUBLIC extern const char *kPreviewGeneratorInUseID;
     19MPUBLIC extern const char *kAudioInspectorInUseID;
    1920
    2021typedef QHash<QString,QString> InfoMap;
    2122
     
    365366    int GetHeight(void);
    366367    void SetVidpropHeight(int width);
    367368
     369    // Audio Set
     370    void SaveAudioProps(int props);
     371
    368372    // In-use, autodeletion prevention stuff
    369373    void MarkAsInUse(bool inuse, QString usedFor = "");
    370374
  • libs/libmyth/programinfo.cpp

     
    3333#define LOC_ERR QString("ProgramInfo, Error: ")
    3434
    3535const char *kPreviewGeneratorInUseID = "preview_generator";
     36const char *kAudioInspectorInUseID = "audio_inspector";
    3637
    3738// works only for integer divisors of 60
    3839static const uint kUnknownProgramLength = 30;
     
    28762877    return m_videoWidth;
    28772878}
    28782879
     2880/** \fn ProgramInfo::SaveAudioProps(int props)
     2881 *  \brief Saves the audio properties to DB
     2882 */
     2883void ProgramInfo::SaveAudioProps(int props)
     2884{
     2885    // first set the props in the object
     2886    audioproperties = props;
     2887
     2888    // next write it to the DB
     2889    MSqlQuery query(MSqlQuery::InitCon());
     2890
     2891    VERBOSE(VB_AUDIO, QString("Setting Audio Props %1").arg(props));
     2892    query.prepare("UPDATE recordedprogram SET audioprop ="
     2893    " :PROP WHERE chanid = :CHANID AND starttime = :STARTTIME;");
     2894
     2895    query.bindValue(":PROP", props);
     2896    query.bindValue(":CHANID", chanid);
     2897    query.bindValue(":STARTTIME", startts);
     2898
     2899    if (!query.exec())
     2900        MythDB::DBError("UpdateRes", query);
     2901
     2902}
     2903
     2904
    28792905/** \fn ProgramInfo::SetVidpropHeight(int width)
    28802906 *  \brief Sets overall average height flag in videoprops.
    28812907 */