Linux/テレビ関連/PT2

Last-modified: Mon, 07 Sep 2015 00:30:25 JST (566d)

本家&関連サイト

PT1/PT2ドライバ(旧) http://hg.honeyplanet.jp/pt1/

TS split内蔵版 http://hg.honeyplanet.jp/pt1.oyama/

録画予約システムepgrec(旧本家) http://www.mda.or.jp/epgrec/

@sorceforge.jp http://sourceforge.jp/projects/epgrec/

PT1の解析、ドライバの作成@SourceForge.jp http://sourceforge.jp/projects/pt1dvr/

デバイスの対応

デバイスファイル信号端子
/dev/pt1video0BSデジタル1S1
/dev/pt1video1BSデジタル2S2
/dev/pt1video2地上デジタル1T1
/dev/pt1video3地上デジタル2T2

※アンテナ端子はS1-T1-S2-T2の順で並んでいる

環境(現在)

OSDebian jessie AMD64
CPUAthlon II X4 605e
Memory8GBytes
Kernel4.7.0

Debian Wheezy(↑とは別マシン→Debian/構築メモ_新reginleif)ではpcscdがOS起動時に自動起動せず、必要に応じて動き出す(引数に--auto-exitというのがついてる)ようになっているが、これだとrecpt1の--b25オプションが機能しない。
/etc/init.d/pcscdの下記箇所の"exit"をコメントアウトすると以前と同じく自動起動するようになり、recpt1も正常に動くようになる

# DO NOT start the daemon on startup
# comment the line to have the same behavior as in version < 1.6.0
#exit 0

libccidパッケージのバージョンが上がってNTTComのカードリーダーが認識されない場合は修正が必要→Linux/テレビ関連/libccid

事前準備等

PT1/PT2ドライバの開発がmercurialで管理されているので、mercurialをインストール

# aptitude install mercurial

カードリーダー関連

# aptitude install libpcsclite-dev
# aptitude install pcsc-tools
# aptitude install pcscd

カードリーダー確認

# pcsc_scan
PC/SC device scanner
V 1.4.16 (c) 2001-2009, Ludovic Rousseau <ludovic.rousseau@free.fr>
Compiled with PC/SC lite version: 1.5.5
Scanning present readers...
0: SCM SCR 3310 NTTCom [Vendor Interface] 00 00

Mon Apr  5 22:17:21 2010
 Reader 0: SCM SCR 3310 NTTCom [Vendor Interface] 00 00
  Card state: Card inserted, 
  ATR: 3B F0 12 00 FF 91 81 B1 7C 45 1F 03 99

ATR: 3B F0 12 00 FF 91 81 B1 7C 45 1F 03 99
+ TS = 3B --> Direct Convention
+ T0 = F0, Y(1): 1111, K: 0 (historical bytes)
  TA(1) = 12 --> Fi=372, Di=2, 186 cycles/ETU
    21505 bits/s at 4 MHz, fMax for Fi = 5 MHz => 26881 bits/s
  TB(1) = 00 --> VPP is not electrically connected
  TC(1) = FF --> Extra guard time: 255 (special value)
  TD(1) = 91 --> Y(i+1) = 1001, Protocol T = 1 
-----
  TA(2) = 81 --> Protocol to be used in spec mode: T=1 - Unable to change - defined by interface bytes
  TD(2) = B1 --> Y(i+1) = 1011, Protocol T = 1 
-----
  TA(3) = 7C --> IFSC: 124
  TB(3) = 45 --> Block Waiting Integer: 4 - Character Waiting Integer: 5
  TD(3) = 1F --> Y(i+1) = 0001, Protocol T = 15 - Global interface bytes following 
-----
  TA(4) = 03 --> Clock stop: not supported - Class accepted by the card: (3G) A 5V B 3V 
+ Historical bytes: 
+ TCK = 99 (correct checksum)

Possibly identified card (using /usr/share/pcsc/smartcard_list.txt):
3B F0 12 00 FF 91 81 B1 7C 45 1F 03 99
	Japanese Chijou Digital B-CAS Card (pay TV)

→Ctrl+Cで停止

上記以外にautoconf,pkg-configも必要(大抵入ってるけど)

PT1/PT2ドライバのダウンロードおよび修正

※このページのコピペは自由です。2.6.39対応パッチ以外は他所様からのコピペです。※
※2.6.39対応パッチも2chの情報をきっかけに作っただけです。※

