Ticket #7659: audioprops.100526.patch

File audioprops.100526.patch, 19.5 KB (added by Doug Haber <doug@…>, 14 years ago)

This patch should apply against 24875 (post hdaudio merge)

  • libs/libmythtv/nuppeldecoder.cpp

     
    13321332    return true;
    13331333}
    13341334
     1335int NuppelDecoder::GetAudioProperties(void)
     1336{
     1337    VERBOSE(VB_AUDIO, LOC + QString("Getting Nuppel Audio Props"));
     1338     
     1339    if (!mpa_audctx)
     1340    {
     1341        VERBOSE(VB_AUDIO, LOC + QString("No Audio Context, ignoring audio props"));
     1342        return -1;
     1343    }
     1344
     1345    int props = GetAudioPropertiesFromContext(mpa_audctx);
     1346
     1347    // no way to find AUD_HARDHEAR so ignore
     1348    // DH: I don't know what AUD_VISUALIMPAIR is so ignore
     1349
     1350    return props;
     1351}
     1352
    13351353void NuppelDecoder::SeekReset(long long newKey, uint skipFrames,
    13361354                              bool doFlush, bool discardFrames)
    13371355{
  • libs/libmythtv/NuppelVideoPlayer.cpp

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

     
    187187
    188188    virtual QString GetXDS(const QString&) const { return QString::null; }
    189189
     190    virtual int GetAudioProperties(void) = 0;
     191
     192    int GetAudioPropertiesFromContext(AVCodecContext *context);
     193
    190194    // MHEG/MHI stuff
    191195    virtual bool SetAudioByComponentTag(int) { return false; }
    192196    virtual bool SetVideoByComponentTag(int) { return false; }
  • libs/libmythtv/avformatdecoder.cpp

     
    20952095                VERBOSE(VB_GENERAL, LOC + QString("codec %1 has %2 channels")
    20962096                        .arg(codec_id_string(enc->codec_id))
    20972097                        .arg(enc->channels));
    2098 
    20992098#if 0
    21002099                // HACK MULTICHANNEL DTS passthru disabled for multichannel,
    21012100                // dont know how to handle this
     
    46824681    return passthru;
    46834682}
    46844683
     4684// returns the AudioProperties for the current data
     4685int AvFormatDecoder::GetAudioProperties(void)
     4686{
     4687    VERBOSE(VB_AUDIO, LOC + QString("Getting AFD Audio Props"));
     4688
     4689    if (!ic)
     4690    {
     4691        VERBOSE(VB_IMPORTANT, LOC + QString("No FormatContext, ignoring audio props"));
     4692        return -1;
     4693    }
     4694   
     4695    int props = 0;
     4696
     4697    // first try to find audio properties form the audio tracks
     4698    sinfo_vec_t::iterator it = tracks[kTrackTypeAudio].begin();
     4699    for (; it != tracks[kTrackTypeAudio].end(); ++it)
     4700    // for (uint i = 0; i < ic->nb_streams; i++)
     4701    {
     4702        //AVStream *stream = ic->streams[i];
     4703        AVStream *stream = ic->streams[it->av_stream_index];
     4704        int i = it->av_stream_index;
     4705
     4706        VERBOSE(VB_AUDIO, LOC + QString("Inspecting Audio Stream id #%1 ").arg(i));
     4707
     4708        // make sure there's a stream
     4709        if (!stream)
     4710        {
     4711             VERBOSE(VB_IMPORTANT, LOC + QString("No Stream for Stream id #%1").arg(i));
     4712             continue;
     4713        }
     4714
     4715        AVCodecContext *codec = stream->codec;
     4716
     4717        // mmake sure there's a codec
     4718        if (!codec)
     4719        {
     4720             VERBOSE(VB_IMPORTANT, LOC + QString("No Codec for Stream id #%1").arg(i));
     4721             continue;
     4722        }
     4723
     4724        props |= GetAudioPropertiesFromContext(codec);
     4725    }
     4726
     4727    // if there are any of these assume hard hearing
     4728    int track_count = kTrackTypeCount;
     4729    if (
     4730         (track_count >= kTrackTypeSubtitle         && tracks[kTrackTypeSubtitle].size() > 0)         ||
     4731         (track_count >= kTrackTypeCC608            && tracks[kTrackTypeCC608].size() > 0)            ||
     4732         (track_count >= kTrackTypeCC708            && tracks[kTrackTypeCC708].size() > 0)            ||
     4733         (track_count >= kTrackTypeTeletextCaptions && tracks[kTrackTypeTeletextCaptions].size() > 0) ||
     4734         (track_count >= kTrackTypeTeletextMenu     && tracks[kTrackTypeTeletextMenu].size() > 0)     ||
     4735         (track_count >= kTrackTypeTextSubtitle     && tracks[kTrackTypeTextSubtitle].size() > 0)     
     4736        )
     4737    {
     4738            VERBOSE(VB_AUDIO, LOC + QString("Found HARDHEARING Track"));
     4739            props |= AUD_HARDHEAR;
     4740    }
     4741
     4742    // DH: I don't know what AUD_VISUALIMPAIR is, so ignore it
     4743
     4744    return props;
     4745}
     4746
    46854747/** \fn AvFormatDecoder::SetupAudioStream(void)
    46864748 *  \brief Reinitializes audio if it needs to be reinitialized.
    46874749 *
     
    47604822    if (info == audioIn)
    47614823        return false; // no change
    47624824
    4763     VERBOSE(VB_AUDIO, LOC + "Initializing audio parms from " +
     4825    VERBOSE(VB_AUDIO, LOC + "Initializing audio params from " +
    47644826            QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1));
    47654827
    47664828    audioOut = audioIn = info;
  • libs/libmythtv/libmythtv.pro

     
    153153HEADERS += signalmonitorvalue.h     signalmonitorlistener.h
    154154HEADERS += livetvchain.h            playgroup.h
    155155HEADERS += channelsettings.h        previewgenerator.h
     156HEADERS += audiopropsgenerator.h
    156157HEADERS += transporteditor.h        listingsources.h
    157158HEADERS += myth_imgconvert.h
    158159HEADERS += channelgroup.h           channelgroupsettings.h
     
    176177SOURCES += signalmonitorvalue.cpp
    177178SOURCES += livetvchain.cpp          playgroup.cpp
    178179SOURCES += channelsettings.cpp      previewgenerator.cpp
     180SOURCES += audiopropsgenerator.cpp
    179181SOURCES += transporteditor.cpp
    180182SOURCES += channelgroup.cpp         channelgroupsettings.cpp
    181183SOURCES += myth_imgconvert.cpp
  • libs/libmythtv/nuppeldecoder.h

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

     
    196196    QString   GetXDS(const QString &key) const;
    197197    bool      GetAudioBufferStatus(uint &fill, uint &total) const;
    198198    PIPLocation GetNextPIPLocation(void) const;
     199    int       GetAudioProperties(void);
    199200
    200201    // Bool Gets
    201202    bool    GetRawAudioState(void) const;
  • libs/libmythtv/decoderbase.cpp

     
    991991    return currentTrack[type];
    992992}
    993993
     994/** \fn DecoderBase::GetAudioPropertiesFromContext(AVCodecContext *context)
     995 *  \brief Get Audio Properties Enum from context object
     996 *
     997 *  \return int with bitwise properties, -1 otherwise
     998 */
     999int DecoderBase::GetAudioPropertiesFromContext(AVCodecContext *context)
     1000{
     1001    int props = 0;
     1002    // mmake sure there's a context
     1003    if (!context)
     1004    {
     1005        VERBOSE(VB_IMPORTANT, LOC + QString("No context; ignoring audio props"));
     1006        return -1;
     1007    }
     1008
     1009    // use the channel_layout to approximate the data sound type
     1010    // we can't use channels because it gets overwritten in AutoSelectAudioTrack
     1011    int channel_layout = context->channel_layout;
     1012
     1013    VERBOSE(VB_AUDIO, LOC + QString("Channel Layout: %1").arg(channel_layout));
     1014
     1015    // assume DOLBY
     1016    if (    (channel_layout & CH_LAYOUT_5POINT1) == CH_LAYOUT_5POINT1 )
     1017    {
     1018        VERBOSE(VB_AUDIO, LOC + QString("Found DOLBY"));
     1019        props |= AUD_DOLBY;
     1020    }
     1021
     1022    // assume SURROUND
     1023    else if ( (channel_layout & CH_LAYOUT_SURROUND) == CH_LAYOUT_SURROUND)
     1024    {
     1025        VERBOSE(VB_AUDIO, LOC + QString("Found SURROUND"));
     1026        props |= AUD_SURROUND;
     1027    }
     1028
     1029    // assume stereo
     1030    else if ( (channel_layout & CH_LAYOUT_STEREO) == CH_LAYOUT_STEREO )
     1031    {
     1032        VERBOSE(VB_AUDIO, LOC + QString("Found STEREO"));
     1033        props |= AUD_STEREO;
     1034    }
     1035
     1036    // assume mono
     1037    else if ((channel_layout & CH_LAYOUT_MONO) == CH_LAYOUT_MONO)
     1038    {
     1039        VERBOSE(VB_AUDIO, LOC + QString("Found MONO"));
     1040        props |= AUD_MONO;
     1041    }
     1042   
     1043    // otherwise unknown
     1044    else
     1045    {
     1046        VERBOSE(VB_AUDIO, LOC + QString("Found UNKNOWN"));
     1047        props |= AUD_UNKNOWN;
     1048    }
     1049
     1050    return props;
     1051}
     1052
    9941053StreamInfo DecoderBase::GetTrackInfo(uint type, uint trackNo) const
    9951054{
    9961055    QMutexLocker locker(avcodeclock);
     
    10201079    return true;
    10211080}
    10221081
     1082
     1083
    10231084/** \fn DecoderBase::AutoSelectTrack(uint)
    10241085 *  \brief Select best track.
    10251086 *
  • libs/libmythtv/avformatdecoder.h

     
    219219    bool GenerateDummyVideoFrame(void);
    220220    bool HasVideo(const AVFormatContext *ic);
    221221
     222    virtual int GetAudioProperties(void);
     223
    222224  private:
    223225    class AvFormatDecoderPrivate *d;
    224226
  • libs/libmythtv/tv_rec.cpp

     
    2727#include "eitscanner.h"
    2828#include "RingBuffer.h"
    2929#include "previewgenerator.h"
     30#include "audiopropsgenerator.h"
    3031#include "storagegroup.h"
    3132#include "remoteutil.h"
    3233#include "tvremoteutil.h"
     
    11011102
    11021103        recorder->StopRecording();
    11031104        pthread_join(recorder_thread, NULL);
     1105
    11041106    }
    11051107    ClearFlags(kFlagRecorderRunning);
    11061108
     
    11251127                (new PreviewGenerator(
    11261128                    curRecording, PreviewGenerator::kLocal))->Start();
    11271129            }
     1130            (new AudioPropsGenerator(curRecording))->Start();
    11281131
    11291132            if (!tvchain)
    11301133            {
  • 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/programtypes.cpp

     
    1616const char *kTranscoderInUseID       = "transcoder";
    1717const char *kPreviewGeneratorInUseID = "preview_generator";
    1818const char *kJobQueueInUseID         = "jobqueue";
     19const char *kAudioGeneratorInUseID   = "audio_generator";
    1920
    2021QString toString(MarkTypes type)
    2122{
  • libs/libmyth/programinfo.h

     
    503503    bool        Reload(void);
    504504
    505505    // Slow DB sets
     506    void SaveAudioProps(int props);
    506507    void SaveFilesize(uint64_t fsize);
    507508    void SaveBookmark(uint64_t frame);
    508509    void SaveDVDBookmark(const QStringList &fields) const;
  • libs/libmyth/programinfo.cpp

     
    20482048    updater->insert(chanid, recstartts, kPIUpdateFileSize, fsize);
    20492049}
    20502050
     2051/** \fn ProgramInfo::SaveAudioProps(int props)
     2052 *  \brief Saves the audio properties to DB
     2053 */
     2054void ProgramInfo::SaveAudioProps(int props)
     2055{
     2056    // first set the props in the object
     2057    properties |= props;
     2058
     2059    // next write it to the DB
     2060    MSqlQuery query(MSqlQuery::InitCon());
     2061
     2062    VERBOSE(VB_AUDIO, QString("Setting Audio Props %1").arg(props));
     2063    query.prepare("UPDATE recordedprogram SET audioprop ="
     2064    " :PROP WHERE chanid = :CHANID AND starttime = :STARTTIME;");
     2065
     2066    query.bindValue(":PROP", props);
     2067    query.bindValue(":CHANID", chanid);
     2068    query.bindValue(":STARTTIME", startts);
     2069
     2070    if (!query.exec())
     2071        MythDB::DBError("UpdateRes", query);
     2072
     2073}
     2074
     2075
    20512076/// \brief Gets recording file size from database.
    20522077uint64_t ProgramInfo::QueryFilesize(void) const
    20532078{
  • libs/libmyth/programtypes.h

     
    3131MPUBLIC extern const char *kTranscoderInUseID;
    3232MPUBLIC extern const char *kPreviewGeneratorInUseID;
    3333MPUBLIC extern const char *kJobQueueInUseID;
     34MPUBLIC extern const char *kAudioGeneratorInUseID;
    3435
    3536typedef QHash<QString,QString> InfoMap;
    3637