VideoHelp Forum

Our website is made possible by displaying online advertisements to our visitors. Consider supporting us by disable your adblocker or Try ConvertXtoDVD and convert all your movies to DVD. Free trial ! :)
+ Reply to Thread
Page 2 of 2
FirstFirst 1 2
Results 31 to 45 of 45
Thread
  1. If ffmpeg is in use it is highly recommended also to control video signal flow by using:
    Code:
      -color_primaries   <int>        ED.V.... color primaries (from 1 to 10) (default unspecified)
         bt709                        ED.V.... BT.709
         unspecified                  ED.V.... Unspecified
         bt470m                       ED.V.... BT.470 M
         bt470bg                      ED.V.... BT.470 BG
         smpte170m                    ED.V.... SMPTE 170 M
         smpte240m                    ED.V.... SMPTE 240 M
         film                         ED.V.... Film
         bt2020                       ED.V.... BT.2020
         smpte428_1                   ED.V.... SMPTE ST 428-1
      -color_trc         <int>        ED.V.... color transfer characteristics (from 1 to 17) (default unspecified)
         bt709                        ED.V.... BT.709
         unspecified                  ED.V.... Unspecified
         gamma22                      ED.V.... BT.470 M
         gamma28                      ED.V.... BT.470 BG
         smpte170m                    ED.V.... SMPTE 170 M
         smpte240m                    ED.V.... SMPTE 240 M
         linear                       ED.V.... Linear
         log                          ED.V.... Log
         log_sqrt                     ED.V.... Log square root
         iec61966_2_4                 ED.V.... IEC 61966-2-4
         bt1361                       ED.V.... BT.1361
         iec61966_2_1                 ED.V.... IEC 61966-2-1
         bt2020_10bit                 ED.V.... BT.2020 - 10 bit
         bt2020_12bit                 ED.V.... BT.2020 - 12 bit
         smpte2084                    ED.V.... SMPTE ST 2084
         smpte428_1                   ED.V.... SMPTE ST 428-1
      -colorspace        <int>        ED.V.... color space (from 0 to 10) (default unspecified)
         rgb                          ED.V.... RGB
         bt709                        ED.V.... BT.709
         unspecified                  ED.V.... Unspecified
         fcc                          ED.V.... FCC
         bt470bg                      ED.V.... BT.470 BG
         smpte170m                    ED.V.... SMPTE 170 M
         smpte240m                    ED.V.... SMPTE 240 M
         ycocg                        ED.V.... YCOCG
         bt2020_ncl                   ED.V.... BT.2020 NCL
         bt2020_cl                    ED.V.... BT.2020 CL
      -color_range       <int>        ED.V.... color range (from 0 to 2) (default unspecified)
         unspecified                  ED.V.... Unspecified
         mpeg                         ED.V.... MPEG (219*2^(n-8))
         jpeg                         ED.V.... JPEG (2^n-1)
    Last edited by pandy; 1st Jun 2016 at 03:22.
    Quote Quote  
  2. Jagabo: where did you find these high-precision values on Wikipedia? I'm looking on the Rec 601 page and not seeing them.

    High-precision values for 709?

    // high precision values from wikipedia
    fr = (1.16438 * fy + 1.59603 * fv);
    fg = (1.16438 * fy - 0.391762 * fu - 0.81297 * fv);
    fb = (1.16438 * fy + 2.017234 * fu
    Quote Quote  
  3. I think I started with this at wikipedia:

    Click image for larger version

Name:	matrix.png
Views:	88
Size:	54.6 KB
ID:	37235

    Or maybe I actually found the equation somewhere else. I made the post a few days ago but it was actually a month ago when I wrote the program. I do remember finding some slight discrepancies at different sites.
    Last edited by jagabo; 1st Jun 2016 at 08:09.
    Quote Quote  
  4. Here is what I use for 709, taken from the ITU spec. Good to four decimal places.

    KR = 0.2126
    KG = 0.7152
    KB = 0.0722
    Quote Quote  
  5. jagabo:

    At the end of your function yuv_to_rgb() you have:

    Code:
    *R = (int)(fr + 0.5);
    *G = (int)(fg + 0.5);
    *B = (int)(fb + 0.5);
    Should that be?

    Code:
    *nr = (int)(fr + 0.5);
    *ng = (int)(fg + 0.5);
    *nb = (int)(fb + 0.5);
    I ported it to PureBasic and get reasonable results with the above modification. Either that or my C is rusty beyond salvation
    Quote Quote  
  6. Originally Posted by chris319 View Post
    jagabo:

    At the end of your function yuv_to_rgb() you have:

    Code:
    *R = (int)(fr + 0.5);
    *G = (int)(fg + 0.5);
    *B = (int)(fb + 0.5);
    Should that be?

    Code:
    *nr = (int)(fr + 0.5);
    *ng = (int)(fg + 0.5);
    *nb = (int)(fb + 0.5);
    No. yuv_to_rgb() doesn't know the name of the caller's variables. It only know R, G, and B are pointers to the place to put the results.
    Quote Quote  
  7. If I'm reading your code right, you have nr, ng and nb but they are never modified.

    Here is your code ported to PureBasic with global variables. Zero color differences.
    The C code compiled by Pelles C compiler keeps crashing for no reason I can see.

    Also, what would be the high-precision values for 709? That math is way over my head.
    Code:
    ;/************************************************************************/
    ;//  Convert an 8 bit RGB value To a 10 bit YUV value. Rec.601.
    ;/************************************************************************/
    OpenConsole()
    
    Global fr.d, fg.d, fb.d, fy.d, fu.d, fv.d
    Global R.w, G.w, B.w, Y.w, U.w, V.w, nr.w, ng.w, nb.w
    
    Procedure rgb_to_yuv(R.w, G.w, B.w)
    	fr.d = R.w
    	fg.d = G.w
    	fb.d = B.w
    
    ;higher precision matrix from wikipedia
    fy.d = ( 0.256789*fr + 0.504129*fg + 0.097906*fb) +  16.0
    fu.d = (-0.148223*fr - 0.290992*fg + 0.439215*fb) + 128.0
    fv.d = ( 0.439215*fr - 0.367789*fg - 0.071426*fb) + 128.0
    	
    Y.w = Int(fy * 4 + 0.5); // + 0.5 to get rounding rather than truncation
    U.w = Int(fu * 4 + 0.5)
    V.w = Int(fv * 4 + 0.5)
    EndProcedure	
    
    ;/************************************************************************/
    ;//  Convert a 10 bit YUV value To an 8 bit RGB value. Rec.601.
    ;/************************************************************************/
    
    Procedure yuv_to_rgb(Y.w, U.w, V.w)
    fy.d = Y.w / 4 - 16
    fu.d = U.w / 4 - 128
    fv.d = V.w / 4 - 128
    
    ; high precision values from wikipedia
    fr.d = (1.16438 * fy.d                 + 1.59603 * fv.d)
    fg.d = (1.16438 * fy.d - 0.391762 * fu.d - 0.81297 * fv.d)
    fb.d = (1.16438 * fy.d + 2.017234 * fu.d               )
    
    nR.w = Int(fr + 0.5)
    nG.w = Int(fg + 0.5)
    nB.w = Int(fb + 0.5)
    EndProcedure
    
    ;/************************************************************************/
    ;//  Test all 16 million 8 bit RGB values through a round trip
    ;//  from 8 bit RGB To 10 bit YUV And back To 8 bit RGB.
    ;/************************************************************************/
    
    PrintN(Chr(10)+" Testing round trip...")
    
    count = 0
    diff = 0
    
    	For r=0 To 255
    		For g = 0 To 255
    			For b=0 To 255
    
    rgb_to_yuv(r, g, b)
    yuv_to_rgb(y, u, v)
    
    If (r.w <> nr.w) Or (g.w <> ng.w) Or (b.w <> nb.w)
    ;PrintN(Str(r)+"  "+ Str(g)+ "  "+ Str(b)+ "  "+ Str(y)+ "  "+ Str (u)+ "  "+ "  "+ Str(v)+ "  "+ Str(nr)+ "  "+ Str(ng)+ Str(nb))
    diff +1
    				EndIf	
    
    				count +1
    			Next
    		Next
    	Next
    	
    Print(Chr(10)+" Colors tested:  "): PrintN(Str(count))
    Print(" Colors differed:  "): PrintN(Str(diff))
    
    While Inkey() = ""
      Delay(20)
    Wend
    End
    Last edited by chris319; 1st Jun 2016 at 20:12.
    Quote Quote  
  8. You're not reading my code correctly. In my code, nr, ng, and nb are local variables whose names are only known to test_round_trip(). test_round_trip() passes pointers to those variables to yuv_to_rgb(). yuv_to_rgb() doesn't know, and doesn't need to know, what test_round_trip() calls those variables, all it needs to know is their addresses and types. It refers to them by the pointers *R, *G, and *B. Ie, nr, ng, and nb are modified by yuv_to_rgb() by writing to their addresses.

    Your code is using globals for those variables. All functions know the names and types of those globals and each function accesses them directly.

    You're confusing pointers to variables with the variables themselves.
    Quote Quote  
  9. The code from the Pelles C compiler kept crashing on yuv_to_rgb() for some unknown reason. Rather than spend more hours than I had already spent trying to suss out the problem, it was significantly more expedient to port it to PureBasic and make the variables global. Now it works and there are no color differences and I didn't spend all day on it

    The code compiled by Pelles C was a copy & paste job.
    Last edited by chris319; 1st Jun 2016 at 21:59.
    Quote Quote  
  10. Originally Posted by chris319 View Post
    The code from the Pelles C compiler kept crashing on yuv_to_rgb()
    The code is pretty generic. I don't see any reason a compiler would choke on it. I just copied from my post and pasted it into a C file and it built with no problems. Did you get an error message? Try making the three functions type void. They should be defined that way anyway since they don't return a value.

    void rgb_to_yuv(int R, int G, int B, int *Y, int *U, int *V)...
    void yuv_to_rgb(int Y, int U, int V, int *R, int *G, int *B)...
    void test_round_trip(void)...

    Maybe the one of the variable names is reserved in that compiler? Did you include the standard C libs and a main() routine? I only provided the three core routines that do the conversions and the test. Try adding this to the start of the file:
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    and this to the end:

    Code:
    int main(int argc, char *argv)
    {
        test_round_trip();
        return(0);
    }
    That should be enough to generate a fully function program.
    Quote Quote  
  11. Got it to work by updating the Pelles C compiler.

    Nothing like a buggy C compiler.

    Works great now, thank you very much!

    Could I trouble you for the precision values for 709?

    Many thanks again!
    Quote Quote  
  12. I don't have higher precision values for rec.709. You should be able to derive them from the KB and Kr values given at wikipedia.

    https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.709_conversion

    Follow what they did with rec.601 and do the same with rec.709. For example, with rec.601 they show that KB is 0.114 and KR is 0.299. In the full range conversion KG will then be 1.0 - 0.114 - 0.299, or 0.587. You can see those three values on the first line of the analog YPbPr equaqtion:

    Code:
    Y = 0.299 * R + 0.587 * G + 0.114 * B
    But with limited range YUV the Y value of 16 is defined as full black and 235 is defined as full white. So the range is 235 - 16 = 219. If you multiply by 219 and divide by 255 (full range) you'll see that the equation becomes

    Code:
    Y = 0.299*219/255 * R + 0.587*219/255 * G + 0.114*219/255 * B + 16.0
    or
    Code:
    Y = 0.256788 * R + 0.504129 * G + 0.097906 * B + 16.0
    the values I used in my sample code (I notice that the last digit of the R component differs by 1, probably a typo or rounding error on my part).
    Quote Quote  
  13. By the way, thanks for the heads up about Pelles C. I do most of my programming these days on Atmel microcontrollers so I don't have up to date tools for Windows programming (I used a very old version of MS C running in a VM to build this test code). I'm going to check out Pelles C and its IDE.
    Quote Quote  
  14. Thanks again for all of your help. Glad I could help with Pelles C.

    I have now reworked my 4:4:4 encoder. I had been cheating and using floats for the color-difference values. Now I use signed 16-bit words and shift off 6 bits to simulate a 10-bit payload. It works OK but I need to check the values as you did in your C program.
    Quote Quote  



Similar Threads