ここで手動で修正している内容の多くは現在では不要なものです。
大抵はオリジナルのドライバ作者様のリポジトリで同様の修正が行われています。

  1. ダウンロード(pt1.oyama版)
    ローカルにmercurialのリポジトリコピー作成
    $ hg clone http://hg.honeyplanet.jp/pt1.oyama/ pt1_driver_oyama
    全チェンジセットを取得中
    チェンジセットを追加中
    マニフェストを追加中
    ファイルの変更を追加中
    136 のチェンジセット(900 の変更を 670 ファイルに適用)を追加
    ブランチ default へ更新中
    ファイル状態: 更新数 565、マージ数 0、削除数 0、衝突未解決数 0
    
  2. arib25ディレクトリ復活
    一部のディレクトリ(arib25)が削除されている(74:b6607f6e2851)ので、一旦過去のリビジョン(73:c44e16dbb0e2)にもどしてから、最新に戻す。
    $ cd pt1_driver_oyama
    $ hg revert -r c44e16dbb0e2 --all
    (snip)
    $ hg revert -r tip --all
    (snip)
    
  3. ドライバunload時のOops回避
    http://hibari.2ch.net/test/read.cgi/linux/1309182037/153
    > ようやく地デジ化したので参戦。よろしく
    > >>61 で出てる rmmod で oops 吐く問題は、pt1_pci_cleanup の中の
    > class_destroy と pci_unregister_driver の順番が逆なせいじゃないかな。
    > unregister が先だよね?
    
    driver/pt1_pci.cを修正
    $ cd driver
    $ vi pt1_pci.c
    
    修正箇所
    --- pt1_pci.c_oops	2011-05-20 22:39:18.000000000 +0900
    +++ pt1_pci.c	2011-07-27 19:52:59.000000000 +0900
    @@ -1011,8 +1011,8 @@
     
     static void __exit pt1_pci_cleanup(void)
     {
    -	class_destroy(pt1video_class);
     	pci_unregister_driver(&pt1_driver);
    +	class_destroy(pt1video_class);
     }
     
     module_init(pt1_pci_init);
    
  4. 2.6.36対応
    http://sourceforge.jp/projects/pt1dvr/ からのパクリ
    pt1_drv.cを下記のとおり修正
    --- a/driver/pt1_pci.c	Thu Aug 25 08:30:08 2011 +0900
    +++ b/driver/pt1_pci.c	Fri Aug 26 00:34:17 2011 +0900
    @@ -18,6 +18,9 @@
     #include <linux/mutex.h>
     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
     #include <linux/freezer.h>
    +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
    +#include <linux/smp_lock.h>
    +#endif
     #else
     #define set_freezable()
     #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
    @@ -76,6 +79,7 @@
     #define		DMA_SIZE	4096			// DMAバッファサイズ
     #define		DMA_RING_SIZE	128			// RINGサイズ
     #define		DMA_RING_MAX	511			// 1RINGにいくつ詰めるか(1023はNGで511まで)
    +#define		MAX_READ_SIZE	(1024 * 4)
     #define		CHANEL_DMA_SIZE	(2*1024*1024)	// 地デジ用(16Mbps)
     #define		BS_CHANEL_DMA_SIZE	(4*1024*1024)	// BS用(32Mbps)
     
    @@ -309,12 +313,12 @@
     			// 頻度を落す(4Kで起動させる)
     			for(lp = 0 ; lp < MAX_CHANNEL ; lp++){
     				channel = dev_conf->channel[real_channel[lp]] ;
    -				if((channel->size >= DMA_SIZE) && (channel->valid == TRUE)){
    +				if((channel->size >= MAX_READ_SIZE ) && (channel->valid == TRUE)){
     					wake_up(&channel->wait_q);
     				}
     			}
     		}
    -		schedule_timeout_interruptible(msecs_to_jiffies(1));
    +		schedule_timeout_interruptible(msecs_to_jiffies(10));
     	}
     	return 0 ;
     }
    @@ -403,9 +407,9 @@
     	__u32	size ;
     	unsigned long dummy;
     
    -	// 4K単位で起こされるのを待つ(CPU負荷対策)
    -	if(channel->size < DMA_SIZE){
    -		wait_event_timeout(channel->wait_q, (channel->size >= DMA_SIZE),
    +	// 128K単位で起こされるのを待つ(CPU負荷対策)
    +	if(channel->size < MAX_READ_SIZE){
    +		wait_event_timeout(channel->wait_q, (channel->size >= MAX_READ_SIZE),
     							msecs_to_jiffies(500));
     	}
     	mutex_lock(&channel->lock);
    @@ -568,6 +572,18 @@
     	return -EINVAL;
     }
     
    +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) 
    +static long pt1_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
    +{
    +	long rc;
    +
    +	lock_kernel();
    +	rc = pt1_ioctl(file->f_path.dentry->d_inode, file, cmd, arg);
    +	unlock_kernel();
    +	return rc;
    +}
    +#endif
    +
     /*
     */
     static const struct file_operations pt1_fops = {
    @@ -575,7 +591,11 @@
     	.open		=	pt1_open,
     	.release	=	pt1_release,
     	.read		=	pt1_read,
    +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
    +	.unlocked_ioctl	=	pt1_unlocked_ioctl,
    +#else
     	.ioctl		=	pt1_ioctl,
    +#endif
     	.llseek		=	no_llseek,
     };
    
  5. 2.6.39対応(mutex版)
    ioctl時の排他をmutexで行う。CPUコア数+1以上並列で録画してもフリーズしない (^_-
    STOP_REC時のウェイトはおまけ(稀に発生するチューナー設定不能対策)
    --- a/driver/pt1_pci.c	Tue Nov 08 22:47:17 2011 +0900
    +++ b/driver/pt1_pci.c	Fri Nov 11 22:56:07 2011 +0900
    @@ -19,8 +19,10 @@
     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
     #include <linux/freezer.h>
     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
    +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39)
     #include <linux/smp_lock.h>
     #endif
    +#endif
     #else
     #define set_freezable()
     #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
    @@ -148,6 +150,10 @@
     #define		PT1MAJOR	251
     #define		DRIVERNAME	"pt1video"
     
    +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
    +static DEFINE_MUTEX(pt1_ioctl_mutex);
    +#endif
    +
     static	void	reset_dma(PT1_DEVICE *dev_conf)
     {
     
    @@ -537,6 +543,7 @@
     			return 0 ;
     		case STOP_REC:
     			SetStream(channel->ptr->regs, channel->channel, FALSE);
    +			schedule_timeout_interruptible(msecs_to_jiffies(100));
     			return 0 ;
     		case GET_SIGNAL_STRENGTH:
     			switch(channel->type){
    @@ -577,9 +584,18 @@
     {
     	long rc;
     
    +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
    +	if(mutex_lock_interruptible(&pt1_ioctl_mutex))
    +		return -EINTR;
    +#else
     	lock_kernel();
    +#endif
     	rc = pt1_ioctl(file->f_path.dentry->d_inode, file, cmd, arg);
    +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
    +	mutex_unlock(&pt1_ioctl_mutex);
    +#else
     	unlock_kernel();
    +#endif
     	return rc;
     }
     #endif
    
  6. kernel 3.4対応
    "asm/system.h"が分割されて無くなったことへの対応
    http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commit;h=0195c00244dc2e9f522475868fa278c473ba7339
    というか、元々使ってない(多分)のでincludeする必要無し。以下の4ファイルからinclude文削除
    pt1_tuner.c pt1_pci.c pt1_i2c.c pt1_tuner_data.c
    変更箇所
    $ diff -u pt1_pci.c_20120525 pt1_pci.c
    --- pt1_pci.c_20120525	2011-11-11 19:20:54.000000000 +0900
    +++ pt1_pci.c	2012-05-25 22:17:06.000000000 +0900
    @@ -10,7 +10,6 @@
     #include <linux/init.h>
     #include <linux/interrupt.h>
     
    -#include <asm/system.h>
     #include <asm/io.h>
     #include <asm/irq.h>
     #include <asm/uaccess.h>
    
    他の3ファイルも同様にinclude文削除(詳細略)
  7. kernel3.8対応
    CONFIG_HOTPLUGが常に"y"になり、関連するマクロ(__devinitdata等)が削除されたことに対応
    # diff -u pt1_pci.c_20130220 pt1_pci.c
    --- pt1_pci.c_20130220	2012-05-22 00:45:08.000000000 +0900
    +++ pt1_pci.c	2013-02-20 23:56:44.000000000 +0900
    @@ -41,7 +41,11 @@
     #include	"pt1_ioctl.h"
     
     /* These identify the driver base version and may not be removed. */
    +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
     static char version[] __devinitdata =
    +#else
    +static char version[] =
    +#endif
     DRV_NAME ".c: " DRV_VERSION " " DRV_RELDATE " \n";
     
     MODULE_AUTHOR("Tomoaki Ishikawa tomy@users.sourceforge.jp and Yoshiki Yazawa yaz@honeyplanet.jp");
    @@ -690,7 +694,11 @@
     	}
     	return 0 ;
     }
    +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
     static int __devinit pt1_pci_init_one (struct pci_dev *pdev,
    +#else
    +static int pt1_pci_init_one (struct pci_dev *pdev,
    +#endif
     				     const struct pci_device_id *ent)
     {
     	int			rc ;
    @@ -916,7 +924,11 @@
     
     }
     
    +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
     static void __devexit pt1_pci_remove_one(struct pci_dev *pdev)
    +#else
    +static void pt1_pci_remove_one(struct pci_dev *pdev)
    +#endif
     {
     
     	int		lp ;
    @@ -983,7 +995,11 @@
     static struct pci_driver pt1_driver = {
     	.name		= DRV_NAME,
     	.probe		= pt1_pci_init_one,
    +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
     	.remove		= __devexit_p(pt1_pci_remove_one),
    +#else
    +	.remove		= pt1_pci_remove_one,
    +#endif
     	.id_table	= pt1_pci_tbl,
     #ifdef CONFIG_PM
     	.suspend	= pt1_pci_suspend,
    
  8. kernel4.2対応
    asm/io.hからのlinux/vmalloc.hのincludeが削除されたので明示的にincludeが必要になった
    --- pt1_pci.c_20150907	2014-01-02 13:04:05.000000000 +0900
    +++ pt1_pci.c	2015-09-07 00:33:45.920593395 +0900
    @@ -16,6 +16,9 @@
     #include <asm/system.h>
     #endif
     #include <asm/io.h>
    +#if LINUX_VERSION_CODE >=KERNEL_VERSION(4,2,0)
    +#include <linux/vmalloc.h>
    +#endif
     #include <asm/irq.h>
     #include <asm/uaccess.h>
    
    以上の修正でカーネル4.7まで動作確認
    パッチ適用済みpt1_pci.c→最新のリポジトリからGet推奨。このページの変なパッチ群は不要になっているはずなので
    Debian/Ubuntu用debパッケージ作成(ドライバのみ)→Linux/テレビ関連/PT2_debパッケージ作成(新)

    ■(旧)2.6.39対応(spin_lock版)
    kernel 2.6.39でBKLが無くなった事への対応
    lock_kernel/unlock_kernel→spin_lock/spin_unlockに置き換える
    ※CPUコア数+1以上並列で録画するとフリーズする。mutex版を推奨※

    http://hibari.2ch.net/test/read.cgi/linux/1309182037/690
    > kernel 3.0.7にspin_lockパッチを当てたchardev版を使ってたんですけど、
    > recpt1複数が同時に走るとOSごと応答しなくなりません?(デッドロック状態?)
    >
    > このスレを参考にlock_kernelをspin_lockではなくmutex_lockに置き換えるとrecpt1が4本同時でも走るようになったんですが
    > この修正で問題ないでしょうか
    > http://2sen.dip.jp/cgi-bin/pt1up/source/up0343.gz
    > chardev版本家の pt1-7662d0ecd74b の pt1_pci.c にそのまま当たると思います 
    
    --- a/driver/pt1_pci.c	Fri Aug 26 00:42:32 2011 +0900
    +++ b/driver/pt1_pci.c	Fri Aug 26 01:27:02 2011 +0900
    @@ -19,8 +19,12 @@
     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
     #include <linux/freezer.h>
     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
    +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
    +#include <linux/spinlock.h>
    +#else
     #include <linux/smp_lock.h>
     #endif
    +#endif
     #else
     #define set_freezable()
     #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
    @@ -148,6 +152,10 @@
     #define		PT1MAJOR	251
     #define		DRIVERNAME	"pt1video"
     
    +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
    +static spinlock_t pt1_ioctl_spin_lock;
    +#endif
    +
     static	void	reset_dma(PT1_DEVICE *dev_conf)
     {
     
    @@ -577,9 +585,17 @@
     {
     	long rc;
     
    +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39) 
    +	spin_lock(&pt1_ioctl_spin_lock);
    +#else
     	lock_kernel();
    +#endif
     	rc = pt1_ioctl(file->f_path.dentry->d_inode, file, cmd, arg);
    +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
    +	spin_unlock(&pt1_ioctl_spin_lock);
    +#else
     	unlock_kernel();
    +#endif
     	return rc;
     }
     #endif
    @@ -984,6 +1000,9 @@
     	pt1video_class = class_create(THIS_MODULE, DRIVERNAME);
     	if (IS_ERR(pt1video_class))
     		return PTR_ERR(pt1video_class);
    +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
    +	spin_lock_init(&pt1_ioctl_spin_lock);
    +#endif
     	return pci_register_driver(&pt1_driver);
     }
    

コンパイル&インストール

  1. デバイスドライバインストール
    ローカルに作成したリポジトリコピーのdriverディレクトリでmake
    $ cd driver
    $ make
    (snip)
    
    インストールはrootで
    $ su -c "make install"
    パスワード:
    install -m 644 pt1_drv.ko /lib/modules/`uname -r`/kernel/drivers/video
    if [ -d /etc/udev/rules.d -a ! -f /etc/udev/rules.d/99-pt1.rules ] ; then \
    		install -m 644 etc/99-pt1.rules /etc/udev/rules.d ; \
    	fi
    depmod -a
    
    rootでデバイスドライバのロード
    # modprobe pt1_drv
    
  2. libalib25/b25の導入
    ローカルリポジトリの"arib25"ディレクトリ(※事前に復活させておく)でmakeする
    $ cd ../arib25/
    $ make
    (snip)
    
    インストール
    $ su -c "make install"
    (snip)
    $ /sbin/ldconfig -p | grep libarib25
    	libarib25.so.0 (libc6,x86-64) => /usr/local/lib/libarib25.so.0
    	libarib25.so (libc6,x86-64) => /usr/local/lib/libarib25.so
    
  3. recpt1の導入
    $ cd ../recpt1/
    $ make
    revh=`hg parents --template 'const char *version = "r{rev}:{node|short} ({date|isodate})";\n' 2>/dev/null`; \
    	if [ -n "$revh" ] ; then \
    		echo "$revh" > version.h; \
    	else \
    		echo "const char *version = \"'1.0.0'\";" > version.h; \
    	fi
    gcc -MM recpt1.c decoder.c mkpath.c -I../driver -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DB25 > .deps
    gcc -O2 -g -pthread -I../driver -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DB25  -c -o recpt1.o recpt1.c
    recpt1.c: In function ‘reader_func’:
    recpt1.c:200:25: warning: variable ‘addr’ set but not used [-Wunused-but-set-variable]
    gcc -O2 -g -pthread -I../driver -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DB25  -c -o decoder.o decoder.c
    gcc -O2 -g -pthread -I../driver -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DB25  -c -o mkpath.o mkpath.c
    gcc  -o recpt1 recpt1.o decoder.o mkpath.o `pkg-config libpcsclite --libs` -larib25 -lm -lpthread
    
    インストール
    $ su -c "make install"
    パスワード:
    install -m 755 recpt1 recpt1ctl checksignal /usr/local/bin
    

    旧版( http://hg.honeyplanet.jp/pt1/ )のrecpt1の場合、autogen.sh→configureが必要だった

    $ cd ../recpt1/
    $ ./autogen.sh 
    Generating configure script and Makefiles for recpt1.
    Running aclocal ...
    Running autoheader ...
    Running autoconf ...
    $ ./configure --prefix=/usr/local/ --enable-b25
    (snip)
    $ make
    (snip)
    
  • 実行
    $ recpt1 --b25 --strip --device /dev/pt1video2 25 30 /mnt/video/ch25.ts

デバイスの指定は不要。(元からなのか、特定バージョン以降なのかは不明)

録画後のいろいろ

要はゴミ消し&サイズ削減

不要な情報の削除

tss.pyの場合

$ tss.py 'hogehoge.ts'

tsspliter_liteの場合(ffmpegでも同じ事が出来るけど)

$ tsspliter_lite "入力ファイル.ts" "出力ファイル.ts" プログラムID
※プログラムIDは事前にffmpegで確認しておく

TS -> MPEG-PS変換

http://pc11.2ch.net/test/read.cgi/linux/1230616112/467

$ ffmpeg -f mpegts -i "入力ファイル.ts" -vcodec copy -acodec mp2 -ab 224k -ar 48000 -ac 2 -y -f vob "出力ファイル.mpeg"

編集はAvidemuxを使用。音が遅れる場合は音声の[ずれ]にチェックを付けて、マイナスの値で調整する。(-800ms)
先頭がキーフレームじゃないとエラーになるっぽい

特定のプログラムID抽出&mpeg変換

tss.py,tsspliter_liteがやってる事をffmpegでやる場合。まず、TSファイル内のProgramIDを確認

$ ffmpeg -i "TSファイル.ts"
(snip)
Input #0, mpegts, from 'TSファイル.ts':
 Duration: 00:30:09.82, start: 45586.935233, bitrate: 14774 kb/s
 Program 10xx
   Metadata:
(snip)
 Program 10xy
   Metadata:
(snip)

"Program"の所に表示されている数字がProgramID。基本的に一番小さい数値がメイン
確認したProgramIDを指定して、抽出する。

$ ffmpeg -i "TSファイル.ts" -programid 10xx -vcodec copy -acodec mp2 -ab 224k -ar 48000 -ac 2 -f vob "MEPGファイル.mpeg"

特定のプログラムID抽出&mpeg変換(ffmpeg 0.9?以降)

最近のffmpegではprogramidオプションが無くなった。(0.8.12にはあるので多分0.9以降)
なのでprogramidの代わりにmapオプションで必要なストリームを指定する。 例えばffmpeg -iの実行結果が下記の場合、

$ ffmpeg -i "TSファイル.ts"
Seems stream 12 codec frame rate differs from container frame rate: 29.97 (30000/1001) -> 29.97 (30000/1001)
Input #0, mpegts, from 'TSファイル名.ts':
  Duration: 00:30:09.75, start: 70129.959289, bitrate: 11301 kb/s
  Program 100xx .........
    Metadata:
      name            : ..........
      provider_name   : 
    Stream #0.0[0x111]: Video: mpeg2video, yuv420p, 1440x1080 [PAR 4:3 DAR 16:9], 20000 kb/s, 30.81 fps, 29.97 tbr, 90k tbn, 59.94 tbc
    Stream #0.1[0x112]: Audio: aac, 48000 Hz, stereo, s16, 196 kb/s
    Stream #0.2[0x740]: Data: 0x000d
    Stream #0.3[0x750]: Data: 0x000d
    Stream #0.4[0x751]: Data: 0x000d
    Stream #0.5[0x752]: Data: 0x000d
    Stream #0.6[0x960]: Data: 0x000d
    Stream #0.7[0x961]: Data: 0x000d
    Stream #0.8[0x75e]: Data: 0x000d
    Stream #0.9[0x75f]: Data: 0x000d
    Stream #0.10[0x96e]: Data: 0x000d
(中略)
  Program 200xx .......
    Metadata:
      name            : ...........
      provider_name   : 
    Stream #0.12[0x281]: Video: h264, yuv420p, 320x180, 17.13 fps, 29.97 tbr, 90k tbn, 29.97 tbc
    Stream #0.11[0x283]: Audio: aac, 48000 Hz, stereo, s16, 48 kb/s
    Stream #0.13[0x780]: Data: 0x000d
    Stream #0.14[0x789]: Data: 0x000d
    Stream #0.15[0x98a]: Data: 0x000d
(以下略)

ProgramID"100xx"の中のStream #0.0と#0.1を抽出する場合、mapオプション2つで指定する

$ ffmpeg -i "TSファイル.ts" -map 0:0 -map 0:1 -vcodec copy -acodec mp2 -ab 224k -ar 48000 -ac 2 -f vob "MEPGファイル.mpeg"

2ヶ国語の対応と同じ。

ドライバ更新

本家リポジトリからpullしてコンパイルしなおすだけ
本家が更新されないかぎり以下の作業は不要

$ cd pt1_driver
$ hg pull -u
http://hg.honeyplanet.jp/pt1/ から取り込み中
変更点を探索中
チェンジセットを追加中
マニフェストを追加中
ファイルの変更を追加中
32 のチェンジセット(58 の変更を 15 ファイルに適用)を追加
ファイル状態: 更新数 15、マージ数 0、削除数 0、衝突未解決数 0
$ cd driver/
$ make
(snip)
$ su -c "make install"
(snip)

ドライバロード

# modprobe pt1_drv
pt1-pci.c: 1.1.0 2010-01-27 
Bus Mastering Enabled.
PT1:ISDB-S Sleep
PT1:ISDB-S Sleep
PT1:ISDB-T Sleep
PT1:ISDB-T Sleep
PT1:device[0]=(null)
PT1:card_number = 0
PT1:card_number = 0
PT1:card_number = 0
PT1:card_number = 0
pt1_thread run
  • TS split内蔵版への更新
    $ hg clone http://hg.honeyplanet.jp/pt1.oyama/ pt1_driver_split
    全チェンジセットを取得中
    チェンジセットを追加中
    マニフェストを追加中
    ファイルの変更を追加中
    123 のチェンジセット(319 の変更を 115 ファイルに適用)を追加
    ブランチ default へ更新中
    ファイル状態: 更新数 31、マージ数 0、削除数 0、衝突未解決数 0
    $ cd pt1_driver_split/driver
    $ make
    (snip)
    $ su -c "make install"
    パスワード:
    install -m 644 pt1_drv.ko /lib/modules/`uname -r`/kernel/drivers/video
    if [ -d /etc/udev/rules.d -a ! -f /etc/udev/rules.d/99-pt1.rules ] ; then \
    		install -m 644 etc/99-pt1.rules /etc/udev/rules.d ; \
    	fi
    depmod -a
    rootユーザーでrmmod->modprobe。続けてrecpt1インストール
    $ cd ../recpt1/
    $ ./autogen.sh 
    Generating configure script and Makefiles for recpt1.
    Running aclocal ...
    Running autoheader ...
    Running autoconf ...
    $ ./configure --prefix=/usr/local/ --enable-b25
    checking for gcc... gcc
    checking whether the C compiler works... yes
    checking for C compiler default output file name... a.out
    checking for suffix of executables... 
    checking whether we are cross compiling... no
    checking for suffix of object files... o
    checking whether we are using the GNU C compiler... yes
    checking whether gcc accepts -g... yes
    checking for gcc option to accept ISO C89... none needed
    checking for create_arib_std_b25 in -larib25... yes
    checking for log10 in -lm... yes
    checking for pthread_kill in -lpthread... yes
    configure: creating ./config.status
    config.status: creating Makefile
    config.status: creating config.h
    $ make
    $ su -c "make install"
    パスワード:
    install -m 755 recpt1 recpt1ctl checksignal /usr/local/bin

アンロード時のOops(解決済み)

  • 2.6.39.1+自前spin_lock
    BUG: unable to handle kernel NULL pointer dereference at 0000000000000038
    IP: [<ffffffff81109827>] sysfs_delete_link+0x33/0x5b
    PGD 179721067 PUD 20be95067 PMD 0 
    Oops: 0000 [#1] SMP 
    last sysfs file: /sys/devices/virtual/net/virbr2/statistics/collisions
    CPU 0 
    Modules linked in: nfsd lockd auth_rpcgss sunrpc ip6table_filter ip6_tables pt1_drv(-) cryptd aes_x86_64 aes_generic cbc tun
    ipt_MASQUERADE iptable_nat nf_nat ipt_REJECT parport_pc lp parport xt_TCPMSS xt_tcpmss iptable_mangle powernow_k8
    mperf cpufreq_powersave cpufreq_conservative cpufreq_userspace cpufreq_stats pppoe pppox kvm_amd kvm iscsi_tcp
    libiscsi_tcp libiscsi scsi_transport_iscsi fuse bridge stp llc xt_multiport xt_owner xt_tcpudp nf_conntrack_ipv4
    nf_defrag_ipv4 xt_state nf_conntrack ipt_LOG xt_limit iptable_filter ip_tables x_tables af_packet ppp_generic slhc ipv6
    loop dm_crypt fglrx(P) rtc_cmos snd_hda_codec_hdmi snd_hda_codec_realtek agpgart snd_hda_intel snd_hda_codec asus_atk0110
    processor snd_hwdep snd_pcm snd_timer rtc_core thermal_sys rtc_lib snd soundcore snd_page_alloc k10temp evdev amd64_edac_mod
    edac_core button raid1 md_mod btrfs lzo_compress zlib_deflate crc32c libcrc32c sg sr_mod sd_mod cdrom ata_generic
    pata_acpi e1000e ahci pata_atiixp r8169 ohci_hcd libahci mii [last unloaded: scsi_wait_scan]
    
    Pid: 14195, comm: rmmod Tainted: P            2.6.39.1-yuk #1 System manufacturer System Product Name/M4A79T Deluxe
    RIP: 0010:[<ffffffff81109827>]  [<ffffffff81109827>] sysfs_delete_link+0x33/0x5b
    RSP: 0018:ffff8802057e5cc8  EFLAGS: 00010282
    RAX: ffff8801ee472cd0 RBX: ffff880221978618 RCX: 0000000000000000
    RDX: ffff8801f653af00 RSI: ffff880220cfa810 RDI: ffffffff8152d4f0
    RBP: ffff8802057e5ce8 R08: 00000000000039f4 R09: 000000000000000f
    R10: 0000000000000000 R11: 0000000000000000 R12: ffff880220cfa810
    R13: 0000000000000001 R14: 0000000000000004 R15: 00000000000001c0
    FS:  00007fadc7f92700(0000) GS:ffff88022fc00000(0000) knlGS:00000000f4db1710
    CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
    CR2: 0000000000000038 CR3: 00000001de4a6000 CR4: 00000000000006f0
    DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
    DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
    Process rmmod (pid: 14195, threadinfo ffff8802057e4000, task ffff8802231a7910)
    Stack:
     ffff880220cfa800 ffff8801f653af00 ffff880220cfa810 ffff880220cfa800
     ffff8802057e5d08 ffffffff811cf0bd ffff880220cfa800 0000000000000000
     ffff8802057e5d38 ffffffff811cf3b1 ffff880220cfa810 ffff880220cfa800
    Call Trace:
     [<ffffffff811cf0bd>] device_remove_class_symlinks+0x6f/0x74
     [<ffffffff811cf3b1>] device_del+0x81/0x18c
     [<ffffffff811cf4cd>] device_unregister+0x11/0x1e
     [<ffffffff811cf510>] device_destroy+0x36/0x3d
     [<ffffffffa01aa3b0>] pt1_pci_remove_one+0xf6/0x19b [pt1_drv]
     [<ffffffff8116ee55>] pci_device_remove+0x28/0x4c
     [<ffffffff811d12e5>] __device_release_driver+0x67/0xb0
     [<ffffffff811d13ac>] driver_detach+0x7e/0xa4
     [<ffffffff811d0669>] bus_remove_driver+0x8c/0xaf
     [<ffffffff811d19c5>] driver_unregister+0x67/0x6f
     [<ffffffff8116f100>] pci_unregister_driver+0x41/0xa1
     [<ffffffffa01aa2b8>] pt1_pci_cleanup+0x1c/0x1e [pt1_drv]
     [<ffffffff8105fc3b>] sys_delete_module+0x1ba/0x226
     [<ffffffff8109ca0f>] ? do_munmap+0x30b/0x32d
     [<ffffffff812c7e52>] system_call_fastpath+0x16/0x1b
    Code: f4 53 48 89 fb 48 c7 c7 f0 d4 52 81 48 83 ec 10 48 89 55 e8 e8 31 db 1b 00 49 8b 44 24 30 48 8b 55 e8 48 85 c0 74 14 48 8b 4b 30 <8b> 49 38 0f b6 cd 85 c9 74 06 48 8b 70 20 eb 02 31 f6 fe 05 b1 
    RIP  [<ffffffff81109827>] sysfs_delete_link+0x33/0x5b
     RSP <ffff8802057e5cc8>
    CR2: 0000000000000038
    ---[ end trace f3d03c391b9bf7fb ]---
    

修正はこのページの↑ドライバunload時のOops回避を参照

kernel 2.6.39コンパイルエラー(解決済み)

make[1]: ディレクトリ `/usr/src/linux-2.6.39.0' に入ります
  CC [M]  /home/usk/work/pt1_driver_oyama/driver/pt1_pci.o
/home/usk/work/pt1_driver_oyama/driver/pt1_pci.c:24:28: error: linux/smp_lock.h: そのようなファイルやディレクトリはありません
/home/usk/work/pt1_driver_oyama/driver/pt1_pci.c: In function ‘pt1_unlocked_ioctl’:
/home/usk/work/pt1_driver_oyama/driver/pt1_pci.c:582: error: implicit declaration of function ‘lock_kernel’
/home/usk/work/pt1_driver_oyama/driver/pt1_pci.c:584: error: implicit declaration of function ‘unlock_kernel’
make[2]: *** [/home/usk/work/pt1_driver_oyama/driver/pt1_pci.o] エラー 1
make[1]: *** [_module_/home/usk/work/pt1_driver_oyama/driver] エラー 2
make[1]: ディレクトリ `/usr/src/linux-2.6.39.0' から出ます
make: *** [pt1_drv.ko] エラー 2

2.6.39からBKLが無くなったので、lock_kernel/unlock_kernelは使用不可
spin_lockで代替
mutexで代替。2.6.39対応を参照

kernel 3.4.0コンパイルエラー(解決済み)

$ make 
revh=`hg parents --template '#define DRV_VERSION "r{rev}:{node|short}"\n#define DRV_RELDATE "{date|shortdate}"\n' 2>/dev/null`; \
	if [ -n "$revh" ] ; then \
		echo "$revh" > version.h; \
	else \
		printf "#define DRV_VERSION \""1.1.0"\"\n#define DRV_RELDATE \""2010-01-27"\"\n" > version.h; \
	fi
make -C /lib/modules/3.4.0-yuk/build M=`pwd` V=0 modules
make[1]: ディレクトリ `/usr/src/linux-3.4.0' に入ります
  CC [M]  /mnt/work/pt1_driver_oyama/driver/pt1_pci.o
/mnt/work/pt1_driver_oyama/driver/pt1_pci.c:13:24: error: asm/system.h: そのようなファイルやディレクトリはありません
make[2]: *** [/mnt/work/pt1_driver_oyama/driver/pt1_pci.o] エラー 1
make[1]: *** [_module_/mnt/work/pt1_driver_oyama/driver] エラー 2
make[1]: ディレクトリ `/usr/src/linux-3.4.0' から出ます
make: *** [pt1_drv.ko] エラー 2

3.4.0でsystem.hが複数に分割されて無くなった為↓
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commit;h=0195c00244dc2e9f522475868fa278c473ba7339
元々使ってないっぽいのでinclude自体不要(3.3.7と2.6.32ではincludeせずにコンパイルOK)
このページの"PT1/PT2ドライバのダウンロードおよび修正"のkernel 3.4対応を参照

kernel3.8コンパイルエラー(解決済み)

kernel3.8でビルドに失敗する(↓はdkmsパッケージのものだけど)

DKMS make.log for pt1-chardev-1.1.0 for kernel 3.8.0-yuk (x86_64)
2013年  2月 20日 水曜日 20:35:59 JST
make: ディレクトリ `/usr/src/linux-3.8.0' に入ります
/usr/src/linux-3.8.0/arch/x86/Makefile:103: CONFIG_X86_X32 enabled but no binutils support
  LD      /var/lib/dkms/pt1-chardev/1.1.0/build/built-in.o
  CC [M]  /var/lib/dkms/pt1-chardev/1.1.0/build/pt1_pci.o
/var/lib/dkms/pt1-chardev/1.1.0/build/pt1_pci.c:44: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘__devinitdata’
/var/lib/dkms/pt1-chardev/1.1.0/build/pt1_pci.c:693: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘pt1_pci_init_one’
/var/lib/dkms/pt1-chardev/1.1.0/build/pt1_pci.c:919: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘pt1_pci_remove_one’
/var/lib/dkms/pt1-chardev/1.1.0/build/pt1_pci.c:985: error: ‘pt1_pci_init_one’ undeclared here (not in a function)
/var/lib/dkms/pt1-chardev/1.1.0/build/pt1_pci.c:986: error: implicit declaration of function ‘__devexit_p’
/var/lib/dkms/pt1-chardev/1.1.0/build/pt1_pci.c:986: error: ‘pt1_pci_remove_one’ undeclared here (not in a function)
/var/lib/dkms/pt1-chardev/1.1.0/build/pt1_pci.c: In function ‘pt1_pci_init’:
/var/lib/dkms/pt1-chardev/1.1.0/build/pt1_pci.c:998: error: ‘version’ undeclared (first use in this function)
/var/lib/dkms/pt1-chardev/1.1.0/build/pt1_pci.c:998: error: (Each undeclared identifier is reported only once
/var/lib/dkms/pt1-chardev/1.1.0/build/pt1_pci.c:998: error: for each function it appears in.)
make[1]: *** [/var/lib/dkms/pt1-chardev/1.1.0/build/pt1_pci.o] エラー 1
make: *** [_module_/var/lib/dkms/pt1-chardev/1.1.0/build] エラー 2
make: ディレクトリ `/usr/src/linux-3.8.0' から出ます

CONFIG_HOTPLUGが常に"y"になり、__devinitdata,__devexit_p等が削除されたため(3.8-rc1以降)
https://lkml.org/lkml/2012/11/16/660
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commit;h=cff2f741b8ee8a70b208830e330de053efd4fc45

pt1_pci.cから__devinitdata等を削除すればOK
このページの"PT1/PT2ドライバのダウンロードおよび修正"のkernel 3.8対応を参照

kernel3.8はPT2ドライバ以外にも以下の対応が必要だった (^-^
AMD Catalyst12.3の修正
mdraid(RAID-1)なマシンが起動しない

Kernel 4.2コンパイルエラー(解決済み)

kernel4.2でドライバのコンパイルに失敗する。

make: Entering directory '/usr/src/linux-4.2.0'
  LD      /var/lib/dkms/pt1-chardev/1.1.0/build/built-in.o
  CC [M]  /var/lib/dkms/pt1-chardev/1.1.0/build/pt1_pci.o
/var/lib/dkms/pt1-chardev/1.1.0/build/pt1_pci.c: In function ‘pt1_pci_init_one’:
/var/lib/dkms/pt1-chardev/1.1.0/build/pt1_pci.c:857:5: error: implicit declaration of function ‘vmalloc’ [-Werror=implicit-function-declaration]
     channel->buf = vmalloc(CHANNEL_DMA_SIZE);
     ^
/var/lib/dkms/pt1-chardev/1.1.0/build/pt1_pci.c:857:18: warning: assignment makes pointer from integer without a cast
     channel->buf = vmalloc(CHANNEL_DMA_SIZE);
                  ^
/var/lib/dkms/pt1-chardev/1.1.0/build/pt1_pci.c:862:18: warning: assignment makes pointer from integer without a cast
     channel->buf = vmalloc(BS_CHANNEL_DMA_SIZE);
                  ^
/var/lib/dkms/pt1-chardev/1.1.0/build/pt1_pci.c:911:5: error: implicit declaration of function ‘vfree’ [-Werror=implicit-function-declaration]
     vfree(dev_conf->channel[lp]->buf);
     ^
cc1: some warnings being treated as errors
scripts/Makefile.build:258: recipe for target '/var/lib/dkms/pt1-chardev/1.1.0/build/pt1_pci.o' failed
make[1]: *** [/var/lib/dkms/pt1-chardev/1.1.0/build/pt1_pci.o] Error 1
Makefile:1386: recipe for target '_module_/var/lib/dkms/pt1-chardev/1.1.0/build' failed
make: *** [_module_/var/lib/dkms/pt1-chardev/1.1.0/build] Error 2
make: Leaving directory '/usr/src/linux-4.2.0'

"<asm/io.h>"からのvmalloc.hのincludeが削除された為
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=d6472302f242
vmallocを使う場合は<linux/vmalloc.h>を明示的にincludeしないといけなくなった。