Record TV over USB

Here for general support for B series TVs, request and problem solve area.

User avatar
erdem_ua
SamyGO Admin
Posts: 3125
Joined: Thu Oct 01, 2009 6:02 am
Location: Istanbul, Turkey
Contact:

Re: Record TV over USB

Post by erdem_ua »

I just tried geoPVR via NFS but no lock. Just zero length file created. :p
Also I have crash on exiting pvr mode (using LE40B650 CI with 2005.0)
Will diagnose soon I wish.

But rec icon make me emotionally happy :)
Also key lock is working good.
Thanks. ;)
sbav1
Official SamyGO Developer
Posts: 374
Joined: Fri Jan 15, 2010 10:20 am

Re: Record TV over USB

Post by sbav1 »

There is DVB-T broadcast in Cracow (finally), so I started messing with TSD/PVR hardware :). Got some ideas:

1) Recording multiple programs concurrently (from the same multiplex): we just need to set additional PIDs in PID filter bank/PID table.
TSD/PVR PID filter table: 32 hardware registers (128 bytes), starting at 0x30110100 address. E.g.:

Code: Select all

root@localhost:~/bin# reg-range-print 0x30110100 32
0x30110100: 0xA0CA
0x30110104: 0xA0CC
0x30110108: 0x9FFF
0x3011010C: 0x9FFF
0x30110110: 0x9FFF
0x30110114: 0xA000
0x30110118: 0xA010
0x3011011C: 0xA011
0x30110120: 0xA012
0x30110124: 0xA014
0x30110128: 0xA0C9
0x3011012C: 0xA0CD
0x30110130: 0x1FFF
0x30110134: 0x1FFF
0x30110138: 0x1FFF
0x3011013C: 0x1FFF
0x30110140: 0x1FFF
0x30110144: 0x1FFF
0x30110148: 0x0
0x3011014C: 0x0
0x30110150: 0x0
0x30110154: 0x0
0x30110158: 0x0
0x3011015C: 0x0
0x30110160: 0x0
0x30110164: 0x0
0x30110168: 0x0
0x3011016C: 0x0
0x30110170: 0x0
0x30110174: 0x0
0x30110178: 0x0
0x3011017C: 0x0
For each register/filter entry, bits [0-12] are actual PIDs.
Bits [3-13]: flags-switches, details unknown. Typically (I guess) 0x9E000/0x9A000 bitmask is used for PVR on, and 0xA000 for PVR off.
We can add extra PIDs to this table (unused entries == 0x0), like this:

Code: Select all

#!/bin/sh
# reg-range-print 0x30110100 32

## Polsat
devmem2 0x30110150 w 0xA065
devmem2 0x30110154 w 0xA066
devmem2 0x30110158 w 0xA067

## Polsat Sport News
devmem2 0x3011015C w 0xA321
devmem2 0x30110160 w 0xA322
devmem2 0x30110164 w 0xA323

## Tv Puls
devmem2 0x30110168 w 0xA191
devmem2 0x3011016C w 0xA192
devmem2 0x30110170 w 0xA193

## TVN
devmem2 0x30110174 w 0xA0C9
devmem2 0x30110178 w 0xA0CA
devmem2 0x3011017C w 0xA0CC
With such settings, it's possible to record up to 4 programs concurrently (bitrate ca 1.5-2.0 MB/s for SD channels, YMMV). It works much better while recording on network share. For unknown reasons, USB writes seem very slow, even for fast SSD SLC drive!
Generally (I don't know much about DVB-T/C), I think we need to add at least 3 PIDs per program (PMT, video, audio). E.g, PIDs for Polish MUX2 in Cracow:

Code: Select all

GP PID[s]
   0x0000 (PAT), 0x1FFF (NULL)
   0x0010, 0x0011, 0x0012, 0x0014: channel/network data, EPG, ...(???)

Programs (PMT PID, Video PID, Audio PID, ...)
   1: Polsat               0x0065, 0x0066, 0x0067, 0x0069 (TTX ?)
   2: Polsat Sport News    0x0321, 0x0322, 0x0323
   3: PULS 2               0x0259, 0x025A, 0x025B
   4: Tv Puls              0x0191, 0x0192, 0x0193
   5: TV4                  0x012D, 0x012E, 0x012F, 0x0131 (TTX ?)
   6: TV6                  0x02BD, 0x02BE, 0x02BF
   7: TVN                  0x00C9, 0x00CA, 0x00CC, 0x00CD (TTX ?)
   8: TVN Siedem           0x01F5, 0x01F6, 0x01F8, 0x01F9 (TTX ?)
Individual programs can be extracted from recorded .ts file with TS Doctor.
Replacing entries 0 & 1 in PID filter table (while watching TV) results in funny/special effects: video from one program, audio from another one etc. :).

