On Saturday 13 September 2008, Laz wrote: > On Saturday 13 September 2008 17:24:46 Laz wrote: > > On Saturday 13 September 2008 17:13:00 Stefan Lucke wrote: > > > Can you both try attached patch ?
> > > 2nd Feature makes field selectable which is displayed in still picture > > > mode, but unfortunately this doesn't work at the moment. > > > > Excellent: I had toyed with the idea of implementing that in the past but > never got anywhere! I take it that this will remove flicker from a paused > interlaced stream? Here is an other version of the patch. 2nd feature seems to work most of the time. When switching between play / pause real fast, it doesn't work, as the frame is displayed just before the Freeze() command arrives. -- Stefan Lucke
Index: mpeg2decoder.c =================================================================== RCS file: /cvsroot/softdevice/softdevice/mpeg2decoder.c,v retrieving revision 1.83 diff -U3 -r1.83 mpeg2decoder.c --- mpeg2decoder.c 20 Jul 2008 16:41:01 -0000 1.83 +++ mpeg2decoder.c 14 Sep 2008 16:29:56 -0000 @@ -1047,6 +1047,8 @@ IsSuspended=false; Speed=1; pb = NULL; + + useAVReadFrame = setupStore->useAVReadFrame; } cMpeg2Decoder::~cMpeg2Decoder() @@ -1176,15 +1178,21 @@ usleep(50000); BUFDEB("av_read_frame start\n"); - ret = av_read_frame(ic, &pkt); - //ret = av_read_packet(ic, &pkt); + + 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); + usleep(10000); continue; } - av_dup_packet(&pkt); + if (useAVReadFrame) + av_dup_packet(&pkt); + PacketCount++; BUFDEB("got packet from av_read_frame!\n"); @@ -1413,6 +1421,8 @@ { CMDDEB("Play\n"); freezeMode=false; +fprintf(stderr,"MP Play\n"); + videoOut->SetStillPictureMode (false); if (running) { aoutMutex.Lock(); @@ -1433,6 +1443,9 @@ { curPlayMode=playMode; this->packetMode=packetMode; +fprintf(stderr,"MP SetPlayMode (%d, packetMode(%s))\n",playMode, packetMode?"ON":"OFF"); + + videoOut->SetStillPictureMode (false); switch (curPlayMode) { case PmAudioVideo: CMDDEB("SetPlayMode PmAudioVideo\n"); @@ -1456,6 +1469,10 @@ CMDDEB("Freeze Streams %d freeze %d\n",Stream,freeze); if (Stream & SOFTDEVICE_BOTH_STREAMS == SOFTDEVICE_BOTH_STREAMS ) freezeMode=freeze; +fprintf(stderr,"MP Freeze(%s)\n", freeze ? "ON":"OFF"); + if (freeze) + videoOut->SetStillPictureMode (true); + // sleep a short while before putting the // audio and video stream decoders to sleep usleep(20000); @@ -1537,41 +1554,47 @@ /* ---------------------------------------------------------------------------- */ - static uint8_t pes_packet_header[] = { 0x00,0x00,0x01, 0xe0, 0x00,0x00, 0x84, 0x00, 0x00,0x00}; // startcode, video-stream 0, packet length, no pts + +/* ---------------------------------------------------------------------------- + */ int cMpeg2Decoder::StillPicture(uchar *Data, int Length) { - bool has_pesheader=false; - CMDDEB("StillPicture %p length %d \n",Data,Length); + bool has_pesheader = false; + CMDDEB("StillPicture %p length %d \n", Data,Length); // XXX hack to ingore audio junk sent by vdr in the still picture - AudioIdx=DONT_PLAY; + AudioIdx = DONT_PLAY; // check if data contains a valid pes header #define SEARCH_LENGTH 64 - if (Length>SEARCH_LENGTH) { - uchar *start=Data+1; + if (Length > SEARCH_LENGTH) { + uchar *start = Data + 1; do { start++; - start=(uchar *)memchr(start,0x01,Data+SEARCH_LENGTH-start); - if ( start && start[-1]==0 && start[-2] == 0 - && ((start[1] &0xF0)==0xe0) ) { // video stream pes header - has_pesheader=true; + start = (uchar *) memchr (start, 0x01, Data + SEARCH_LENGTH - start); + if ( start && + start[-1] == 0 && start[-2] == 0 && + ((start[1] &0xF0) == 0xe0) ) { // video stream pes header + has_pesheader = true; break; - }; - } while (start<Data+SEARCH_LENGTH && start); - }; + } + } while (start < Data + SEARCH_LENGTH && start); + } - for (int i=0; 4>i;i++) { + videoOut->SetStillPictureMode (true); + for (int i = 0; 4 > i; i++) { if (!has_pesheader) { // send a fake pes header - pes_packet_header[4]=(Length+2)>>8 & 0xFF; - pes_packet_header[5]=(Length+2) & 0xFF; - Decode(pes_packet_header,9); - }; - Decode(Data,Length); + pes_packet_header[4] = (Length + 2) >> 8 & 0xFF; + pes_packet_header[5] = (Length + 2) & 0xFF; + Decode (pes_packet_header, 9); + } + Decode (Data,Length); } + //videoOut->SetStillPictureMode (false); + CMDDEB("StillPicture end \n"); return Length; } @@ -1582,6 +1605,7 @@ { mutex.Lock(); CMDDEB("Clear\n"); + videoOut->SetStillPictureMode (true); Stop(false); Start(false); CMDDEB("Clear finished\n"); @@ -1593,6 +1617,7 @@ void cMpeg2Decoder::TrickSpeed(int trickSpeed) { CMDDEB("TrickSpeed %d\n",Speed); +fprintf(stderr,"MP TrickSpeed A (%d -> %d)\n", Speed, trickSpeed); Speed=trickSpeed; // XXX hack to ingore audio junk sent by vdr in the if (trickSpeed!=1) { @@ -1604,6 +1629,11 @@ AudioIdx=DONT_PLAY; } else if (AudioIdx==DONT_PLAY) AudioIdx=NO_STREAM; + + if (trickSpeed > 1) + videoOut->SetStillPictureMode (true); +fprintf(stderr,"MP TrickSpeed B (%d -> %d)\n", Speed, trickSpeed); + Play(); if (running) { Index: mpeg2decoder.h =================================================================== RCS file: /cvsroot/softdevice/softdevice/mpeg2decoder.h,v retrieving revision 1.44 diff -U3 -r1.44 mpeg2decoder.h --- mpeg2decoder.h 26 Feb 2008 08:06:18 -0000 1.44 +++ mpeg2decoder.h 14 Sep 2008 16:29:56 -0000 @@ -284,6 +284,7 @@ AVFormatContext *ic; ByteIOContext *pb; + bool useAVReadFrame; int LastSize; cMutex mutex; cSigTimer EnablePutSignal; Index: setup-softdevice.c =================================================================== RCS file: /cvsroot/softdevice/softdevice/setup-softdevice.c,v retrieving revision 1.56 diff -U3 -r1.56 setup-softdevice.c --- setup-softdevice.c 20 Jul 2008 16:41:01 -0000 1.56 +++ setup-softdevice.c 14 Sep 2008 16:29:57 -0000 @@ -74,6 +74,8 @@ const char *fieldOrderNames[SETUP_FIELD_ORDER_NAMES]; +const char *preferredFieldNames[SETUP_PREFERRED_FIELD_NAMES]; + /* ---------------------------------------------------------------------------- */ cSetupStore *setupStore=NULL; @@ -116,6 +118,8 @@ useStretchBlit = 0; stretchBlitLocked = false; fieldOrderMode = 2; + preferredField = bothFields; + useAVReadFrame = true; bufferMode = 0; mainMenu = 1; syncTimerMode = 2; @@ -209,6 +213,11 @@ fieldOrderNames[1] = "Top field first"; fieldOrderNames[2] = "Auto"; fieldOrderNames[3] = NULL; + + preferredFieldNames[0] = tr("Both Fields"); + preferredFieldNames[1] = tr("First Field"); + preferredFieldNames[2] = tr("Later Field"); + preferredFieldNames[3] = NULL; } bool cSetupStore::SetupParse(const char *Name, const char *Value) @@ -381,6 +390,14 @@ fieldOrderMode = clamp (0, fieldOrderMode, 2); fprintf(stderr, "[setup-softdevice] fieldOrderMode: %s\n", fieldOrderNames[fieldOrderMode]); + } else if (!strcasecmp(Name, "preferredField")) { + preferredField = (tPreferredField) atoi (Value); + preferredField = (tPreferredField) clamp (bothFields, preferredField, laterField); + fprintf(stderr, "[setup-softdevice] preferrenField: %s\n", + preferredFieldNames[preferredField]); + } else if (!strcasecmp(Name, "useAVReadFrame")) { + useAVReadFrame = (bool) atoi (Value); + fprintf(stderr, "[setup-softdevice] useAVReadFrame: %s\n", (useAVReadFrame) ? "yes": "no"); } else if (!strcasecmp(Name, "vidBrightness")) { vidBrightness = atoi (Value); vidBrightness = clamp (-1, vidBrightness, 100); Index: setup-softdevice.h =================================================================== RCS file: /cvsroot/softdevice/softdevice/setup-softdevice.h,v retrieving revision 1.46 diff -U3 -r1.46 setup-softdevice.h --- setup-softdevice.h 10 Sep 2008 17:15:38 -0000 1.46 +++ setup-softdevice.h 14 Sep 2008 16:29:57 -0000 @@ -105,6 +105,9 @@ #define SETUP_FIELD_ORDER_NAMES 4 extern const char *fieldOrderNames[SETUP_FIELD_ORDER_NAMES]; +#define SETUP_PREFERRED_FIELD_NAMES 4 +extern const char *preferredFieldNames[SETUP_PREFERRED_FIELD_NAMES]; + /* ---------------------------------------------------------------------------- * allow changing of output pixfmt */ @@ -116,6 +119,14 @@ #define SETUP_SUSPENDVIDEO 3 extern const char *suspendVideo[SETUP_SUSPENDVIDEO]; +/*----------------------------------------------------------------------------- + */ +typedef enum preferredField { + bothFields, + earlierField, + laterField +} tPreferredField; + /* --------------------------------------------------------------------------- */ struct cSetupStore { @@ -149,6 +160,7 @@ int ppQuality; int mirror; int syncOnFrames; + bool useAVReadFrame; int avOffset; int screenPixelAspect; int zoom; @@ -182,6 +194,8 @@ char alsaAC3Device [ALSA_DEVICE_NAME_LENGTH]; int setupStoreShmid; + + tPreferredField preferredField; }; #define OSDMODE_PSEUDO 0 Index: setup-softdevice-menu.c =================================================================== RCS file: /cvsroot/softdevice/softdevice/setup-softdevice-menu.c,v retrieving revision 1.15 diff -U3 -r1.15 setup-softdevice-menu.c --- setup-softdevice-menu.c 20 Jul 2008 16:41:01 -0000 1.15 +++ setup-softdevice-menu.c 14 Sep 2008 16:29:57 -0000 @@ -370,6 +370,15 @@ (SETUP_FIELD_ORDER_NAMES-1), fieldOrderNames)); + Add(new cMenuEditStraItem(tr("Still Picture Field"), + (int *) &data->preferredField, + (SETUP_PREFERRED_FIELD_NAMES-1), + preferredFieldNames)); + + Add(new cMenuEditBoolItem(tr("Use av_read_frame()"), + (int *) &data->useAVReadFrame, tr("no"), tr("yes"))); + + #if VDRVERSNUM >= 10334 Add(new cOsdItem(" ", osUnknown, false)); #else @@ -489,6 +498,8 @@ SetupStore ("mainMenu", setupStore->mainMenu); SetupStore ("syncTimerMode", setupStore->syncTimerMode); SetupStore ("fieldOrderMode", setupStore->fieldOrderMode); + SetupStore ("preferredField", setupStore->preferredField); + SetupStore ("useAVReadFrame", setupStore->useAVReadFrame); SetupStore ("vidBrightness", setupStore->vidBrightness); SetupStore ("vidContrast", setupStore->vidContrast); SetupStore ("vidHue", setupStore->vidHue); Index: softdevice.c =================================================================== RCS file: /cvsroot/softdevice/softdevice/softdevice.c,v retrieving revision 1.93 diff -U3 -r1.93 softdevice.c --- softdevice.c 18 Apr 2008 15:15:41 -0000 1.93 +++ softdevice.c 14 Sep 2008 16:29:58 -0000 @@ -113,7 +113,7 @@ #define AOUT_OSS 3 #define AOUT_MACOS 4 -//#define SOFTDEB(out...) {printf("softdeb[%04d]:",(int)(getTimeMilis() % 10000));printf(out);} +#define SOFTDEB(out...) {printf("softdeb[%04d]:",(int)(getTimeMilis() % 10000));printf(out);} #ifndef SOFTDEB #define SOFTDEB(out...) @@ -497,9 +497,9 @@ void cSoftDevice::Freeze(void) { SOFTDEB("Freeze...\n"); - cDevice::Freeze(); if (decoder) decoder->Freeze(); + cDevice::Freeze(); SOFTDEB("Freeze finished.\n"); } @@ -585,7 +585,7 @@ int cSoftDevice::PlayAudio(const uchar *Data, int Length) # endif { - SOFTDEB("PlayAudio... %p length %d\n",Data,Length); + //SOFTDEB("PlayAudio... %p length %d\n",Data,Length); #if VDRVERSNUM >= 10342 if (SHOULD_SUSPEND && !Transferring()) { usleep(10000); // avoid burning CPU @@ -646,7 +646,7 @@ */ int cSoftDevice::PlayVideo(const uchar *Data, int Length) { - SOFTDEB("PlayVideo %x length %d\n",Data,Length); + //SOFTDEB("PlayVideo %x length %d\n",Data,Length); #if VDRVERSNUM >= 10342 if (SHOULD_SUSPEND && !Transferring()) { usleep(10000); // avoid burning CPU Index: video.c =================================================================== RCS file: /cvsroot/softdevice/softdevice/video.c,v retrieving revision 1.77 diff -U3 -r1.77 video.c --- video.c 20 Jul 2008 16:41:01 -0000 1.77 +++ video.c 14 Sep 2008 16:29:58 -0000 @@ -461,6 +461,60 @@ /* --------------------------------------------------------------------------- */ +void cVideoOut::SetStillPictureMode(bool on) +{ +fprintf(stderr,"SetStillPictureMode: %s\n", on ? "ON " : "OFF "); + stillPictureMode = on; +} + +/* --------------------------------------------------------------------------- + */ +void cVideoOut::SelectField (sPicBuffer *pic) +{ + unsigned char *dest, + *src; + int i; + + if (!pic->interlaced_frame) + return; + if (setupStore->preferredField == bothFields) + return; + + dest = src = pic->pixel[0] + + (pic->edge_height) * pic->stride[0] + + pic->edge_width; + + if (setupStore->preferredField == earlierField) { + + if (pic->top_field_first) + dest += pic->stride[0]; + else + src += pic->stride[0]; + + } else { + + if (pic->top_field_first) + src += pic->stride[0]; + else + dest += pic->stride[0]; + } + + for (i = 0; i < pic->height; i += 2) { +#if 1 + // copy part + memcpy (dest, src, pic->stride[0]); +#else + // set frame to very dark + memset (dest, 0, pic->stride[0]); + memset (src, 0, pic->stride[0]); +#endif + dest += 2 * pic->stride[0]; + src += 2 * pic->stride[0]; + } +} + +/* --------------------------------------------------------------------------- + */ void cVideoOut::DrawVideo_420pl(cSyncTimer *syncTimer, sPicBuffer *pic) { @@ -472,6 +526,11 @@ return; } + if (stillPictureMode) { +fprintf(stderr,"0"); + SelectField (pic); + } + sPicBuffer *scale_pic=NULL; if (scaleVid != 0) { scale_pic=GetBuffer(pic->format,pic->max_width,pic->max_height); @@ -554,7 +613,7 @@ offsetIndex %= AVRG_OFF_CNT; softlog->Log(SOFT_LOG_TRACE, 0, - "[VideoOut] A/V (%d - %d) off = %d avoff = %d\n", + "[VideoOut] A/V (%lld - %lld) off = %d avoff = %d\n", aPTS, pts, offset, offsetAverage); dropOffset = (useAverage4Drop) ? offsetAverage : offset; Index: video.h =================================================================== RCS file: /cvsroot/softdevice/softdevice/video.h,v retrieving revision 1.56 diff -U3 -r1.56 video.h --- video.h 20 Jul 2008 16:41:01 -0000 1.56 +++ video.h 14 Sep 2008 16:29:58 -0000 @@ -66,6 +66,7 @@ // sPicBuffer *oldPicture; cMutex oldPictureMutex; + bool stillPictureMode; void SetOldPicture(sPicBuffer *pic); protected: @@ -192,6 +193,8 @@ oldPictureMutex.Unlock(); }; + virtual void SetStillPictureMode (bool on); + virtual void SelectField (sPicBuffer *pic); virtual void Action(void); // osd control thread. Refreshes the osd on dimension changes and
_______________________________________________ Softdevice-devel mailing list Softdevice-devel@lists.berlios.de https://lists.berlios.de/mailman/listinfo/softdevice-devel