linux/drivers/staging/media/av7110/dvb_filter.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#include <linux/kernel.h>
   3#include <linux/module.h>
   4#include <linux/string.h>
   5#include "dvb_filter.h"
   6
   7static u32 freq[4] = {480, 441, 320, 0};
   8
   9static unsigned int ac3_bitrates[32] =
  10    {32,40,48,56,64,80,96,112,128,160,192,224,256,320,384,448,512,576,640,
  11     0,0,0,0,0,0,0,0,0,0,0,0,0};
  12
  13static u32 ac3_frames[3][32] =
  14    {{64,80,96,112,128,160,192,224,256,320,384,448,512,640,768,896,1024,
  15      1152,1280,0,0,0,0,0,0,0,0,0,0,0,0,0},
  16     {69,87,104,121,139,174,208,243,278,348,417,487,557,696,835,975,1114,
  17      1253,1393,0,0,0,0,0,0,0,0,0,0,0,0,0},
  18     {96,120,144,168,192,240,288,336,384,480,576,672,768,960,1152,1344,
  19      1536,1728,1920,0,0,0,0,0,0,0,0,0,0,0,0,0}};
  20
  21int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr)
  22{
  23        u8 *headr;
  24        int found = 0;
  25        int c = 0;
  26        u8 frame = 0;
  27        int fr = 0;
  28
  29        while ( !found  && c < count){
  30                u8 *b = mbuf+c;
  31
  32                if ( b[0] == 0x0b &&  b[1] == 0x77 )
  33                        found = 1;
  34                else {
  35                        c++;
  36                }
  37        }
  38
  39        if (!found) return -1;
  40        if (pr)
  41                printk(KERN_DEBUG "Audiostream: AC3");
  42
  43        ai->off = c;
  44        if (c+5 >= count) return -1;
  45
  46        ai->layer = 0;  // 0 for AC3
  47        headr = mbuf+c+2;
  48
  49        frame = (headr[2]&0x3f);
  50        ai->bit_rate = ac3_bitrates[frame >> 1]*1000;
  51
  52        if (pr)
  53                printk(KERN_CONT "  BRate: %d kb/s", (int) ai->bit_rate/1000);
  54
  55        ai->frequency = (headr[2] & 0xc0 ) >> 6;
  56        fr = (headr[2] & 0xc0 ) >> 6;
  57        ai->frequency = freq[fr]*100;
  58        if (pr)
  59                printk(KERN_CONT "  Freq: %d Hz\n", (int) ai->frequency);
  60
  61        ai->framesize = ac3_frames[fr][frame >> 1];
  62        if ((frame & 1) &&  (fr == 1)) ai->framesize++;
  63        ai->framesize = ai->framesize << 1;
  64        if (pr)
  65                printk(KERN_DEBUG "  Framesize %d\n", (int) ai->framesize);
  66
  67        return 0;
  68}
  69
  70void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, unsigned short pid,
  71                            dvb_filter_pes2ts_cb_t *cb, void *priv)
  72{
  73        unsigned char *buf=p2ts->buf;
  74
  75        buf[0]=0x47;
  76        buf[1]=(pid>>8);
  77        buf[2]=pid&0xff;
  78        p2ts->cc=0;
  79        p2ts->cb=cb;
  80        p2ts->priv=priv;
  81}
  82
  83int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes,
  84                      int len, int payload_start)
  85{
  86        unsigned char *buf=p2ts->buf;
  87        int ret=0, rest;
  88
  89        //len=6+((pes[4]<<8)|pes[5]);
  90
  91        if (payload_start)
  92                buf[1]|=0x40;
  93        else
  94                buf[1]&=~0x40;
  95        while (len>=184) {
  96                buf[3]=0x10|((p2ts->cc++)&0x0f);
  97                memcpy(buf+4, pes, 184);
  98                if ((ret=p2ts->cb(p2ts->priv, buf)))
  99                        return ret;
 100                len-=184; pes+=184;
 101                buf[1]&=~0x40;
 102        }
 103        if (!len)
 104                return 0;
 105        buf[3]=0x30|((p2ts->cc++)&0x0f);
 106        rest=183-len;
 107        if (rest) {
 108                buf[5]=0x00;
 109                if (rest-1)
 110                        memset(buf+6, 0xff, rest-1);
 111        }
 112        buf[4]=rest;
 113        memcpy(buf+5+rest, pes, len);
 114        return p2ts->cb(p2ts->priv, buf);
 115}
 116