112 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			112 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include "platglue.h"
 | |
| 
 | |
| #include "SimStreamer.h"
 | |
| #include "CRtspSession.h"
 | |
| #include "JPEGSamples.h"
 | |
| 
 | |
| 
 | |
| // From RFC2435 generates standard quantization tables
 | |
| 
 | |
| /*
 | |
|  * Table K.1 from JPEG spec.
 | |
|  */
 | |
| static const int jpeg_luma_quantizer[64] = {
 | |
|     16, 11, 10, 16, 24, 40, 51, 61,
 | |
|     12, 12, 14, 19, 26, 58, 60, 55,
 | |
|     14, 13, 16, 24, 40, 57, 69, 56,
 | |
|     14, 17, 22, 29, 51, 87, 80, 62,
 | |
|     18, 22, 37, 56, 68, 109, 103, 77,
 | |
|     24, 35, 55, 64, 81, 104, 113, 92,
 | |
|     49, 64, 78, 87, 103, 121, 120, 101,
 | |
|     72, 92, 95, 98, 112, 100, 103, 99
 | |
| };
 | |
| 
 | |
| /*
 | |
|  * Table K.2 from JPEG spec.
 | |
|  */
 | |
| static const int jpeg_chroma_quantizer[64] = {
 | |
|     17, 18, 24, 47, 99, 99, 99, 99,
 | |
|     18, 21, 26, 66, 99, 99, 99, 99,
 | |
|     24, 26, 56, 99, 99, 99, 99, 99,
 | |
|     47, 66, 99, 99, 99, 99, 99, 99,
 | |
|     99, 99, 99, 99, 99, 99, 99, 99,
 | |
|     99, 99, 99, 99, 99, 99, 99, 99,
 | |
|     99, 99, 99, 99, 99, 99, 99, 99,
 | |
|     99, 99, 99, 99, 99, 99, 99, 99
 | |
| };
 | |
| 
 | |
| /*
 | |
|  * Call MakeTables with the Q factor and two u_char[64] return arrays
 | |
|  */
 | |
| void
 | |
| MakeTables(int q, u_char *lqt, u_char *cqt)
 | |
| {
 | |
|     int i;
 | |
|     int factor = q;
 | |
| 
 | |
|     if (q < 1) factor = 1;
 | |
|     if (q > 99) factor = 99;
 | |
|     if (q < 50)
 | |
|         q = 5000 / factor;
 | |
|     else
 | |
|         q = 200 - factor*2;
 | |
| 
 | |
|     for (i=0; i < 64; i++) {
 | |
|         int lq = (jpeg_luma_quantizer[i] * q + 50) / 100;
 | |
|         int cq = (jpeg_chroma_quantizer[i] * q + 50) / 100;
 | |
| 
 | |
|         /* Limit the quantizers to 1 <= q <= 255 */
 | |
|         if (lq < 1) lq = 1;
 | |
|         else if (lq > 255) lq = 255;
 | |
|         lqt[i] = lq;
 | |
| 
 | |
|         if (cq < 1) cq = 1;
 | |
|         else if (cq > 255) cq = 255;
 | |
|         cqt[i] = cq;
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| // analyze an imge from our camera to find which quant table it is using...
 | |
| // Used to see if our camera is spitting out standard RTP tables (it isn't)
 | |
| 
 | |
| // So we have to use Q of 255 to indicate that each frame has unique quant tables
 | |
| // use 0 for precision in the qant header, 64 for length
 | |
| void findCameraQuant()
 | |
| {
 | |
|     BufPtr bytes = capture_jpg;
 | |
|     uint32_t len = capture_jpg_len;
 | |
| 
 | |
|     if(!findJPEGheader(&bytes, &len, 0xdb)) {
 | |
|         printf("error can't find quant table 0\n");
 | |
|         return;
 | |
|     }
 | |
|     else {
 | |
|         printf("found quant table %x (len %d)\n", bytes[2], bytes[1]);
 | |
|     }
 | |
|     BufPtr qtable0 = bytes + 3; // 3 bytes of header skipped
 | |
| 
 | |
|     nextJpegBlock(&bytes);
 | |
|     if(!findJPEGheader(&bytes, &len, 0xdb)) {
 | |
|         printf("error can't find quant table 1\n");
 | |
|         return;
 | |
|     }
 | |
|     else {
 | |
|         printf("found quant table %x\n", bytes[2]);
 | |
|     }
 | |
|     BufPtr qtable1 = bytes + 3;
 | |
| 
 | |
|     nextJpegBlock(&bytes);
 | |
| 
 | |
|     for(int q = 0; q < 128; q++) {
 | |
|         uint8_t lqt[64], cqt[64];
 | |
|         MakeTables(q, lqt, cqt);
 | |
| 
 | |
|         if(memcmp(qtable0, lqt, sizeof(lqt)) == 0 && memcmp(qtable1, cqt, sizeof(cqt)) == 0) {
 | |
|             printf("Found matching quant table %d\n", q);
 | |
|         }
 | |
|     }
 | |
|     printf("No matching quant table found!\n");
 | |
| }
 |