📄 transform.c
字号:
headr = mbuf+c+2; frame = (headr[2]&0x3f); ai->bit_rate = ac3_bitrates[frame>>1]*1000; if (pr) fprintf (stderr," BRate: %d kb/s", ai->bit_rate/1000); fr = (headr[2] & 0xc0 ) >> 6; ai->frequency = freq[fr]*100; if (pr) fprintf (stderr," Freq: %d Hz\n", ai->frequency); ai->framesize = ac3_frames[fr][frame >> 1]; if ((frame & 1) && (fr == 1)) ai->framesize++; ai->framesize = ai->framesize << 1; if (pr) fprintf (stderr," Framesize %d\n", ai->framesize); return c;}void ps_pes(ipack *p){ int check; uint8_t pbuf[PS_HEADER_L2]; static int muxr = 0; static int ai = 0; static int vi = 0; static int start = 0; static uint32_t SCR = 0; if (p->mpeg == 2){ switch(p->buf[3]){ case VIDEO_STREAM_S ... VIDEO_STREAM_E: if (!p->has_vi){ if(get_vinfo(p->buf, p->count, &p->vi,1) >=0) { p->has_vi = 1; vi = p->vi.bit_rate; } } break; case AUDIO_STREAM_S ... AUDIO_STREAM_E: if (!p->has_ai){ if(get_ainfo(p->buf, p->count, &p->ai,1) >=0) { p->has_ai = 1; ai = p->ai.bit_rate; } } break; } if (p->has_vi && vi && !muxr){ muxr = (vi+ai)/400; } if ( start && muxr && (p->buf[7] & PTS_ONLY) && (p->has_ai || p->buf[9+p->buf[8]+4] == 0xb3)){ SCR = trans_pts_dts(p->pts)-3600; check = write_ps_header(pbuf, SCR, muxr, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0); p->func(pbuf, check , p->data); } if (muxr && !start && vi){ SCR = trans_pts_dts(p->pts)-3600; check = write_ps_header(pbuf, SCR, muxr, 1, 0, 0, 1, 1, 1, 0xC0, 0, 64, 0xE0, 1, 460); start = 1; p->func(pbuf, check , p->data); } if (start) p->func(p->buf, p->count, p->data); }}void send_ipack(ipack *p){ int streamid=0; int off; int ac3_off = 0; AudioInfo ai; int nframes= 0; int f=0; if (p->count < 10) return; p->buf[3] = p->cid; p->buf[4] = (uint8_t)(((p->count-6) & 0xFF00) >> 8); p->buf[5] = (uint8_t)((p->count-6) & 0x00FF); if (p->cid == PRIVATE_STREAM1){ off = 9+p->buf[8]; streamid = p->buf[off]; if ((streamid & 0xF8) == 0x80){ ai.off = 0; ac3_off = ((p->buf[off+2] << 8)| p->buf[off+3]); if (ac3_off < p->count) f=get_ac3info(p->buf+off+3+ac3_off, p->count-ac3_off, &ai,0); if ( !f ){ nframes = (p->count-off-3-ac3_off)/ ai.framesize + 1; p->buf[off+2] = (ac3_off >> 8)& 0xFF; p->buf[off+3] = (ac3_off)& 0xFF; p->buf[off+1] = nframes; ac3_off += nframes * ai.framesize - p->count; } } } if (p->ps) ps_pes(p); else p->func(p->buf, p->count, p->data); switch ( p->mpeg ){ case 2: p->buf[6] = 0x80; p->buf[7] = 0x00; p->buf[8] = 0x00; p->count = 9; if (p->cid == PRIVATE_STREAM1 && (streamid & 0xF8)==0x80 ){ p->count += 4; p->buf[9] = streamid; p->buf[10] = (ac3_off >> 8)& 0xFF; p->buf[11] = (ac3_off)& 0xFF; p->buf[12] = 0; } break; case 1: p->buf[6] = 0x0F; p->count = 7; break; }}static void write_ipack(ipack *p, uint8_t *data, int count){ uint8_t headr[3] = { 0x00, 0x00, 0x01} ; int diff =0; if (p->count < 6){ if (trans_pts_dts(p->pts) > trans_pts_dts(p->last_pts)) memcpy(p->last_pts, p->pts, 5); p->count = 0; memcpy(p->buf+p->count, headr, 3); p->count += 6; } if ( p->size == p->size_orig && p->plength && (diff = 6+p->plength - p->found + p->count +count) > p->size && diff < 3*p->size/2){ p->size = diff/2;// fprintf(stderr,"size: %d \n",p->size); } if (p->count + count < p->size){ memcpy(p->buf+p->count, data, count); p->count += count; } else { int rest = p->size - p->count; if (rest < 0) rest = 0; memcpy(p->buf+p->count, data, rest); p->count += rest;// fprintf(stderr,"count: %d \n",p->count); send_ipack(p); if (count - rest > 0) write_ipack(p, data+rest, count-rest); }}void instant_repack (uint8_t *buf, int count, ipack *p){ int l; unsigned short *pl; int c=0; while (c < count && (p->mpeg == 0 || (p->mpeg == 1 && p->found < 7) || (p->mpeg == 2 && p->found < 9)) && (p->found < 5 || !p->done)){ switch ( p->found ){ case 0: case 1: if (buf[c] == 0x00) p->found++; else p->found = 0; c++; break; case 2: if (buf[c] == 0x01) p->found++; else if (buf[c] == 0){ p->found = 2; } else p->found = 0; c++; break; case 3: p->cid = 0; switch (buf[c]){ case PROG_STREAM_MAP: case PRIVATE_STREAM2: case PROG_STREAM_DIR: case ECM_STREAM : case EMM_STREAM : case PADDING_STREAM : case DSM_CC_STREAM : case ISO13522_STREAM: p->done = 1; case PRIVATE_STREAM1: case VIDEO_STREAM_S ... VIDEO_STREAM_E: case AUDIO_STREAM_S ... AUDIO_STREAM_E: p->found++; p->cid = buf[c]; c++; break; default: p->found = 0; break; } break; case 4: if (count-c > 1){ pl = (unsigned short *) (buf+c); p->plength = ntohs(*pl); p->plen[0] = buf[c]; c++; p->plen[1] = buf[c]; c++; p->found+=2; } else { p->plen[0] = buf[c]; p->found++; return; } break; case 5: p->plen[1] = buf[c]; c++; pl = (unsigned short *) p->plen; p->plength = ntohs(*pl); p->found++; break; case 6: if (!p->done){ p->flag1 = buf[c]; c++; p->found++; if ( (p->flag1 & 0xC0) == 0x80 ) p->mpeg = 2; else { p->hlength = 0; p->which = 0; p->mpeg = 1; p->flag2 = 0; } } break; case 7: if ( !p->done && p->mpeg == 2){ p->flag2 = buf[c]; c++; p->found++; } break; case 8: if ( !p->done && p->mpeg == 2){ p->hlength = buf[c]; c++; p->found++; } break; default: break; } } if (c == count) return; if (!p->plength) p->plength = MMAX_PLENGTH-6; if ( p->done || ((p->mpeg == 2 && p->found >= 9) || (p->mpeg == 1 && p->found >= 7)) ){ switch (p->cid){ case AUDIO_STREAM_S ... AUDIO_STREAM_E: case VIDEO_STREAM_S ... VIDEO_STREAM_E: case PRIVATE_STREAM1: if (p->mpeg == 2 && p->found == 9){ write_ipack(p, &p->flag1, 1); write_ipack(p, &p->flag2, 1); write_ipack(p, &p->hlength, 1); } if (p->mpeg == 1 && p->found == 7){ write_ipack(p, &p->flag1, 1); } if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) && p->found < 14){ while (c < count && p->found < 14){ p->pts[p->found-9] = buf[c]; write_ipack(p, buf+c, 1); c++; p->found++; } if (c == count) return; } if (p->mpeg == 1 && p->which < 2000){ if (p->found == 7) { p->check = p->flag1; p->hlength = 1; } while (!p->which && c < count && p->check == 0xFF){ p->check = buf[c]; write_ipack(p, buf+c, 1); c++; p->found++; p->hlength++; } if ( c == count) return; if ( (p->check & 0xC0) == 0x40 && !p->which){ p->check = buf[c]; write_ipack(p, buf+c, 1); c++; p->found++; p->hlength++; p->which = 1; if ( c == count) return; p->check = buf[c]; write_ipack(p, buf+c, 1); c++; p->found++; p->hlength++; p->which = 2; if ( c == count) return; } if (p->which == 1){ p->check = buf[c]; write_ipack(p, buf+c, 1); c++; p->found++; p->hlength++; p->which = 2; if ( c == count) return; } if ( (p->check & 0x30) && p->check != 0xFF){ p->flag2 = (p->check & 0xF0) << 2; p->pts[0] = p->check; p->which = 3; } if ( c == count) return; if (p->which > 2){ if ((p->flag2 & PTS_DTS_FLAGS) == PTS_ONLY){ while (c < count && p->which < 7){ p->pts[p->which-2] = buf[c]; write_ipack(p,buf+c,1); c++; p->found++; p->which++; p->hlength++; } if ( c == count) return; } else if ((p->flag2 & PTS_DTS_FLAGS) == PTS_DTS){ while (c < count && p->which< 12){ if (p->which< 7) p->pts[p->which -2] = buf[c]; write_ipack(p,buf+c,1); c++; p->found++; p->which++; p->hlength++; } if ( c == count) return; } p->which = 2000; } } while (c < count && p->found < p->plength+6){ l = count -c; if (l+p->found > p->plength+6) l = p->plength+6-p->found; write_ipack(p, buf+c, l); p->found += l; c += l; } break; } if ( p->done ){ if( p->found + count - c < p->plength+6){ p->found += count-c; c = count; } else { c += p->plength+6 - p->found; p->found = p->plength+6; } } if (p->plength && p->found == p->plength+6) { send_ipack(p); reset_ipack(p); if (c < count) instant_repack(buf+c, count-c, p); } } return;}void write_out_es(uint8_t *buf, int count,void *priv){ ipack *p = (ipack *) priv; u8 payl = buf[8]+9+p->start-1; write(p->fd, buf+payl, count-payl); p->start = 1;}void write_out_pes(uint8_t *buf, int count,void *priv){ ipack *p = (ipack *) priv; write(p->fd, buf, count);}int64_t ts_demux(int fdin, int fdv_out,int fda_out,uint16_t pida, uint16_t pidv, int es){ uint8_t buf[IN_SIZE]; uint8_t mbuf[TS_SIZE]; int i; int count = 1; uint16_t pid; ipack pa, pv; ipack *p; u8 *sb; int64_t apts=0; int64_t vpts=0; int verb = 0; uint64_t length =0; uint64_t l=0; int perc =0; int last_perc =0; if (fdin != STDIN_FILENO) verb = 1; if (verb) { length = lseek(fdin, 0, SEEK_END); lseek(fdin,0,SEEK_SET); } if (!pida || !pidv) find_avpids(fdin, &pidv, &pida); if (es){ init_ipack(&pa, IPACKS,write_out_es, 0); init_ipack(&pv, IPACKS,write_out_es, 0); } else { init_ipack(&pa, IPACKS,write_out_pes, 0); init_ipack(&pv, IPACKS,write_out_pes, 0); } pa.fd = fda_out; pv.fd = fdv_out; pa.data = (void *)&pa; pv.data = (void *)&pv; count = read(fdin,mbuf,TS_SIZE); if (count) l+=count; for ( i = 0; i < 188 ; i++){ if ( mbuf[i] == 0x47 ) break; } if ( i == 188){ fprintf(stderr,"Not a TS\n"); return 0; } else { memcpy(buf,mbuf+i,TS_SIZE-i); count = read(fdin,mbuf,i); if (count) l+=count; memcpy(buf+TS_SIZE-i,mbuf,i); i = 188; } count = 1; while (count > 0){ count = read(fdin,buf+i,IN_SIZE-i); if (count) l+=count; if (verb && perc >last_perc){ perc = (100*l)/length; fprintf(stderr,"Reading TS %d %%\r",perc); last_perc = perc; } for( i = 0; i < count; i+= TS_SIZE){ uint8_t off = 0; if ( count - i < TS_SIZE) break; pid = get_pid(buf+i+1); if (!(buf[3+i]&0x10)) // no payload? continue; if (pid == pidv){ p = &pv; } else { if (pid == pida){ p = &pa; } else continue; } if ( buf[3+i] & 0x20) { // adaptation field? off = buf[4+i] + 1; } if ( buf[1+i]&0x40) { if (p->plength == MMAX_PLENGTH-6){ p->plength = p->found-6; p->found = 0; send_ipack(p); reset_ipack(p); } sb = buf+4+off+i; if( es && !p->start && (sb[7] & PTS_DTS_FLAGS)){ uint8_t *pay = sb+sb[8]+9; int l = TS_SIZE - 13 - off - sb[8]; if ( pid == pidv && (p->start = get_vinfo( pay, l,&p->vi,1)+1) >0 ){ vpts = trans_pts_dts(sb+9); printf("vpts : %fs\n", vpts/90000.); } if ( pid == pida && (p->start = get_ainfo( pay, l,&p->ai,1)+1) >0 ){ apts = trans_pts_dts(sb+9); printf("apts : %fs\n", apts/90000.); } } } if (p->start) instant_repack(buf+4+off+i, TS_SIZE-4-off, p); } i = 0; } return (vpts-apts);}void ts2es(int fdin, uint16_t pidv){ uint8_t buf[IN_SIZE]; uint8_t mbuf[TS_SIZE]; int i; int count = 1; ipack p; int verb = 0; uint64_t length =0; uint64_t l=0; int perc =0; int last_perc =0; uint16_t pid; if (fdin != STDIN_FILENO) verb = 1; if (verb) { length = lseek(fdin, 0, SEEK_END); lseek(fdin,0,SEEK_SET); } init_ipack(&p, IPACKS,write_out_es, 0); p.fd = STDOUT_FILENO; p.data = (void *)&p; count = read(fdin,mbuf,TS_SIZE); if (count) l+=count; for ( i = 0; i < 188 ; i++){ if ( mbuf[i] == 0x47 ) break; } if ( i == 188){ fprintf(stderr,"Not a TS\n"); return; } else { memcpy(buf,mbuf+i,TS_SIZE-i); count = read(fdin,mbuf,i); if (count) l+=count; memcpy(buf+TS_SIZE-i,mbuf,i); i = 188; } count = 1; while (count > 0){ count = read(fdin,buf+i,IN_SIZE-i); if (count) l+=count; if (verb && perc >last_perc){ perc = (100*l)/length; fprintf(stderr,"Reading TS %d %%\r",perc); last_perc = perc; } for( i = 0; i < count; i+= TS_SIZE){ uint8_t off = 0; if ( count - i < TS_SIZE) break; pid = get_pid(buf+i+1); if (!(buf[3+i]&0x10)) // no payload? continue; if (pid != pidv){ continue; } if ( buf[3+i] & 0x20) { // adaptation field? off = buf[4+i] + 1; } if ( buf[1+i]&0x40) { if (p.plength == MMAX_PLENGTH-6){ p.plength = p.found-6; p.found = 0; send_ipack(&p); reset_ipack(&p); } } instant_repack(buf+4+off+i, TS_SIZE-4-off, &p); } i = 0; }}void change_aspect(int fdin, int fdout, int aspect){ ps_packet ps; pes_packet pes; int neof,i; do { init_ps(&ps); neof = read_ps(fdin,&ps); write_ps(fdout,&ps); for (i = 0; i < ps.npes; i++){ u8 *buf; int c = 0; int l; init_pes(&pes); read_pes(fdin, &pes); buf = pes.pes_pckt_data; switch (pes.stream_id){ case VIDEO_STREAM_S ... VIDEO_STREAM_E: l=pes.length; break; default: l = 0; break; } while ( c < l - 6){ if (buf[c] == 0x00 && buf[c+1] == 0x00 && buf[c+2] == 0x01 && buf[c+3] == 0xB3) { c += 4; buf[c+3] &= 0x0f; buf[c+3] |= aspect; } else c++; } write_pes(fdout,&pes); } } while( neof > 0 );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -