Go to the documentation of this file.
36 #include <sys/types.h>
50 #include "libavcodec/avcodec.h"
51 #include "libavformat/avformat.h"
76 for (i=0; i<rx->
apidn; i++)
80 for (i=0; i<rx->
ac3n; i++)
88 uint8_t *buf,
int buf_size,
93 int ret, samples_size;
95 pkt = av_packet_alloc();
98 LOG(VB_GENERAL, LOG_ERR,
"packet allocation failed");
99 return AVERROR(ENOMEM);
103 pkt->size = buf_size;
106 frame = av_frame_alloc();
109 av_packet_free(&pkt);
110 return AVERROR(ENOMEM);
113 if (avctx->frame_size) {
114 frame->nb_samples = avctx->frame_size;
119 if (!av_get_bits_per_sample(avctx->codec_id)) {
120 av_log(avctx, AV_LOG_ERROR,
"avcodec_encode_audio() does not "
121 "support this codec\n");
122 av_frame_free(&frame);
123 av_packet_free(&pkt);
124 return AVERROR(EINVAL);
126 nb_samples = (int64_t)buf_size * 8 /
127 (av_get_bits_per_sample(avctx->codec_id) *
128 avctx->ch_layout.nb_channels);
129 if (nb_samples >= INT_MAX) {
130 av_frame_free(&frame);
131 av_packet_free(&pkt);
132 return AVERROR(EINVAL);
134 frame->nb_samples = nb_samples;
139 samples_size = av_samples_get_buffer_size(
nullptr, avctx->ch_layout.nb_channels,
141 avctx->sample_fmt, 1);
142 if ((ret = avcodec_fill_audio_frame(frame, avctx->ch_layout.nb_channels,
145 samples_size, 1)) < 0) {
146 av_frame_free(&frame);
147 av_packet_free(&pkt);
151 frame->pts = AV_NOPTS_VALUE;
160 ret = avcodec_receive_packet(avctx, pkt);
163 if (ret == AVERROR(EAGAIN))
166 ret = avcodec_send_frame(avctx, frame);
170 char error[AV_ERROR_MAX_STRING_SIZE+25];
171 strcpy(
error,
"audio encode error: ");
177 av_packet_free_side_data(pkt);
179 if (frame && frame->extended_data != frame->data)
180 av_freep(&frame->extended_data);
182 av_frame_free(&frame);
183 int size = pkt->size;
184 av_packet_free(&pkt);
185 return ret ? ret : size;
190 const AVCodec *codec;
191 AVCodecContext *c=
nullptr;
192 int frame_size, j, out_size;
195 LOG(VB_GENERAL, LOG_INFO,
"encoding an MP2 audio frame");
198 codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
200 LOG(VB_GENERAL, LOG_ERR,
"codec not found");
204 c = avcodec_alloc_context3(codec);
209 c->ch_layout.nb_channels = 2;
210 c->sample_fmt = AV_SAMPLE_FMT_S16;
213 if (avcodec_open2(c, codec,
nullptr) < 0) {
214 LOG(VB_GENERAL, LOG_ERR,
"could not open codec");
220 frame_size = c->frame_size;
221 samples =
static_cast<short*
>(malloc(frame_size * 2 * c->ch_layout.nb_channels));
224 for (j=0;j<frame_size;j++) {
232 if (out_size != bufsize) {
233 LOG(VB_GENERAL, LOG_ERR,
234 QString(
"frame size (%1) does not equal required size (%2)?")
235 .arg(out_size).arg(bufsize));
237 avcodec_free_context(&c);
242 avcodec_free_context(&c);
253 ringbuffer *rbuf =
nullptr, *index_buf =
nullptr;
254 uint64_t *acount=
nullptr;
255 uint64_t *fpts=
nullptr;
256 uint64_t *lpts=
nullptr;
261 int *apes_abort=
nullptr;
267 LOG(VB_GENERAL, LOG_DEBUG,
"AC3");
282 LOG(VB_GENERAL, LOG_DEBUG,
"MPEG AUDIO");
284 aframe = &rx->
aframe[num];
315 *apes_abort = len -c;
324 LOG(VB_GENERAL, LOG_INFO,
325 "starting audio PTS: ");
327 }
else aframe->
set = 0;
330 if (aframe->
set && first)
342 *apes_abort = len -c;
354 LOG(VB_GENERAL, LOG_DEBUG,
355 QString(
"WRONG HEADER1 %1").arg(diff));
363 LOG(VB_GENERAL, LOG_ERR,
364 QString(
"WRONG HEADER2 %1").arg(diff));
375 if (abs ((
int)diff) >= frame_time){
376 LOG(VB_GENERAL, LOG_INFO,
377 "fixing audio PTS inconsistency - diff: ");
382 int framesdiff = diff / frame_time;
383 LOG(VB_GENERAL, LOG_INFO,
384 QString(
" - need to remove %1 frame(s)")
394 int framesdiff = diff / frame_time;
395 LOG(VB_GENERAL, LOG_INFO,
396 QString(
" - need to add %1 frame(s)")
405 if ( !(framebuf = (uint8_t *) malloc(
sizeof(uint8_t) * aframe->
framesize))) {
406 LOG(VB_GENERAL, LOG_ERR,
407 "Not enough memory for audio frame");
417 LOG(VB_GENERAL, LOG_ERR,
418 QString(
"ring buffer failed to peek frame res: %1")
426 for (x = 0; x < framesdiff; x++){
447 LOG(VB_GENERAL, LOG_ERR,
448 QString(
"Wrong audio frame size: %1")
455 LOG(VB_GENERAL, LOG_ERR,
456 "audio ring buffer overrun error");
474 LOG(VB_GENERAL, LOG_ERR,
475 "audio PTS inconsistent:");
478 LOG(VB_GENERAL, LOG_ERR,
491 LOG(VB_GENERAL, LOG_WARNING,
492 "Warning negative audio PTS increase!\n");
504 iu->
start = (
p->ini_pos+pos+c)%bsize;
509 LOG(VB_GENERAL, LOG_INFO,
510 QString(
"SHORT %1").arg(len-c));
525 std::vector<uint8_t> buf(8);
556 LOG(VB_GENERAL, LOG_DEBUG, QString(
" ini pos %1")
562 LOG(VB_GENERAL, LOG_INFO, QString(
"len %1 %2").arg(len).arg(off));
570 LOG(VB_GENERAL, LOG_DEBUG, QString(
" seq headr %1")
581 pos+c+off, len -c -pos);
584 LOG(VB_GENERAL, LOG_DEBUG,
585 QString(
" seq headr result %1")
608 LOG(VB_GENERAL, LOG_DEBUG,
609 QString(
" seq ext headr %1")
633 LOG(VB_GENERAL, LOG_INFO,
634 "starting with video PTS:");
641 LOG(VB_GENERAL, LOG_DEBUG,
642 QString(
"fcount %1 gcount %2 tempref %3 %4")
662 LOG(VB_GENERAL, LOG_INFO,
663 "video PTS inconsistent:");
668 LOG(VB_GENERAL, LOG_INFO,
682 LOG(VB_GENERAL, LOG_INFO,
683 "video DTS inconsistent: ");
688 LOG(VB_GENERAL, LOG_INFO,
704 }
else iu->
dts = newdts;
717 LOG(VB_GENERAL, LOG_WARNING,
718 "Warning negative video PTS increase!");
741 LOG(VB_GENERAL, LOG_DEBUG, QString(
" seq end %1")
752 LOG(VB_GENERAL, LOG_DEBUG, QString(
" %1")
757 if (!seq_h) flush = 1;
760 gop_off = c+pos - seq_p;
762 if (
ring_peek(rbuf, buf, 7, off+c+pos) < 0) {
767 int hour = (int)((buf[4]>>2)& 0x1F);
768 int min = (int)(((buf[4]<<4)& 0x30)|
769 ((buf[5]>>4)& 0x0F));
770 int sec = (int)(((buf[5]<<3)& 0x38)|
771 ((buf[6]>>5)& 0x07));
772 LOG(VB_GENERAL, LOG_DEBUG,
773 QString(
" gop %1:%2.%3 %4")
774 .arg(hour,2,10,QChar(
'0'))
775 .arg(min, 2,10,QChar(
'0'))
776 .arg(sec, 2,10,QChar(
'0'))
785 if (len-(c+pos) < 14){
791 off+c+pos) < 0)
return;
794 frame = ((buf[5]&0x38) >>3);
808 frame_off = c+pos - seq_p;
810 if (!seq_h && !gop) flush = 1;
812 tempref = (buf[5]>>6) & 0x03;
813 tempref |= buf[4] << 2;
818 LOG(VB_GENERAL, LOG_DEBUG,
"I");
821 LOG(VB_GENERAL, LOG_DEBUG,
822 QString(
" I-frame %1")
828 LOG(VB_GENERAL, LOG_DEBUG,
"B");
831 LOG(VB_GENERAL, LOG_DEBUG,
832 QString(
" B-frame %1")
838 LOG(VB_GENERAL, LOG_DEBUG,
"P");
841 LOG(VB_GENERAL, LOG_DEBUG,
842 QString(
" P-frame %1")
855 LOG(VB_GENERAL, LOG_ERR,
856 QString(
"other header 0x%1 (%2+%3)")
857 .arg(head, 2,16,QChar(
'0')).arg(c).arg(pos));
876 LOG(VB_GENERAL, LOG_ERR,
877 "video ring buffer overrun error");
893 iu->
start = (
p->ini_pos+pos+c-frame_off)
896 LOG(VB_GENERAL, LOG_DEBUG,
897 QString(
"START %1").arg(iu->
start));
903 iu->
frame = (frame&0xFF);
933 len =
p->plength-3-
p->hlength;
935 rx = (
struct replex *)
p->priv;
940 sprintf(
t,
"Video ");
955 sprintf(
t,
"Audio%d ", l);
971 sprintf(
t,
"AC3 %d ",
p->type);
984 LOG(VB_GENERAL, LOG_ERR,
985 QString(
"UNKNOWN AUDIO type %1").arg(
p->type));
992 LOG(VB_GENERAL, LOG_DEBUG, QString(
"%1 PES").arg(
t));
1004 len =
p->plength-3-
p->hlength;
1005 rx = (
struct replex *)
p->priv;
1009 if (rx->
vpid !=
p->cid)
break;
1014 LOG(VB_GENERAL, LOG_ERR,
1015 "video ring buffer overrun error");
1022 sprintf(
t,
"Video ");
1030 p->type =
p->cid - 0xc0 + 1;
1032 for (i=0; i<rx->
apidn; i++)
1033 if (
p->cid == rx->
apid[i])
1038 LOG(VB_GENERAL, LOG_ERR,
1039 "video ring buffer overrun error");
1048 sprintf(
t,
"Audio%d ", l);
1065 fframe =
p->buf[9+
p->hlength+3];
1066 fframe |= (
p->buf[9+
p->hlength+2]<<8);
1068 if (fframe >
p->plength)
break;
1070 p->type =
p->buf[9+
p->hlength];
1072 for (i=0; i<rx->
ac3n; i++)
1081 LOG(VB_GENERAL, LOG_ERR,
1082 "video ring buffer overrun error");
1091 sprintf(
t,
"AC3 %d ",
p->type);
1104 LOG(VB_GENERAL, LOG_DEBUG, QString(
"%1 PES %2").arg(
t).arg(len));
1117 rx = (
struct replex *)
p->priv;
1123 sprintf(
t,
"Video ");
1138 sprintf(
t,
"Audio%d ", l);
1150 case 0x80 ... 0x87:{
1154 sprintf(
t,
"AC3 %d ",
p->type);
1171 LOG(VB_GENERAL, LOG_DEBUG, QString(
"%1 PES").arg(
t));
1209 p->plength =
p->found-6;
1217 if (off+4 >=
TS_SIZE)
return 0;
1234 if ( l <= 0)
return 0;
1235 if ( (
int) count > l) count = l;
1237 while(neof >= 0 && re < count){
1238 neof =
read(fd, ((
char*)buf)+re, count - re);
1239 if (neof > 0) re += neof;
1248 if (per % 10 == 0 && rx->
lastper < per){
1249 LOG(VB_GENERAL, LOG_DEBUG, QString(
"read %1%%")
1254 LOG(VB_GENERAL, LOG_DEBUG, QString(
"read %1 MB")
1255 .arg(rx->
finread/1024.0/1024.0, 0,
'f',2,QChar(
'0')));
1257 if (neof < 0 && re == 0)
return neof;
1263 int vavail, aavail, ac3avail, i, fill;
1275 for (i=0; i<rx->
apidn;i++){
1282 for (i=0; i<rx->
ac3n;i++){
1290 LOG(VB_GENERAL, LOG_INFO,
1291 QString(
"free %1 %2 %3 %4")
1292 .arg(fill).arg(vavail).arg(aavail).arg(ac3avail));
1296 if(vavail && (aavail || ac3avail))
return 0;
1305 #define IN_SIZE (1000*TS_SIZE)
1315 LOG(VB_GENERAL, LOG_INFO,
"Trying to find PIDs");
1316 while (!afound && !vfound && count < (
int) rx->
inflength){
1317 if (rx->
vpid) vfound = 1;
1318 if (rx->
apidn) afound = 1;
1320 LOG(VB_GENERAL, LOG_ERR,
1321 QString(
"reading: %1").arg(strerror(errno)));
1327 LOG(VB_GENERAL, LOG_INFO,QString(
"vpid 0x%1")
1328 .arg(rx->
vpid, 4,16,QChar(
'0')));
1333 LOG(VB_GENERAL, LOG_INFO, QString(
"apid 0x%1")
1334 .arg(rx->
apid[0], 4,16,QChar(
'0')));
1338 if (!rx->
ac3n && ac3pid){
1340 LOG(VB_GENERAL, LOG_INFO, QString(
"ac3pid 0x%1")
1341 .arg(rx->
ac3_id[0], 4,16,QChar(
'0')));
1351 if (!afound || !vfound){
1352 LOG(VB_GENERAL, LOG_ERR,
"Couldn't find all pids");
1360 #define MAXAC3PID 16
1368 int vn=0, an=0,
ac3n=0;
1370 int vpos, apos, cpos;
1376 LOG(VB_GENERAL, LOG_INFO,
"Trying to find PIDs");
1379 LOG(VB_GENERAL, LOG_ERR, QString(
"reading: %1")
1380 .arg(strerror(errno)));
1384 &vpos, &apos, &cpos))){
1387 for (j=0; j < vn; j++){
1389 LOG(VB_GENERAL, LOG_INFO,
1390 QString(
"%1. %2").arg(j+1).arg(
vpid[j]));
1400 LOG(VB_GENERAL, LOG_INFO,
1401 QString(
"vpid %1: 0x%2 (%3) PES ID: 0x%4")
1403 .arg(
vpid[vn], 4,16,QChar(
'0'))
1405 .arg(buf[vpos], 2,16,QChar(
'0')));
1412 for (j=0; j < an; j++)
1419 LOG(VB_GENERAL, LOG_INFO,
1420 QString(
"apid %1: 0x%2 (%3) PES ID: 0x%4")
1422 .arg(
apid[an], 4,16,QChar(
'0'))
1424 .arg(buf[apos], 2,16,QChar(
'0')));
1431 for (j=0; j <
ac3n; j++)
1432 if (ac3pid[j] == cp){
1438 LOG(VB_GENERAL, LOG_INFO,
1439 QString(
"ac3pid %1: 0x%2 (%3)")
1441 .arg(ac3pid[
ac3n], 4,16,QChar(
'0'))
1442 .arg(ac3pid[
ac3n]));
1459 if (rx->
vpid) vfound = 1;
1460 if (rx->
apidn) afound = 1;
1461 LOG(VB_GENERAL, LOG_INFO,
"Trying to find PIDs");
1481 if (!rx->
ac3n && ac3pid){
1497 if (afound && vfound){
1498 LOG(VB_GENERAL, LOG_INFO,
"found");
1500 LOG(VB_GENERAL, LOG_INFO, QString(
"vpid %1 (0x%2)")
1501 .arg(rx->
vpid).arg(rx->
vpid, 4,16,QChar(
'0')));
1503 LOG(VB_GENERAL, LOG_INFO, QString(
"apid %1 (0x%2)")
1504 .arg(rx->
apid[0]).arg(rx->
apid[0], 4,16,QChar(
'0')));
1506 LOG(VB_GENERAL, LOG_INFO, QString(
"ac3pid %1 (0x%2)")
1507 .arg(rx->
ac3_id[0]).arg(rx->
ac3_id[0], 4,16,QChar(
'0')));
1509 LOG(VB_GENERAL, LOG_ERR,
"Couldn't find pids");
1538 uint8_t
id =
p->buf[9+
p->hlength];
1546 fframe =
p->buf[9+
p->hlength+3];
1547 fframe |= (
p->buf[9+
p->hlength+2]<<8);
1549 if (fframe < p->plength){
1551 9+
p->hlength+4+fframe,
1552 AC3,
p->plength+6)) >= 0){
1555 LOG(VB_GENERAL, LOG_INFO,
1556 QString(
"0x%1 0x%2 \n")
1557 .arg(c-9-
p->hlength-4, 4,16,QChar(
'0'))
1558 .arg(fframe, 4,16,QChar(
'0')));
1585 int vn=0, an=0,
ac3n=0;
1591 LOG(VB_GENERAL, LOG_INFO,
"Trying to find PES IDs");
1596 LOG(VB_GENERAL, LOG_ERR, QString(
"reading: %1")
1597 .arg(strerror(errno)));
1610 for (j=0; j < vn; j++){
1612 LOG(VB_GENERAL, LOG_INFO,
1613 QString(
"%1. %2").arg(j+1).arg(
vpid[j]));
1623 LOG(VB_GENERAL, LOG_INFO,
1624 QString(
"MPEG VIDEO %1: 0x%2 (%3)")
1626 .arg(
vpid[vn], 2,16,QChar(
'0'))
1637 for (j=0; j < an; j++)
1644 LOG(VB_GENERAL, LOG_INFO,
1645 QString(
"MPEG AUDIO %1: 0x%2 (%3)")
1647 .arg(
apid[an], 2,16,QChar(
'0'))
1657 for (j=0; j <
ac3n; j++)
1665 LOG(VB_GENERAL, LOG_INFO,
1666 "possible AC3 AUDIO with private stream 1 pid (0xbd)");
1668 LOG(VB_GENERAL, LOG_INFO,
1669 QString(
"AC3 AUDIO %1: 0x%2 (%3)")
1671 .arg(ac3pid[
ac3n], 2,16,QChar(
'0'))
1672 .arg(ac3pid[
ac3n]));
1690 LOG(VB_GENERAL, LOG_ERR,
"Can't find all required streams");
1692 LOG(VB_GENERAL, LOG_ERR,
1693 "Please check if audio and video have standard IDs (0xc0 or 0xe0)");
1713 if (rx->
finish)
return 0;
1716 LOG(VB_GENERAL, LOG_INFO,
1717 QString(
"trying to fill buffers with %1").arg(fill));
1719 if (fill < 0)
return -1;
1726 rsize = fill - (fill%188);
1730 LOG(VB_GENERAL, LOG_INFO, QString(
"filling with %1").arg(rsize));
1733 if (!rsize)
return 0;
1738 for ( i = 0; i < 188 ; i++){
1739 if ( mbuf[i] == 0x47 )
break;
1743 LOG(VB_GENERAL, LOG_ERR,
"Not a TS");
1746 memcpy(buf,mbuf+i,2*
TS_SIZE-i);
1748 LOG(VB_GENERAL, LOG_ERR, QString(
"reading: %1")
1749 .arg(strerror(errno)));
1750 memcpy(buf+2*
TS_SIZE-i,mbuf,i);
1757 while (count < rsize && tries <
MAX_TRIES){
1758 if ((re =
save_read(rx,buf+i,rsize-i)+i)<0)
1759 LOG(VB_GENERAL, LOG_ERR, QString(
"reading: %1")
1760 .arg(strerror(errno)));
1769 for( j = 0; j < re; j+=
TS_SIZE){
1774 LOG(VB_GENERAL, LOG_ERR,
1775 "Error reading TS");
1793 while (count < rsize && tries <
MAX_TRIES){
1795 LOG(VB_GENERAL, LOG_ERR, QString(
"reading PS: %1")
1796 .arg(strerror(errno)));
1822 while (count < rsize && tries <
MAX_TRIES){
1824 LOG(VB_GENERAL, LOG_ERR,
1825 QString(
"reading AVI: %1")
1826 .arg(strerror(errno)));
1870 for (i=0; i < rx->
ac3n ;i++){
1873 for (i=0; i<rx->
apidn;i++){
1878 if (set == (rx->
ac3n+ rx->
apidn + 1))
return 1;
1892 LOG(VB_GENERAL, LOG_ERR,
"cannot determine streamtype");
1896 LOG(VB_GENERAL, LOG_INFO,
"Checking for TS: ");
1897 while (c < len && buf[c]!=0x47) c++;
1900 LOG(VB_GENERAL, LOG_INFO,
"confirmed");
1902 }
else LOG(VB_GENERAL, LOG_INFO,
"failed");
1903 }
else LOG(VB_GENERAL, LOG_INFO,
"failed");
1905 LOG(VB_GENERAL, LOG_INFO,
"Checking for AVI: ");
1907 LOG(VB_GENERAL, LOG_INFO,
"confirmed");
1914 }
else LOG(VB_GENERAL, LOG_INFO,
"failed");
1916 LOG(VB_GENERAL, LOG_INFO,
"Checking for PS: ");
1918 LOG(VB_GENERAL, LOG_INFO,
"confirmed(maybe)");
1920 LOG(VB_GENERAL, LOG_INFO,
"failed, trying it anyway");
1940 LOG(VB_GENERAL, LOG_ERR,
1941 QString(
"reading: %1").arg(strerror(errno)));
1984 for (i=0; i<rx->
apidn;i++){
2003 for (i=0; i<rx->
ac3n;i++){
2022 LOG(VB_GENERAL, LOG_ERR,
"error filling buffer");
2030 ssize_t read_count = 0;
2035 if ((read_count =
save_read(rx, buf, 12)) != 12) {
2036 LOG(VB_GENERAL, LOG_ERR,
2037 QString(
"Error reading in 12 bytes from replex. Read %1 bytes")
2043 LOG(VB_GENERAL, LOG_ERR,
"Wrong RIFF header");
2046 LOG(VB_GENERAL, LOG_INFO,
"Found RIFF header");
2052 LOG(VB_GENERAL, LOG_ERR,
"Error reading index");
2061 LOG(VB_GENERAL, LOG_INFO, QString(
"AVI initial frames %1")
2064 LOG(VB_GENERAL, LOG_ERR,
"Error reading AVI header");
2069 LOG(VB_GENERAL, LOG_ERR,
"error filling buffer");
2074 LOG(VB_GENERAL, LOG_ERR,
"error filling buffer");
2090 for ( i = 0; i < rx->
apidn; i++){
2095 LOG(VB_GENERAL, LOG_ERR,
2096 "error in fix audio");
2107 mx->
ext[i].pts_off = aiu.
pts;
2109 LOG(VB_GENERAL, LOG_INFO, QString(
"Audio%1 offset: ").arg(i));
2114 for ( i = 0; i < rx->
ac3n; i++){
2119 LOG(VB_GENERAL, LOG_ERR,
2120 "error in fix audio");
2131 mx->
ext[i].pts_off = aiu.
pts;
2133 LOG(VB_GENERAL, LOG_INFO, QString(
"AC3%1 offset: ").arg(i));
2182 uint64_t lastac3pts[
N_AC3];
2189 memset(lastapts, 0,
N_AUDIO*
sizeof(uint64_t));
2190 memset(lastac3pts, 0,
N_AC3*
sizeof(uint64_t));
2192 LOG(VB_GENERAL, LOG_INFO,
"STARTING ANALYSIS");
2197 LOG(VB_GENERAL, LOG_ERR,
2198 "error in get next video unit");
2201 for (i=0; i< rx->
apidn; i++){
2206 LOG(VB_GENERAL, LOG_INFO,
2207 QString(
"MPG2 Audio%1 unit: length %2 PTS ")
2208 .arg(i).arg(dummy2.
length));
2212 LOG(VB_GENERAL, LOG_INFO,
2216 lastapts[i] = dummy2.
pts;
2221 for (i=0; i< rx->
ac3n; i++){
2226 LOG(VB_GENERAL, LOG_INFO,
2227 QString(
"AC3 Audio%1 unit: length %2 PTS ")
2228 .arg(i).arg(dummy2.
length));
2231 LOG(VB_GENERAL, LOG_INFO,
2235 lastac3pts[i] = dummy2.
pts;
2243 if (av==0 || av==2){
2244 LOG(VB_GENERAL, LOG_INFO,
"Video unit: ");
2246 LOG(VB_GENERAL, LOG_INFO,
2247 "Sequence header ");
2250 LOG(VB_GENERAL, LOG_INFO,
2253 switch (dummy.
frame){
2255 LOG(VB_GENERAL, LOG_INFO,
"I-frame");
2258 LOG(VB_GENERAL, LOG_INFO,
"B-frame");
2261 LOG(VB_GENERAL, LOG_INFO,
"P-frame");
2264 LOG(VB_GENERAL, LOG_INFO, QString(
" length %1 PTS ")
2268 LOG(VB_GENERAL, LOG_INFO,
" diff:");
2271 lastvpts = dummy.
pts;
2273 LOG(VB_GENERAL, LOG_INFO,
" DTS ");
2276 LOG(VB_GENERAL, LOG_INFO,
" diff:");
2279 lastvdts = dummy.
dts;
2294 LOG(VB_GENERAL, LOG_ERR, QString(
"reading: %1")
2295 .arg(strerror(errno)));
2297 LOG(VB_GENERAL, LOG_INFO,
"STARTING SCAN");
2322 LOG(VB_GENERAL, LOG_INFO,
"STARTING DEMUX");
2326 LOG(VB_GENERAL, LOG_ERR,
2327 "error in get next video unit");
2330 for (i=0; i< rx->
apidn; i++){
2338 for (i=0; i< rx->
ac3n; i++){
2362 LOG(VB_GENERAL, LOG_INFO,
"STARTING REPLEX");
2363 memset(&mx, 0,
sizeof(mx));
2367 LOG(VB_GENERAL, LOG_INFO,
"error filling buffer");
2373 for (i = 0; i < rx->
apidn; i++){
2390 mx.
priv = (
void *) rx;
2391 rx->
priv = (
void *) &mx;
2408 LOG(VB_GENERAL, LOG_ERR,
"error while writing");
2417 printf (
"usage: %s [options] <input files>\n\n",progname);
2418 printf (
"options:\n");
2419 printf (
" --help, -h: print help message\n");
2420 printf (
" --type, -t: set output type (MPEG2, DVD, HDTV)\n");
2421 printf (
" --of, -o: set output file\n");
2422 printf (
" --input_stream, -i: set input stream type (TS(default), PS, AVI)\n");
2423 printf (
" --audio_pid, -a: audio PID for TS stream (also used for PS id)\n");
2424 printf (
" --ac3_id, -c: ID of AC3 audio for demux (also used for PS id)\n");
2425 printf (
" --video_pid, -v: video PID for TS stream (also used for PS id)\n");
2426 printf (
" --video_delay, -d: video delay in ms\n");
2427 printf (
" --audio_delay, -e: audio delay in ms\n");
2428 printf (
" --ignore_PTS, -f: ignore all PTS information of original\n");
2429 printf (
" --keep_PTS, -k: keep and don't correct PTS information of original\n");
2430 printf (
" --fix_sync, -n: try to fix audio sync while demuxing\n");
2431 printf (
" --demux, -z: demux only (-o is basename)\n");
2432 printf (
" --analyze, -y: analyze (0=video,1=audio, 2=both)\n");
2433 printf (
" --scan, -s: scan for streams\n");
2434 printf (
" --vdr, -x: handle AC3 for vdr input file\n");
2444 const char *
type =
"SVCD";
2445 const char *inpt =
"TS";
2449 memset(&rx, 0,
sizeof(
struct replex));
2452 int option_index = 0;
2453 static struct option long_options[] = {
2454 {
"type", required_argument,
nullptr,
't'},
2455 {
"input_stream", required_argument,
nullptr,
'i'},
2456 {
"video_pid", required_argument,
nullptr,
'v'},
2457 {
"audio_pid", required_argument,
nullptr,
'a'},
2458 {
"audio_delay", required_argument,
nullptr,
'e'},
2459 {
"video_delay", required_argument,
nullptr,
'd'},
2460 {
"ac3_id", required_argument,
nullptr,
'c'},
2461 {
"of",required_argument,
nullptr,
'o'},
2462 {
"ignore_PTS",required_argument,
nullptr,
'f'},
2463 {
"keep_PTS",required_argument,
nullptr,
'k'},
2464 {
"fix_sync",no_argument,
nullptr,
'n'},
2465 {
"demux",no_argument,
nullptr,
'z'},
2466 {
"analyze",required_argument,
nullptr,
'y'},
2467 {
"scan",required_argument,
nullptr,
's'},
2468 {
"vdr",required_argument,
nullptr,
'x'},
2469 {
"help", no_argument ,
nullptr,
'h'},
2470 {
nullptr, 0,
nullptr, 0}
2472 c = getopt_long (argc, argv,
2473 "t:o:a:v:i:hp:q:d:c:n:fkd:e:zy:sx",
2474 long_options, &option_index);
2486 rx.
video_delay = strtol(optarg,(
char **)
nullptr, 0)
2490 rx.
audio_delay = strtol(optarg,(
char **)
nullptr, 0)
2495 LOG(VB_GENERAL, LOG_ERR,
"Too many audio PIDs");
2498 rx.
apid[rx.
apidn] = strtol(optarg,(
char **)
nullptr, 0);
2502 rx.
vpid = strtol(optarg,(
char **)
nullptr, 0);
2506 LOG(VB_GENERAL, LOG_ERR,
"Too many audio PIDs");
2509 rx.
ac3_id[rx.
ac3n] = strtol(optarg,(
char **)
nullptr, 0);
2528 analyze = strtol(optarg,(
char **)
nullptr, 0);
2529 if (analyze>2)
usage(argv[0]);
2545 if (optind == argc-1) {
2547 perror(
"Error opening input file ");
2550 LOG(VB_GENERAL, LOG_INFO,
2551 QString(
"Reading from %1").arg(argv[optind]));
2553 LOG(VB_GENERAL, LOG_INFO,
2554 QString(
"Input file length: %1 MB")
2555 .arg(rx.
inflength/1024.0/1024.0, 0,
'f',2,QChar(
'0')));
2560 LOG(VB_GENERAL, LOG_INFO,
"using stdin as input");
2561 rx.
fd_in = STDIN_FILENO;
2572 perror(
"Error opening output file");
2575 LOG(VB_GENERAL, LOG_INFO,
2576 QString(
"Output File is: %1").arg(
filename));
2578 rx.
fd_out = STDOUT_FILENO;
2579 LOG(VB_GENERAL, LOG_INFO,
"using stdout as output");
2583 if (rx.
fd_in == STDIN_FILENO){
2584 LOG(VB_GENERAL, LOG_ERR,
"Can`t scan from pipe");
2591 if (!strncmp(
type,
"MPEG2",6))
2593 else if (!strncmp(
type,
"DVD",4))
2595 else if (!strncmp(
type,
"HDTV",4))
2600 if (!strncmp(inpt,
"TS",3)){
2602 }
else if (!strncmp(inpt,
"PS",3)){
2609 }
else if (!strncmp(inpt,
"AVI",4)){
2626 filename =
static_cast<char*
>(malloc(4));
2630 LOG(VB_GENERAL, LOG_ERR,
"Basename too long");
2634 snprintf(fname,256,
"%s.mv2",
filename);
2635 if ((rx.
dmx_out[0] = open(fname,O_WRONLY|
2642 perror(
"Error opening output file");
2645 LOG(VB_GENERAL, LOG_INFO,
2646 QString(
"Video output File is: %1").arg(fname));
2648 for (i=0; i < rx.
apidn; i++){
2649 snprintf(fname,256,
"%s%d.mp2",
filename
2652 open(fname,O_WRONLY|
2659 perror(
"Error opening output file");
2662 LOG(VB_GENERAL, LOG_INFO,
2663 QString(
"Audio%1 output File is: %2")
2664 .arg(i).arg(fname));
2668 for (i=0; i < rx.
ac3n; i++){
2669 snprintf(fname,256,
"%s%d.ac3",
filename
2672 open(fname,O_WRONLY|
2679 perror(
"Error opening output file");
2682 LOG(VB_GENERAL, LOG_INFO,
2683 QString(
"AC3%1 output File is: %2")
2684 .arg(i).arg(fname));
2687 }
else if (analyze){
static unsigned int ring_free(ringbuffer *rbuf)
static void find_pes_ids(struct replex *rx)
static int ring_posdiff(ringbuffer *rbuf, int pos1, int pos2)
static int replex_tsp(struct replex *rx, uint8_t *tsp)
int write_out_packs(multiplex_t *mx, int video_ok, aok_arr &ext_ok)
int ring_init(ringbuffer *rbuf, int size)
static void ptsdec(uint64_t *pts1, uint64_t pts2)
avi_audio_info ai[MAX_TRACK]
static void error(const char *str,...)
int find_audio_sync(ringbuffer *rbuf, audio_sync_buf &buf, int off, int type, int le)
audio_frame_t extframe[N_AUDIO]
index_unit current_vindex
static int fill_buffers(void *r, int finish)
int ring_peek(ringbuffer *rbuf, uint8_t *data, unsigned int count, uint32_t off)
uint64_t next_ptsdts_video(uint64_t *pts, sequence_t *s, uint64_t fcount, uint64_t gcount)
int find_audio_s(const uint8_t *rbuf, int off, int type, int le)
int find_any_header(uint8_t *head, const uint8_t *buf, int length)
def read(device=None, features=[])
int get_video_info(ringbuffer *rbuf, sequence_t *s, int off, int le)
uint16_t get_pid(const uint8_t *pid)
static void fix_audio(struct replex *rx, multiplex_t *mx)
ringbuffer extrbuffer[N_AUDIO]
void fix_video_count(sequence_t *s, uint64_t *frame, uint64_t origpts, uint64_t pts, uint64_t origdts, uint64_t dts)
void init_index(index_unit *iu)
static int get_next_video_unit(struct replex *rx, index_unit *viu)
static void avi_es_out(pes_in_t *p)
static void pes_es_out(pes_in_t *p)
int get_audio_info(ringbuffer *rbuf, audio_frame_t *af, int off, int le)
def write(text, progress=True)
int get_ac3_info(ringbuffer *rbuf, audio_frame_t *af, int off, int le)
uint64_t aframe_count[N_AUDIO]
#define PICTURE_START_CODE
uint64_t last_ac3pts[N_AC3]
int read_avi_header(avi_context *ac, int fd)
void printpts(int64_t pts)
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
static void find_pids_file(struct replex *rx)
void init_multiplex(multiplex_t *mx, sequence_t *seq_head, audio_frame_t *extframe, int *exttype, const int *exttypcnt, uint64_t video_delay, uint64_t audio_delay, int fd, int(*fill_buffers)(void *p, int f), ringbuffer *vrbuffer, ringbuffer *index_vrbuffer, ringbuffer *extrbuffer, ringbuffer *index_extrbuffer, int otype)
void fix_audio_count(uint64_t *acount, audio_frame_t *aframe, uint64_t origpts, uint64_t pts)
int ring_read_file(ringbuffer *rbuf, int fd, int count)
index_unit current_ac3index[N_AC3]
int avi_read_index(avi_context *ac, int fd)
ringbuffer index_vrbuffer
def scan(profile, smoonURL, gate)
int check_audio_header(ringbuffer *rbuf, audio_frame_t *af, int off, int le, int type)
int64_t ptsdiff(uint64_t pts1, uint64_t pts2)
static void do_replex(struct replex *rx)
index_unit current_aindex[N_AUDIO]
static void pes_id_out(pes_in_t *p)
static int guess_fill(struct replex *rx)
#define SEQUENCE_END_CODE
static void analyze_audio(pes_in_t *p, struct replex *rx, int len, int num, int type)
audio_frame_t ac3frame[N_AC3]
uint64_t trans_pts_dts(const uint8_t *pts)
static void do_analyze(struct replex *rx)
ringbuffer index_arbuffer[N_AUDIO]
std::array< uint8_t, 7 > audio_sync_buf
static constexpr uint8_t PAY_START
uint64_t last_apts[N_AUDIO]
ringbuffer index_ac3rbuffer[N_AC3]
int find_pids(uint16_t *vpid, uint16_t *apid, uint16_t *ac3pid, uint8_t *buf, int len)
int get_avi_from_index(pes_in_t *p, int fd, avi_context *ac, void(*func)(pes_in_t *p), uint32_t insize)
static int get_next_audio_unit(struct replex *rx, index_unit *aiu, int i)
static int replex_fill_buffers(struct replex *rx, uint8_t *mbuf)
int find_pids_pos(uint16_t *vpid, uint16_t *apid, uint16_t *ac3pid, uint8_t *buf, int len, int *vpos, int *apos, int *ac3pos)
void check_times(multiplex_t *mx, int *video_ok, aok_arr &ext_ok, int *start)
static int replex_all_set(struct replex *rx)
static constexpr qint64 TS_SIZE
int ring_write(ringbuffer *rbuf, uint8_t *data, int count)
uint64_t add_pts_audio(uint64_t pts, audio_frame_t *aframe, uint64_t frames)
static constexpr uint8_t ADAPT_FIELD
static void usage(char *progname)
static void do_scan(struct replex *rx)
int finish_mpg(multiplex_t *mx)
static int get_next_ac3_unit(struct replex *rx, index_unit *aiu, int i)
static int encode_mp2_audio(audio_frame_t *aframe, uint8_t *buffer, int bufsize)
static int replex_check_id(struct replex *rx, uint16_t id)
ringbuffer ac3rbuffer[N_AC3]
static int ring_wpos(ringbuffer *rbuf)
static void es_out(pes_in_t *p)
void get_pes(pes_in_t *p, uint8_t *buf, int count, void(*func)(pes_in_t *p))
ringbuffer index_extrbuffer[N_AUDIO]
uint64_t uptsdiff(uint64_t pts1, uint64_t pts2)
#define SEQUENCE_HDR_CODE
int ring_read(ringbuffer *rbuf, uint8_t *data, int count)
ringbuffer arbuffer[N_AUDIO]
int ring_find_any_header(ringbuffer *rbuf, uint8_t *head, int off, int le)
void init_pes_in(pes_in_t *p, int t, ringbuffer *rb, int wi)
static int check_stream_type(struct replex *rx, uint8_t *buf, int len)
void get_avi(pes_in_t *p, uint8_t *buf, int count, void(*func)(pes_in_t *p))
static int avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, const short *samples)
static void find_pids_stdin(struct replex *rx, uint8_t *buf, int len)
static unsigned int ring_avail(ringbuffer *rbuf)
static ssize_t save_read(struct replex *rx, void *buf, size_t count)
int ring_skip(ringbuffer *rbuf, int count)
#define PICTURE_CODING_EXTENSION
void setup_multiplex(multiplex_t *mx)
int main(int argc, char **argv)
int check_riff(avi_context *ac, uint8_t *buf, int len)
int get_video_ext_info(ringbuffer *rbuf, sequence_t *s, int off, int le)
static void do_demux(struct replex *rx)
int ptscmp(uint64_t pts1, uint64_t pts2)
audio_frame_t aframe[N_AUDIO]
int dmx_out[N_AC3+N_AUDIO+1]
void printptss(int64_t pts)
static void analyze_video(pes_in_t *p, struct replex *rx, int len)
static void init_replex(struct replex *rx)
static const std::array< const uint64_t, 4 > samples
uint64_t first_apts[N_AUDIO]
void show_buf(uint8_t *buf, int length)
uint64_t first_ac3pts[N_AC3]
static void replex_finish(struct replex *rx)
std::array< bool, N_AUDIO > aok_arr
static void find_all_pids_file(struct replex *rx)
#define EXTENSION_START_CODE
static int ring_rdiff(ringbuffer *rbuf, int pos)
uint64_t ac3frame_count[N_AC3]