2) Recording in the background: works for external sources (HDMI/PC/Component/...) with active PIP window, but not quite perfectly.. I guess we can improve it a little:
- PIP window can be hidden, by turning Chelsea scaler #1 off. It's possible from TDM. Probably doable from Content Library application level with simple SdVideo_Get()/SdVideo_Set() calls (not tested yet).
- audio not recorded for PIP Sound Select = MAIN: that's because audio PID is missing from filter table. I think it's easily remedied with 1) workaround.

reg-range-print.c (simple tool for figuring out register values / program PIDs):

Code: Select all

#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/mman.h>

#define FATAL do { fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", \
  __LINE__, __FILE__, errno, strerror(errno)); exit(1); } while(0)

#define MAP_SIZE 0xB00000

int main(int argc, char **argv) {
   int fd;
   void *map_base, *virt_addr; 
   unsigned read_result, target;
   int count=1;

   if (argc < 2) {
      fprintf(stderr, "Usage: %s addr [cnt]\n\taddr: register range (0x3000000-0x30B00000|0x0-0xCFFFFC)\n\tcnt: number of U32 registers to print\n", argv[0]);
      exit(1);
   }
   target = strtoul(argv[1], 0, 0);
   if (target >= 0x30000000 && target < 0x30B00000) target-=0x30000000;
   if (target < 0 || target >= MAP_SIZE || target % 4) {
      fprintf(stderr, "Error: invalid Address '0x%x'\n", target);
      exit(1);
   }
   if (argc > 2) count=strtoul(argv[2], 0, 0);

   if ((fd=open("/dev/mem", O_RDWR | O_SYNC)) == -1) FATAL;
   map_base=mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0x30000000);
   if (map_base == (void *) -1) FATAL;

   int i=0; while (i < count) {
      if ((target+4*i) >= MAP_SIZE) break;
      virt_addr = map_base + target + 4*i;
      read_result = *((unsigned long *) virt_addr);
      printf("0x30%X: 0x%X\n", (target+4*i), read_result); fflush(stdout);
      i++;
   }

   if (munmap(map_base, MAP_SIZE) == -1) FATAL;
   close(fd);
   return 0;
} 
majonezz
SamyGO Project Donor
Posts: 63
Joined: Sat Feb 06, 2010 10:44 am
Location: Wroclaw, Poland

Re: Record TV over USB

Post by majonezz »

sbav1 <- well done :)
I found another advantage.
Look at my memdump before inserting CI Module:

Code: Select all

0x30110100: 0xA0CA
0x30110104: 0xA0CB
0x30110108: 0x9FFF
0x3011010C: 0x9FFF
0x30110110: 0x9FFF
0x30110114: 0xA000
0x30110118: 0xA010
0x3011011C: 0xA011
0x30110120: 0xA012
0x30110124: 0xA014
0x30110128: 0xA0C9
0x3011012C: 0xA0CD
0x30110130: 0x1FFF
0x30110134: 0x1FFF
0x30110138: 0x1FFF
0x3011013C: 0x1FFF
0x30110140: 0x1FFF
0x30110144: 0x1FFF
0x30110148: 0x0
0x3011014C: 0x0
0x30110150: 0x0
0x30110154: 0x0
0x30110158: 0x0
0x3011015C: 0x0
0x30110160: 0x0
0x30110164: 0x0
0x30110168: 0x0
0x3011016C: 0x0
0x30110170: 0x0
0x30110174: 0x0
0x30110178: 0x0
0x3011017C: 0x0
And after:

Code: Select all

