diff options
Diffstat (limited to 'abs/core-testing/mythtv')
-rw-r--r-- | abs/core-testing/mythtv/trunk/mythmusic/aacdecoder.cpp.patch (renamed from abs/core-testing/mythtv/trunk/mythtv/aacdecoder.cpp.patch) | 0 | ||||
-rwxr-xr-x | abs/core-testing/mythtv/trunk/mythtv/PKGBUILD | 12 | ||||
-rw-r--r-- | abs/core-testing/mythtv/trunk/mythtv/hdpvr-livetv.patch | 109 | ||||
-rw-r--r-- | abs/core-testing/mythtv/trunk/mythtv/hdpvr_audio_codec_selection-v1.1.diff | 96 | ||||
-rw-r--r-- | abs/core-testing/mythtv/trunk/mythtv/mpegrecorder-hdpvr-v2a.patch | 668 |
5 files changed, 102 insertions, 783 deletions
diff --git a/abs/core-testing/mythtv/trunk/mythtv/aacdecoder.cpp.patch b/abs/core-testing/mythtv/trunk/mythmusic/aacdecoder.cpp.patch index 8796eb4..8796eb4 100644 --- a/abs/core-testing/mythtv/trunk/mythtv/aacdecoder.cpp.patch +++ b/abs/core-testing/mythtv/trunk/mythmusic/aacdecoder.cpp.patch diff --git a/abs/core-testing/mythtv/trunk/mythtv/PKGBUILD b/abs/core-testing/mythtv/trunk/mythtv/PKGBUILD index 4277f16..4c03923 100755 --- a/abs/core-testing/mythtv/trunk/mythtv/PKGBUILD +++ b/abs/core-testing/mythtv/trunk/mythtv/PKGBUILD @@ -1,6 +1,6 @@ pkgname=mythtv-svn -pkgver=19974 -pkgrel=3 +pkgver=20018 +pkgrel=1 pkgdesc="A personal video recorder for Linux" url="http://www.mythtv.org" license="GPL" @@ -10,16 +10,16 @@ makedepends=('libgl' 'subversion') conflicts=('mythtv') replaces=() groups=('pvr') -backup=() +#backup=() #options=(!strip) #MAKEFLAGS="-j6" install='mythtv.install' -patchs=('smolt_jump.patch' 'DeviceReadBuffer-polltimeout.2.patch' 'mpegrecorder-hdpvr-v2a.patch' 'hdpvr-livetv.patch') -#patchs=('svn_main_menu_popup.patch' 'smolt_jump.patch' 'DeviceReadBuffer-polltimeout.2.patch' 'mpegrecorder-hdpvr-v2a.patch' 'hdpvr-livetv.patch') +patchs=('smolt_jump.patch' 'DeviceReadBuffer-polltimeout.2.patch' 'hdpvr_audio_codec_selection-v1.1.diff') +#patchs=('svn_main_menu_popup.patch' 'smolt_jump.patch' 'DeviceReadBuffer-polltimeout.2.patch' 'hdpvr_audio_codec_selection-v1.1.diff') source=('mythbackend' 'myth.sh' `echo ${patchs[@]:0}` ) arch=('i686' 'x86_64') -md5sums=() +#md5sums=() _svntrunk=http://cvs.mythtv.org/svn/trunk/mythtv _svnmod=mythtv diff --git a/abs/core-testing/mythtv/trunk/mythtv/hdpvr-livetv.patch b/abs/core-testing/mythtv/trunk/mythtv/hdpvr-livetv.patch deleted file mode 100644 index 6297ae1..0000000 --- a/abs/core-testing/mythtv/trunk/mythtv/hdpvr-livetv.patch +++ /dev/null @@ -1,109 +0,0 @@ -Index: libs/libmythtv/mpegrecorder.cpp -=================================================================== ---- libs/libmythtv/mpegrecorder.cpp.orig -+++ libs/libmythtv/mpegrecorder.cpp -@@ -1109,6 +1109,14 @@ void MpegRecorder::StartRecording(void) - - if (driver == "hdpvr") - { -+ if (curRecording->recgroup == "LiveTV") -+ { -+ // Don't bother checking resolution, always use best bitrate -+ int maxbitrate = std::max(high_mpeg4peakbitrate, -+ high_mpeg4avgbitrate); -+ SetBitrate(high_mpeg4avgbitrate, maxbitrate, "LiveTV"); -+ } -+ - int progNum = 1; - MPEGStreamData *sd = new MPEGStreamData(progNum, true); - sd->SetRecordingType(_recording_type); -@@ -1553,7 +1561,7 @@ bool MpegRecorder::StartEncoding(int fd) - memset(&command, 0, sizeof(struct v4l2_encoder_cmd)); - command.cmd = V4L2_ENC_CMD_START; - -- if (driver == "hdpvr") -+ if (driver == "hdpvr" && curRecording->recgroup != "LiveTV") - HandleResolutionChanges(); - - VERBOSE(VB_RECORD, LOC + "StartEncoding"); -@@ -1755,6 +1763,35 @@ bool MpegRecorder::WaitFor_HDPVR(void) - return false; - } - -+void MpegRecorder::SetBitrate(int bitrate, int maxbitrate, -+ const QString & reason) -+{ -+ if (maxbitrate == bitrate) -+ { -+ VERBOSE(VB_RECORD, LOC + QString("%1 bitrate %2 kbps CBR") -+ .arg(reason).arg(bitrate)); -+ } -+ else -+ { -+ VERBOSE(VB_RECORD, LOC + QString("%1 bitrate %2/%3 kbps VBR") -+ .arg(reason).arg(bitrate).arg(maxbitrate)); -+ } -+ -+ vector<struct v4l2_ext_control> ext_ctrls; -+ add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_BITRATE_MODE, -+ (maxbitrate == bitrate) ? -+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR : -+ V4L2_MPEG_VIDEO_BITRATE_MODE_VBR); -+ -+ add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_BITRATE, -+ bitrate * 1000); -+ -+ add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, -+ maxbitrate * 1000); -+ -+ set_ctrls(readfd, ext_ctrls); -+} -+ - void MpegRecorder::HandleResolutionChanges(void) - { - VERBOSE(VB_RECORD, LOC + "Checking Resolution"); -@@ -1819,30 +1856,7 @@ void MpegRecorder::HandleResolutionChang - .arg(old_avg).arg(old_max)); - } - -- if (maxbitrate == bitrate) -- { -- VERBOSE(VB_RECORD, LOC + QString("New bitrate %1 kbps CBR") -- .arg(bitrate)); -- } -- else -- { -- VERBOSE(VB_RECORD, LOC + QString("New bitrate %1/%2 kbps VBR") -- .arg(bitrate).arg(maxbitrate)); -- } -- -- vector<struct v4l2_ext_control> ext_ctrls; -- add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_BITRATE_MODE, -- (maxbitrate == bitrate) ? -- V4L2_MPEG_VIDEO_BITRATE_MODE_CBR : -- V4L2_MPEG_VIDEO_BITRATE_MODE_VBR); -- -- add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_BITRATE, -- bitrate * 1000); -- -- add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, -- maxbitrate * 1000); -- -- set_ctrls(readfd, ext_ctrls); -- -+ SetBitrate(bitrate, maxbitrate, "New"); - } - } -+ -Index: libs/libmythtv/mpegrecorder.h -=================================================================== ---- libs/libmythtv/mpegrecorder.h.orig -+++ libs/libmythtv/mpegrecorder.h -@@ -87,6 +87,7 @@ class MpegRecorder : public DTVRecorder, - void ResetForNewFile(void); - - bool WaitFor_HDPVR(void); -+ void SetBitrate(int bitrate, int maxbitrate, const QString & reason); - void HandleResolutionChanges(void); - - inline bool CheckCC(uint pid, uint cc); diff --git a/abs/core-testing/mythtv/trunk/mythtv/hdpvr_audio_codec_selection-v1.1.diff b/abs/core-testing/mythtv/trunk/mythtv/hdpvr_audio_codec_selection-v1.1.diff new file mode 100644 index 0000000..7589dd3 --- /dev/null +++ b/abs/core-testing/mythtv/trunk/mythtv/hdpvr_audio_codec_selection-v1.1.diff @@ -0,0 +1,96 @@ +Index: libs/libmythtv/mpegrecorder.cpp +=================================================================== +--- libs/libmythtv/mpegrecorder.cpp (revision 19989) ++++ libs/libmythtv/mpegrecorder.cpp (working copy) +@@ -285,6 +285,13 @@ + QString("%1 is invalid").arg(value)); + } + } ++ else if (opt == "audiocodec") ++ { ++ if (value == "AAC Hardware Encoder") ++ audtype = 4; ++ else if (value == "AC3 Hardware Encoder") ++ audtype = 5; ++ } + else + { + RecorderBase::SetOption(opt, value); +@@ -340,6 +347,8 @@ + SetIntOption(profile, "medium_mpeg4peakbitrate"); + SetIntOption(profile, "high_mpeg4avgbitrate"); + SetIntOption(profile, "high_mpeg4peakbitrate"); ++ ++ SetStrOption(profile, "audiocodec"); + } + + // same as the base class, it just doesn't complain if an option is missing +@@ -829,6 +838,22 @@ + { + maxbitrate = high_mpeg4peakbitrate; + bitrate = high_mpeg4avgbitrate; ++ ++ // query supported audio codecs ++ struct v4l2_queryctrl qctrl; ++ qctrl.id = V4L2_CID_MPEG_AUDIO_ENCODING; ++ ++ if (ioctl(chanfd, VIDIOC_QUERYCTRL, &qctrl) < 0) ++ { ++ VERBOSE(VB_IMPORTANT, LOC_WARN + ++ "Unable to get supported audio codecs." + ENO); ++ } ++ else ++ { ++ uint audio_encoding = max(min(audtype-1, qctrl.maximum), qctrl.minimum); ++ add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_AUDIO_ENCODING, ++ audio_encoding); ++ } + } + maxbitrate = std::max(maxbitrate, bitrate); + +Index: libs/libmythtv/recordingprofile.cpp +=================================================================== +--- libs/libmythtv/recordingprofile.cpp (revision 19988) ++++ libs/libmythtv/recordingprofile.cpp (working copy) +@@ -424,6 +424,15 @@ + params->addChild(new SampleRate(parent)); + params->addChild(new BTTVVolume(parent)); + addTarget("Uncompressed", params); ++ ++ params = new VerticalConfigurationGroup(false); ++ params->setLabel("AC3 Hardware Encoder"); ++ addTarget("AC3 Hardware Encoder", params); ++ ++ params = new VerticalConfigurationGroup(false); ++ params->setLabel("AAC Hardware Encoder"); ++ addTarget("AAC Hardware Encoder", params); ++ + }; + + void selectCodecs(QString groupType) +@@ -432,6 +441,11 @@ + { + if (groupType == "MPEG") + codecName->addSelection("MPEG-2 Hardware Encoder"); ++ else if (groupType == "HDPVR") ++ { ++ codecName->addSelection("AC3 Hardware Encoder"); ++ codecName->addSelection("AAC Hardware Encoder"); ++ } + else + { + // V4L, TRANSCODE (and any undefined types) +@@ -1260,11 +1274,8 @@ + videoSettings = new VideoCompressionSettings(*this, profileName); + addChild(videoSettings); + +- if (type.toUpper() != "HDPVR") +- { +- audioSettings = new AudioCompressionSettings(*this, profileName); +- addChild(audioSettings); +- } ++ audioSettings = new AudioCompressionSettings(*this, profileName); ++ addChild(audioSettings); + + if (!profileName.isEmpty() && profileName.left(11) == "Transcoders") + { diff --git a/abs/core-testing/mythtv/trunk/mythtv/mpegrecorder-hdpvr-v2a.patch b/abs/core-testing/mythtv/trunk/mythtv/mpegrecorder-hdpvr-v2a.patch deleted file mode 100644 index dbef933..0000000 --- a/abs/core-testing/mythtv/trunk/mythtv/mpegrecorder-hdpvr-v2a.patch +++ /dev/null @@ -1,668 +0,0 @@ -Index: libs/libmythtv/DeviceReadBuffer.cpp -=================================================================== ---- libs/libmythtv/DeviceReadBuffer.cpp.orig -+++ libs/libmythtv/DeviceReadBuffer.cpp -@@ -169,7 +169,17 @@ bool DeviceReadBuffer::IsPaused(void) co - return paused; - } - --bool DeviceReadBuffer::WaitForUnpause(int timeout) -+bool DeviceReadBuffer::WaitForPaused(unsigned long timeout) -+{ -+ QMutexLocker locker(&lock); -+ -+ if (!paused) -+ pauseWait.wait(&lock, timeout); -+ -+ return paused; -+} -+ -+bool DeviceReadBuffer::WaitForUnpause(unsigned long timeout) - { - QMutexLocker locker(&lock); - -Index: libs/libmythtv/DeviceReadBuffer.h -=================================================================== ---- libs/libmythtv/DeviceReadBuffer.h.orig -+++ libs/libmythtv/DeviceReadBuffer.h -@@ -42,7 +42,8 @@ class DeviceReadBuffer - - void SetRequestPause(bool request); - bool IsPaused(void) const; -- bool WaitForUnpause(int timeout); -+ bool WaitForUnpause(unsigned long timeout); -+ bool WaitForPaused(unsigned long timeout); - - bool IsErrored(void) const { return error; } - bool IsEOF(void) const { return eof; } -Index: libs/libmythtv/mpegrecorder.cpp -=================================================================== ---- libs/libmythtv/mpegrecorder.cpp.orig -+++ libs/libmythtv/mpegrecorder.cpp -@@ -19,6 +19,7 @@ using namespace std; - #include <sys/stat.h> - #include <sys/ioctl.h> - #include <sys/time.h> -+#include <sys/poll.h> - - // avlib headers - extern "C" { -@@ -86,7 +87,7 @@ MpegRecorder::MpegRecorder(TVRec *rec) : - requires_special_pause(false), - // State - recording(false), encoding(false), -- needs_resolution(false), start_stop_encoding_lock(QMutex::Recursive), -+ start_stop_encoding_lock(QMutex::Recursive), - recording_wait_lock(), recording_wait(), - // Pausing state - cleartimeonpause(false), -@@ -493,12 +494,20 @@ bool MpegRecorder::OpenV4L2DeviceAsInput - - bool MpegRecorder::SetFormat(int chanfd) - { -+ uint idx; - struct v4l2_format vfmt; - bzero(&vfmt, sizeof(vfmt)); - - vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - -- if (ioctl(chanfd, VIDIOC_G_FMT, &vfmt) < 0) -+ for (idx = 0; idx < 20; ++idx) -+ { -+ if (ioctl(chanfd, VIDIOC_G_FMT, &vfmt) == 0) -+ break; -+ usleep(100 * 1000); -+ } -+ -+ if (idx == 10) - { - VERBOSE(VB_IMPORTANT, LOC_ERR + "Error getting format" + ENO); - return false; -@@ -507,7 +516,14 @@ bool MpegRecorder::SetFormat(int chanfd) - vfmt.fmt.pix.width = width; - vfmt.fmt.pix.height = height; - -- if (ioctl(chanfd, VIDIOC_S_FMT, &vfmt) < 0) -+ for (idx = 0; idx < 20; ++idx) -+ { -+ if (ioctl(chanfd, VIDIOC_S_FMT, &vfmt) == 0) -+ break; -+ usleep(100 * 1000); -+ } -+ -+ if (idx == 20) - { - VERBOSE(VB_IMPORTANT, LOC_ERR + "Error setting format" + ENO); - return false; -@@ -519,9 +535,18 @@ bool MpegRecorder::SetFormat(int chanfd) - /// Set audio language mode - bool MpegRecorder::SetLanguageMode(int chanfd) - { -+ uint idx; - struct v4l2_tuner vt; - bzero(&vt, sizeof(struct v4l2_tuner)); -- if (ioctl(chanfd, VIDIOC_G_TUNER, &vt) < 0) -+ -+ for (idx = 0; idx < 20; ++idx) -+ { -+ if (ioctl(chanfd, VIDIOC_G_TUNER, &vt) == 0) -+ break; -+ usleep(100 * 1000); -+ } -+ -+ if (idx == 20) - { - VERBOSE(VB_IMPORTANT, LOC_WARN + "Unable to get audio mode" + ENO); - return false; -@@ -555,7 +580,14 @@ bool MpegRecorder::SetLanguageMode(int c - success = false; - } - -- if (ioctl(chanfd, VIDIOC_S_TUNER, &vt) < 0) -+ for (idx = 0; idx < 20; ++idx) -+ { -+ if (ioctl(chanfd, VIDIOC_S_TUNER, &vt) == 0) -+ break; -+ usleep(100 * 1000); -+ } -+ -+ if (idx == 20) - { - VERBOSE(VB_IMPORTANT, LOC_WARN + "Unable to set audio mode" + ENO); - success = false; -@@ -567,9 +599,18 @@ bool MpegRecorder::SetLanguageMode(int c - bool MpegRecorder::SetRecordingVolume(int chanfd) - { - // Get volume min/max values -+ uint idx; - struct v4l2_queryctrl qctrl; - qctrl.id = V4L2_CID_AUDIO_VOLUME; -- if (ioctl(chanfd, VIDIOC_QUERYCTRL, &qctrl) < 0) -+ -+ for (idx = 0; idx < 20; ++idx) -+ { -+ if (ioctl(chanfd, VIDIOC_QUERYCTRL, &qctrl) == 0) -+ break; -+ usleep(100 * 1000); -+ } -+ -+ if (idx == 20) - { - VERBOSE(VB_IMPORTANT, LOC_WARN + - "Unable to get recording volume parameters(max/min)" + ENO + -@@ -588,7 +629,14 @@ bool MpegRecorder::SetRecordingVolume(in - ctrl.id = V4L2_CID_AUDIO_VOLUME; - ctrl.value = ctrl_volume; - -- if (ioctl(chanfd, VIDIOC_S_CTRL, &ctrl) < 0) -+ for (idx = 0; idx < 20; ++idx) -+ { -+ if (ioctl(chanfd, VIDIOC_S_CTRL, &ctrl) == 0) -+ break; -+ usleep(100 * 1000); -+ } -+ -+ if (idx == 20) - { - VERBOSE(VB_IMPORTANT, LOC_WARN + - "Unable to set recording volume" + ENO + "\n\t\t\t" + -@@ -771,6 +819,7 @@ static void set_ctrls(int fd, vector<str - - for (uint i = 0; i < ext_ctrls.size(); i++) - { -+ uint idx; - struct v4l2_ext_controls ctrls; - bzero(&ctrls, sizeof(struct v4l2_ext_controls)); - -@@ -780,7 +829,14 @@ static void set_ctrls(int fd, vector<str - ctrls.count = 1; - ctrls.controls = &ext_ctrls[i]; - -- if (ioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls) < 0) -+ for (idx = 0; idx < 20; ++idx) -+ { -+ if (ioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls) == 0) -+ break; -+ usleep(100 * 1000); -+ } -+ -+ if (idx == 20) - { - QMutexLocker locker(&control_description_lock); - VERBOSE(VB_IMPORTANT, QString("mpegrecorder.cpp:set_ctrls(): ") + -@@ -820,6 +876,30 @@ bool MpegRecorder::SetV4L2DeviceOptions( - { - maxbitrate = high_mpeg4peakbitrate; - bitrate = high_mpeg4avgbitrate; -+ -+ // query supported audio codecs and prefer AC3 -+ uint idx; -+ struct v4l2_queryctrl qctrl; -+ qctrl.id = V4L2_CID_MPEG_AUDIO_ENCODING; -+ -+ for (idx = 0; idx < 20; ++idx) -+ { -+ if (ioctl(chanfd, VIDIOC_QUERYCTRL, &qctrl) == 0) -+ break; -+ usleep(100 * 1000); -+ } -+ -+ if (idx == 20) -+ { -+ VERBOSE(VB_IMPORTANT, LOC_WARN + -+ "Unable to get supported audio codecs." + ENO); -+ } -+ else -+ { -+ if (qctrl.minimum != qctrl.maximum) -+ add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_AUDIO_ENCODING, -+ qctrl.maximum); -+ } - } - maxbitrate = std::max(maxbitrate, bitrate); - -@@ -843,10 +923,19 @@ bool MpegRecorder::SetV4L2DeviceOptions( - int audioinput = audiodevice.toUInt(&ok); - if (ok) - { -+ uint idx; - struct v4l2_audio ain; - bzero(&ain, sizeof(ain)); - ain.index = audioinput; -- if (ioctl(chanfd, VIDIOC_ENUMAUDIO, &ain) < 0) -+ -+ for (idx = 0; idx < 20; ++idx) -+ { -+ if (ioctl(chanfd, VIDIOC_ENUMAUDIO, &ain) == 0) -+ break; -+ usleep(100 * 1000); -+ } -+ -+ if (idx == 20) - { - VERBOSE(VB_IMPORTANT, LOC_WARN + - "Unable to get audio input."); -@@ -854,7 +943,15 @@ bool MpegRecorder::SetV4L2DeviceOptions( - else - { - ain.index = audioinput; -- if (ioctl(chanfd, VIDIOC_S_AUDIO, &ain) < 0) -+ -+ for (idx = 0; idx < 20; ++idx) -+ { -+ if (ioctl(chanfd, VIDIOC_S_AUDIO, &ain) == 0) -+ break; -+ usleep(100 * 1000); -+ } -+ -+ if (idx == 20) - { - VERBOSE(VB_IMPORTANT, LOC_WARN + - "Unable to set audio input."); -@@ -1042,17 +1139,26 @@ void MpegRecorder::StartRecording(void) - if (deviceIsMpegFile) - elapsedTimer.start(); - else if (_device_read_buffer) -- _device_read_buffer->Start(); -+ { -+ VERBOSE(VB_RECORD, LOC + "Initial startup of recorder"); - -- needs_resolution = (driver == "hdpvr"); -+ if (StartEncoding(readfd)) -+ _device_read_buffer->Start(); -+ else -+ { -+ VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to start recording"); -+ recording = false; -+ QMutexLocker locker(&recording_wait_lock); -+ recording_wait.wakeAll(); -+ _error = true; -+ } -+ } - - QByteArray vdevice = videodevice.toAscii(); - while (encoding && !_error) - { - if (PauseAndWait(100)) - continue; -- -- HandleResolutionChanges(); - - if (deviceIsMpegFile) - { -@@ -1096,35 +1202,7 @@ void MpegRecorder::StartRecording(void) - { - VERBOSE(VB_IMPORTANT, LOC_ERR + "Device error detected"); - -- _device_read_buffer->Stop(); -- -- QMutexLocker locker(&start_stop_encoding_lock); -- -- StopEncoding(readfd); -- -- // Make sure the next things in the file are a PAT & PMT -- if (_stream_data->PATSingleProgram() && -- _stream_data->PMTSingleProgram()) -- { -- bool tmp = _wait_for_keyframe_option; -- _wait_for_keyframe_option = false; -- HandleSingleProgramPAT(_stream_data->PATSingleProgram()); -- HandleSingleProgramPMT(_stream_data->PMTSingleProgram()); -- _wait_for_keyframe_option = tmp; -- } -- -- if (StartEncoding(readfd)) -- { -- _device_read_buffer->Start(); -- } -- else -- { -- if (0 != close(readfd)) -- VERBOSE(VB_IMPORTANT, LOC_ERR + "Close error" + ENO); -- -- // Force card to be reopened on next iteration.. -- readfd = -1; -- } -+ RestartEncoding(); - } - else if (_device_read_buffer->IsEOF()) - { -@@ -1222,6 +1300,8 @@ void MpegRecorder::StartRecording(void) - } - } - -+ VERBOSE(VB_RECORD, LOC + "StartRecording finishing up"); -+ - if (_device_read_buffer) - { - if (_device_read_buffer->IsRunning()) -@@ -1230,6 +1310,7 @@ void MpegRecorder::StartRecording(void) - delete _device_read_buffer; - _device_read_buffer = NULL; - } -+ - StopEncoding(readfd); - - FinishRecording(); -@@ -1379,19 +1460,14 @@ bool MpegRecorder::PauseAndWait(int time - - if (!paused) - { -+ VERBOSE(VB_RECORD, LOC + "PauseAndWait pause"); -+ - if (_device_read_buffer) - { - QMutex drb_lock; - drb_lock.lock(); -- - _device_read_buffer->SetRequestPause(true); -- -- pauseWait.wait(&drb_lock, timeout); -- } -- else -- { -- paused = true; -- pauseWait.wakeAll(); -+ _device_read_buffer->WaitForPaused(4000); - } - - // Some drivers require streaming to be disabled before -@@ -1399,32 +1475,76 @@ bool MpegRecorder::PauseAndWait(int time - if (requires_special_pause) - StopEncoding(readfd); - -+ paused = true; -+ pauseWait.wakeAll(); -+ - if (tvrec) - tvrec->RecorderPaused(); - } - - unpauseWait.wait(&waitlock, timeout); - } -- if (!request_pause) -+ -+ if (!request_pause && paused) - { -- if (paused) -+ VERBOSE(VB_RECORD, LOC + "PauseAndWait unpause"); -+ -+ if (driver == "hdpvr") - { -- // Some drivers require streaming to be disabled before -- // an input switch and other channel format setting. -- if (requires_special_pause) -- StartEncoding(readfd); -+ m_h264_parser.Reset(); -+ _wait_for_keyframe_option = true; -+ _seen_sps = false; -+ } - -- if (_device_read_buffer) -- _device_read_buffer->SetRequestPause(false); -+ // Some drivers require streaming to be disabled before -+ // an input switch and other channel format setting. -+ if (requires_special_pause) -+ StartEncoding(readfd); -+ -+ if (_device_read_buffer) -+ _device_read_buffer->SetRequestPause(false); -+ -+ if (_stream_data) -+ _stream_data->Reset(_stream_data->DesiredProgram()); - -- if (_stream_data) -- _stream_data->Reset(_stream_data->DesiredProgram()); -- } - paused = false; - } -+ - return paused; - } - -+void MpegRecorder::RestartEncoding(void) -+{ -+ VERBOSE(VB_RECORD, LOC + "RestartEncoding"); -+ -+ _device_read_buffer->Stop(); -+ -+ QMutexLocker locker(&start_stop_encoding_lock); -+ -+ StopEncoding(readfd); -+ -+ // Make sure the next things in the file are a PAT & PMT -+ if (_stream_data->PATSingleProgram() && -+ _stream_data->PMTSingleProgram()) -+ { -+ _wait_for_keyframe_option = false; -+ HandleSingleProgramPAT(_stream_data->PATSingleProgram()); -+ HandleSingleProgramPMT(_stream_data->PMTSingleProgram()); -+ } -+ -+ if (StartEncoding(readfd)) -+ { -+ _device_read_buffer->Start(); -+ } -+ else -+ { -+ if (0 != close(readfd)) -+ VERBOSE(VB_IMPORTANT, LOC_ERR + "Close error" + ENO); -+ -+ readfd = -1; -+ } -+} -+ - bool MpegRecorder::StartEncoding(int fd) - { - QMutexLocker locker(&start_stop_encoding_lock); -@@ -1433,13 +1553,22 @@ bool MpegRecorder::StartEncoding(int fd) - memset(&command, 0, sizeof(struct v4l2_encoder_cmd)); - command.cmd = V4L2_ENC_CMD_START; - -+ if (driver == "hdpvr") -+ HandleResolutionChanges(); -+ - VERBOSE(VB_RECORD, LOC + "StartEncoding"); -- needs_resolution = (driver == "hdpvr"); - -- for (int idx = 0; idx < 10; ++idx) -+ for (int idx = 0; idx < 20; ++idx) - { - if (ioctl(fd, VIDIOC_ENCODER_CMD, &command) == 0) - { -+ if (driver == "hdpvr") -+ { -+ m_h264_parser.Reset(); -+ _wait_for_keyframe_option = true; -+ _seen_sps = false; -+ } -+ - VERBOSE(VB_RECORD, LOC + "Encoding started"); - return true; - } -@@ -1450,7 +1579,7 @@ bool MpegRecorder::StartEncoding(int fd) - return false; - } - -- usleep(250 * 1000); -+ usleep(100 * 1000); - } - - VERBOSE(VB_IMPORTANT, LOC_ERR + "StartEncoding - giving up" + ENO); -@@ -1467,9 +1596,8 @@ bool MpegRecorder::StopEncoding(int fd) - - VERBOSE(VB_RECORD, LOC + "StopEncoding"); - -- for (int idx = 0; idx < 10; ++idx) -+ for (int idx = 0; idx < 20; ++idx) - { -- - if (ioctl(fd, VIDIOC_ENCODER_CMD, &command) == 0) - { - VERBOSE(VB_RECORD, LOC + "Encoding stopped"); -@@ -1482,7 +1610,7 @@ bool MpegRecorder::StopEncoding(int fd) - return false; - } - -- usleep(250 * 1000); -+ usleep(100 * 1000); - } - - VERBOSE(VB_IMPORTANT, LOC_ERR + "StopEncoding - giving up" + ENO); -@@ -1550,7 +1678,7 @@ void MpegRecorder::HandleSingleProgramPA - void MpegRecorder::HandleSingleProgramPMT(ProgramMapTable *pmt) - { - if (!pmt) --{ -+ { - return; - } - -@@ -1570,27 +1698,94 @@ void MpegRecorder::HandleSingleProgramPM - DTVRecorder::BufferedWrite(*(reinterpret_cast<TSPacket*>(&buf[i]))); - } - --void MpegRecorder::HandleResolutionChanges(void) -+bool MpegRecorder::WaitFor_HDPVR(void) - { -- if (!needs_resolution) -- return; -+ // After a resolution change, it can take the HD-PVR a few -+ // seconds before it is usable again. -+ -+ // Tell it to start encoding, then wait for it to actually feed us -+ // some data. -+ QMutexLocker locker(&start_stop_encoding_lock); -+ -+ -+ // Sleep any less than 1.5 seconds, and the HD-PVR will -+ // return the old resolution, when the resolution is changing. -+ usleep(1500 * 1000); - -+ struct v4l2_encoder_cmd command; -+ struct pollfd polls; -+ int idx; -+ -+ memset(&command, 0, sizeof(struct v4l2_encoder_cmd)); -+ command.cmd = V4L2_ENC_CMD_START; -+ -+ for (idx = 0; idx < 20; ++idx) -+ { -+ if (ioctl(readfd, VIDIOC_ENCODER_CMD, &command) == 0) -+ break; -+ usleep(100 * 1000); -+ } -+ -+ if (idx == 20) -+ return false; -+ -+ polls.fd = readfd; -+ polls.events = POLLIN; -+ polls.revents = 0; -+ -+ for (idx = 0; idx < 10; ++idx) -+ { -+ if (poll(&polls, 1, 250) > 0) -+ break; -+ } -+ -+ if (idx == 10) -+ return false; -+ -+ // HD-PVR should now be "ready" -+ command.cmd = V4L2_ENC_CMD_STOP; -+ -+ for (idx = 0; idx < 20; ++idx) -+ { -+ if (ioctl(readfd, VIDIOC_ENCODER_CMD, &command) == 0) -+ return true; -+ usleep(100 * 1000); -+ } -+ -+ return false; -+} -+ -+void MpegRecorder::HandleResolutionChanges(void) -+{ - VERBOSE(VB_RECORD, LOC + "Checking Resolution"); - struct v4l2_format vfmt; - memset(&vfmt, 0, sizeof(vfmt)); - vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - -+ if (driver == "hdpvr") -+ WaitFor_HDPVR(); -+ -+ uint idx; - uint pix = 0; -+ -+ for (idx = 0; idx < 20; ++idx) -+ { - if (0 == ioctl(chanfd, VIDIOC_G_FMT, &vfmt)) - { - VERBOSE(VB_RECORD, LOC + QString("Got Resolution %1x%2") - .arg(vfmt.fmt.pix.width).arg(vfmt.fmt.pix.height)); - pix = vfmt.fmt.pix.width * vfmt.fmt.pix.height; -- needs_resolution = false; -+ break; -+ } -+ // Typically takes 0.9 seconds after a resolution change -+ usleep(100 * 1000); - } - - if (!pix) -+ { -+ VERBOSE(VB_RECORD, LOC + "Giving up detecting resolution"); - return; // nothing to do, we don't have a resolution yet -+ } - - int old_max = maxbitrate, old_avg = bitrate; - if (pix <= 768*568) -@@ -1648,12 +1843,6 @@ void MpegRecorder::HandleResolutionChang - maxbitrate * 1000); - - set_ctrls(readfd, ext_ctrls); -- } - -- // Restart streaming. Shouldn't be needed? seems to be with current driver. -- QMutexLocker locker(&start_stop_encoding_lock); -- StopEncoding(readfd); -- StartEncoding(readfd); -- -- needs_resolution = false; -+ } - } -Index: libs/libmythtv/mpegrecorder.h -=================================================================== ---- libs/libmythtv/mpegrecorder.h.orig -+++ libs/libmythtv/mpegrecorder.h -@@ -80,11 +80,13 @@ class MpegRecorder : public DTVRecorder, - uint GetFilteredAudioLayer(void) const; - uint GetFilteredAudioBitRate(uint audio_layer) const; - -+ void RestartEncoding(void); - bool StartEncoding(int fd); - bool StopEncoding(int fd); - - void ResetForNewFile(void); - -+ bool WaitFor_HDPVR(void); - void HandleResolutionChanges(void); - - inline bool CheckCC(uint pid, uint cc); -@@ -104,7 +106,6 @@ class MpegRecorder : public DTVRecorder, - // State - bool recording; - bool encoding; -- bool needs_resolution; - mutable QMutex start_stop_encoding_lock; - QMutex recording_wait_lock; - QWaitCondition recording_wait; -@@ -113,7 +114,7 @@ class MpegRecorder : public DTVRecorder, - bool cleartimeonpause; - - // Encoding info -- int width, height; -+ uint width, height; - int bitrate, maxbitrate, streamtype, aspectratio; - int audtype, audsamplerate, audbitratel1, audbitratel2, audbitratel3; - int audvolume; |