4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

MPEG-2 TSファイル処理 -PCRを使用したTSファイルの解析 ビットレートの算出-

Last updated at Posted at 2018-10-19

#はじめに
前回はTSファイルからPCRを取得して表示してみました。今回は、PATやPMTの解析をする予定でしたが、予定を変更してPCRを使用したTSファイルの解析を行いたいと思います。

とりあえずTSファイルの解析としてTSファイルのビットレートを算出してみます。TSファイルには複数のストリーム(サービス)が含まれている場合が有りますが、今回求めるのはそれを全て合算したものになります。

プログラムは以下を参照ください。
https://github.com/sagesagesagesagesage

ビットレートの計算方法

ビットレートの計算は以下の様に行います。

  • TSファイルの先頭のPCR(s)を取得
  • **一定個数(N)**のPCRを読み込むまでTSファイルを末尾に向けてシーク
  • N個目のPCR(e)を読み込むまでのTSパケットのSizeをPCR(e)-PCR(s)で除算
  • さらに27MHzで除算しビットレートbps(bit per second)を算出
ビットレート = Size ÷ ( PCR(e) - PCR(s) ) ÷ 27,000,000

イメージです。

pcr.png

プログラム

以下の様な関数を作成しました。N個は引数で与えるようにしています。また、PCRは最大値から最小値の0へ戻る場合が有る。その場合、簡易的にPCR(s)を再取得するようにした。

/**
* @brief		Calculate bit rate of TS file
* @param[in]	ts_file			TS file path
* @param[in]	use_pcr_count	Sampling PCR count
* @return		double			bitrate. if error return 0.0
*/
static	double		ts_calc_bitrate( const char* ts_file, const uint32_t use_pcr_count )
{
	FILE*		ifp = NULL;
	
	uint8_t		ts_packet[ TS_PACKET_SIZE ];
	
	uint64_t	total_packet = 0;
	
	uint64_t	start_pcr = PCR_NONE;
	uint64_t	end_pcr = PCR_NONE;
	int			pcr_count = 0;
	double		bitrate = 0.0;
	uint16_t	pcr_pid = PID_NULL;
	
	ifp = fopen( ts_file, "rb" );
	total_packet = 0;
	if( ifp ){
		while( TS_PACKET_SIZE == fread( ts_packet, 1, sizeof( ts_packet ), ifp ) ){
			if( TS_SYNC_BYTE != ts_packet[ 0 ] ){
				break;
			}
			
			if( 0 < pcr_count ){
				total_packet++;
			}else{
				total_packet = 0;
			}
			
			if( ts_packet[ 3 ] & TS_ADAPTATION_FIELD ){			// Is adaptaion_file ON ?
				if( ts_packet[ 5 ] & ADAPTATION_FIELD_PCR ){	// PCR Flag ?
					if( PID_NULL == pcr_pid ){
						pcr_pid = GET_PID( ts_packet[ 1 ], ts_packet[ 2 ] );
					}
					
					if( pcr_pid != GET_PID( ts_packet[ 1 ], ts_packet[ 2 ] ) ){
						continue;
					}
					
					if( 0 == pcr_count ){
						GET_PCR_EXT( &ts_packet[ 6 ], start_pcr );
						DEBUG_PRINT( "Start PCR = %lu\n", start_pcr );
						pcr_count++;
					}else if( 0 < pcr_count ){
						GET_PCR_EXT( &ts_packet[ 6 ], end_pcr );
						
						if( start_pcr > end_pcr ){
							DEBUG_PRINT( "PCR RESET %lu => %lu\n", start_pcr, end_pcr );
							pcr_count = 0;
							total_packet = 0;
							continue;
						}
						
						pcr_count++;
						
						if( use_pcr_count < pcr_count ){
							break;
						}
					}
				}
			}
		}
		fclose( ifp );
		
		if(    ( PCR_NONE != start_pcr )
			&& ( PCR_NONE != end_pcr ) ){
			DEBUG_PRINT("End   PCR = %lu / Total = %lu\n", end_pcr, total_packet );
			bitrate = ( total_packet * TS_PACKET_SIZE * 8 ) / ( ( end_pcr - start_pcr ) / ( double )PCR_CLOCK_EXT );
			DEBUG_PRINT( "TS Bitrate = %lf\n", bitrate );
		}
	}
	
	return bitrate;
}

おわりに

今回は予定を変更してPCRを使用してTSファイルのビットレートを算出してみました。ビットレートが求まるとTSファイルのシークや一定レートでの送出に使用できます。

次回こそPATやPMTの解析をする予定です。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?