0x30110100: 0x141A0CA
0x30110104: 0x1A0CB
0x30110108: 0x19FFF
0x3011010C: 0x19FFF
0x30110110: 0x19FFF
0x30110114: 0x1A000
0x30110118: 0x1A010
0x3011011C: 0x1A011
0x30110120: 0x1A012
0x30110124: 0x1A014
0x30110128: 0x1A0C9
0x3011012C: 0x1A0CD
0x30110130: 0x11FFF
0x30110134: 0x11FFF
0x30110138: 0x11FFF
0x3011013C: 0x11FFF
0x30110140: 0x11FFF
0x30110144: 0x11FFF
0x30110148: 0x10000
0x3011014C: 0x10000
0x30110150: 0x10000
0x30110154: 0x10000
0x30110158: 0x10000
0x3011015C: 0x10000
0x30110160: 0x10000
0x30110164: 0x10000
0x30110168: 0x10000
0x3011016C: 0x10000
0x30110170: 0x10000
0x30110174: 0x10000
0x30110178: 0x10000
0x3011017C: 0x10000
Now when i change two first dwords to previous values:
0x30110100: 0xA0CA
0x30110104: 0xA0CB
recording function forks fine even with CI module inserted!
So, guys who have problem with recording and CI CAM, try this.
Now the only question is how to automate this process?
Each time i change channel, this mem area is rewriten with new values - that is obvious.
But how to trace, that user changes channel and read & write back changed value?

UPDATE:
For those, who had problems with CI+ CAM. I've made a simple tool based on devmem2 to check memory area at 0x30110103 and reset it.

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/mman.h>

#define FATAL do { fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", \
  __LINE__, __FILE__, errno, strerror(errno)); exit(1); } while(0)

#define MAP_SIZE 4096UL
#define MAP_MASK (MAP_SIZE - 1)

int main(int argc, char **argv) {
    int fd;
    void *map_base, *virt_addr;
        unsigned long read_result;
        off_t target;
    target = 0x30110100;
    while(1==1)  {
        if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) FATAL;
        map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, target & ~MAP_MASK);
        if(map_base == (void *) -1) FATAL;
        virt_addr = map_base + (target & MAP_MASK);
        read_result = *((unsigned long *) virt_addr);
        if (read_result & 0x1000000) {
            *((unsigned long *) virt_addr) = read_result&0x000FFFFFF;
            printf("Detected!! %lX\n",(read_result&0x000FFFFFF));
            fflush(stdout);
            }
        sleep(1);
        if(munmap(map_base, MAP_SIZE) == -1) FATAL;
        close(fd);
        }
    return 0;
}

You can simply daemonize it, by running with ending "&": ./regwatch &
It just check memarea at 0x30110103 for any value each second and reset it if result is not 0. For unknown reason, when a wrote single byte to this address, strange things happened. Only operating with long values gave good results. Good luck.
User avatar
erdem_ua
SamyGO Admin
Posts: 3125
Joined: Thu Oct 01, 2009 6:02 am
Location: Istanbul, Turkey
Contact:

Re: Record TV over USB

Post by erdem_ua »

Guys, you are amazing. Nothing to say :D
majonezz
SamyGO Project Donor
Posts: 63
Joined: Sat Feb 06, 2010 10:44 am
Location: Wroclaw, Poland

Re: Record TV over USB

Post by majonezz »

viper3k wrote:Hmm I was thinking .. could it be that in some weird way my tv needs the oppisite effect ?? that the memory allocation needs to be filled instead of emptied ..

I disabled all other scripts and apps ... and put the watchreg & in samygo.sh ...
Result is ... I get a few seconds of TV then the signal dies the same way it does when I start recording with my CAM module inserted.. first audio ends then the screen turns blank saying scrambled signal.
Try to read mem at 0x30110100 as described by sbav1. Take a closer look at first returned value (long).
Strip higher word of returned long and write it back. Ie:
when you get 0x141A0A1, write 0xA0A1 back.
majonezz
SamyGO Project Donor
Posts: 63
Joined: Sat Feb 06, 2010 10:44 am
Location: Wroclaw, Poland

Re: Record TV over USB

Post by majonezz »

viper3k wrote:how do I read a memory block ???
I am familiar in working in linux enviroments so I don't need step by step help .. but what application do I use ??

And how do I write something back ??
Get this file. Extract it somwhere and copy two extracted files to TV.
Go to directory, where files was extracted.
Type:

Code: Select all

./regrange 0x30110100 1
You should get something like this:
0x30110100: 0x141A0CA
Next, type:

Code: Select all

./devmem2 0x30110100 w 0xA0CA
Answer should be:

Memory mapped at address 0x40001000.
Value at address 0x30110100 (0x40001100): 0xA0CA
Written 0xA0CA; readback 0xA0CA

Check if signal doesn't disappear. If not, try to record something. Good luck!

P.S.
Thanks to sbav1 for proposing this tools.

Post Reply

Return to “[B] Support”