After upgrading to VDR 2.0, I got Softdevice to almost work (see the mail archive a couple of months ago). Sometimes it is showing garbage (really random noise) on the MGA350 OSD layer; I can live with that, as this box is only used for infrequent recordings.
The last annoying problem is that going to the next or previous I-frame when editing (buttons 4 and 6 on the remote control) are not updating the video screen at all. Only the edit mark is moving on the OSD layer. If I press Play, it will start playing from the current edit mark. So, it is possible but much more clumsy to cut recordings.
SoftDevice is overriding the method with this:
void cSoftDevice::StillPicture(const uchar *Data, int Length) { SOFTDEB("StillPicture...\n"); if (decoder) decoder->StillPicture((uchar *)Data,Length); }
It seems to me that mpeg2decoder.c in softdevice is creating a new thread every time I try to move editing mark, and calling cMpeg2Decoder::Action(). In gdb, it will fail as follows:
while(ThreadActive) { while (freezeMode && ThreadActive) usleep(50000);
BUFDEB("av_read_frame start\n");
if (useAVReadFrame) ret = av_read_frame(ic, &pkt); else ret = av_read_packet(ic, &pkt);
if (ret < 0) { BUFDEB("cMpeg2Decoder Stream Error!\n"); if (ThreadActive) usleep(10000); continue; }
useAVReadFrame=true, so it is calling av_read_frame(). That will block when running under gdb, like this:
#2 0xb68f83a9 in cSigTimer::Sleep (this=0xb2c121f4, timeoutUS=50000, lowLimitUS=0) at sync-timer.c:75 #3 0xb68f1cf0 in cMpeg2Decoder::read_packet (this=this@entry=0xb2c120f0, buf=buf@entry=0x87fc5b0 "v\253T)\251z\366\020[\231a\202\275\237@\006\266\067k*r\370JV\255\364\020\177\247:\353 \004\024\277\004jhjG|] t$X", buf_size=buf_size@entry=10864) at mpeg2decoder.c:1128 #4 0xb68f1dcf in read_packet_RingBuffer (opaque=0xb2c120f0, buf=0x87fc5b0 "v\253T)\251z\366\020[\231a\202\275\237@\006\266\067k*r\370JV\255\364\020\177\247:\353 \004\024\277\004jhjG|] t$X", buf_size=10864) at mpeg2decoder.c:1042 #5 0xb69140c9 in fill_buffer (s=s@entry=0x85ac040) at libavformat/aviobuf.c:319 #6 0xb6916ff7 in get_byte (s=0x85ac040) at libavformat/aviobuf.c:365 #7 get_byte (s=s@entry=0x85ac040) at libavformat/aviobuf.c:360 #8 0xb6958984 in find_next_start_code (header_state=0x8a075e0, size_ptr=<synthetic pointer>, pb=0x85ac040) at libavformat/mpeg.c:142 #9 mpegps_read_pes_header (s=s@entry=0x89f2080, ppos=ppos@entry=0xb10cc190, pstart_code=pstart_code@entry=0xb10cc160, ppts=ppts@entry=0xb10cc170, pdts=pdts@entry=0xb10cc180) at libavformat/mpeg.c:246 #10 0xb695933a in mpegps_read_packet (s=0x89f2080, pkt=0xb10cc290) at libavformat/mpeg.c:419 #11 0xb690c3b4 in av_read_packet (s=s@entry=0x89f2080, pkt=pkt@entry=0xb10cc290) at libavformat/utils.c:591 #12 0xb690ce8b in av_read_frame_internal (s=0x89f2080, pkt=0xb10cc304) at libavformat/utils.c:998 #13 0xb68f2527 in cMpeg2Decoder::Action (this=0xb2c120f0) at mpeg2decoder.c:1228
It will unblock when I hit 4 or 6 again, because the thread would be killed (ThreadActive=false) by this:
#0 cMpeg2Decoder::Stop (this=this@entry=0xb2c120f0, GetMutex=GetMutex@entry=false) at mpeg2decoder.c:1545 #1 0xb68f2cec in cMpeg2Decoder::Clear (this=0xb2c120f0) at mpeg2decoder.c:1655 #2 0xb68ea1b6 in Clear (this=0x83d3130) at softdevice.c:492 #3 cSoftDevice::Clear (this=0x83d3130) at softdevice.c:484 #4 0x080cf2da in cDvbPlayer::Empty() () #5 0x080cf7e9 in cDvbPlayer::Goto(int, bool) () #6 0x080d1303 in cDvbPlayerControl::Goto(int, bool) () #7 0x080fd676 in cReplayControl::MarkMove(bool) () #8 0x080fdcc6 in cReplayControl::ProcessKey(eKeys) () #9 0x080aac39 in main ()
I wonder why this worked in VDR 1.6 but no longer in VDR 2.0? Is it because Softdevice is expecting a PES packet here instead of TS, or is it something else?
Marko
If you haven't done so already, please bring this to Johns (author of softhddevice) at the vdrportal forum.
Thanks
On Wed, Dec 25, 2013 at 6:50 AM, Marko Mäkelä marko.makela@iki.fi wrote:
After upgrading to VDR 2.0, I got Softdevice to almost work (see the mail archive a couple of months ago). Sometimes it is showing garbage (really random noise) on the MGA350 OSD layer; I can live with that, as this box is only used for infrequent recordings.
The last annoying problem is that going to the next or previous I-frame when editing (buttons 4 and 6 on the remote control) are not updating the video screen at all. Only the edit mark is moving on the OSD layer. If I press Play, it will start playing from the current edit mark. So, it is possible but much more clumsy to cut recordings.
SoftDevice is overriding the method with this:
void cSoftDevice::StillPicture(const uchar *Data, int Length) { SOFTDEB("StillPicture...\n"); if (decoder) decoder->StillPicture((uchar *)Data,Length); }
It seems to me that mpeg2decoder.c in softdevice is creating a new thread every time I try to move editing mark, and calling cMpeg2Decoder::Action(). In gdb, it will fail as follows:
while(ThreadActive) { while (freezeMode && ThreadActive) usleep(50000);
BUFDEB("av_read_frame start\n"); if (useAVReadFrame) ret = av_read_frame(ic, &pkt); else ret = av_read_packet(ic, &pkt); if (ret < 0) { BUFDEB("cMpeg2Decoder Stream Error!\n"); if (ThreadActive) usleep(10000); continue; }
useAVReadFrame=true, so it is calling av_read_frame(). That will block when running under gdb, like this:
#2 0xb68f83a9 in cSigTimer::Sleep (this=0xb2c121f4, timeoutUS=50000, lowLimitUS=0) at sync-timer.c:75 #3 0xb68f1cf0 in cMpeg2Decoder::read_packet (this=this@entry=0xb2c120f0, buf=buf@entry=0x87fc5b0 "v\253T)\251z\366\020[\231a\202\275\237@\006\266\067k*r\370JV\255\364\020\177\247:\353 \004\024\277\004jhjG|] t$X", buf_size=buf_size@entry=10864) at mpeg2decoder.c:1128 #4 0xb68f1dcf in read_packet_RingBuffer (opaque=0xb2c120f0, buf=0x87fc5b0 "v\253T)\251z\366\020[\231a\202\275\237@\006\266\067k*r\370JV\255\364\020\177\247:\353 \004\024\277\004jhjG|] t$X", buf_size=10864) at mpeg2decoder.c:1042 #5 0xb69140c9 in fill_buffer (s=s@entry=0x85ac040) at libavformat/aviobuf.c:319 #6 0xb6916ff7 in get_byte (s=0x85ac040) at libavformat/aviobuf.c:365 #7 get_byte (s=s@entry=0x85ac040) at libavformat/aviobuf.c:360 #8 0xb6958984 in find_next_start_code (header_state=0x8a075e0, size_ptr=<synthetic pointer>, pb=0x85ac040) at libavformat/mpeg.c:142 #9 mpegps_read_pes_header (s=s@entry=0x89f2080, ppos=ppos@entry=0xb10cc190, pstart_code=pstart_code@entry=0xb10cc160, ppts=ppts@entry=0xb10cc170, pdts=pdts@entry=0xb10cc180) at libavformat/mpeg.c:246 #10 0xb695933a in mpegps_read_packet (s=0x89f2080, pkt=0xb10cc290) at libavformat/mpeg.c:419 #11 0xb690c3b4 in av_read_packet (s=s@entry=0x89f2080, pkt=pkt@entry=0xb10cc290) at libavformat/utils.c:591 #12 0xb690ce8b in av_read_frame_internal (s=0x89f2080, pkt=0xb10cc304) at libavformat/utils.c:998 #13 0xb68f2527 in cMpeg2Decoder::Action (this=0xb2c120f0) at mpeg2decoder.c:1228
It will unblock when I hit 4 or 6 again, because the thread would be killed (ThreadActive=false) by this:
#0 cMpeg2Decoder::Stop (this=this@entry=0xb2c120f0, GetMutex=GetMutex@entry=false) at mpeg2decoder.c:1545 #1 0xb68f2cec in cMpeg2Decoder::Clear (this=0xb2c120f0) at mpeg2decoder.c:1655 #2 0xb68ea1b6 in Clear (this=0x83d3130) at softdevice.c:492 #3 cSoftDevice::Clear (this=0x83d3130) at softdevice.c:484 #4 0x080cf2da in cDvbPlayer::Empty() () #5 0x080cf7e9 in cDvbPlayer::Goto(int, bool) () #6 0x080d1303 in cDvbPlayerControl::Goto(int, bool) () #7 0x080fd676 in cReplayControl::MarkMove(bool) () #8 0x080fdcc6 in cReplayControl::ProcessKey(eKeys) () #9 0x080aac39 in main ()
I wonder why this worked in VDR 1.6 but no longer in VDR 2.0? Is it because Softdevice is expecting a PES packet here instead of TS, or is it something else?
Marko
vdr mailing list vdr@linuxtv.org http://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr
On Wed, Dec 25, 2013 at 12:23:23PM -0800, VDR User wrote:
If you haven't done so already, please bring this to Johns (author of softhddevice) at the vdrportal forum.
I did not yet, because softdevice has little to do with softhddevice. But thanks for the hint, I think I should set up vdr, softhddevice and some "dummy tuner" plugin on a more modern system, so that I can compare what is different. (I will stick to softdevice+DirectFB on the low-end system that is equipped with a budget tuner card.)
Marko
Oops! I misread softdevice as softhddevice. Sorry for the confusion there.
On Wed, Dec 25, 2013 at 1:17 PM, Marko Mäkelä marko.makela@iki.fi wrote:
On Wed, Dec 25, 2013 at 12:23:23PM -0800, VDR User wrote:
If you haven't done so already, please bring this to Johns (author of softhddevice) at the vdrportal forum.
I did not yet, because softdevice has little to do with softhddevice. But thanks for the hint, I think I should set up vdr, softhddevice and some "dummy tuner" plugin on a more modern system, so that I can compare what is different. (I will stick to softdevice+DirectFB on the low-end system that is equipped with a budget tuner card.)
Marko
vdr mailing list vdr@linuxtv.org http://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr
On Wed, Dec 25, 2013 at 04:50:39PM +0200, Marko Mäkelä wrote:
After upgrading to VDR 2.0, I got Softdevice to almost work (see the mail archive a couple of months ago). Sometimes it is showing garbage (really random noise) on the MGA350 OSD layer; I can live with that, as this box is only used for infrequent recordings.
I guess that I removed some memset() call that was essential, when I was trying to debug the display of subtitles. Apparently when no OSD layer is displayed on top of the video layer, the memory can be reused for something else, and I have to clear it again before enabling the OSD layer display.
The last annoying problem is that going to the next or previous I-frame when editing (buttons 4 and 6 on the remote control) are not updating the video screen at all. Only the edit mark is moving on the OSD layer. If I press Play, it will start playing from the current edit mark. So, it is possible but much more clumsy to cut recordings.
Today I found an old PES recording from VDR 1.6, and to my surprise I did see the still frames when moving the edit mark around by pressing 4 or 6.
So, it seems that in order to fix this for TS video, I would have to do something differently. That something is actually documented in device.h:
virtual void StillPicture(const uchar *Data, int Length); ///< Displays the given I-frame as a still picture. ///< Data points either to TS (first byte is 0x47) or PES (first //byte ///< is 0x00) data of the given Length. The default //implementation ///< converts TS to PES and calls itself again, allowing a //derived class ///< to display PES if it can't handle TS directly.
SoftHDDevice is implementing the TS to PES conversion exactly like that. With the following patch, also Softdevice is doing the trick:
--- softdevice.c 2011-04-17 20:22:19.000000000 +0300 +++ softdevice.c 2014-05-31 12:00:21.159478808 +0300 @@ -527,7 +527,9 @@ void cSoftDevice::SetVolumeDevice(int Vo void cSoftDevice::StillPicture(const uchar *Data, int Length) { SOFTDEB("StillPicture...\n"); - if (decoder) + if (Data[0] == 0x47) // TS packet? + cDevice::StillPicture(Data, Length); // convert to PES and call us again + else if (decoder) decoder->StillPicture((uchar *)Data,Length); }
I guess I might soon set up a repository on vdr-developer.org for the revived Softdevice. If not for anything else, it would be the Linus method of backing up. :)
Marko