Ticket #7659: audioprops.100526.patch
File audioprops.100526.patch, 19.5 KB (added by , 14 years ago) |
---|
-
libs/libmythtv/nuppeldecoder.cpp
1332 1332 return true; 1333 1333 } 1334 1334 1335 int 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 1335 1353 void NuppelDecoder::SeekReset(long long newKey, uint skipFrames, 1336 1354 bool doFlush, bool discardFrames) 1337 1355 { -
libs/libmythtv/NuppelVideoPlayer.cpp
8028 8028 osdtheme = themename; osdtheme.detach(); 8029 8029 } 8030 8030 8031 int 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 8031 8053 // EIA-708 caption support -- end 8032 8054 8033 8055 static 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 */ 34 AudioPropsGenerator::AudioPropsGenerator(const ProgramInfo *pginfo) 35 : programInfo(*pginfo) 36 { 37 VERBOSE(VB_AUDIO, LOC + QString("Constructing Audio Props Generator")); 38 } 39 40 AudioPropsGenerator::~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 50 void 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 */ 66 void 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 */ 75 void 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 82 bool 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 95 void *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 106 bool 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
187 187 188 188 virtual QString GetXDS(const QString&) const { return QString::null; } 189 189 190 virtual int GetAudioProperties(void) = 0; 191 192 int GetAudioPropertiesFromContext(AVCodecContext *context); 193 190 194 // MHEG/MHI stuff 191 195 virtual bool SetAudioByComponentTag(int) { return false; } 192 196 virtual bool SetVideoByComponentTag(int) { return false; } -
libs/libmythtv/avformatdecoder.cpp
2095 2095 VERBOSE(VB_GENERAL, LOC + QString("codec %1 has %2 channels") 2096 2096 .arg(codec_id_string(enc->codec_id)) 2097 2097 .arg(enc->channels)); 2098 2099 2098 #if 0 2100 2099 // HACK MULTICHANNEL DTS passthru disabled for multichannel, 2101 2100 // dont know how to handle this … … 4682 4681 return passthru; 4683 4682 } 4684 4683 4684 // returns the AudioProperties for the current data 4685 int 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 4685 4747 /** \fn AvFormatDecoder::SetupAudioStream(void) 4686 4748 * \brief Reinitializes audio if it needs to be reinitialized. 4687 4749 * … … 4760 4822 if (info == audioIn) 4761 4823 return false; // no change 4762 4824 4763 VERBOSE(VB_AUDIO, LOC + "Initializing audio par ms from " +4825 VERBOSE(VB_AUDIO, LOC + "Initializing audio params from " + 4764 4826 QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1)); 4765 4827 4766 4828 audioOut = audioIn = info; -
libs/libmythtv/libmythtv.pro
153 153 HEADERS += signalmonitorvalue.h signalmonitorlistener.h 154 154 HEADERS += livetvchain.h playgroup.h 155 155 HEADERS += channelsettings.h previewgenerator.h 156 HEADERS += audiopropsgenerator.h 156 157 HEADERS += transporteditor.h listingsources.h 157 158 HEADERS += myth_imgconvert.h 158 159 HEADERS += channelgroup.h channelgroupsettings.h … … 176 177 SOURCES += signalmonitorvalue.cpp 177 178 SOURCES += livetvchain.cpp playgroup.cpp 178 179 SOURCES += channelsettings.cpp previewgenerator.cpp 180 SOURCES += audiopropsgenerator.cpp 179 181 SOURCES += transporteditor.cpp 180 182 SOURCES += channelgroup.cpp channelgroupsettings.cpp 181 183 SOURCES += myth_imgconvert.cpp -
libs/libmythtv/nuppeldecoder.h
53 53 QString GetCodecDecoderName(void) const { return "nuppel"; } 54 54 MythCodecID GetVideoCodecID(void) const; 55 55 56 int GetAudioProperties(void); 57 56 58 private: 57 59 inline bool ReadFileheader(struct rtfileheader *fileheader); 58 60 inline bool ReadFrameheader(struct rtframeheader *frameheader); -
libs/libmythtv/NuppelVideoPlayer.h
196 196 QString GetXDS(const QString &key) const; 197 197 bool GetAudioBufferStatus(uint &fill, uint &total) const; 198 198 PIPLocation GetNextPIPLocation(void) const; 199 int GetAudioProperties(void); 199 200 200 201 // Bool Gets 201 202 bool GetRawAudioState(void) const; -
libs/libmythtv/decoderbase.cpp
991 991 return currentTrack[type]; 992 992 } 993 993 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 */ 999 int 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 994 1053 StreamInfo DecoderBase::GetTrackInfo(uint type, uint trackNo) const 995 1054 { 996 1055 QMutexLocker locker(avcodeclock); … … 1020 1079 return true; 1021 1080 } 1022 1081 1082 1083 1023 1084 /** \fn DecoderBase::AutoSelectTrack(uint) 1024 1085 * \brief Select best track. 1025 1086 * -
libs/libmythtv/avformatdecoder.h
219 219 bool GenerateDummyVideoFrame(void); 220 220 bool HasVideo(const AVFormatContext *ic); 221 221 222 virtual int GetAudioProperties(void); 223 222 224 private: 223 225 class AvFormatDecoderPrivate *d; 224 226 -
libs/libmythtv/tv_rec.cpp
27 27 #include "eitscanner.h" 28 28 #include "RingBuffer.h" 29 29 #include "previewgenerator.h" 30 #include "audiopropsgenerator.h" 30 31 #include "storagegroup.h" 31 32 #include "remoteutil.h" 32 33 #include "tvremoteutil.h" … … 1101 1102 1102 1103 recorder->StopRecording(); 1103 1104 pthread_join(recorder_thread, NULL); 1105 1104 1106 } 1105 1107 ClearFlags(kFlagRecorderRunning); 1106 1108 … … 1125 1127 (new PreviewGenerator( 1126 1128 curRecording, PreviewGenerator::kLocal))->Start(); 1127 1129 } 1130 (new AudioPropsGenerator(curRecording))->Start(); 1128 1131 1129 1132 if (!tvchain) 1130 1133 { -
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 12 class 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
30 30 virtual MythCodecID GetVideoCodecID(void) const { return kCodec_NONE; } 31 31 32 32 virtual bool SyncPositionMap(void) { return false; } 33 34 virtual int GetAudioProperties(void) { return -1; } 33 35 }; 34 36 35 37 #endif -
libs/libmyth/programtypes.cpp
16 16 const char *kTranscoderInUseID = "transcoder"; 17 17 const char *kPreviewGeneratorInUseID = "preview_generator"; 18 18 const char *kJobQueueInUseID = "jobqueue"; 19 const char *kAudioGeneratorInUseID = "audio_generator"; 19 20 20 21 QString toString(MarkTypes type) 21 22 { -
libs/libmyth/programinfo.h
503 503 bool Reload(void); 504 504 505 505 // Slow DB sets 506 void SaveAudioProps(int props); 506 507 void SaveFilesize(uint64_t fsize); 507 508 void SaveBookmark(uint64_t frame); 508 509 void SaveDVDBookmark(const QStringList &fields) const; -
libs/libmyth/programinfo.cpp
2048 2048 updater->insert(chanid, recstartts, kPIUpdateFileSize, fsize); 2049 2049 } 2050 2050 2051 /** \fn ProgramInfo::SaveAudioProps(int props) 2052 * \brief Saves the audio properties to DB 2053 */ 2054 void 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 2051 2076 /// \brief Gets recording file size from database. 2052 2077 uint64_t ProgramInfo::QueryFilesize(void) const 2053 2078 { -
libs/libmyth/programtypes.h
31 31 MPUBLIC extern const char *kTranscoderInUseID; 32 32 MPUBLIC extern const char *kPreviewGeneratorInUseID; 33 33 MPUBLIC extern const char *kJobQueueInUseID; 34 MPUBLIC extern const char *kAudioGeneratorInUseID; 34 35 35 36 typedef QHash<QString,QString> InfoMap; 36 37