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;
100 frame = av_frame_alloc();
102 return AVERROR(ENOMEM);
104 if (avctx->frame_size) {
105 frame->nb_samples = avctx->frame_size;
110 if (!av_get_bits_per_sample(avctx->codec_id)) {
111 av_log(avctx, AV_LOG_ERROR,
"avcodec_encode_audio() does not "
112 "support this codec\n");
113 av_frame_free(&frame);
114 return AVERROR(EINVAL);
116 nb_samples = (int64_t)buf_size * 8 /
117 (av_get_bits_per_sample(avctx->codec_id) *
119 if (nb_samples >= INT_MAX) {
120 av_frame_free(&frame);
121 return AVERROR(EINVAL);
123 frame->nb_samples = nb_samples;
128 samples_size = av_samples_get_buffer_size(
nullptr, avctx->channels,
130 avctx->sample_fmt, 1);
131 if ((ret = avcodec_fill_audio_frame(frame, avctx->channels,
134 samples_size, 1)) < 0) {
135 av_frame_free(&frame);
139 frame->pts = AV_NOPTS_VALUE;
148 ret = avcodec_receive_packet(avctx, &pkt);
151 if (ret == AVERROR(EAGAIN))
154 ret = avcodec_send_frame(avctx, frame);
158 char error[AV_ERROR_MAX_STRING_SIZE+25];
159 strcpy(
error,
"audio encode error: ");
165 av_packet_free_side_data(&pkt);
167 if (frame && frame->extended_data != frame->data)
168 av_freep(&frame->extended_data);
170 av_frame_free(&frame);
171 return ret ? ret : pkt.size;
177 AVCodecContext *c=
nullptr;
178 int frame_size, j, out_size;
181 LOG(VB_GENERAL, LOG_INFO,
"encoding an MP2 audio frame");
184 codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
186 LOG(VB_GENERAL, LOG_ERR,
"codec not found");
190 c = avcodec_alloc_context3(codec);
196 c->sample_fmt = AV_SAMPLE_FMT_S16;
199 if (avcodec_open2(c, codec,
nullptr) < 0) {
200 LOG(VB_GENERAL, LOG_ERR,
"could not open codec");
206 frame_size = c->frame_size;
207 samples =
static_cast<short*
>(malloc(frame_size * 2 * c->channels));
210 for (j=0;j<frame_size;j++) {
218 if (out_size != bufsize) {
219 LOG(VB_GENERAL, LOG_ERR,
220 QString(
"frame size (%1) does not equal required size (%2)?")
221 .
arg(out_size).
arg(bufsize));
223 avcodec_free_context(&c);
228 avcodec_free_context(&c);
239 ringbuffer *rbuf =
nullptr, *index_buf =
nullptr;
240 uint64_t *acount=
nullptr;
241 uint64_t *fpts=
nullptr;
242 uint64_t *lpts=
nullptr;
247 int *apes_abort=
nullptr;
253 LOG(VB_GENERAL, LOG_DEBUG,
"AC3");
268 LOG(VB_GENERAL, LOG_DEBUG,
"MPEG AUDIO");
270 aframe = &rx->
aframe[num];
301 *apes_abort = len -c;
310 LOG(VB_GENERAL, LOG_INFO,
311 "starting audio PTS: ");
313 }
else aframe->
set = 0;
316 if (aframe->
set && first)
328 *apes_abort = len -c;
340 LOG(VB_GENERAL, LOG_DEBUG,
341 QString(
"WRONG HEADER1 %1").
arg(diff));
349 LOG(VB_GENERAL, LOG_ERR,
350 QString(
"WRONG HEADER2 %1").
arg(diff));
361 if (abs ((
int)diff) >= frame_time){
362 LOG(VB_GENERAL, LOG_INFO,
363 "fixing audio PTS inconsistency - diff: ");
368 int framesdiff = diff / frame_time;
369 LOG(VB_GENERAL, LOG_INFO,
370 QString(
" - need to remove %1 frame(s)")
380 int framesdiff = diff / frame_time;
381 LOG(VB_GENERAL, LOG_INFO,
382 QString(
" - need to add %1 frame(s)")
391 if ( !(framebuf = (uint8_t *) malloc(
sizeof(uint8_t) * aframe->
framesize))) {
392 LOG(VB_GENERAL, LOG_ERR,
393 "Not enough memory for audio frame");
403 LOG(VB_GENERAL, LOG_ERR,
404 QString(
"ring buffer failed to peek frame res: %1")
412 for (x = 0; x < framesdiff; x++){
433 LOG(VB_GENERAL, LOG_ERR,
434 QString(
"Wrong audio frame size: %1")
441 LOG(VB_GENERAL, LOG_ERR,
442 "audio ring buffer overrun error");
460 LOG(VB_GENERAL, LOG_ERR,
461 "audio PTS inconsistent:");
464 LOG(VB_GENERAL, LOG_ERR,
477 LOG(VB_GENERAL, LOG_WARNING,
478 "Warning negative audio PTS increase!\n");
490 iu->
start = (
p->ini_pos+pos+c)%bsize;
495 LOG(VB_GENERAL, LOG_INFO,
496 QString(
"SHORT %1").
arg(len-c));
511 std::vector<uint8_t> buf(8);
542 LOG(VB_GENERAL, LOG_DEBUG, QString(
" ini pos %1")
548 LOG(VB_GENERAL, LOG_INFO, QString(
"len %1 %2").
arg(len).
arg(off));
556 LOG(VB_GENERAL, LOG_DEBUG, QString(
" seq headr %1")
567 pos+c+off, len -c -pos);
570 LOG(VB_GENERAL, LOG_DEBUG,
571 QString(
" seq headr result %1")
594 LOG(VB_GENERAL, LOG_DEBUG,
595 QString(
" seq ext headr %1")
619 LOG(VB_GENERAL, LOG_INFO,
620 "starting with video PTS:");
627 LOG(VB_GENERAL, LOG_DEBUG,
628 QString(
"fcount %1 gcount %2 tempref %3 %4")
648 LOG(VB_GENERAL, LOG_INFO,
649 "video PTS inconsistent:");
654 LOG(VB_GENERAL, LOG_INFO,
668 LOG(VB_GENERAL, LOG_INFO,
669 "video DTS inconsistent: ");
674 LOG(VB_GENERAL, LOG_INFO,
690 }
else iu->
dts = newdts;
703 LOG(VB_GENERAL, LOG_WARNING,
704 "Warning negative video PTS increase!");
727 LOG(VB_GENERAL, LOG_DEBUG, QString(
" seq end %1")
738 LOG(VB_GENERAL, LOG_DEBUG, QString(
" %1")
743 if (!seq_h) flush = 1;
746 gop_off = c+pos - seq_p;
748 if (
ring_peek(rbuf, buf, 7, off+c+pos) < 0) {
753 int hour = (int)((buf[4]>>2)& 0x1F);
754 int min = (int)(((buf[4]<<4)& 0x30)|
755 ((buf[5]>>4)& 0x0F));
756 int sec = (int)(((buf[5]<<3)& 0x38)|
757 ((buf[6]>>5)& 0x07));
758 LOG(VB_GENERAL, LOG_DEBUG,
759 QString(
" gop %1:%2.%3 %4")
760 .
arg(hour,2,10,QChar(
'0'))
761 .
arg(min, 2,10,QChar(
'0'))
762 .
arg(sec, 2,10,QChar(
'0'))
771 if (len-(c+pos) < 14){
777 off+c+pos) < 0)
return;
780 frame = ((buf[5]&0x38) >>3);
794 frame_off = c+pos - seq_p;
796 if (!seq_h && !gop) flush = 1;
798 tempref = (buf[5]>>6) & 0x03;
799 tempref |= buf[4] << 2;
804 LOG(VB_GENERAL, LOG_DEBUG,
"I");
807 LOG(VB_GENERAL, LOG_DEBUG,
808 QString(
" I-frame %1")
814 LOG(VB_GENERAL, LOG_DEBUG,
"B");
817 LOG(VB_GENERAL, LOG_DEBUG,
818 QString(
" B-frame %1")
824 LOG(VB_GENERAL, LOG_DEBUG,
"P");
827 LOG(VB_GENERAL, LOG_DEBUG,
828 QString(
" P-frame %1")
841 LOG(VB_GENERAL, LOG_ERR,
842 QString(
"other header 0x%1 (%2+%3)")
843 .
arg(head, 2,16,QChar(
'0')).
arg(c).
arg(pos));
862 LOG(VB_GENERAL, LOG_ERR,
863 "video ring buffer overrun error");
879 iu->
start = (
p->ini_pos+pos+c-frame_off)
882 LOG(VB_GENERAL, LOG_DEBUG,
883 QString(
"START %1").arg(iu->
start));
889 iu->
frame = (frame&0xFF);
919 len =
p->plength-3-
p->hlength;
921 rx = (
struct replex *)
p->priv;
926 sprintf(
t,
"Video ");
941 sprintf(
t,
"Audio%d ", l);
957 sprintf(
t,
"AC3 %d ",
p->type);
970 LOG(VB_GENERAL, LOG_ERR,
971 QString(
"UNKNOWN AUDIO type %1").
arg(
p->type));
978 LOG(VB_GENERAL, LOG_DEBUG, QString(
"%1 PES").
arg(
t));
990 len =
p->plength-3-
p->hlength;
991 rx = (
struct replex *)
p->priv;
995 if (rx->
vpid !=
p->cid)
break;
1000 LOG(VB_GENERAL, LOG_ERR,
1001 "video ring buffer overrun error");
1008 sprintf(
t,
"Video ");
1016 p->type =
p->cid - 0xc0 + 1;
1018 for (i=0; i<rx->
apidn; i++)
1019 if (
p->cid == rx->
apid[i])
1024 LOG(VB_GENERAL, LOG_ERR,
1025 "video ring buffer overrun error");
1034 sprintf(
t,
"Audio%d ", l);
1051 fframe =
p->buf[9+
p->hlength+3];
1052 fframe |= (
p->buf[9+
p->hlength+2]<<8);
1054 if (fframe >
p->plength)
break;
1056 p->type =
p->buf[9+
p->hlength];
1058 for (i=0; i<rx->
ac3n; i++)
1067 LOG(VB_GENERAL, LOG_ERR,
1068 "video ring buffer overrun error");
1077 sprintf(
t,
"AC3 %d ",
p->type);
1090 LOG(VB_GENERAL, LOG_DEBUG, QString(
"%1 PES %2").
arg(
t).
arg(len));
1103 rx = (
struct replex *)
p->priv;
1109 sprintf(
t,
"Video ");
1124 sprintf(
t,
"Audio%d ", l);
1136 case 0x80 ... 0x87:{
1140 sprintf(
t,
"AC3 %d ",
p->type);
1157 LOG(VB_GENERAL, LOG_DEBUG, QString(
"%1 PES").
arg(
t));
1195 p->plength =
p->found-6;
1203 if (off+4 >=
TS_SIZE)
return 0;
1220 if ( l <= 0)
return 0;
1221 if ( (
int) count > l) count = l;
1223 while(neof >= 0 && re < count){
1224 neof =
read(fd, ((
char*)buf)+re, count - re);
1225 if (neof > 0) re += neof;
1234 if (per % 10 == 0 && rx->
lastper < per){
1235 LOG(VB_GENERAL, LOG_DEBUG, QString(
"read %1%%")
1240 LOG(VB_GENERAL, LOG_DEBUG, QString(
"read %1 MB")
1241 .
arg(rx->
finread/1024.0/1024.0, 0,
'f',2,QChar(
'0')));
1243 if (neof < 0 && re == 0)
return neof;
1249 int vavail, aavail, ac3avail, i, fill;
1261 for (i=0; i<rx->
apidn;i++){
1268 for (i=0; i<rx->
ac3n;i++){
1276 LOG(VB_GENERAL, LOG_INFO,
1277 QString(
"free %1 %2 %3 %4")
1282 if(vavail && (aavail || ac3avail))
return 0;
1291 #define IN_SIZE (1000*TS_SIZE)
1301 LOG(VB_GENERAL, LOG_INFO,
"Trying to find PIDs");
1302 while (!afound && !vfound && count < (
int) rx->
inflength){
1303 if (rx->
vpid) vfound = 1;
1304 if (rx->
apidn) afound = 1;
1306 LOG(VB_GENERAL, LOG_ERR,
1307 QString(
"reading: %1").
arg(strerror(errno)));
1313 LOG(VB_GENERAL, LOG_INFO,QString(
"vpid 0x%1")
1314 .
arg(rx->
vpid, 4,16,QChar(
'0')));
1319 LOG(VB_GENERAL, LOG_INFO, QString(
"apid 0x%1")
1320 .
arg(rx->
apid[0], 4,16,QChar(
'0')));
1324 if (!rx->
ac3n && ac3pid){
1326 LOG(VB_GENERAL, LOG_INFO, QString(
"ac3pid 0x%1")
1337 if (!afound || !vfound){
1338 LOG(VB_GENERAL, LOG_ERR,
"Couldn't find all pids");
1346 #define MAXAC3PID 16
1354 int vn=0, an=0,
ac3n=0;
1356 int vpos, apos, cpos;
1362 LOG(VB_GENERAL, LOG_INFO,
"Trying to find PIDs");
1365 LOG(VB_GENERAL, LOG_ERR, QString(
"reading: %1")
1366 .
arg(strerror(errno)));
1370 &vpos, &apos, &cpos))){
1373 for (j=0; j < vn; j++){
1375 LOG(VB_GENERAL, LOG_INFO,
1386 LOG(VB_GENERAL, LOG_INFO,
1387 QString(
"vpid %1: 0x%2 (%3) PES ID: 0x%4")
1389 .
arg(
vpid[vn], 4,16,QChar(
'0'))
1391 .
arg(buf[vpos], 2,16,QChar(
'0')));
1398 for (j=0; j < an; j++)
1405 LOG(VB_GENERAL, LOG_INFO,
1406 QString(
"apid %1: 0x%2 (%3) PES ID: 0x%4")
1408 .
arg(
apid[an], 4,16,QChar(
'0'))
1410 .
arg(buf[apos], 2,16,QChar(
'0')));
1417 for (j=0; j <
ac3n; j++)
1418 if (ac3pid[j] == cp){
1424 LOG(VB_GENERAL, LOG_INFO,
1425 QString(
"ac3pid %1: 0x%2 (%3)")
1427 .
arg(ac3pid[
ac3n], 4,16,QChar(
'0'))
1445 if (rx->
vpid) vfound = 1;
1446 if (rx->
apidn) afound = 1;
1447 LOG(VB_GENERAL, LOG_INFO,
"Trying to find PIDs");
1467 if (!rx->
ac3n && ac3pid){
1483 if (afound && vfound){
1484 LOG(VB_GENERAL, LOG_INFO,
"found");
1486 LOG(VB_GENERAL, LOG_INFO, QString(
"vpid %1 (0x%2)")
1489 LOG(VB_GENERAL, LOG_INFO, QString(
"apid %1 (0x%2)")
1490 .
arg(rx->
apid[0]).arg(rx->
apid[0], 4,16,QChar(
'0')));
1492 LOG(VB_GENERAL, LOG_INFO, QString(
"ac3pid %1 (0x%2)")
1495 LOG(VB_GENERAL, LOG_ERR,
"Couldn't find pids");
1524 uint8_t
id =
p->buf[9+
p->hlength];
1532 fframe =
p->buf[9+
p->hlength+3];
1533 fframe |= (
p->buf[9+
p->hlength+2]<<8);
1535 if (fframe < p->plength){
1537 9+
p->hlength+4+fframe,
1538 AC3,
p->plength+6)) >= 0){
1541 LOG(VB_GENERAL, LOG_INFO,
1542 QString(
"0x%1 0x%2 \n")
1543 .
arg(c-9-
p->hlength-4, 4,16,QChar(
'0'))
1544 .
arg(fframe, 4,16,QChar(
'0')));
1571 int vn=0, an=0,
ac3n=0;
1577 LOG(VB_GENERAL, LOG_INFO,
"Trying to find PES IDs");
1582 LOG(VB_GENERAL, LOG_ERR, QString(
"reading: %1")
1583 .
arg(strerror(errno)));
1596 for (j=0; j < vn; j++){
1598 LOG(VB_GENERAL, LOG_INFO,
1609 LOG(VB_GENERAL, LOG_INFO,
1610 QString(
"MPEG VIDEO %1: 0x%2 (%3)")
1612 .
arg(
vpid[vn], 2,16,QChar(
'0'))
1623 for (j=0; j < an; j++)
1630 LOG(VB_GENERAL, LOG_INFO,
1631 QString(
"MPEG AUDIO %1: 0x%2 (%3)")
1633 .
arg(
apid[an], 2,16,QChar(
'0'))
1643 for (j=0; j <
ac3n; j++)
1651 LOG(VB_GENERAL, LOG_INFO,
1652 "possible AC3 AUDIO with private stream 1 pid (0xbd)");
1654 LOG(VB_GENERAL, LOG_INFO,
1655 QString(
"AC3 AUDIO %1: 0x%2 (%3)")
1657 .
arg(ac3pid[
ac3n], 2,16,QChar(
'0'))
1676 LOG(VB_GENERAL, LOG_ERR,
"Can't find all required streams");
1678 LOG(VB_GENERAL, LOG_ERR,
1679 "Please check if audio and video have standard IDs (0xc0 or 0xe0)");
1699 if (rx->
finish)
return 0;
1702 LOG(VB_GENERAL, LOG_INFO,
1703 QString(
"trying to fill buffers with %1").
arg(fill));
1705 if (fill < 0)
return -1;
1712 rsize = fill - (fill%188);
1716 LOG(VB_GENERAL, LOG_INFO, QString(
"filling with %1").
arg(rsize));
1719 if (!rsize)
return 0;
1724 for ( i = 0; i < 188 ; i++){
1725 if ( mbuf[i] == 0x47 )
break;
1729 LOG(VB_GENERAL, LOG_ERR,
"Not a TS");
1732 memcpy(buf,mbuf+i,2*
TS_SIZE-i);
1734 LOG(VB_GENERAL, LOG_ERR, QString(
"reading: %1")
1735 .
arg(strerror(errno)));
1736 memcpy(buf+2*
TS_SIZE-i,mbuf,i);
1743 while (count < rsize && tries <
MAX_TRIES){
1744 if ((re =
save_read(rx,buf+i,rsize-i)+i)<0)
1745 LOG(VB_GENERAL, LOG_ERR, QString(
"reading: %1")
1746 .
arg(strerror(errno)));
1755 for( j = 0; j < re; j+=
TS_SIZE){
1760 LOG(VB_GENERAL, LOG_ERR,
1761 "Error reading TS");
1779 while (count < rsize && tries <
MAX_TRIES){
1781 LOG(VB_GENERAL, LOG_ERR, QString(
"reading PS: %1")
1782 .
arg(strerror(errno)));
1808 while (count < rsize && tries <
MAX_TRIES){
1810 LOG(VB_GENERAL, LOG_ERR,
1811 QString(
"reading AVI: %1")
1812 .
arg(strerror(errno)));
1856 for (i=0; i < rx->
ac3n ;i++){
1859 for (i=0; i<rx->
apidn;i++){
1864 if (set == (rx->
ac3n+ rx->
apidn + 1))
return 1;
1878 LOG(VB_GENERAL, LOG_ERR,
"cannot determine streamtype");
1882 LOG(VB_GENERAL, LOG_INFO,
"Checking for TS: ");
1883 while (c < len && buf[c]!=0x47) c++;
1886 LOG(VB_GENERAL, LOG_INFO,
"confirmed");
1888 }
else LOG(VB_GENERAL, LOG_INFO,
"failed");
1889 }
else LOG(VB_GENERAL, LOG_INFO,
"failed");
1891 LOG(VB_GENERAL, LOG_INFO,
"Checking for AVI: ");
1893 LOG(VB_GENERAL, LOG_INFO,
"confirmed");
1900 }
else LOG(VB_GENERAL, LOG_INFO,
"failed");
1902 LOG(VB_GENERAL, LOG_INFO,
"Checking for PS: ");
1904 LOG(VB_GENERAL, LOG_INFO,
"confirmed(maybe)");
1906 LOG(VB_GENERAL, LOG_INFO,
"failed, trying it anyway");
1926 LOG(VB_GENERAL, LOG_ERR,
1927 QString(
"reading: %1").
arg(strerror(errno)));
1970 for (i=0; i<rx->
apidn;i++){
1989 for (i=0; i<rx->
ac3n;i++){
2008 LOG(VB_GENERAL, LOG_ERR,
"error filling buffer");
2016 ssize_t read_count = 0;
2021 if ((read_count =
save_read(rx, buf, 12)) != 12) {
2022 LOG(VB_GENERAL, LOG_ERR,
2023 QString(
"Error reading in 12 bytes from replex. Read %1 bytes")
2029 LOG(VB_GENERAL, LOG_ERR,
"Wrong RIFF header");
2032 LOG(VB_GENERAL, LOG_INFO,
"Found RIFF header");
2038 LOG(VB_GENERAL, LOG_ERR,
"Error reading index");
2047 LOG(VB_GENERAL, LOG_INFO, QString(
"AVI initial frames %1")
2050 LOG(VB_GENERAL, LOG_ERR,
"Error reading AVI header");
2055 LOG(VB_GENERAL, LOG_ERR,
"error filling buffer");
2060 LOG(VB_GENERAL, LOG_ERR,
"error filling buffer");
2076 for ( i = 0; i < rx->
apidn; i++){
2081 LOG(VB_GENERAL, LOG_ERR,
2082 "error in fix audio");
2093 mx->
ext[i].pts_off = aiu.
pts;
2095 LOG(VB_GENERAL, LOG_INFO, QString(
"Audio%1 offset: ").
arg(i));
2100 for ( i = 0; i < rx->
ac3n; i++){
2105 LOG(VB_GENERAL, LOG_ERR,
2106 "error in fix audio");
2117 mx->
ext[i].pts_off = aiu.
pts;
2119 LOG(VB_GENERAL, LOG_INFO, QString(
"AC3%1 offset: ").
arg(i));
2168 uint64_t lastac3pts[
N_AC3];
2175 memset(lastapts, 0,
N_AUDIO*
sizeof(uint64_t));
2176 memset(lastac3pts, 0,
N_AC3*
sizeof(uint64_t));
2178 LOG(VB_GENERAL, LOG_INFO,
"STARTING ANALYSIS");
2183 LOG(VB_GENERAL, LOG_ERR,
2184 "error in get next video unit");
2187 for (i=0; i< rx->
apidn; i++){
2192 LOG(VB_GENERAL, LOG_INFO,
2193 QString(
"MPG2 Audio%1 unit: length %2 PTS ")
2198 LOG(VB_GENERAL, LOG_INFO,
2202 lastapts[i] = dummy2.
pts;
2207 for (i=0; i< rx->
ac3n; i++){
2212 LOG(VB_GENERAL, LOG_INFO,
2213 QString(
"AC3 Audio%1 unit: length %2 PTS ")
2217 LOG(VB_GENERAL, LOG_INFO,
2221 lastac3pts[i] = dummy2.
pts;
2229 if (av==0 || av==2){
2230 LOG(VB_GENERAL, LOG_INFO,
"Video unit: ");
2232 LOG(VB_GENERAL, LOG_INFO,
2233 "Sequence header ");
2236 LOG(VB_GENERAL, LOG_INFO,
2239 switch (dummy.
frame){
2241 LOG(VB_GENERAL, LOG_INFO,
"I-frame");
2244 LOG(VB_GENERAL, LOG_INFO,
"B-frame");
2247 LOG(VB_GENERAL, LOG_INFO,
"P-frame");
2250 LOG(VB_GENERAL, LOG_INFO, QString(
" length %1 PTS ")
2254 LOG(VB_GENERAL, LOG_INFO,
" diff:");
2257 lastvpts = dummy.
pts;
2259 LOG(VB_GENERAL, LOG_INFO,
" DTS ");
2262 LOG(VB_GENERAL, LOG_INFO,
" diff:");
2265 lastvdts = dummy.
dts;
2280 LOG(VB_GENERAL, LOG_ERR, QString(
"reading: %1")
2281 .
arg(strerror(errno)));
2283 LOG(VB_GENERAL, LOG_INFO,
"STARTING SCAN");
2308 LOG(VB_GENERAL, LOG_INFO,
"STARTING DEMUX");
2312 LOG(VB_GENERAL, LOG_ERR,
2313 "error in get next video unit");
2316 for (i=0; i< rx->
apidn; i++){
2324 for (i=0; i< rx->
ac3n; i++){
2348 LOG(VB_GENERAL, LOG_INFO,
"STARTING REPLEX");
2349 memset(&mx, 0,
sizeof(mx));
2353 LOG(VB_GENERAL, LOG_INFO,
"error filling buffer");
2359 for (i = 0; i < rx->
apidn; i++){
2376 mx.
priv = (
void *) rx;
2377 rx->
priv = (
void *) &mx;
2394 LOG(VB_GENERAL, LOG_ERR,
"error while writing");
2403 printf (
"usage: %s [options] <input files>\n\n",progname);
2404 printf (
"options:\n");
2405 printf (
" --help, -h: print help message\n");
2406 printf (
" --type, -t: set output type (MPEG2, DVD, HDTV)\n");
2407 printf (
" --of, -o: set output file\n");
2408 printf (
" --input_stream, -i: set input stream type (TS(default), PS, AVI)\n");
2409 printf (
" --audio_pid, -a: audio PID for TS stream (also used for PS id)\n");
2410 printf (
" --ac3_id, -c: ID of AC3 audio for demux (also used for PS id)\n");
2411 printf (
" --video_pid, -v: video PID for TS stream (also used for PS id)\n");
2412 printf (
" --video_delay, -d: video delay in ms\n");
2413 printf (
" --audio_delay, -e: audio delay in ms\n");
2414 printf (
" --ignore_PTS, -f: ignore all PTS information of original\n");
2415 printf (
" --keep_PTS, -k: keep and don't correct PTS information of original\n");
2416 printf (
" --fix_sync, -n: try to fix audio sync while demuxing\n");
2417 printf (
" --demux, -z: demux only (-o is basename)\n");
2418 printf (
" --analyze, -y: analyze (0=video,1=audio, 2=both)\n");
2419 printf (
" --scan, -s: scan for streams\n");
2420 printf (
" --vdr, -x: handle AC3 for vdr input file\n");
2430 const char *
type =
"SVCD";
2431 const char *inpt =
"TS";
2435 memset(&rx, 0,
sizeof(
struct replex));
2438 int option_index = 0;
2439 static struct option long_options[] = {
2440 {
"type", required_argument,
nullptr,
't'},
2441 {
"input_stream", required_argument,
nullptr,
'i'},
2442 {
"video_pid", required_argument,
nullptr,
'v'},
2443 {
"audio_pid", required_argument,
nullptr,
'a'},
2444 {
"audio_delay", required_argument,
nullptr,
'e'},
2445 {
"video_delay", required_argument,
nullptr,
'd'},
2446 {
"ac3_id", required_argument,
nullptr,
'c'},
2447 {
"of",required_argument,
nullptr,
'o'},
2448 {
"ignore_PTS",required_argument,
nullptr,
'f'},
2449 {
"keep_PTS",required_argument,
nullptr,
'k'},
2450 {
"fix_sync",no_argument,
nullptr,
'n'},
2451 {
"demux",no_argument,
nullptr,
'z'},
2452 {
"analyze",required_argument,
nullptr,
'y'},
2453 {
"scan",required_argument,
nullptr,
's'},
2454 {
"vdr",required_argument,
nullptr,
'x'},
2455 {
"help", no_argument ,
nullptr,
'h'},
2456 {
nullptr, 0,
nullptr, 0}
2458 c = getopt_long (argc, argv,
2459 "t:o:a:v:i:hp:q:d:c:n:fkd:e:zy:sx",
2460 long_options, &option_index);
2472 rx.
video_delay = strtol(optarg,(
char **)
nullptr, 0)
2476 rx.
audio_delay = strtol(optarg,(
char **)
nullptr, 0)
2481 LOG(VB_GENERAL, LOG_ERR,
"Too many audio PIDs");
2484 rx.
apid[rx.
apidn] = strtol(optarg,(
char **)
nullptr, 0);
2488 rx.
vpid = strtol(optarg,(
char **)
nullptr, 0);
2492 LOG(VB_GENERAL, LOG_ERR,
"Too many audio PIDs");
2495 rx.
ac3_id[rx.
ac3n] = strtol(optarg,(
char **)
nullptr, 0);
2514 analyze = strtol(optarg,(
char **)
nullptr, 0);
2515 if (analyze>2)
usage(argv[0]);
2531 if (optind == argc-1) {
2533 perror(
"Error opening input file ");
2536 LOG(VB_GENERAL, LOG_INFO,
2537 QString(
"Reading from %1").
arg(argv[optind]));
2539 LOG(VB_GENERAL, LOG_INFO,
2540 QString(
"Input file length: %1 MB")
2546 LOG(VB_GENERAL, LOG_INFO,
"using stdin as input");
2547 rx.
fd_in = STDIN_FILENO;
2558 perror(
"Error opening output file");
2561 LOG(VB_GENERAL, LOG_INFO,
2564 rx.
fd_out = STDOUT_FILENO;
2565 LOG(VB_GENERAL, LOG_INFO,
"using stdout as output");
2569 if (rx.
fd_in == STDIN_FILENO){
2570 LOG(VB_GENERAL, LOG_ERR,
"Can`t scan from pipe");
2577 if (!strncmp(
type,
"MPEG2",6))
2579 else if (!strncmp(
type,
"DVD",4))
2581 else if (!strncmp(
type,
"HDTV",4))
2586 if (!strncmp(inpt,
"TS",3)){
2588 }
else if (!strncmp(inpt,
"PS",3)){
2595 }
else if (!strncmp(inpt,
"AVI",4)){
2612 filename =
static_cast<char*
>(malloc(4));
2616 LOG(VB_GENERAL, LOG_ERR,
"Basename too long");
2620 snprintf(fname,256,
"%s.mv2",
filename);
2621 if ((rx.
dmx_out[0] = open(fname,O_WRONLY|
2628 perror(
"Error opening output file");
2631 LOG(VB_GENERAL, LOG_INFO,
2632 QString(
"Video output File is: %1").
arg(fname));
2634 for (i=0; i < rx.
apidn; i++){
2635 snprintf(fname,256,
"%s%d.mp2",
filename
2638 open(fname,O_WRONLY|
2645 perror(
"Error opening output file");
2648 LOG(VB_GENERAL, LOG_INFO,
2649 QString(
"Audio%1 output File is: %2")
2654 for (i=0; i < rx.
ac3n; i++){
2655 snprintf(fname,256,
"%s%d.ac3",
filename
2658 open(fname,O_WRONLY|
2665 perror(
"Error opening output file");
2668 LOG(VB_GENERAL, LOG_INFO,
2669 QString(
"AC3%1 output File is: %2")
2673 }
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)
arg(title).arg(filename).arg(doDelete))
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
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)
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 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]