CCC_TS2PSCoreをLinuxで使う

※あまり検証していないので、間違っていたらすみません。

用意するもの

CCC_TS2PSCore (CCC_TS2PSCore_009.zip)
Linux環境

必要に応じて
音声多重放送対応差分 (CCC_TS2PSCore_diff_009_2.zip)
  スキップチャンネルに 3 を指定すると2ヶ国語放送などの音声多重放送時のCMカットができます。

手順

ビルドの手順を示しますが、詳細説明は省略します。ポイントのみ記述しておきます。

(1)ソース解凍と修正
CCC_TS2PSCore_009.zipを解凍する(必要ならCCC_TS2PSCore_009_2.zipも解凍する)
$ cd CCC_TS2PSCore_009
$ cd src
ソースを修正する

→main.c
修正前:#include <ctools.h>
修正後:#include "ctools.h"

以下の行を削除
//    WORD version;
//  WSADATA wsa;
//            version = MAKEWORD(1,1);
//            if(WSAStartup(version, &wsa)!=0) {
//                    fio_fprintf(STDERR_FILENO,"Fatal: bad Winsock version\n");
//            }
//            WSACleanup();


→ctools.h
修正前://#include <stdio.h>
修正前://#include <stdlib.h>
修正前://#include <netinet/in.h>
修正前://#include <netdb.h>
修正前://#include <sys/socket.h>
修正前:#include <winsock2.h>

修正後:#include <stdio.h>
修正後:#include <stdlib.h>
修正後:#include <netinet/in.h>
修正後:#include <netdb.h>
修正後:#include <sys/socket.h>
修正後:#include "winsock2.h"

→fileio.h
修正前:typedef long off_t;
修正前:typedef long ssize_t;
修正後://typedef long off_t;
修正後://typedef long ssize_t;

(3)ファイル追加

以下の内容のファイル winsock2.h を作成する。
#ifndef _WINSOCK2_H_
#define _WINSOCK2_H_

typedef u_int SOCKET;
typedef struct in_addr IN_ADDR;
typedef struct in_addr *LPIN_ADDR;
typedef struct hostent *LPHOSTENT;
typedef struct sockaddr *LPSOCKADDR;
typedef struct sockaddr_in SOCKADDR_IN;
#define INVALID_SOCKET (SOCKET)(~0)
#define SOCKET_ERROR (-1)
#define closesocket close

#endif //_WINSOCK2_H_


(4)ビルド

$ gcc -c ctools.c -o ctools.o
$ gcc -c fileio.c -o fileio.o
$ gcc -c transform.c -o transform.o
$ gcc -c main.c -o main.o
$ gcc ctools.o fileio.o transform.o main.o -o CCC_TS2PSCore
$ strip CCC_TS2PSCore

(5)サンプル

MPEG2TSファイルをMPEG2PSに変換するファイル同士の場合はファイル名を2つ並べるだけです。

転送しながら変換させる場合の手順については解説は面倒なので省略します。手抜きサンプルを付けるので解読してください。
CCC_TS2PSCoreを起動すると、CCC_TS2PSCore側から、起動時に引数で指定したポートにコネクションを張ってきます。
そのためCCC_TS2PSCore起動時に、呼び出し側でlistenしておく必要があります。
#!/usr/local/bin/perl
use Socket;

$filename = "video.mpg";
$wget = '/usr/bin/wget --proxy=off -q -O - "http://192.168.xxx.xxx:51002/video?O=V1111&P=2&C=1&B=6&I=1111"';
$ts2ps = "./CCC_TS2PSCore";
$port = 11111;

$proto = getprotobyname('tcp');
socket(PS, AF_INET, SOCK_STREAM, $proto) || die "socket(PS): $!\n";
setsockopt(PS, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) || die "setsockopt(PS): $!\n";
bind(PS, sockaddr_in($port, INADDR_ANY)) || die "bind(PS): $!\n";
listen(PS, SOMAXCONN) || die "listen(PS): $!\n";

system("$ts2ps port:$port $filename > /dev/null 2>&1 &");

accept(TS, PS) || die "accept(TS,PS): $!\n";
select(TS); $|=1; select(STDOUT);
binmode TS;

$blocksize = 1024*1024;
open(CC, "$wget |") || die "open(CC): $!\n";
do {
        read(CC, $data, $blocksize) || die "read(CC): $!\n";
        print TS $data;
} while( length($data)==$blocksize );
close(CC);
close(TS);

exit 0;

(注意)
x86系のLinux以外の場合にも期待した変換処理が動くかはわかりません。
バイトオーダとか違っても大丈夫な作りになっているのかは不明です。

Solaris9 (sparc, gcc-3.3.2) で以下の変更を施すことで、使用できたという情報を頂きました。
(1) fileio.cに以下を追加(solarisのnetinet/in.hにはないようなので)
	#define	INADDR_NONE		((in_addr_t) 0xffffffff)
(2) 手順の最後で
	gcc ctools.o fileio.o transform.o main.o -o CCC_TS2PSCore
するところで "-lsocket -lxnet" が必要



戻る