Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[mpeg2] Re: Setting Audio, Video, and PCR PIDs



> Unfortunately, I don't know about other MPEG encoders... I see that in
> the saa6752hs there is a 1-byte parameter for selecting the video format
> (D1, 2/3D1, 1/2D1, or SIF) and I was thinking about adding a field to
> mpeg_params for setting the format. But I don't know if this is flexible
> enough.
>
> Finally, I also have a patch against saa7134-ts.c, for transforming
> TS_NR_PACKETS in a module parameter (very useful for reducing the jitter
> in the PCR!!!), and I wanted to submit it to Gerd Knorr, but it seems
> that the v4l mailing list is not working (or I have been unsubscribed
> for some reason, I don't know). I attach it to this mail; maybe you can
> submit it when you will submit the next update to saa6752hs.c?

Hi, please find attached a patch merging both our changes. I modified yours a 
bit, mainly to avoid writing to static values shared by all saa6752hs 
instances (I have machines with five MPEX cards in them).

My bit of the patch basically cleans up the mpeg_params structure, and changes 
to some better defaults for the bitrate parameters - I've been testing these 
for months on several sites now, and they seem to be more stable.

Lemme know what you think.... (I've not submitted anything to Gerd Knorr yet).

Did you get round to doing the video format selection patch? 
Common subdirectories: saa7134-0.2.12.orig/.tmp_versions and saa7134-0.2.12/.tmp_versions
Common subdirectories: saa7134-0.2.12.orig/doc and saa7134-0.2.12/doc
Common subdirectories: saa7134-0.2.12.orig/linux and saa7134-0.2.12/linux
Common subdirectories: saa7134-0.2.12.orig/media and saa7134-0.2.12/media
diff -Naub saa7134-0.2.12.orig/saa6752hs.c saa7134-0.2.12/saa6752hs.c
--- saa7134-0.2.12.orig/saa6752hs.c	2004-02-22 01:59:35.000000000 +0000
+++ saa7134-0.2.12/saa6752hs.c	2004-05-17 12:28:22.229901136 +0100
@@ -11,6 +11,7 @@
 #include <linux/types.h>
 #include <linux/videodev.h>
 #include <linux/init.h>
+#include <linux/crc32.h>
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 #include "i2c-compat.h"
@@ -73,9 +74,9 @@
 
 	0x00, 0x01, // program_number(1)
 	
-	0xe0, 0x10, // PMT PID(0x10)
+	0xe0, 0x00, // PMT PID
 
-	0x76, 0xf1, 0x44, 0xd1 // CRC32
+	0x00, 0x00, 0x00, 0x00 // CRC32
 };
 
 static u8 PMT[] = {
@@ -83,7 +84,7 @@
 	0x01, // table number for encoder
   
 	0x47, // sync
-	0x40, 0x10, // transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid(0x10)
+	0x40, 0x00, // transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid
 	0x10, // transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0)
      
 	0x00, // PSI pointer to start of table
@@ -97,22 +98,27 @@
     
 	0x00, 0x00, // section_number(0), last_section_number(0)
     
-	0xe1, 0x04, // PCR_PID (0x104)
+	0xe0, 0x00, // PCR_PID
    
 	0xf0, 0x00, // program_info_length(0)
     
-	0x02, 0xe1, 0x00, 0xf0, 0x00, // video stream type(2), pid(0x100)
-	0x04, 0xe1, 0x03, 0xf0, 0x00, // audio stream type(4), pid(0x103)
+	0x02, 0xe0, 0x00, 0xf0, 0x00, // video stream type(2), pid
+	0x04, 0xe0, 0x00, 0xf0, 0x00, // audio stream type(4), pid
     
-	0xa1, 0xca, 0x0f, 0x82 // CRC32
+	0x00, 0x00, 0x00, 0x00 // CRC32
 };
 
 static struct mpeg_params mpeg_params_template =
 {
-	.bitrate_mode = MPEG_BITRATE_MODE_CBR,
-	.video_target_bitrate = 5000,
+	.video_bitrate_mode = MPEG_VIDEO_BITRATE_MODE_VBR,
+	.video_target_bitrate = 4000,
+     	.video_max_bitrate = 6000,
 	.audio_bitrate = MPEG_AUDIO_BITRATE_256,
-	.total_bitrate = 6000,
+	.total_bitrate = 7000,
+	.pmt_pid = 16,
+	.video_pid = 260,
+	.audio_pid = 256,
+	.pcr_pid = 259,
 };
 
   
@@ -197,11 +203,11 @@
   
 	// set the bitrate mode
 	buf[0] = 0x71;
-	buf[1] = params->bitrate_mode;
+	buf[1] = params->video_bitrate_mode;
 	i2c_master_send(client, buf, 2);
 	  
 	// set the video bitrate
-	if (params->bitrate_mode == MPEG_BITRATE_MODE_VBR) {
+	if (params->video_bitrate_mode == MPEG_VIDEO_BITRATE_MODE_VBR) {
 		// set the target bitrate
 		buf[0] = 0x80;
 	    	buf[1] = params->video_target_bitrate >> 8;
@@ -239,25 +245,73 @@
 static int saa6752hs_init(struct i2c_client* client, struct mpeg_params* params)
 {  
 	unsigned char buf[3];
-	void *data;
+	struct mpeg_params* cachedParams;
+	u32 crc;
+	unsigned char localPAT[256];
+   	unsigned char localPMT[256];
+
+	// grab the previous set of parameters
+	cachedParams = (struct mpeg_params*) i2c_get_clientdata(client);
 
 	// check the bitrate parameters first
 	if (params != NULL) {
-		if (params->bitrate_mode >= MPEG_BITRATE_MODE_MAX)
+		unsigned int pmt_pid = 0, pcr_pid = 0, video_pid = 0 , audio_pid = 0;
+
+	   	// check supplied params are valid
+		if (params->video_bitrate_mode >= MPEG_VIDEO_BITRATE_MODE_MAX)
 			return -EINVAL;
 		if (params->video_target_bitrate >= MPEG_VIDEO_TARGET_BITRATE_MAX)
 			return -EINVAL;
-  		if (params->video_max_bitrate >= MPEG_VIDEO_MAX_BITRATE_MAX)
-			return -EINVAL;
 		if (params->audio_bitrate >= MPEG_AUDIO_BITRATE_MAX)
 			return -EINVAL;
 		if (params->total_bitrate >= MPEG_TOTAL_BITRATE_MAX)
         		return -EINVAL;
-		if (params->bitrate_mode         == MPEG_BITRATE_MODE_MAX &&
-		    params->video_target_bitrate <= params->video_max_bitrate)
+		if (params->video_bitrate_mode == MPEG_VIDEO_BITRATE_MODE_VBR) {
+			if (params->video_max_bitrate >= MPEG_VIDEO_MAX_BITRATE_MAX)
+				return -EINVAL;
+			if (params->video_target_bitrate <= params->video_max_bitrate)
+				return -EINVAL;
+		}
+		if (params->pmt_pid != 0) {
+			if (params->pmt_pid > MPEG_PID_MAX)
+				return -EINVAL;
+		   	pmt_pid = params->pmt_pid;
+		} else {
+			pmt_pid = cachedParams->pmt_pid;
+		}
+		if (params->pcr_pid != 0) {
+		   	if (params->pcr_pid > MPEG_PID_MAX)
+				return -EINVAL;
+		   	pcr_pid = params->pcr_pid;
+		} else {
+			pcr_pid = cachedParams->pcr_pid;
+		}
+   		if (params->video_pid != 0) {
+		   	if (params->video_pid > MPEG_PID_MAX)
+				return -EINVAL;
+		   	video_pid = params->video_pid;
+		} else {
+			video_pid = cachedParams->video_pid;
+		}
+   		if (params->audio_pid != 0) {
+		   	if (params->audio_pid > MPEG_PID_MAX)
 			return -EINVAL; 
+		   	audio_pid = params->audio_pid;
+		} else {
+			audio_pid = cachedParams->audio_pid;
 	}
   
+	   	// update cache
+   		memcpy(cachedParams, params, sizeof(struct mpeg_params));
+	   	cachedParams->pmt_pid = pmt_pid;
+   	   	cachedParams->pcr_pid = pcr_pid;
+   	   	cachedParams->video_pid = video_pid;
+   	   	cachedParams->audio_pid = audio_pid;
+	}
+
+	// set bitrate
+	saa6752hs_set_bitrate(client, cachedParams);
+
     	// Set GOP structure {3, 13}
 	buf[0] = 0x72;
 	buf[1] = 0x03;
@@ -284,25 +338,53 @@
 	buf[1] = 0x05;
 	i2c_master_send(client,buf,2);
   
-    	// Set Audio PID {0x103}
+	/* compute PAT */
+	memcpy(localPAT, PAT, sizeof(PAT));
+	localPAT[17] = 0xe0 | ((cachedParams->pmt_pid >> 8) & 0x0f);
+	localPAT[18] = cachedParams->pmt_pid & 0xff;
+	crc = crc32_be(~0, &localPAT[7], sizeof(PAT) - 7 - 4);
+	localPAT[sizeof(PAT) - 4] = (crc >> 24) & 0xFF;
+	localPAT[sizeof(PAT) - 3] = (crc >> 16) & 0xFF;
+	localPAT[sizeof(PAT) - 2] = (crc >> 8) & 0xFF;
+	localPAT[sizeof(PAT) - 1] = crc & 0xFF;
+
+	/* compute PMT */
+      	memcpy(localPMT, PMT, sizeof(PMT));
+   	localPAT[3] = 0x40 | ((cachedParams->pmt_pid >> 8) & 0x0f);
+   	localPAT[4] = cachedParams->pmt_pid & 0xff;
+	localPMT[15] = 0xE0 | ((cachedParams->pcr_pid >> 8) & 0x0F);
+	localPMT[16] = cachedParams->pcr_pid & 0xFF;
+	localPMT[20] = 0xE0 | ((cachedParams->video_pid >> 8) & 0x0F);
+	localPMT[21] = cachedParams->video_pid & 0xFF;
+	localPMT[25] = 0xE0 | ((cachedParams->audio_pid >> 8) & 0x0F);
+	localPMT[26] = cachedParams->audio_pid & 0xFF;
+	crc = crc32_be(~0, &localPMT[7], sizeof(PMT) - 7 - 4);
+	localPMT[sizeof(PMT) - 4] = (crc >> 24) & 0xFF;
+	localPMT[sizeof(PMT) - 3] = (crc >> 16) & 0xFF;
+	localPMT[sizeof(PMT) - 2] = (crc >> 8) & 0xFF;
+	localPMT[sizeof(PMT) - 1] = crc & 0xFF;
+
+    	// Set Audio PID
 	buf[0] = 0xC1;
-	buf[1] = 0x01;
-	buf[2] = 0x03;
+	buf[1] = (cachedParams->audio_pid >> 8) & 0xFF;
+	buf[2] = cachedParams->audio_pid & 0xFF;
 	i2c_master_send(client,buf,3);
   
-        // setup bitrate settings
-	data = i2c_get_clientdata(client);
-	if (params) {
-		saa6752hs_set_bitrate(client, params);
-		memcpy(data, params, sizeof(struct mpeg_params));
-	} else {
-		// parameters were not supplied. use the previous set
-   		saa6752hs_set_bitrate(client, (struct mpeg_params*) data);
-	}
+	// Set Video PID
+	buf[0] = 0xC0;
+	buf[1] = (cachedParams->video_pid >> 8) & 0xFF;
+	buf[2] = cachedParams->video_pid & 0xFF;
+	i2c_master_send(client,buf,3);
+
+ 	// Set PCR PID
+	buf[0] = 0xC4;
+	buf[1] = (cachedParams->pcr_pid >> 8) & 0xFF;
+	buf[2] = cachedParams->pcr_pid & 0xFF;
+	i2c_master_send(client,buf,3);
 	  
 	// Send SI tables
-  	i2c_master_send(client,PAT,sizeof(PAT));
-  	i2c_master_send(client,PMT,sizeof(PMT));
+  	i2c_master_send(client,localPAT,sizeof(PAT));
+  	i2c_master_send(client,localPMT,sizeof(PMT));
 	  
 	// mute then unmute audio. This removes buzzing artefacts
 	buf[0] = 0xa4;
diff -Naub saa7134-0.2.12.orig/saa6752hs.h saa7134-0.2.12/saa6752hs.h
--- saa7134-0.2.12.orig/saa6752hs.h	2004-02-22 01:59:35.000000000 +0000
+++ saa7134-0.2.12/saa6752hs.h	2004-05-17 11:47:13.400220296 +0100
@@ -21,11 +21,11 @@
 #ifndef _SAA6752HS_H
 #define _SAA6752HS_H
 
-enum mpeg_bitrate_mode {
-	MPEG_BITRATE_MODE_VBR = 0, /* Variable bitrate */
-	MPEG_BITRATE_MODE_CBR = 1, /* Constant bitrate */
+enum mpeg_video_bitrate_mode {
+	MPEG_VIDEO_BITRATE_MODE_VBR = 0, /* Variable bitrate */
+	MPEG_VIDEO_BITRATE_MODE_CBR = 1, /* Constant bitrate */
 
-	MPEG_BITRATE_MODE_MAX
+	MPEG_VIDEO_BITRATE_MODE_MAX
 };
 
 enum mpeg_audio_bitrate {
@@ -38,13 +38,19 @@
 #define MPEG_VIDEO_TARGET_BITRATE_MAX 27000
 #define MPEG_VIDEO_MAX_BITRATE_MAX 27000
 #define MPEG_TOTAL_BITRATE_MAX 27000
+#define MPEG_PID_MAX ((1 << 14) - 1)
     
 struct mpeg_params {
-	enum mpeg_bitrate_mode bitrate_mode;
+	enum mpeg_video_bitrate_mode video_bitrate_mode;
 	unsigned int video_target_bitrate;
 	unsigned int video_max_bitrate; // only used for VBR
 	enum mpeg_audio_bitrate audio_bitrate;
 	unsigned int total_bitrate;
+
+   	unsigned int pmt_pid;
+	unsigned int video_pid;
+	unsigned int audio_pid;
+	unsigned int pcr_pid;
 };
 
 #define MPEG_SETPARAMS             _IOW('6',100,struct mpeg_params)

Home | Main Index | Thread Index