From c204bc735e90da9edde2ceb958404020733df19a Mon Sep 17 00:00:00 2001 From: Manuel Santos Date: Thu, 30 Dec 2021 18:43:20 +0000 Subject: [PATCH] Fixes the processing of images encoding using PD* modes --- video.c | 196 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 137 insertions(+), 59 deletions(-) diff --git a/video.c b/video.c index e479b2d..389751f 100644 --- a/video.c +++ b/video.c @@ -78,13 +78,26 @@ gboolean GetVideo(guchar Mode, double Rate, int Skip, gboolean Redraw) { ChanStart[2] = ChanStart[1] + ChanLen[1] + ModeSpec[Mode].SyncTime + ModeSpec[Mode].PorchTime; break; + case PD50: + case PD90: + case PD120: + case PD160: + case PD180: + case PD240: + case PD290: + ChanLen[0] = ChanLen[1] = ChanLen[2] = ChanLen[3] = ModeSpec[Mode].PixelTime * ModeSpec[Mode].ImgWidth; + ChanStart[0] = ModeSpec[Mode].SyncTime + ModeSpec[Mode].PorchTime; + ChanStart[1] = ChanStart[0] + ChanLen[0] + ModeSpec[Mode].SeptrTime; + ChanStart[2] = ChanStart[1] + ChanLen[1] + ModeSpec[Mode].SeptrTime; + ChanStart[3] = ChanStart[2] + ChanLen[2] + ModeSpec[Mode].SeptrTime; + break; + default: ChanLen[0] = ChanLen[1] = ChanLen[2] = ModeSpec[Mode].PixelTime * ModeSpec[Mode].ImgWidth; ChanStart[0] = ModeSpec[Mode].SyncTime + ModeSpec[Mode].PorchTime; ChanStart[1] = ChanStart[0] + ChanLen[0] + ModeSpec[Mode].SeptrTime; ChanStart[2] = ChanStart[1] + ChanLen[1] + ModeSpec[Mode].SeptrTime; break; - } // Number of channels per line @@ -98,6 +111,19 @@ gboolean GetVideo(guchar Mode, double Rate, int Skip, gboolean Redraw) { case R36: NumChans = 2; break; + + //In PD* modes, each radio frame encodes + //4 channels, two luminance and two chroma + case PD50: + case PD90: + case PD120: + case PD160: + case PD180: + case PD240: + case PD290: + NumChans = 4; + break; + default: NumChans = 3; break; @@ -105,43 +131,91 @@ gboolean GetVideo(guchar Mode, double Rate, int Skip, gboolean Redraw) { // Plan ahead the time instants (in samples) at which to take pixels out int PixelIdx = 0; - for (y=0; y= 0) { PixelIdx = k; break; } } - /*case PD50: + /*case PD50: case PD90: case PD120: case PD160: @@ -173,9 +247,13 @@ gboolean GetVideo(guchar Mode, double Rate, int Skip, gboolean Redraw) { gtk_image_set_from_pixbuf(GTK_IMAGE(gui.image_rx), pixbuf_disp); gdk_threads_leave(); - Length = ModeSpec[Mode].LineTime * ModeSpec[Mode].NumLines * 44100; - SyncTargetBin = GetBin(1200+CurrentPic.HedrShift, FFTLen); - Abort = FALSE; + + if(NumChans == 4) //In PD* modes, each radio frame encodes two image lines + Length = ModeSpec[Mode].LineTime * ModeSpec[Mode].NumLines/2 * 44100; + else + Length = ModeSpec[Mode].LineTime * ModeSpec[Mode].NumLines * 44100; + SyncTargetBin = GetBin(1200 + CurrentPic.HedrShift, FFTLen); + Abort = FALSE; SyncSampleNum = 0; // Loop through signal @@ -330,26 +408,28 @@ gboolean GetVideo(guchar Mode, double Rate, int Skip, gboolean Redraw) { } /* endif (!Redraw) */ - if (SampleNum == PixelGrid[PixelIdx].Time) { - - x = PixelGrid[PixelIdx].X; - y = PixelGrid[PixelIdx].Y; - Channel = PixelGrid[PixelIdx].Channel; - // Store pixel - Image[x][y][Channel] = StoredLum[SampleNum]; + //In PD* modes, two pixels need data from the same sample + //Can't move on from SampleNum, until all are processed + while (SampleNum == PixelGrid[PixelIdx].Time) { + x = PixelGrid[PixelIdx].X; + y = PixelGrid[PixelIdx].Y; + Channel = PixelGrid[PixelIdx].Channel; - // Some modes have R-Y & B-Y channels that are twice the height of the Y channel - if (Channel > 0 && (Mode == R36 || Mode == R24)) - Image[x][y+1][Channel] = StoredLum[SampleNum]; + // Store pixel + Image[x][y][Channel] = StoredLum[SampleNum]; - // Calculate and draw pixels to pixbuf on line change - if (x == ModeSpec[Mode].ImgWidth-1 || PixelGrid[PixelIdx].Last) { - for (tx = 0; tx < ModeSpec[Mode].ImgWidth; tx++) { - p = pixels + y * rowstride + tx * 3; + // Some modes have R-Y & B-Y channels that are twice the height of the Y channel + if (Channel > 0 && (Mode == R36 || Mode == R24)) + Image[x][y+1][Channel] = StoredLum[SampleNum]; - switch(ModeSpec[Mode].ColorEnc) { + // Calculate and draw pixels to pixbuf on line change + if (x == ModeSpec[Mode].ImgWidth - 1 || PixelGrid[PixelIdx].Last) { + for (tx = 0; tx < ModeSpec[Mode].ImgWidth; tx++) { + p = pixels + y * rowstride + tx * 3; + + switch(ModeSpec[Mode].ColorEnc) { case RGB: p[0] = Image[tx][y][0]; @@ -373,27 +453,25 @@ gboolean GetVideo(guchar Mode, double Rate, int Skip, gboolean Redraw) { case BW: p[0] = p[1] = p[2] = Image[tx][y][0]; break; + } + } + if (!Redraw || y % 5 == 0 || PixelGrid[PixelIdx].Last) { + // Scale and update image + g_object_unref(pixbuf_disp); + pixbuf_disp = gdk_pixbuf_scale_simple(pixbuf_rx, 500, + 500.0 / ModeSpec[Mode].ImgWidth * ModeSpec[Mode].NumLines * ModeSpec[Mode].LineHeight, GDK_INTERP_BILINEAR); + + gdk_threads_enter(); + gtk_image_set_from_pixbuf(GTK_IMAGE(gui.image_rx), pixbuf_disp); + gdk_threads_leave(); } } - if (!Redraw || y % 5 == 0 || PixelGrid[PixelIdx].Last) { - // Scale and update image - g_object_unref(pixbuf_disp); - pixbuf_disp = gdk_pixbuf_scale_simple(pixbuf_rx, 500, - 500.0/ModeSpec[Mode].ImgWidth * ModeSpec[Mode].NumLines * ModeSpec[Mode].LineHeight, GDK_INTERP_BILINEAR); - - gdk_threads_enter(); - gtk_image_set_from_pixbuf(GTK_IMAGE(gui.image_rx), pixbuf_disp); - gdk_threads_leave(); - } + PixelIdx++; } - - PixelIdx ++; - - } /* endif (SampleNum == PixelGrid[PixelIdx].Time) */ - + if (!Redraw && SampleNum % 8820 == 0) { setVU(Power, FFTLen, WinIdx, TRUE); }