MythTV  master
replex.cpp
Go to the documentation of this file.
1 /*
2  * replex.c
3  *
4  *
5  * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de>
6  * Metzler Brothers Systementwicklung GbR
7  * Changes to use MythTV logging
8  * Copyright (C) 2011 Gavin Hurlbut <ghurlbut@mythtv.org>
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * General Public License for more details.
20  *
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
26  *
27  */
28 //#define IN_DEBUG
29 
30 
31 #include <stdlib.h>
32 #include <getopt.h>
33 #include <stdarg.h>
34 #include <stdio.h>
35 #include <stdint.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <fcntl.h>
39 #include <string.h>
40 #include <unistd.h>
41 
42 #include "replex.h"
43 #include "pes.h"
44 
45 #ifndef O_LARGEFILE
46 #define O_LARGEFILE 0
47 #endif
48 
49 extern "C" {
50 #include "libavcodec/avcodec.h"
51 #include "libavformat/avformat.h"
52 }
53 
54 #ifdef _WIN32
55 # define S_IRGRP 0
56 # define S_IWGRP 0
57 # define S_IROTH 0
58 # define S_IWOTH 0
59 #endif
60 
61 #ifndef O_LARGEFILE
62 #define O_LARGEFILE 0
63 #endif
64 
65 #include "mythlogging.h"
66 
67 static int replex_all_set(struct replex *rx);
68 
69 static int replex_check_id(struct replex *rx, uint16_t id)
70 {
71  int i;
72 
73  if (id==rx->vpid)
74  return 0;
75 
76  for (i=0; i<rx->apidn; i++)
77  if (id==rx->apid[i])
78  return i+1;
79 
80  for (i=0; i<rx->ac3n; i++)
81  if (id==rx->ac3_id[i])
82  return i+0x80;
83 
84  return -1;
85 }
86 
87 static int avcodec_encode_audio(AVCodecContext *avctx,
88  uint8_t *buf, int buf_size,
89  const short *samples)
90 {
91  AVPacket pkt;
92  AVFrame *frame;
93  int ret, samples_size;
94 
95  av_init_packet(&pkt);
96  pkt.data = buf;
97  pkt.size = buf_size;
98 
99  if (samples) {
100  frame = av_frame_alloc();
101  if (!frame)
102  return AVERROR(ENOMEM);
103 
104  if (avctx->frame_size) {
105  frame->nb_samples = avctx->frame_size;
106  } else {
107  /* if frame_size is not set, the number of samples must be
108  * calculated from the buffer size */
109  int64_t nb_samples;
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);
115  }
116  nb_samples = (int64_t)buf_size * 8 /
117  (av_get_bits_per_sample(avctx->codec_id) *
118  avctx->channels);
119  if (nb_samples >= INT_MAX) {
120  av_frame_free(&frame);
121  return AVERROR(EINVAL);
122  }
123  frame->nb_samples = nb_samples;
124  }
125 
126  /* it is assumed that the samples buffer is large enough based on the
127  * relevant parameters */
128  samples_size = av_samples_get_buffer_size(nullptr, avctx->channels,
129  frame->nb_samples,
130  avctx->sample_fmt, 1);
131  if ((ret = avcodec_fill_audio_frame(frame, avctx->channels,
132  avctx->sample_fmt,
133  (const uint8_t *)samples,
134  samples_size, 1)) < 0) {
135  av_frame_free(&frame);
136  return ret;
137  }
138 
139  frame->pts = AV_NOPTS_VALUE;
140  } else {
141  frame = nullptr;
142  }
143 
144  // SUGGESTION
145  // Now that avcodec_encode_audio2 is deprecated and replaced
146  // by 2 calls, this could be optimized
147  // into separate routines or separate threads.
148  ret = avcodec_receive_packet(avctx, &pkt);
149  if (ret != 0)
150  pkt.size=0;
151  if (ret == AVERROR(EAGAIN))
152  ret = 0;
153  if (ret == 0)
154  ret = avcodec_send_frame(avctx, frame);
155 
156  if (ret < 0)
157  {
158  char error[AV_ERROR_MAX_STRING_SIZE+25];
159  strcpy(error,"audio encode error: ");
160  strcat(error, av_make_error_string(error, sizeof(error), ret));
161  LOG(VB_GENERAL, LOG_ERR, error);
162  }
163 
164  /* free any side data since we cannot return it */
165  av_packet_free_side_data(&pkt);
166 
167  if (frame && frame->extended_data != frame->data)
168  av_freep(&frame->extended_data);
169 
170  av_frame_free(&frame);
171  return ret ? ret : pkt.size;
172 }
173 
174 static int encode_mp2_audio(audio_frame_t *aframe, uint8_t *buffer, int bufsize)
175 {
176  AVCodec *codec;
177  AVCodecContext *c= nullptr;
178  int frame_size, j, out_size;
179  short *samples;
180 
181  LOG(VB_GENERAL, LOG_INFO, "encoding an MP2 audio frame");
182 
183  /* find the MP2 encoder */
184  codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
185  if (!codec) {
186  LOG(VB_GENERAL, LOG_ERR, "codec not found");
187  return 1;
188  }
189 
190  c = avcodec_alloc_context3(codec);
191 
192  /* put sample parameters */
193  c->bit_rate = aframe->bit_rate;
194  c->sample_rate = aframe->frequency;
195  c->channels = 2;
196  c->sample_fmt = AV_SAMPLE_FMT_S16;
197 
198  /* open it */
199  if (avcodec_open2(c, codec, nullptr) < 0) {
200  LOG(VB_GENERAL, LOG_ERR, "could not open codec");
201  av_free(c);
202  return 1;
203  }
204 
205  /* the codec gives us the frame size, in samples */
206  frame_size = c->frame_size;
207  samples = static_cast<short*>(malloc(frame_size * 2 * c->channels));
208 
209  /* create samples for a single blank frame */
210  for (j=0;j<frame_size;j++) {
211  samples[2*j] = 0;
212  samples[2*j+1] = 0;
213  }
214 
215  /* encode the samples */
216  out_size = avcodec_encode_audio(c, buffer, bufsize, samples);
217 
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));
222  free(samples);
223  avcodec_free_context(&c);
224  return 1;
225  }
226 
227  free(samples);
228  avcodec_free_context(&c);
229 
230  return 0;
231 }
232 
233 static void analyze_audio( pes_in_t *p, struct replex *rx, int len, int num, int type)
234 {
235  int c=0;
236  int pos=0;
237  audio_frame_t *aframe = nullptr;
238  index_unit *iu = nullptr;
239  ringbuffer *rbuf = nullptr, *index_buf = nullptr;
240  uint64_t *acount=nullptr;
241  uint64_t *fpts=nullptr;
242  uint64_t *lpts=nullptr;
243  int bsize = 0;
244  int first = 1;
245  audio_sync_buf buf;
246  int off=0;
247  int *apes_abort=nullptr;
248  int re=0;
249 
250  switch ( type ){
251  case AC3:
252 #ifdef IN_DEBUG
253  LOG(VB_GENERAL, LOG_DEBUG, "AC3");
254 #endif
255  aframe = &rx->ac3frame[num];
256  iu = &rx->current_ac3index[num];
257  rbuf = &rx->ac3rbuffer[num];
258  index_buf = &rx->index_ac3rbuffer[num];
259  acount = &rx->ac3frame_count[num];
260  fpts = &rx->first_ac3pts[num];
261  lpts = &rx->last_ac3pts[num];
262  bsize = rx->ac3buf;
263  apes_abort = &rx->ac3pes_abort[num];
264  break;
265 
266  case MPEG_AUDIO:
267 #ifdef IN_DEBUG
268  LOG(VB_GENERAL, LOG_DEBUG, "MPEG AUDIO");
269 #endif
270  aframe = &rx->aframe[num];
271  iu = &rx->current_aindex[num];
272  rbuf = &rx->arbuffer[num];
273  index_buf = &rx->index_arbuffer[num];
274  acount = &rx->aframe_count[num];
275  fpts = &rx->first_apts[num];
276  lpts = &rx->last_apts[num];
277  bsize = rx->audiobuf;
278  apes_abort = &rx->apes_abort[num];
279  break;
280  }
281 
282  *apes_abort = 0;
283  off = ring_rdiff(rbuf, p->ini_pos);
284  while (c < len){
285  if ( (pos = find_audio_sync(rbuf, buf, c+off, type, len-c) )
286  >= 0 ){
287  if (!aframe->set){
288  switch( type ){
289  case AC3:
290  re = get_ac3_info(rbuf, aframe,
291  pos+c+off,
292  len-c-pos);
293  break;
294  case MPEG_AUDIO:
295  re = get_audio_info(rbuf, aframe,
296  pos+c+off,
297  len-c-pos);
298  break;
299  }
300  if ( re == -2){
301  *apes_abort = len -c;
302  return;
303  }
304  if (re < 0) return;
305 
306 
307  if (!rx->ignore_pts){
308  if ((p->flag2 & PTS_ONLY)){
309  *fpts = trans_pts_dts(p->pts);
310  LOG(VB_GENERAL, LOG_INFO,
311  "starting audio PTS: ");
312  printpts(*fpts);
313  } else aframe->set = 0;
314  }
315 
316  if (aframe->set && first)
317  ring_skip(rbuf,pos+c);
318 
319  } else {
320  int diff = ring_posdiff(rbuf, iu->start,
321  p->ini_pos + pos+c);
322 
323  if ( (re = check_audio_header(rbuf, aframe,
324  pos+c+off,len-c-pos,
325  type)) < 0){
326 
327  if ( re == -2){
328  *apes_abort = len -c;
329  return;
330  }
331 
332  if ((int) aframe->framesize > diff){
333  if ( re == -3){
334  c += pos+1;
335  continue;
336  }
337 
338  c += pos+2;
339 #ifdef IN_DEBUG
340  LOG(VB_GENERAL, LOG_DEBUG,
341  QString("WRONG HEADER1 %1").arg(diff));
342 #endif
343  continue;
344  }
345  }
346  if ((int) aframe->framesize > diff){
347  c += pos+2;
348 #if 0
349  LOG(VB_GENERAL, LOG_ERR,
350  QString("WRONG HEADER2 %1").arg(diff));
351 #endif
352  continue;
353  }
354  }
355 
356  // try to fix audio sync - only works for mpeg audio for now
357  if (aframe->set && rx->fix_sync && first && type == MPEG_AUDIO){
358  int frame_time = aframe->frametime;
359  int64_t diff;
360  diff = ptsdiff(trans_pts_dts(p->pts), add_pts_audio(0, aframe,*acount + 1) + *fpts);
361  if (abs ((int)diff) >= frame_time){
362  LOG(VB_GENERAL, LOG_INFO,
363  "fixing audio PTS inconsistency - diff: ");
364  printpts(abs(diff));
365 
366  if (diff < 0){
367  diff = abs(diff);
368  int framesdiff = diff / frame_time;
369  LOG(VB_GENERAL, LOG_INFO,
370  QString(" - need to remove %1 frame(s)")
371  .arg(framesdiff));
372 
373  // FIXME can only remove one frame at a time for now
374  if (framesdiff > 1)
375  framesdiff = 1;
376  iu->pts = add_pts_audio(0, aframe, -framesdiff);
377  c += aframe->framesize;
378  continue;
379  } else {
380  int framesdiff = diff / frame_time;
381  LOG(VB_GENERAL, LOG_INFO,
382  QString(" - need to add %1 frame(s)")
383  .arg(framesdiff));
384 
385  // limit inserts to a maximum of 5 frames
386  if (framesdiff > 5)
387  framesdiff = 5;
388 
389  // alloc memmory for audio frame
390  uint8_t *framebuf;
391  if ( !(framebuf = (uint8_t *) malloc(sizeof(uint8_t) * aframe->framesize))) {
392  LOG(VB_GENERAL, LOG_ERR,
393  "Not enough memory for audio frame");
394  exit(1);
395  }
396 
397  // try to encode a blank frame
398  if (encode_mp2_audio(aframe, framebuf, sizeof(uint8_t) * aframe->framesize) != 0) {
399  // encode failed so just use a copy of the current frame
400  int res;
401  res = ring_peek(rbuf, framebuf, aframe->framesize, 0);
402  if (res != (int) aframe->framesize) {
403  LOG(VB_GENERAL, LOG_ERR,
404  QString("ring buffer failed to peek frame res: %1")
405  .arg(res));
406  exit(1);
407  }
408  }
409 
410  // add each extra frame required direct to the output file
411  int x;
412  for (x = 0; x < framesdiff; x++){
413  if (rx->dmx_out[num+1]){
414  write(rx->dmx_out[num+1], framebuf, aframe->framesize);
415  }
416  *acount += 1;
417  }
418 
419  free(framebuf);
420  }
421  }
422  }
423 
424  if (aframe->set){
425  if(iu->active){
426  iu->length = ring_posdiff(rbuf,
427  iu->start,
428  p->ini_pos +
429  pos+c);
430 
431  if (iu->length < aframe->framesize ||
432  iu->length > aframe->framesize+1){
433  LOG(VB_GENERAL, LOG_ERR,
434  QString("Wrong audio frame size: %1")
435  .arg(iu->length));
436  iu->err= FRAME_ERR;
437  }
438  if (ring_write(index_buf,
439  (uint8_t *)iu,
440  sizeof(index_unit)) < 0){
441  LOG(VB_GENERAL, LOG_ERR,
442  "audio ring buffer overrun error");
443  exit(1);
444  }
445  *acount += 1;
446  }
447 
448  init_index(iu);
449  iu->active = 1;
450  iu->pts = add_pts_audio(0, aframe,*acount);
451  iu->framesize = aframe->framesize;
452 
453  if (!rx->ignore_pts &&
454  first && (p->flag2 & PTS_ONLY)){
455  int64_t diff;
456 
457  diff = ptsdiff(trans_pts_dts(p->pts),
458  iu->pts + *fpts);
459  if( !rx->keep_pts && (llabs(diff) > 40*CLOCK_MS)){
460  LOG(VB_GENERAL, LOG_ERR,
461  "audio PTS inconsistent:");
462  printpts(trans_pts_dts(p->pts)-*fpts);
463  printpts(iu->pts);
464  LOG(VB_GENERAL, LOG_ERR,
465  "diff: ");
466  printpts(abs(diff));
467  }
468  if (rx->keep_pts){
469  fix_audio_count(acount, aframe,
471  p->pts),
472  *fpts),
473  iu->pts);
474  iu->pts = uptsdiff(trans_pts_dts(p->pts),
475  *fpts);
476  if (*lpts && ptsdiff(iu->pts,*lpts)<0)
477  LOG(VB_GENERAL, LOG_WARNING,
478  "Warning negative audio PTS increase!\n");
479  *lpts = iu->pts;
480  }
481  first = 0;
482  }
483  if (rx->analyze >1){
484  if ((p->flag2 & PTS_ONLY)){
485  iu->pts = trans_pts_dts(p->pts);
486  } else {
487  iu->pts = 0;
488  }
489  }
490  iu->start = (p->ini_pos+pos+c)%bsize;
491  }
492  c += pos;
493  if (c + (int) aframe->framesize > len){
494 #if 0
495  LOG(VB_GENERAL, LOG_INFO,
496  QString("SHORT %1").arg(len-c));
497 #endif
498  c = len;
499  } else {
500  c += aframe->framesize;
501  }
502  } else {
503  *apes_abort = len-c;
504  c=len;
505  }
506  }
507 }
508 
509 static void analyze_video( pes_in_t *p, struct replex *rx, int len)
510 {
511  std::vector<uint8_t> buf(8);
512  int c=0;
513  int pos=0;
514  uint8_t head;
515  int seq_end = 0;
516  uint8_t frame = 0;
517  uint64_t newpts = 0;
518  uint64_t newdts = 0;
519  index_unit *iu;
520  int off=0;
521  ringbuffer *rbuf;
522  ringbuffer *index_buf;
523  sequence_t *s;
524  int i;
525 
526  uint16_t tempref = 0;
527  int seq_h = 0;
528  int gop = 0;
529  int frame_off = 0;
530  int gop_off = 0;
531  int seq_p = 0;
532  int flush=0;
533 
534  rbuf = &rx->vrbuffer;
535  index_buf = &rx->index_vrbuffer;
536  iu = &rx->current_vindex;
537  s = &rx->seq_head;
538 
539  rx->vpes_abort = 0;
540  off = ring_rdiff(rbuf, p->ini_pos);
541 #ifdef IN_DEBUG
542  LOG(VB_GENERAL, LOG_DEBUG, QString(" ini pos %1")
543  .arg((p->ini_pos)%rx->videobuf));
544 #endif
545 
546 
547 #if 0
548  LOG(VB_GENERAL, LOG_INFO, QString("len %1 %2").arg(len).arg(off));
549 #endif
550  while (c < len){
551  if ((pos = ring_find_any_header( rbuf, &head, c+off, len-c))
552  >=0 ){
553  switch(head){
554  case SEQUENCE_HDR_CODE:
555 #ifdef IN_DEBUG
556  LOG(VB_GENERAL, LOG_DEBUG, QString(" seq headr %1")
557  .arg((p->ini_pos+c+pos)%rx->videobuf));
558 #endif
559 
560  seq_h = 1;
561  seq_p = c+pos;
562 
563 
564  if (!s->set){
565  int re=0;
566  re = get_video_info(rbuf, &rx->seq_head,
567  pos+c+off, len -c -pos);
568 
569 #ifdef IN_DEBUG
570  LOG(VB_GENERAL, LOG_DEBUG,
571  QString(" seq headr result %1")
572  .arg(re));
573 #endif
574  if (re == -2){
575  rx->vpes_abort = len -(c+pos-1);
576  return;
577  }
578  if (s->set){
579  ring_skip(rbuf, pos+c);
580  off -= pos+c;
581  }
582  if (!rx->ignore_pts &&
583  !(p->flag2 & PTS_ONLY)) s->set = 0;
584  }
585  if (s->set){
586  flush = 1;
587  }
588  break;
589 
590  case EXTENSION_START_CODE:{
591  int ext_id = 0;
592 
593 #ifdef IN_DEBUG
594  LOG(VB_GENERAL, LOG_DEBUG,
595  QString(" seq ext headr %1")
596  .arg((p->ini_pos+c+pos)+rx->videobuf));
597 #endif
598  ext_id = get_video_ext_info(rbuf,
599  &rx->seq_head,
600  pos+c+off,
601  len -c -pos);
602  if (ext_id == -2){
603  rx->vpes_abort = len - (pos-1+c);
604  return;
605  }
606 
607 
608  if(ext_id == PICTURE_CODING_EXTENSION
609  && s->ext_set && iu->active){
610  if (!rx->ignore_pts &&
611  !rx->vframe_count &&
612  !rx->first_vpts){
614  p->pts);
615 
616  for (i = 0; i< s->current_tmpref;
617  i++) ptsdec(&rx->first_vpts,
618  SEC_PER);
619  LOG(VB_GENERAL, LOG_INFO,
620  "starting with video PTS:");
621  printpts(rx->first_vpts);
622  }
623 
624  newpts = 0;
625 #ifdef IN_DEBUG
626 
627  LOG(VB_GENERAL, LOG_DEBUG,
628  QString("fcount %1 gcount %2 tempref %3 %4")
629  .arg(rx->vframe_count).arg(rx->vgroup_count)
630  .arg(s->current_tmpref)
631  .arg(s->current_tmpref - rx->vgroup_count
632  + rx->vframe_count));
633 #endif
634  newdts = next_ptsdts_video(
635  &newpts,s, rx->vframe_count,
636  rx->vgroup_count);
637 
638  if (!rx->ignore_pts &&
639  (p->flag2 & PTS_ONLY)){
640  int64_t diff;
641 
642  diff = ptsdiff(iu->pts,
643  rx->first_vpts
644  + newpts);
645 
646  if (!rx->keep_pts &&
647  (llabs(diff) > 3*SEC_PER/2)){
648  LOG(VB_GENERAL, LOG_INFO,
649  "video PTS inconsistent:");
650  printpts(trans_pts_dts(p->pts));
651  printpts(iu->pts);
652  printpts(newpts+rx->first_vpts);
653  printpts(newpts);
654  LOG(VB_GENERAL, LOG_INFO,
655  " diff: ");
656  printpts(abs((int)diff));
657  }
658  }
659 
660  if (!rx->ignore_pts &&
661  (p->flag2 & PTS_DTS) == PTS_DTS){
662  int64_t diff;
663  diff = ptsdiff(iu->dts,
664  newdts +
665  rx->first_vpts);
666  if (!rx->keep_pts &&
667  (llabs(diff) > 3*SEC_PER/2)){
668  LOG(VB_GENERAL, LOG_INFO,
669  "video DTS inconsistent: ");
670  printpts(trans_pts_dts(p->dts));
671  printpts(iu->dts);
672  printpts(newdts+rx->first_vpts);
673  printpts(newdts);
674  LOG(VB_GENERAL, LOG_INFO,
675  "diff: ");
676  printpts(abs((int)diff));
677  }
678  }
679  if (!rx->keep_pts){
680  iu->pts = newpts;
681  iu->dts = newdts;
682  } else {
683  if (p->flag2 & PTS_DTS){
684  ptsdec(&iu->pts,
685  rx->first_vpts);
686 
687  if ((p->flag2 & PTS_DTS) == PTS_DTS){
688  ptsdec(&iu->dts,
689  rx->first_vpts);
690  } else iu->dts = newdts;
691 
693  iu->pts,newpts,
694  iu->dts,newdts);
695 
696  } else {
697  iu->pts = newpts;
698  iu->dts = newdts;
699  }
700  }
701  if (rx->last_vpts &&
702  ptsdiff(iu->dts, rx->last_vpts) <0)
703  LOG(VB_GENERAL, LOG_WARNING,
704  "Warning negative video PTS increase!");
705  rx->last_vpts = iu->dts;
706  }
707 
708  if (rx->analyze){
709  if ((p->flag2 & PTS_DTS) == PTS_DTS){
710  iu->pts = trans_pts_dts(p->pts);
711  iu->dts = trans_pts_dts(p->dts);
712  } else if (p->flag2 & PTS_ONLY){
713  iu->pts = trans_pts_dts(p->pts);
714  iu->dts = 0;
715  } else {
716  iu->pts = 0;
717  iu->dts = 0;
718  }
719  }
720 
721 
722  break;
723  }
724 
725  case SEQUENCE_END_CODE:
726 #ifdef IN_DEBUG
727  LOG(VB_GENERAL, LOG_DEBUG, QString(" seq end %1")
728  .arg((p->ini_pos+c+pos)%rx->videobuf));
729 #endif
730  if (s->set)
731  seq_end = 1;
732 
733  break;
734 
735  case GROUP_START_CODE:{
736 //#define ANA
737 #ifdef ANA
738  LOG(VB_GENERAL, LOG_DEBUG, QString(" %1")
739  .arg(rx->vgroup_count));
740 #endif
741 
742  if (s->set){
743  if (!seq_h) flush = 1;
744  }
745  gop = 1;
746  gop_off = c+pos - seq_p;
747 
748  if (ring_peek(rbuf, buf, 7, off+c+pos) < 0) {
749  rx->vpes_abort = len -(c+pos-1);
750  return;
751  }
752 #ifdef IN_DEBUG
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'))
763  .arg((p->ini_pos+c+pos)%rx->videobuf));
764 #endif
765  rx->vgroup_count = 0;
766 
767  break;
768  }
769 
770  case PICTURE_START_CODE:{
771  if (len-(c+pos) < 14){
772  rx->vpes_abort = len - (pos-1+c);
773  return;
774  }
775 
776  if (ring_peek(rbuf, buf, 6,
777  off+c+pos) < 0) return;
778 
779 
780  frame = ((buf[5]&0x38) >>3);
781 
782  if (frame == I_FRAME){
783  if( !rx->first_iframe){
784  if (s->set){
785  rx->first_iframe = 1;
786  } else {
787  s->set=0;
788  flush = 0;
789  break;
790  }
791  }
792  }
793 
794  frame_off = c+pos - seq_p;
795  if (s->set){
796  if (!seq_h && !gop) flush = 1;
797  }
798  tempref = (buf[5]>>6) & 0x03;
799  tempref |= buf[4] << 2;
800 
801  switch (frame){
802  case I_FRAME:
803 #ifdef ANA
804  LOG(VB_GENERAL, LOG_DEBUG, "I");
805 #endif
806 #ifdef IN_DEBUG
807  LOG(VB_GENERAL, LOG_DEBUG,
808  QString(" I-frame %1")
809  .arg((p->ini_pos+c+pos)%rx->videobuf));
810 #endif
811  break;
812  case B_FRAME:
813 #ifdef ANA
814  LOG(VB_GENERAL, LOG_DEBUG, "B");
815 #endif
816 #ifdef IN_DEBUG
817  LOG(VB_GENERAL, LOG_DEBUG,
818  QString(" B-frame %1")
819  .arg((p->ini_pos+c+pos)%rx->videobuf));
820 #endif
821  break;
822  case P_FRAME:
823 #ifdef ANA
824  LOG(VB_GENERAL, LOG_DEBUG, "P");
825 #endif
826 #ifdef IN_DEBUG
827  LOG(VB_GENERAL, LOG_DEBUG,
828  QString(" P-frame %1")
829  .arg((p->ini_pos+c+pos)%rx->videobuf));
830 #endif
831  break;
832  }
833  s->current_frame = frame;
834  s->current_tmpref = tempref;
835 
836  break;
837  }
838  default:
839 #ifdef IN_DEBUG
840 #if 0
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));
844 #endif
845 #endif
846  break;
847  }
848 
849  if (flush && s->set && rx->first_iframe){
850  if(iu->active){
851  rx->vframe_count++;
852  rx->vgroup_count++;
853 
854  iu->length = ring_posdiff(rbuf,
855  iu->start,
856  p->ini_pos+
857  pos+c-frame_off);
858 
859  if ( ring_write(index_buf, (uint8_t *)
860  &rx->current_vindex,
861  sizeof(index_unit))<0){
862  LOG(VB_GENERAL, LOG_ERR,
863  "video ring buffer overrun error");
864  exit(1);
865 
866  }
867  }
869  flush = 0;
870  iu->active = 1;
871  if (!rx->ignore_pts){
872  if ((p->flag2 & PTS_DTS) == PTS_DTS){
873  iu->pts = trans_pts_dts(p->pts);
874  iu->dts = trans_pts_dts(p->dts);
875  } else if (p->flag2 & PTS_ONLY){
876  iu->pts = trans_pts_dts(p->pts);
877  }
878  }
879  iu->start = (p->ini_pos+pos+c-frame_off)
880  %rx->videobuf;
881 #ifdef IN_DEBUG
882  LOG(VB_GENERAL, LOG_DEBUG,
883  QString("START %1").arg(iu->start));
884 #endif
885  }
886 
887  if (s->set){
888  if (frame)
889  iu->frame = (frame&0xFF);
890  if (seq_h)
891  iu->seq_header = 1;
892  if (seq_end)
893  iu->seq_end = 1;
894  if (gop)
895  iu->gop = 1;
896  if (gop_off)
897  iu->gop_off = gop_off;
898  if (frame_off)
899  iu->frame_off = frame_off;
900  }
901  c+=pos+4;
902  } else {
903  if (pos == -2){
904  rx->vpes_abort = 4;
905 
906  }
907  c = len;
908  }
909  }
910 }
911 
912 static void es_out(pes_in_t *p)
913 {
914 
915  struct replex *rx;
916  char t[80];
917  int len;
918 
919  len = p->plength-3-p->hlength;
920 
921  rx = (struct replex *) p->priv;
922 
923  switch(p->type)
924  {
925  case 0xE0: {
926  sprintf(t, "Video ");
927  if (rx->vpes_abort){
928  p->ini_pos = (p->ini_pos - rx->vpes_abort)%rx->vrbuffer.size;
929  len += rx->vpes_abort;
930  }
931  analyze_video(p, rx, len);
932  if (!rx->seq_head.set){
933  ring_skip(&rx->vrbuffer, len);
934  }
935  break;
936  }
937 
938  case 1 ... 32:{
939  int l;
940  l = p->type - 1;
941  sprintf(t, "Audio%d ", l);
942  if (rx->apes_abort[l]){
943  p->ini_pos = (p->ini_pos - rx->apes_abort[l])
944  %rx->arbuffer[l].size;
945  len += rx->apes_abort[l];
946  }
947  analyze_audio(p, rx, len, l, MPEG_AUDIO);
948  if (!rx->aframe[l].set)
949  ring_skip(&rx->arbuffer[l], len);
950 
951  break;
952  }
953 
954  case 0x80 ... 0x87:{
955  int l;
956  l = p->type - 0x80;
957  sprintf(t, "AC3 %d ", p->type);
958  if (rx->ac3pes_abort[l]){
959  p->ini_pos = (p->ini_pos - rx->ac3pes_abort[l])
960  %rx->ac3rbuffer[l].size;
961  len += rx->ac3pes_abort[l];
962  }
963  analyze_audio(p, rx, len, l, AC3);
964  if (!rx->ac3frame[l].set)
965  ring_skip(&rx->ac3rbuffer[l], len);
966  break;
967  }
968 
969  default:
970  LOG(VB_GENERAL, LOG_ERR,
971  QString("UNKNOWN AUDIO type %1").arg(p->type));
972  return;
973 
974 
975  }
976 
977 #ifdef IN_DEBUG
978  LOG(VB_GENERAL, LOG_DEBUG, QString("%1 PES").arg(t));
979 #endif
980 }
981 
982 static void pes_es_out(pes_in_t *p)
983 {
984 
985  struct replex *rx;
986  char t[80];
987  int len, i;
988  int l=0;
989 
990  len = p->plength-3-p->hlength;
991  rx = (struct replex *) p->priv;
992 
993  switch(p->cid){
995  if (rx->vpid != p->cid) break;
996  p->type = 0xE0;
997  p->ini_pos = ring_wpos(&rx->vrbuffer);
998 
999  if (ring_write(&rx->vrbuffer, p->buf+9+p->hlength, len)<0){
1000  LOG(VB_GENERAL, LOG_ERR,
1001  "video ring buffer overrun error");
1002  exit(1);
1003  }
1004  if (rx->vpes_abort){
1005  p->ini_pos = (p->ini_pos - rx->vpes_abort)%rx->vrbuffer.size;
1006  len += rx->vpes_abort;
1007  }
1008  sprintf(t, "Video ");
1009  analyze_video(p, rx, len);
1010  if (!rx->seq_head.set){
1011  ring_skip(&rx->vrbuffer, len);
1012  }
1013  break;
1014 
1015  case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1016  p->type = p->cid - 0xc0 + 1;
1017  l = -1;
1018  for (i=0; i<rx->apidn; i++)
1019  if (p->cid == rx->apid[i])
1020  l = i;
1021  if (l < 0) break;
1022  p->ini_pos = ring_wpos(&rx->arbuffer[l]);
1023  if (ring_write(&rx->arbuffer[l], p->buf+9+p->hlength, len)<0){
1024  LOG(VB_GENERAL, LOG_ERR,
1025  "video ring buffer overrun error");
1026  exit(1);
1027  }
1028  if (rx->apes_abort[l]){
1029  p->ini_pos = (p->ini_pos - rx->apes_abort[l])
1030  %rx->arbuffer[l].size;
1031  len += rx->apes_abort[l];
1032  }
1033 
1034  sprintf(t, "Audio%d ", l);
1035  analyze_audio(p, rx, len, l, MPEG_AUDIO);
1036  if (!rx->aframe[l].set)
1037  ring_skip(&rx->arbuffer[l], len);
1038 
1039  break;
1040 
1041  case PRIVATE_STREAM1:{
1042  int hl=4;
1043  if (rx->vdr){
1044  hl=0;
1045  p->type=0x80;
1046  l = 0;
1047  } else {
1048  uint16_t fframe;
1049 
1050  fframe=0;
1051  fframe = p->buf[9+p->hlength+3];
1052  fframe |= (p->buf[9+p->hlength+2]<<8);
1053 
1054  if (fframe > p->plength) break;
1055 
1056  p->type = p->buf[9+p->hlength];
1057  l = -1;
1058  for (i=0; i<rx->ac3n; i++)
1059  if (p->type == rx->ac3_id[i])
1060  l = i;
1061  if (l < 0) break;
1062  }
1063  len -= hl;
1064  p->ini_pos = ring_wpos(&rx->ac3rbuffer[l]);
1065 
1066  if (ring_write(&rx->ac3rbuffer[l], p->buf+9+hl+p->hlength, len)<0){
1067  LOG(VB_GENERAL, LOG_ERR,
1068  "video ring buffer overrun error");
1069  exit(1);
1070  }
1071  if (rx->ac3pes_abort[l]){
1072  p->ini_pos = (p->ini_pos - rx->ac3pes_abort[l])
1073  %rx->ac3rbuffer[l].size;
1074  len += rx->ac3pes_abort[l];
1075  }
1076 
1077  sprintf(t, "AC3 %d ", p->type);
1078  analyze_audio(p, rx, len, l, AC3);
1079  sprintf(t,"%d",rx->ac3frame[l].set);
1080  if (!rx->ac3frame[l].set)
1081  ring_skip(&rx->ac3rbuffer[l], len);
1082  }
1083  break;
1084 
1085  default:
1086  return;
1087  }
1088 
1089 #ifdef IN_DEBUG
1090  LOG(VB_GENERAL, LOG_DEBUG, QString("%1 PES %2").arg(t).arg(len));
1091 #endif
1092 }
1093 
1094 static void avi_es_out(pes_in_t *p)
1095 {
1096 
1097  struct replex *rx;
1098  char t[80];
1099  int len;
1100 
1101  len = p->plength;
1102 
1103  rx = (struct replex *) p->priv;
1104 
1105 
1106  switch(p->type)
1107  {
1108  case 0xE0: {
1109  sprintf(t, "Video ");
1110  if (!len){
1111  rx->vframe_count++;
1112  break;
1113  }
1114  analyze_video(p, rx, len);
1115  if (!rx->seq_head.set){
1116  ring_skip(&rx->vrbuffer, len);
1117  }
1118  break;
1119  }
1120 
1121  case 1 ... 32:{
1122  int l;
1123  l = p->type - 1;
1124  sprintf(t, "Audio%d ", l);
1125  if (!len){
1126  rx->aframe_count[l]++;
1127  break;
1128  }
1129  analyze_audio(p, rx, len, l, MPEG_AUDIO);
1130  if (!rx->aframe[l].set)
1131  ring_skip(&rx->arbuffer[l], len);
1132 
1133  break;
1134  }
1135 
1136  case 0x80 ... 0x87:{
1137  int l;
1138 
1139  l = p->type - 0x80;
1140  sprintf(t, "AC3 %d ", p->type);
1141  if (!len){
1142  rx->ac3frame_count[l]++;
1143  break;
1144  }
1145  analyze_audio(p, rx, len, l, AC3);
1146  if (!rx->ac3frame[l].set)
1147  ring_skip(&rx->ac3rbuffer[l], len);
1148  break;
1149  }
1150 
1151  default:
1152  return;
1153 
1154 
1155  }
1156 #ifdef IN_DEBUG
1157  LOG(VB_GENERAL, LOG_DEBUG, QString("%1 PES").arg(t));
1158 #endif
1159 
1160 }
1161 
1162 
1163 static int replex_tsp(struct replex *rx, uint8_t *tsp)
1164 {
1165  uint16_t pid;
1166  int type;
1167  int off=0;
1168  pes_in_t *p=nullptr;
1169 
1170  pid = get_pid(tsp+1);
1171 
1172  if ((type=replex_check_id(rx, pid))<0)
1173  return 0;
1174 
1175  switch(type){
1176  case 0:
1177  p = &rx->pvideo;
1178  break;
1179 
1180  case 1 ... 32:
1181  p = &rx->paudio[type-1];
1182  break;
1183 
1184  case 0x80 ... 0x87:
1185  p = &rx->pac3[type-0x80];
1186  break;
1187  default:
1188  return 0;
1189 
1190  }
1191 
1192 
1193  if ( tsp[1] & PAY_START) {
1194  if (p->plength == MMAX_PLENGTH-6){
1195  p->plength = p->found-6;
1196  es_out(p);
1197  init_pes_in(p, p->type, nullptr, 0);
1198  }
1199  }
1200 
1201  if ( tsp[3] & ADAPT_FIELD) { // adaptation field?
1202  off = tsp[4] + 1;
1203  if (off+4 >= TS_SIZE) return 0;
1204  }
1205 
1206  get_pes(p, tsp+4+off, TS_SIZE-4-off, es_out);
1207 
1208  return 0;
1209 }
1210 
1211 
1212 static ssize_t save_read(struct replex *rx, void *buf, size_t count)
1213 {
1214  ssize_t neof = 1;
1215  size_t re = 0;
1216  int fd = rx->fd_in;
1217 
1218  if (rx->itype== REPLEX_AVI){
1219  int l = rx->inflength - rx->finread;
1220  if ( l <= 0) return 0;
1221  if ( (int) count > l) count = l;
1222  }
1223  while(neof >= 0 && re < count){
1224  neof = read(fd, ((char*)buf)+re, count - re);
1225  if (neof > 0) re += neof;
1226  else break;
1227  }
1228  rx->finread += re;
1229 #ifndef OUT_DEBUG
1230  if (rx->inflength){
1231  uint8_t per=0;
1232 
1233  per = (uint8_t)(rx->finread*100/rx->inflength);
1234  if (per % 10 == 0 && rx->lastper < per){
1235  LOG(VB_GENERAL, LOG_DEBUG, QString("read %1%%")
1236  .arg(per,3));
1237  rx->lastper = per;
1238  }
1239  } else
1240  LOG(VB_GENERAL, LOG_DEBUG, QString("read %1 MB")
1241  .arg(rx->finread/1024.0/1024.0, 0,'f',2,QChar('0')));
1242 #endif
1243  if (neof < 0 && re == 0) return neof;
1244  else return re;
1245 }
1246 
1247 static int guess_fill( struct replex *rx)
1248 {
1249  int vavail, aavail, ac3avail, i, fill;
1250 
1251  vavail = 0;
1252  ac3avail =0;
1253  aavail = 0;
1254  fill =0;
1255 
1256 #define LIMIT 3
1257  if ((vavail = ring_avail(&rx->index_vrbuffer)/sizeof(index_unit))
1258  < LIMIT)
1259  fill = ring_free(&rx->vrbuffer);
1260 
1261  for (i=0; i<rx->apidn;i++){
1262  if ((aavail = ring_avail(&rx->index_arbuffer[i])
1263  /sizeof(index_unit)) < LIMIT)
1264  if (fill < (int) ring_free(&rx->arbuffer[i]))
1265  fill = ring_free(&rx->arbuffer[i]);
1266  }
1267 
1268  for (i=0; i<rx->ac3n;i++){
1269  if ((ac3avail = ring_avail(&rx->index_ac3rbuffer[i])
1270  /sizeof(index_unit)) < LIMIT)
1271  if (fill < (int) ring_free(&rx->ac3rbuffer[i]))
1272  fill = ring_free(&rx->ac3rbuffer[i]);
1273  }
1274 
1275 #if 0
1276  LOG(VB_GENERAL, LOG_INFO,
1277  QString("free %1 %2 %3 %4")
1278  .arg(fill).arg(vavail).arg(aavail).arg(ac3avail));
1279 #endif
1280 
1281  if (!fill){
1282  if(vavail && (aavail || ac3avail)) return 0;
1283  else return -1;
1284  }
1285 
1286  return fill/2;
1287 }
1288 
1289 
1290 
1291 #define IN_SIZE (1000*TS_SIZE)
1292 static void find_pids_file(struct replex *rx)
1293 {
1294  uint8_t buf[IN_SIZE];
1295  int afound=0;
1296  int vfound=0;
1297  int count=0;
1298  int re=0;
1299  uint16_t vpid=0, apid=0, ac3pid=0;
1300 
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;
1305  if ((re = save_read(rx,buf,IN_SIZE))<0)
1306  LOG(VB_GENERAL, LOG_ERR,
1307  QString("reading: %1").arg(strerror(errno)));
1308  else
1309  count += re;
1310  if ( (re = find_pids(&vpid, &apid, &ac3pid, buf, re))){
1311  if (!rx->vpid && vpid){
1312  rx->vpid = vpid;
1313  LOG(VB_GENERAL, LOG_INFO,QString("vpid 0x%1")
1314  .arg(rx->vpid, 4,16,QChar('0')));
1315  vfound++;
1316  }
1317  if (!rx->apidn && apid){
1318  rx->apid[0] = apid;
1319  LOG(VB_GENERAL, LOG_INFO, QString("apid 0x%1")
1320  .arg(rx->apid[0], 4,16,QChar('0')));
1321  rx->apidn++;
1322  afound++;
1323  }
1324  if (!rx->ac3n && ac3pid){
1325  rx->ac3_id[0] = ac3pid;
1326  LOG(VB_GENERAL, LOG_INFO, QString("ac3pid 0x%1")
1327  .arg(rx->ac3_id[0], 4,16,QChar('0')));
1328  rx->ac3n++;
1329  afound++;
1330  }
1331 
1332  }
1333 
1334  }
1335 
1336  lseek(rx->fd_in,0,SEEK_SET);
1337  if (!afound || !vfound){
1338  LOG(VB_GENERAL, LOG_ERR, "Couldn't find all pids");
1339  exit(1);
1340  }
1341 
1342 }
1343 
1344 #define MAXVPID 16
1345 #define MAXAPID 32
1346 #define MAXAC3PID 16
1347 static void find_all_pids_file(struct replex *rx)
1348 {
1349  uint8_t buf[IN_SIZE];
1350  int count=0;
1351  int j;
1352  int re=0;
1353  uint16_t vpid[MAXVPID], apid[MAXAPID], ac3pid[MAXAC3PID];
1354  int vn=0, an=0,ac3n=0;
1355  uint16_t vp,ap,cp;
1356  int vpos, apos, cpos;
1357 
1358  memset (vpid , 0 , MAXVPID*sizeof(uint16_t));
1359  memset (apid , 0 , MAXAPID*sizeof(uint16_t));
1360  memset (ac3pid , 0 , MAXAC3PID*sizeof(uint16_t));
1361 
1362  LOG(VB_GENERAL, LOG_INFO, "Trying to find PIDs");
1363  while (count < (int) rx->inflength-IN_SIZE){
1364  if ((re = save_read(rx,buf,IN_SIZE))<0)
1365  LOG(VB_GENERAL, LOG_ERR, QString("reading: %1")
1366  .arg(strerror(errno)));
1367  else
1368  count += re;
1369  if ( (re = find_pids_pos(&vp, &ap, &cp, buf, re,
1370  &vpos, &apos, &cpos))){
1371  if (vp){
1372  int old=0;
1373  for (j=0; j < vn; j++){
1374 #if 0
1375  LOG(VB_GENERAL, LOG_INFO,
1376  QString("%1. %2").arg(j+1).arg(vpid[j]));
1377 #endif
1378  if (vpid[j] == vp){
1379  old = 1;
1380  break;
1381  }
1382  }
1383  if (!old){
1384  vpid[vn]=vp;
1385 
1386  LOG(VB_GENERAL, LOG_INFO,
1387  QString("vpid %1: 0x%2 (%3) PES ID: 0x%4")
1388  .arg(vn+1)
1389  .arg(vpid[vn], 4,16,QChar('0'))
1390  .arg(vpid[vn])
1391  .arg(buf[vpos], 2,16,QChar('0')));
1392  if (vn+1 < MAXVPID) vn++;
1393  }
1394  }
1395 
1396  if (ap){
1397  int old=0;
1398  for (j=0; j < an; j++)
1399  if (apid[j] == ap){
1400  old = 1;
1401  break;
1402  }
1403  if (!old){
1404  apid[an]=ap;
1405  LOG(VB_GENERAL, LOG_INFO,
1406  QString("apid %1: 0x%2 (%3) PES ID: 0x%4")
1407  .arg(an +1)
1408  .arg(apid[an], 4,16,QChar('0'))
1409  .arg(apid[an])
1410  .arg(buf[apos], 2,16,QChar('0')));
1411  if (an+1 < MAXAPID) an++;
1412  }
1413  }
1414 
1415  if (cp){
1416  int old=0;
1417  for (j=0; j < ac3n; j++)
1418  if (ac3pid[j] == cp){
1419  old = 1;
1420  break;
1421  }
1422  if (!old){
1423  ac3pid[ac3n]=cp;
1424  LOG(VB_GENERAL, LOG_INFO,
1425  QString("ac3pid %1: 0x%2 (%3)")
1426  .arg(ac3n+1)
1427  .arg(ac3pid[ac3n], 4,16,QChar('0'))
1428  .arg(ac3pid[ac3n]));
1429  if (ac3n+1< MAXAC3PID) ac3n++;
1430  }
1431  }
1432  }
1433 
1434  }
1435 
1436  lseek(rx->fd_in,0,SEEK_SET);
1437 }
1438 
1439 static void find_pids_stdin(struct replex *rx, uint8_t *buf, int len)
1440 {
1441  int afound=0;
1442  int vfound=0;
1443  uint16_t vpid=0, apid=0, ac3pid=0;
1444 
1445  if (rx->vpid) vfound = 1;
1446  if (rx->apidn) afound = 1;
1447  LOG(VB_GENERAL, LOG_INFO, "Trying to find PIDs");
1448  if ( find_pids(&vpid, &apid, &ac3pid, buf, len) ){
1449  if (!rx->vpid && vpid){
1450  rx->vpid = vpid;
1451  vfound++;
1452  }
1453  if (!rx->apidn && apid){
1454  rx->apid[0] = apid;
1455  rx->apidn++;
1456  afound++;
1457  ring_init(&rx->arbuffer[0], rx->audiobuf);
1458  init_pes_in(&rx->paudio[0], 1, &rx->arbuffer[0], 0);
1459  rx->paudio[0].priv = (void *) rx;
1460  ring_init(&rx->index_arbuffer[0], INDEX_BUF);
1461  memset(&rx->aframe[0], 0, sizeof(audio_frame_t));
1462  init_index(&rx->current_aindex[0]);
1463  rx->aframe_count[0] = 0;
1464  rx->first_apts[0] = 0;
1465  }
1466 
1467  if (!rx->ac3n && ac3pid){
1468  rx->ac3_id[0] = ac3pid;
1469  rx->ac3n++;
1470  afound++;
1471  ring_init(&rx->ac3rbuffer[0], AC3_BUF);
1472  init_pes_in(&rx->pac3[0], 0x80, &rx->ac3rbuffer[0],0);
1473  rx->pac3[0].priv = (void *) rx;
1475  memset(&rx->ac3frame[0], 0, sizeof(audio_frame_t));
1476  init_index(&rx->current_ac3index[0]);
1477  rx->ac3frame_count[0] = 0;
1478  rx->first_ac3pts[0] = 0;
1479  }
1480 
1481  }
1482 
1483  if (afound && vfound){
1484  LOG(VB_GENERAL, LOG_INFO, "found");
1485  if (rx->vpid)
1486  LOG(VB_GENERAL, LOG_INFO, QString("vpid %1 (0x%2)")
1487  .arg(rx->vpid).arg(rx->vpid, 4,16,QChar('0')));
1488  if (rx->apidn)
1489  LOG(VB_GENERAL, LOG_INFO, QString("apid %1 (0x%2)")
1490  .arg(rx->apid[0]).arg(rx->apid[0], 4,16,QChar('0')));
1491  if (rx->ac3n)
1492  LOG(VB_GENERAL, LOG_INFO, QString("ac3pid %1 (0x%2)")
1493  .arg(rx->ac3_id[0]).arg(rx->ac3_id[0], 4,16,QChar('0')));
1494  } else {
1495  LOG(VB_GENERAL, LOG_ERR, "Couldn't find pids");
1496  exit(1);
1497  }
1498 
1499 }
1500 
1501 
1502 static void pes_id_out(pes_in_t *p)
1503 {
1504 
1505 // int len = p->plength-3-p->hlength;
1506  struct replex *rx = (struct replex *) p->priv;
1507 
1508  rx->scan_found=0;
1509  switch(p->cid){
1510  case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1511  rx->scan_found=p->cid;
1512  break;
1513 
1514  case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1515  rx->scan_found=p->cid;
1516  break;
1517 
1518  case PRIVATE_STREAM1:
1519  if (rx->vdr){
1520  rx->scan_found = 0x80;
1521  break;
1522  } else {
1523 
1524  uint8_t id = p->buf[9+p->hlength];
1525  switch(id){
1526  case 0x80 ... 0x8f:
1527  {
1528  int c=0;
1529  uint16_t fframe;
1530 
1531  fframe=0;
1532  fframe = p->buf[9+p->hlength+3];
1533  fframe |= (p->buf[9+p->hlength+2]<<8);
1534 
1535  if (fframe < p->plength){
1536  if ((c=find_audio_s(p->buf,
1537  9+p->hlength+4+fframe,
1538  AC3, p->plength+6)) >= 0){
1539  rx->scan_found = id;
1540 #if 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')));
1545  if (id>0x80)show_buf(p->buf+9+p->hlength,8);
1546  if (id>0x80)show_buf(p->buf+c,8);
1547 #endif
1548  }
1549  }
1550  break;
1551  }
1552  }
1553  break;
1554  }
1555  default:
1556  p->cid = 0;
1557  p->type = 0;
1558  rx->scan_found=0;
1559  memset(p->buf,0,MAX_PLENGTH*sizeof(uint8_t));
1560  return;
1561  }
1562 }
1563 
1564 static void find_pes_ids(struct replex *rx)
1565 {
1566  uint8_t buf[IN_SIZE];
1567  int count=0;
1568  int j;
1569  int re=0;
1570  uint16_t vpid[MAXVPID], apid[MAXAPID], ac3pid[MAXAC3PID];
1571  int vn=0, an=0,ac3n=0;
1572 
1573  memset (vpid , 0 , MAXVPID*sizeof(uint16_t));
1574  memset (apid , 0 , MAXAPID*sizeof(uint16_t));
1575  memset (ac3pid , 0 , MAXAC3PID*sizeof(uint16_t));
1576 
1577  LOG(VB_GENERAL, LOG_INFO, "Trying to find PES IDs");
1578  rx->scan_found=0;
1579  rx->pvideo.priv = rx ;
1580  while (count < (int) rx->inflength-IN_SIZE){
1581  if ((re = save_read(rx,buf,IN_SIZE))<0)
1582  LOG(VB_GENERAL, LOG_ERR, QString("reading: %1")
1583  .arg(strerror(errno)));
1584  else
1585  count += re;
1586 
1587  get_pes(&rx->pvideo, buf, re, pes_id_out);
1588 
1589  if ( rx->scan_found ){
1590 
1591  switch (rx->scan_found){
1592 
1593  case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1594  {
1595  int old=0;
1596  for (j=0; j < vn; j++){
1597 #if 0
1598  LOG(VB_GENERAL, LOG_INFO,
1599  QString("%1. %2").arg(j+1).arg(vpid[j]));
1600 #endif
1601  if (vpid[j] == rx->scan_found){
1602  old = 1;
1603  break;
1604  }
1605  }
1606  if (!old){
1607  vpid[vn]=rx->scan_found;
1608 
1609  LOG(VB_GENERAL, LOG_INFO,
1610  QString("MPEG VIDEO %1: 0x%2 (%3)")
1611  .arg(vn+1)
1612  .arg(vpid[vn], 2,16,QChar('0'))
1613  .arg(vpid[vn]));
1614  if (vn+1 < MAXVPID) vn++;
1615  }
1616  }
1617  break;
1618 
1619 
1620  case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1621  {
1622  int old=0;
1623  for (j=0; j < an; j++)
1624  if (apid[j] == rx->scan_found){
1625  old = 1;
1626  break;
1627  }
1628  if (!old){
1629  apid[an]=rx->scan_found;
1630  LOG(VB_GENERAL, LOG_INFO,
1631  QString("MPEG AUDIO %1: 0x%2 (%3)")
1632  .arg(an +1)
1633  .arg(apid[an], 2,16,QChar('0'))
1634  .arg(apid[an]));
1635  if (an+1 < MAXAPID) an++;
1636  }
1637  }
1638  break;
1639 
1640  case 0x80 ... 0x8f:
1641  {
1642  int old=0;
1643  for (j=0; j < ac3n; j++)
1644  if (ac3pid[j] == rx->scan_found){
1645  old = 1;
1646  break;
1647  }
1648  if (!old){
1649  ac3pid[ac3n]=rx->scan_found;
1650  if (rx->vdr){
1651  LOG(VB_GENERAL, LOG_INFO,
1652  "possible AC3 AUDIO with private stream 1 pid (0xbd)");
1653  }else{
1654  LOG(VB_GENERAL, LOG_INFO,
1655  QString("AC3 AUDIO %1: 0x%2 (%3)")
1656  .arg(ac3n+1)
1657  .arg(ac3pid[ac3n], 2,16,QChar('0'))
1658  .arg(ac3pid[ac3n]));
1659  }
1660  if (ac3n+1< MAXAC3PID) ac3n++;
1661  }
1662  rx->scan_found = 0;
1663  }
1664  break;
1665  }
1666  rx->scan_found = 0;
1667  }
1668  }
1669 }
1670 
1671 
1672 
1673 static void replex_finish(struct replex *rx)
1674 {
1675  if (!replex_all_set(rx)){
1676  LOG(VB_GENERAL, LOG_ERR, "Can't find all required streams");
1677  if (rx->itype == REPLEX_PS){
1678  LOG(VB_GENERAL, LOG_ERR,
1679  "Please check if audio and video have standard IDs (0xc0 or 0xe0)");
1680  }
1681  exit(1);
1682  }
1683 
1684  if (!rx->demux)
1685  finish_mpg((multiplex_t *)rx->priv);
1686  exit(0);
1687 }
1688 
1689 static int replex_fill_buffers(struct replex *rx, uint8_t *mbuf)
1690 {
1691  uint8_t buf[IN_SIZE];
1692  int i,j;
1693  int count=0;
1694  int fill;
1695  int re;
1696  int rsize;
1697  int tries = 0;
1698 
1699  if (rx->finish) return 0;
1700  fill = guess_fill(rx);
1701 #if 0
1702  LOG(VB_GENERAL, LOG_INFO,
1703  QString("trying to fill buffers with %1").arg(fill));
1704 #endif
1705  if (fill < 0) return -1;
1706 
1707  memset(buf, 0, IN_SIZE);
1708 
1709  switch(rx->itype){
1710  case REPLEX_TS:
1711  if (fill < IN_SIZE){
1712  rsize = fill - (fill%188);
1713  } else rsize = IN_SIZE;
1714 
1715 #if 0
1716  LOG(VB_GENERAL, LOG_INFO, QString("filling with %1").arg(rsize));
1717 #endif
1718 
1719  if (!rsize) return 0;
1720 
1721  memset(buf, 0, IN_SIZE);
1722 
1723  if ( mbuf ){
1724  for ( i = 0; i < 188 ; i++){
1725  if ( mbuf[i] == 0x47 ) break;
1726  }
1727 
1728  if ( i == 188){
1729  LOG(VB_GENERAL, LOG_ERR, "Not a TS");
1730  return -1;
1731  } else {
1732  memcpy(buf,mbuf+i,2*TS_SIZE-i);
1733  if ((count = save_read(rx,mbuf,i))<0)
1734  LOG(VB_GENERAL, LOG_ERR, QString("reading: %1")
1735  .arg(strerror(errno)));
1736  memcpy(buf+2*TS_SIZE-i,mbuf,i);
1737  i = 188;
1738  }
1739  } else i=0;
1740 
1741 
1742 #define MAX_TRIES 5
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)));
1747  else
1748  count += re;
1749  tries++;
1750 
1751  if (!rx->vpid || !(rx->apidn || rx->ac3n)){
1752  find_pids_stdin(rx, buf, re);
1753  }
1754 
1755  for( j = 0; j < re; j+= TS_SIZE){
1756 
1757  if ( re - j < TS_SIZE) break;
1758 
1759  if ( replex_tsp( rx, buf+j) < 0){
1760  LOG(VB_GENERAL, LOG_ERR,
1761  "Error reading TS");
1762  exit(1);
1763  }
1764  }
1765  i=0;
1766  }
1767 
1768  if (tries == MAX_TRIES)
1769  replex_finish(rx);
1770  return 0;
1771  break;
1772 
1773  case REPLEX_PS:
1774  rsize = fill;
1775  if (fill > IN_SIZE) rsize = IN_SIZE;
1776  if (mbuf)
1777  get_pes(&rx->pvideo, mbuf, 2*TS_SIZE, pes_es_out);
1778 
1779  while (count < rsize && tries < MAX_TRIES){
1780  if ((re = save_read(rx, buf, rsize))<0)
1781  LOG(VB_GENERAL, LOG_ERR, QString("reading PS: %1")
1782  .arg(strerror(errno)));
1783  else
1784  count += re;
1785 
1786  get_pes(&rx->pvideo, buf, re, pes_es_out);
1787 
1788  tries++;
1789 
1790  }
1791 
1792  if (tries == MAX_TRIES)
1793  replex_finish(rx);
1794  return 0;
1795  break;
1796 
1797 
1798  case REPLEX_AVI:
1799  rsize = fill;
1800  if (fill > IN_SIZE) rsize = IN_SIZE;
1801 
1802  if (!(rx->ac.avih_flags & AVI_HASINDEX)){
1803 
1804  if (mbuf){
1805  get_avi(&rx->pvideo, mbuf, rx->avi_rest, avi_es_out);
1806  }
1807 
1808  while (count < rsize && tries < MAX_TRIES){
1809  if ((re = save_read(rx, buf, rsize))<0)
1810  LOG(VB_GENERAL, LOG_ERR,
1811  QString("reading AVI: %1")
1812  .arg(strerror(errno)));
1813  else
1814  count += re;
1815 
1816  get_avi(&rx->pvideo, buf, re, avi_es_out);
1817 
1818  tries++;
1819  }
1820  } else {
1821  if (get_avi_from_index(&rx->pvideo, rx->fd_in,
1822  &rx->ac, avi_es_out, rsize) < 0)
1823  tries = MAX_TRIES;
1824  }
1825 
1826  if (tries == MAX_TRIES)
1827  replex_finish(rx);
1828  return 0;
1829  break;
1830  }
1831 
1832  return -1;
1833 }
1834 
1835 static int fill_buffers(void *r, int finish)
1836 {
1837  struct replex *rx = (struct replex *)r;
1838 
1839  rx->finish = finish;
1840 
1841  return replex_fill_buffers(rx, nullptr);
1842 }
1843 
1844 
1846 {
1847  memset(iu,0, sizeof(index_unit));
1848  iu->frame_start = 1;
1849 }
1850 
1851 static int replex_all_set(struct replex *rx)
1852 {
1853  int i;
1854  int set=0;
1855 
1856  for (i=0; i < rx->ac3n ;i++){
1857  set += rx->ac3frame[i].set;
1858  }
1859  for (i=0; i<rx->apidn;i++){
1860  set += rx->aframe[i].set;
1861  }
1862  set += rx->seq_head.set;
1863 
1864  if (set == (rx->ac3n+ rx->apidn + 1)) return 1;
1865  return 0;
1866 }
1867 
1868 
1869 static int check_stream_type(struct replex *rx, uint8_t * buf, int len)
1870 {
1871  int c=0;
1872  avi_context ac;
1873  uint8_t head;
1874 
1875  if (rx->itype != REPLEX_TS) return rx->itype;
1876 
1877  if (len< 2*TS_SIZE){
1878  LOG(VB_GENERAL, LOG_ERR, "cannot determine streamtype");
1879  exit(1);
1880  }
1881 
1882  LOG(VB_GENERAL, LOG_INFO, "Checking for TS: ");
1883  while (c < len && buf[c]!=0x47) c++;
1884  if (c<len && len-c>=TS_SIZE){
1885  if (buf[c+TS_SIZE] == 0x47){
1886  LOG(VB_GENERAL, LOG_INFO, "confirmed");
1887  return REPLEX_TS;
1888  } else LOG(VB_GENERAL, LOG_INFO, "failed");
1889  } else LOG(VB_GENERAL, LOG_INFO, "failed");
1890 
1891  LOG(VB_GENERAL, LOG_INFO, "Checking for AVI: ");
1892  if (check_riff(&ac, buf, len)>=0){
1893  LOG(VB_GENERAL, LOG_INFO, "confirmed");
1894  rx->itype = REPLEX_AVI;
1895  rx->vpid = 0xE0;
1896  rx->apidn = 1;
1897  rx->apid[0] = 0xC0;
1898  rx->ignore_pts =1;
1899  return REPLEX_AVI;
1900  } else LOG(VB_GENERAL, LOG_INFO, "failed");
1901 
1902  LOG(VB_GENERAL, LOG_INFO, "Checking for PS: ");
1903  if (find_any_header(&head, buf, len) >= 0){
1904  LOG(VB_GENERAL, LOG_INFO, "confirmed(maybe)");
1905  } else {
1906  LOG(VB_GENERAL, LOG_INFO,"failed, trying it anyway");
1907  }
1908  rx->itype=REPLEX_PS;
1909  if (!rx->vpid) rx->vpid = 0xE0;
1910  if (!(rx->apidn || rx->ac3n)){
1911  rx->apidn = 1;
1912  rx->apid[0] = 0xC0;
1913  }
1914  return REPLEX_PS;
1915 }
1916 
1917 
1918 static void init_replex(struct replex *rx)
1919 {
1920  int i;
1921  uint8_t mbuf[2*TS_SIZE];
1922 
1923  rx->analyze=0;
1924 
1925  if (save_read(rx, mbuf, 2*TS_SIZE)<0)
1926  LOG(VB_GENERAL, LOG_ERR,
1927  QString("reading: %1").arg(strerror(errno)));
1928 
1929  check_stream_type(rx, mbuf, 2*TS_SIZE);
1930  if (rx->itype == REPLEX_TS){
1931  if (!rx->vpid || !(rx->apidn || rx->ac3n)){
1932  if (rx->inflength){
1933  find_pids_file(rx);
1934  }
1935  }
1936  }
1937 
1938 
1939  if (rx->otype==REPLEX_HDTV){
1940  rx->videobuf = 4*VIDEO_BUF;
1941  } else {
1942  rx->videobuf = VIDEO_BUF;
1943  }
1944  rx->audiobuf = AUDIO_BUF;
1945  rx->ac3buf = AC3_BUF;
1946 
1947  if (rx->itype == REPLEX_AVI){
1948  rx->videobuf = 4*VIDEO_BUF;
1949  rx->audiobuf = 2*rx->videobuf;
1950  }
1951 
1952  rx->vpes_abort = 0;
1953  rx->first_iframe = 0;
1954  ring_init(&rx->vrbuffer, rx->videobuf);
1955  if (rx->itype == REPLEX_TS || rx->itype == REPLEX_AVI)
1956  init_pes_in(&rx->pvideo, 0xE0, &rx->vrbuffer, 0);
1957  else {
1958  init_pes_in(&rx->pvideo, 0, nullptr, 1);
1959  }
1960  rx->pvideo.priv = (void *) rx;
1962  memset(&rx->seq_head, 0, sizeof(sequence_t));
1963  init_index(&rx->current_vindex);
1964  rx->vgroup_count = 0;
1965  rx->vframe_count = 0;
1966  rx->first_vpts = 0;
1967  rx->video_state = S_SEARCH;
1968  rx->last_vpts = 0;
1969 
1970  for (i=0; i<rx->apidn;i++){
1971 
1972  rx->apes_abort[i] = 0;
1973  rx->audio_state[i] = S_SEARCH;
1974  ring_init(&rx->arbuffer[i], rx->audiobuf);
1975 
1976  if (rx->itype == REPLEX_TS){
1977  init_pes_in(&rx->paudio[i], i+1,
1978  &rx->arbuffer[i], 0);
1979  rx->paudio[i].priv = (void *) rx;
1980  }
1981  ring_init(&rx->index_arbuffer[i], INDEX_BUF);
1982  memset(&rx->aframe[i], 0, sizeof(audio_frame_t));
1983  init_index(&rx->current_aindex[i]);
1984  rx->aframe_count[i] = 0;
1985  rx->first_apts[i] = 0;
1986  rx->last_apts[i] = 0;
1987  }
1988 
1989  for (i=0; i<rx->ac3n;i++){
1990  rx->ac3pes_abort[i] = 0;
1991  rx->ac3_state[i] = S_SEARCH;
1992  ring_init(&rx->ac3rbuffer[i], AC3_BUF);
1993  if (rx->itype == REPLEX_TS){
1994  init_pes_in(&rx->pac3[i], 0x80+i,
1995  &rx->ac3rbuffer[i],0);
1996  rx->pac3[i].priv = (void *) rx;
1997  }
1999  memset(&rx->ac3frame[i], 0, sizeof(audio_frame_t));
2000  init_index(&rx->current_ac3index[i]);
2001  rx->ac3frame_count[i] = 0;
2002  rx->first_ac3pts[i] = 0;
2003  rx->last_ac3pts[i] = 0;
2004  }
2005 
2006  if (rx->itype == REPLEX_TS){
2007  if (replex_fill_buffers(rx, mbuf)< 0) {
2008  LOG(VB_GENERAL, LOG_ERR, "error filling buffer");
2009  exit(1);
2010  }
2011  } else if ( rx->itype == REPLEX_AVI){
2012 #define AVI_S 1024
2013  avi_context *ac;
2014  uint8_t buf[AVI_S];
2015  int re=0;
2016  ssize_t read_count = 0;
2017 
2018  lseek(rx->fd_in, 0, SEEK_SET);
2019  ac = &rx->ac;
2020  memset(ac, 0, sizeof(avi_context));
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")
2024  .arg(read_count));
2025  exit(1);
2026  }
2027 
2028  if (check_riff(ac, buf, 12) < 0){
2029  LOG(VB_GENERAL, LOG_ERR, "Wrong RIFF header");
2030  exit(1);
2031  } else {
2032  LOG(VB_GENERAL, LOG_INFO, "Found RIFF header");
2033  }
2034 
2035  memset(ac, 0, sizeof(avi_context));
2036  re = read_avi_header(ac, rx->fd_in);
2037  if (avi_read_index(ac,rx->fd_in) < 0 || re < 0){
2038  LOG(VB_GENERAL, LOG_ERR, "Error reading index");
2039  exit(1);
2040  }
2041 // rx->aframe_count[0] = ac->ai[0].initial_frames;
2042  rx->vframe_count = ac->ai[0].initial_frames*ac->vi.fps/
2043  ac->ai[0].fps;
2044 
2045  rx->inflength = lseek(rx->fd_in, 0, SEEK_CUR)+ac->movi_length;
2046 
2047  LOG(VB_GENERAL, LOG_INFO, QString("AVI initial frames %1")
2048  .arg(rx->vframe_count));
2049  if (!ac->done){
2050  LOG(VB_GENERAL, LOG_ERR, "Error reading AVI header");
2051  exit(1);
2052  }
2053 
2054  if (replex_fill_buffers(rx, buf+re)< 0) {
2055  LOG(VB_GENERAL, LOG_ERR, "error filling buffer");
2056  exit(1);
2057  }
2058  } else {
2059  if (replex_fill_buffers(rx, mbuf)< 0) {
2060  LOG(VB_GENERAL, LOG_ERR, "error filling buffer");
2061  exit(1);
2062  }
2063  }
2064 
2065 }
2066 
2067 
2068 static void fix_audio(struct replex *rx, multiplex_t *mx)
2069 {
2070  int i;
2071  index_unit aiu;
2072  int size;
2073 
2074  size = sizeof(index_unit);
2075 
2076  for ( i = 0; i < rx->apidn; i++){
2077  do {
2078  while (ring_avail(&rx->index_arbuffer[i]) <
2079  sizeof(index_unit)){
2080  if (replex_fill_buffers(rx, nullptr)< 0) {
2081  LOG(VB_GENERAL, LOG_ERR,
2082  "error in fix audio");
2083  exit(1);
2084  }
2085  }
2086  ring_peek(&rx->index_arbuffer[i], (uint8_t *)&aiu, size, 0);
2087  if ( ptscmp(aiu.pts + rx->first_apts[i], rx->first_vpts) < 0){
2088  ring_skip(&rx->index_arbuffer[i], size);
2089  ring_skip(&rx->arbuffer[i], aiu.length);
2090  } else break;
2091 
2092  } while (1);
2093  mx->ext[i].pts_off = aiu.pts;
2094 
2095  LOG(VB_GENERAL, LOG_INFO, QString("Audio%1 offset: ").arg(i));
2096  printpts(mx->ext[i].pts_off);
2097  printpts(rx->first_apts[i]+mx->ext[i].pts_off);
2098  }
2099 
2100  for ( i = 0; i < rx->ac3n; i++){
2101  do {
2102  while (ring_avail(&rx->index_ac3rbuffer[i]) <
2103  sizeof(index_unit)){
2104  if (replex_fill_buffers(rx, nullptr)< 0) {
2105  LOG(VB_GENERAL, LOG_ERR,
2106  "error in fix audio");
2107  exit(1);
2108  }
2109  }
2110  ring_peek(&rx->index_ac3rbuffer[i], (uint8_t *)&aiu,
2111  size, 0);
2112  if ( ptscmp (aiu.pts+rx->first_ac3pts[i], rx->first_vpts) < 0){
2113  ring_skip(&rx->index_ac3rbuffer[i], size);
2114  ring_skip(&rx->ac3rbuffer[i], aiu.length);
2115  } else break;
2116  } while (1);
2117  mx->ext[i].pts_off = aiu.pts;
2118 
2119  LOG(VB_GENERAL, LOG_INFO, QString("AC3%1 offset: ").arg(i));
2120  printpts(mx->ext[i].pts_off);
2121  printpts(rx->first_ac3pts[i]+mx->ext[i].pts_off);
2122 
2123  }
2124 }
2125 
2126 
2127 
2128 static int get_next_video_unit(struct replex *rx, index_unit *viu)
2129 {
2130  if (ring_avail(&rx->index_vrbuffer)){
2131  ring_read(&rx->index_vrbuffer, (uint8_t *)viu,
2132  sizeof(index_unit));
2133  return 1;
2134  }
2135  return 0;
2136 }
2137 
2138 static int get_next_audio_unit(struct replex *rx, index_unit *aiu, int i)
2139 {
2140  if(ring_avail(&rx->index_arbuffer[i])){
2141  ring_read(&rx->index_arbuffer[i], (uint8_t *)aiu,
2142  sizeof(index_unit));
2143  return 1;
2144  }
2145  return 0;
2146 }
2147 
2148 static int get_next_ac3_unit(struct replex *rx, index_unit *aiu, int i)
2149 {
2150  if (ring_avail(&rx->index_ac3rbuffer[i])) {
2151  ring_read(&rx->index_ac3rbuffer[i], (uint8_t *)aiu,
2152  sizeof(index_unit));
2153 
2154  return 1;
2155  }
2156  return 0;
2157 }
2158 
2159 
2160 static void do_analyze(struct replex *rx)
2161 {
2162  index_unit dummy;
2163  index_unit dummy2;
2164  int i;
2165  uint64_t lastvpts;
2166  uint64_t lastvdts;
2167  uint64_t lastapts[N_AUDIO];
2168  uint64_t lastac3pts[N_AC3];
2169  int av;
2170 
2171  av = rx->analyze-1;
2172 
2173  lastvpts = 0;
2174  lastvdts = 0;
2175  memset(lastapts, 0, N_AUDIO*sizeof(uint64_t));
2176  memset(lastac3pts, 0, N_AC3*sizeof(uint64_t));
2177 
2178  LOG(VB_GENERAL, LOG_INFO, "STARTING ANALYSIS");
2179 
2180 
2181  while(!rx->finish){
2182  if (replex_fill_buffers(rx, nullptr)< 0) {
2183  LOG(VB_GENERAL, LOG_ERR,
2184  "error in get next video unit");
2185  return;
2186  }
2187  for (i=0; i< rx->apidn; i++){
2188  while(get_next_audio_unit(rx, &dummy2, i)){
2189  ring_skip(&rx->arbuffer[i],
2190  dummy2.length);
2191  if (av>=1){
2192  LOG(VB_GENERAL, LOG_INFO,
2193  QString("MPG2 Audio%1 unit: length %2 PTS ")
2194  .arg(i).arg(dummy2.length));
2195  printptss(dummy2.pts);
2196 
2197  if (lastapts[i]){
2198  LOG(VB_GENERAL, LOG_INFO,
2199  " diff:");
2200  printptss(ptsdiff(dummy2.pts,lastapts[i]));
2201  }
2202  lastapts[i] = dummy2.pts;
2203  }
2204  }
2205  }
2206 
2207  for (i=0; i< rx->ac3n; i++){
2208  while(get_next_ac3_unit(rx, &dummy2, i)){
2209  ring_skip(&rx->ac3rbuffer[i],
2210  dummy2.length);
2211  if (av>=1){
2212  LOG(VB_GENERAL, LOG_INFO,
2213  QString("AC3 Audio%1 unit: length %2 PTS ")
2214  .arg(i).arg(dummy2.length));
2215  printptss(dummy2.pts);
2216  if (lastac3pts[i]){
2217  LOG(VB_GENERAL, LOG_INFO,
2218  " diff:");
2219  printptss(ptsdiff(dummy2.pts, lastac3pts[i]));
2220  }
2221  lastac3pts[i] = dummy2.pts;
2222  }
2223  }
2224  }
2225 
2226  while (get_next_video_unit(rx, &dummy)){
2227  ring_skip(&rx->vrbuffer,
2228  dummy.length);
2229  if (av==0 || av==2){
2230  LOG(VB_GENERAL, LOG_INFO, "Video unit: ");
2231  if (dummy.seq_header){
2232  LOG(VB_GENERAL, LOG_INFO,
2233  "Sequence header ");
2234  }
2235  if (dummy.gop){
2236  LOG(VB_GENERAL, LOG_INFO,
2237  "GOP header ");
2238  }
2239  switch (dummy.frame){
2240  case I_FRAME:
2241  LOG(VB_GENERAL, LOG_INFO, "I-frame");
2242  break;
2243  case B_FRAME:
2244  LOG(VB_GENERAL, LOG_INFO, "B-frame");
2245  break;
2246  case P_FRAME:
2247  LOG(VB_GENERAL, LOG_INFO, "P-frame");
2248  break;
2249  }
2250  LOG(VB_GENERAL, LOG_INFO, QString(" length %1 PTS ")
2251  .arg(dummy.length));
2252  printptss(dummy.pts);
2253  if (lastvpts){
2254  LOG(VB_GENERAL, LOG_INFO," diff:");
2255  printptss(ptsdiff(dummy.pts, lastvpts));
2256  }
2257  lastvpts = dummy.pts;
2258 
2259  LOG(VB_GENERAL, LOG_INFO, " DTS ");
2260  printptss(dummy.dts);
2261  if (lastvdts){
2262  LOG(VB_GENERAL, LOG_INFO, " diff:");
2263  printptss(ptsdiff(dummy.dts,lastvdts));
2264  }
2265  lastvdts = dummy.dts;
2266  }
2267  }
2268  }
2269 
2270 
2271 }
2272 
2273 static void do_scan(struct replex *rx)
2274 {
2275  uint8_t mbuf[2*TS_SIZE];
2276 
2277  rx->analyze=0;
2278 
2279  if (save_read(rx, mbuf, 2*TS_SIZE)<0)
2280  LOG(VB_GENERAL, LOG_ERR, QString("reading: %1")
2281  .arg(strerror(errno)));
2282 
2283  LOG(VB_GENERAL, LOG_INFO, "STARTING SCAN");
2284 
2285  check_stream_type(rx, mbuf, 2*TS_SIZE);
2286 
2287  switch(rx->itype){
2288  case REPLEX_TS:
2289  find_all_pids_file(rx);
2290  break;
2291 
2292  case REPLEX_PS:
2293  init_pes_in(&rx->pvideo, 0, nullptr, 1);
2294  find_pes_ids(rx);
2295  break;
2296 
2297  case REPLEX_AVI:
2298  break;
2299  }
2300 
2301 }
2302 
2303 static void do_demux(struct replex *rx)
2304 {
2305  index_unit dummy;
2306  index_unit dummy2;
2307  int i;
2308  LOG(VB_GENERAL, LOG_INFO, "STARTING DEMUX");
2309 
2310  while(!rx->finish){
2311  if (replex_fill_buffers(rx, nullptr)< 0) {
2312  LOG(VB_GENERAL, LOG_ERR,
2313  "error in get next video unit");
2314  return;
2315  }
2316  for (i=0; i< rx->apidn; i++){
2317  while(get_next_audio_unit(rx, &dummy2, i)){
2318  ring_read_file(&rx->arbuffer[i],
2319  rx->dmx_out[i+1],
2320  dummy2.length);
2321  }
2322  }
2323 
2324  for (i=0; i< rx->ac3n; i++){
2325  while(get_next_ac3_unit(rx, &dummy2, i)){
2326  ring_read_file(&rx->ac3rbuffer[i],
2327  rx->dmx_out[i+1+rx->apidn],
2328  dummy2.length);
2329  }
2330  }
2331 
2332  while (get_next_video_unit(rx, &dummy)){
2333  ring_read_file(&rx->vrbuffer, rx->dmx_out[0],
2334  dummy.length);
2335  }
2336  }
2337 }
2338 
2339 
2340 static void do_replex(struct replex *rx)
2341 {
2342  int video_ok = 0;
2343  aok_arr ext_ok {};
2344  int start=1;
2345  multiplex_t mx;
2346 
2347 
2348  LOG(VB_GENERAL, LOG_INFO, "STARTING REPLEX");
2349  memset(&mx, 0, sizeof(mx));
2350 
2351  while (!replex_all_set(rx)){
2352  if (replex_fill_buffers(rx, nullptr)< 0) {
2353  LOG(VB_GENERAL, LOG_INFO, "error filling buffer");
2354  exit(1);
2355  }
2356  }
2357 
2358  int i;
2359  for (i = 0; i < rx->apidn; i++){
2360  rx->exttype[i] = 2;
2361  rx->extframe[i] = rx->aframe[i];
2362  rx->extrbuffer[i] = rx->arbuffer[i];
2363  rx->index_extrbuffer[i] = rx->index_arbuffer[i];
2364  rx->exttypcnt[i+1] = i;
2365  }
2366 
2367  int ac3Count = 1;
2368  for (i = rx->apidn; i < rx->apidn + rx->ac3n; i++){
2369  rx->exttype[i] = 1;
2370  rx->extframe[i] = rx->ac3frame[i];
2371  rx->extrbuffer[i] = rx->ac3rbuffer[i];
2372  rx->index_extrbuffer[i] = rx->index_ac3rbuffer[i];
2373  rx->exttypcnt[i] = ac3Count++;
2374  }
2375 
2376  mx.priv = (void *) rx;
2377  rx->priv = (void *) &mx;
2378  init_multiplex(&mx, &rx->seq_head, rx->extframe,
2379  rx->exttype, rx->exttypcnt, rx->video_delay,
2380  rx->audio_delay, rx->fd_out, fill_buffers,
2381  &rx->vrbuffer, &rx->index_vrbuffer,
2382  rx->extrbuffer, rx->index_extrbuffer,
2383  rx->otype);
2384 
2385  if (!rx->ignore_pts){
2386  fix_audio(rx, &mx);
2387  }
2388  setup_multiplex(&mx);
2389 
2390  while(1){
2391  check_times( &mx, &video_ok, ext_ok, &start);
2392 
2393  write_out_packs( &mx, video_ok, ext_ok);
2394  }
2395 }
2396 
2397 
2398 static void usage(char *progname)
2399 {
2400  printf ("usage: %s [options] <input files>\n\n",progname);
2401  printf ("options:\n");
2402  printf (" --help, -h: print help message\n");
2403  printf (" --type, -t: set output type (MPEG2, DVD, HDTV)\n");
2404  printf (" --of, -o: set output file\n");
2405  printf (" --input_stream, -i: set input stream type (TS(default), PS, AVI)\n");
2406  printf (" --audio_pid, -a: audio PID for TS stream (also used for PS id)\n");
2407  printf (" --ac3_id, -c: ID of AC3 audio for demux (also used for PS id)\n");
2408  printf (" --video_pid, -v: video PID for TS stream (also used for PS id)\n");
2409  printf (" --video_delay, -d: video delay in ms\n");
2410  printf (" --audio_delay, -e: audio delay in ms\n");
2411  printf (" --ignore_PTS, -f: ignore all PTS information of original\n");
2412  printf (" --keep_PTS, -k: keep and don't correct PTS information of original\n");
2413  printf (" --fix_sync, -n: try to fix audio sync while demuxing\n");
2414  printf (" --demux, -z: demux only (-o is basename)\n");
2415  printf (" --analyze, -y: analyze (0=video,1=audio, 2=both)\n");
2416  printf (" --scan, -s: scan for streams\n");
2417  printf (" --vdr, -x: handle AC3 for vdr input file\n");
2418  exit(1);
2419 }
2420 
2421 int main(int argc, char **argv)
2422 {
2423  int c;
2424  int analyze=0;
2425  int scan =0;
2426  char *filename = nullptr;
2427  const char *type = "SVCD";
2428  const char *inpt = "TS";
2429 
2430  struct replex rx;
2431 
2432  memset(&rx, 0, sizeof(struct replex));
2433 
2434  while (1) {
2435  int option_index = 0;
2436  static struct option long_options[] = {
2437  {"type", required_argument, nullptr, 't'},
2438  {"input_stream", required_argument, nullptr, 'i'},
2439  {"video_pid", required_argument, nullptr, 'v'},
2440  {"audio_pid", required_argument, nullptr, 'a'},
2441  {"audio_delay", required_argument, nullptr, 'e'},
2442  {"video_delay", required_argument, nullptr, 'd'},
2443  {"ac3_id", required_argument, nullptr, 'c'},
2444  {"of",required_argument, nullptr, 'o'},
2445  {"ignore_PTS",required_argument, nullptr, 'f'},
2446  {"keep_PTS",required_argument, nullptr, 'k'},
2447  {"fix_sync",no_argument, nullptr, 'n'},
2448  {"demux",no_argument, nullptr, 'z'},
2449  {"analyze",required_argument, nullptr, 'y'},
2450  {"scan",required_argument, nullptr, 's'},
2451  {"vdr",required_argument, nullptr, 'x'},
2452  {"help", no_argument , nullptr, 'h'},
2453  {nullptr, 0, nullptr, 0}
2454  };
2455  c = getopt_long (argc, argv,
2456  "t:o:a:v:i:hp:q:d:c:n:fkd:e:zy:sx",
2457  long_options, &option_index);
2458  if (c == -1)
2459  break;
2460 
2461  switch (c) {
2462  case 't':
2463  type = optarg;
2464  break;
2465  case 'i':
2466  inpt = optarg;
2467  break;
2468  case 'd':
2469  rx.video_delay = strtol(optarg,(char **)nullptr, 0)
2470  *CLOCK_MS;
2471  break;
2472  case 'e':
2473  rx.audio_delay = strtol(optarg,(char **)nullptr, 0)
2474  *CLOCK_MS;
2475  break;
2476  case 'a':
2477  if (rx.apidn==N_AUDIO){
2478  LOG(VB_GENERAL, LOG_ERR, "Too many audio PIDs");
2479  exit(1);
2480  }
2481  rx.apid[rx.apidn] = strtol(optarg,(char **)nullptr, 0);
2482  rx.apidn++;
2483  break;
2484  case 'v':
2485  rx.vpid = strtol(optarg,(char **)nullptr, 0);
2486  break;
2487  case 'c':
2488  if (rx.ac3n==N_AC3){
2489  LOG(VB_GENERAL, LOG_ERR, "Too many audio PIDs");
2490  exit(1);
2491  }
2492  rx.ac3_id[rx.ac3n] = strtol(optarg,(char **)nullptr, 0);
2493  rx.ac3n++;
2494  break;
2495  case 'o':
2496  filename = optarg;
2497  break;
2498  case 'f':
2499  rx.ignore_pts =1;
2500  break;
2501  case 'k':
2502  rx.keep_pts =1;
2503  break;
2504  case 'z':
2505  rx.demux =1;
2506  break;
2507  case 'n':
2508  rx.fix_sync =1;
2509  break;
2510  case 'y':
2511  analyze = strtol(optarg,(char **)nullptr, 0);
2512  if (analyze>2) usage(argv[0]);
2513  analyze++;
2514  break;
2515  case 's':
2516  scan = 1;
2517  break;
2518  case 'x':
2519  rx.vdr=1;
2520  break;
2521  case 'h':
2522  case '?':
2523  default:
2524  usage(argv[0]);
2525  }
2526  }
2527 
2528  if (optind == argc-1) {
2529  if ((rx.fd_in = open(argv[optind] ,O_RDONLY| O_LARGEFILE)) < 0) {
2530  perror("Error opening input file ");
2531  exit(1);
2532  }
2533  LOG(VB_GENERAL, LOG_INFO,
2534  QString("Reading from %1").arg(argv[optind]));
2535  rx.inflength = lseek(rx.fd_in, 0, SEEK_END);
2536  LOG(VB_GENERAL, LOG_INFO,
2537  QString("Input file length: %1 MB")
2538  .arg(rx.inflength/1024.0/1024.0, 0,'f',2,QChar('0')));
2539  lseek(rx.fd_in,0,SEEK_SET);
2540  rx.lastper = 0;
2541  rx.finread = 0;
2542  } else {
2543  LOG(VB_GENERAL, LOG_INFO, "using stdin as input");
2544  rx.fd_in = STDIN_FILENO;
2545  rx.inflength = 0;
2546  }
2547 
2548  if (!rx.demux){
2549  if (filename){
2550  if ((rx.fd_out = open(filename,O_WRONLY|O_CREAT
2551  |O_TRUNC|O_LARGEFILE,
2552  S_IRUSR|S_IWUSR|S_IRGRP|
2553  S_IWGRP|
2554  S_IROTH|S_IWOTH)) < 0){
2555  perror("Error opening output file");
2556  exit(1);
2557  }
2558  LOG(VB_GENERAL, LOG_INFO,
2559  QString("Output File is: %1").arg(filename));
2560  } else {
2561  rx.fd_out = STDOUT_FILENO;
2562  LOG(VB_GENERAL, LOG_INFO, "using stdout as output");
2563  }
2564  }
2565  if (scan){
2566  if (rx.fd_in == STDIN_FILENO){
2567  LOG(VB_GENERAL, LOG_ERR, "Can`t scan from pipe");
2568  exit(1);
2569  }
2570  do_scan(&rx);
2571  exit(0);
2572  }
2573 
2574  if (!strncmp(type,"MPEG2",6))
2575  rx.otype=REPLEX_MPEG2;
2576  else if (!strncmp(type,"DVD",4))
2577  rx.otype=REPLEX_DVD;
2578  else if (!strncmp(type,"HDTV",4))
2579  rx.otype=REPLEX_HDTV;
2580  else if (!rx.demux)
2581  usage(argv[0]);
2582 
2583  if (!strncmp(inpt,"TS",3)){
2584  rx.itype=REPLEX_TS;
2585  } else if (!strncmp(inpt,"PS",3)){
2586  rx.itype=REPLEX_PS;
2587  if (!rx.vpid) rx.vpid = 0xE0;
2588  if (!(rx.apidn || rx.ac3n)){
2589  rx.apidn = 1;
2590  rx.apid[0] = 0xC0;
2591  }
2592  } else if (!strncmp(inpt,"AVI",4)){
2593  rx.itype=REPLEX_AVI;
2594  rx.vpid = 0xE0;
2595  rx.apidn = 1;
2596  rx.apid[0] = 0xC0;
2597  rx.ignore_pts =1;
2598  } else {
2599  usage(argv[0]);
2600  }
2601 
2602  init_replex(&rx);
2603  rx.analyze= analyze;
2604 
2605  if (rx.demux) {
2606  int i;
2607  char fname[256];
2608  if (!filename){
2609  filename = static_cast<char*>(malloc(4));
2610  strcpy(filename,"out");
2611  }
2612  if (strlen(filename) > 250){
2613  LOG(VB_GENERAL, LOG_ERR, "Basename too long");
2614  exit(0);
2615  }
2616 
2617  snprintf(fname,256,"%s.mv2",filename);
2618  if ((rx.dmx_out[0] = open(fname,O_WRONLY|
2619  O_CREAT|O_TRUNC|
2620  O_LARGEFILE,
2621  S_IRUSR|S_IWUSR|
2622  S_IRGRP|S_IWGRP|
2623  S_IROTH|S_IWOTH))
2624  < 0){
2625  perror("Error opening output file");
2626  exit(1);
2627  }
2628  LOG(VB_GENERAL, LOG_INFO,
2629  QString("Video output File is: %1").arg(fname));
2630 
2631  for (i=0; i < rx.apidn; i++){
2632  snprintf(fname,256,"%s%d.mp2",filename
2633  ,i);
2634  if ((rx.dmx_out[i+1] =
2635  open(fname,O_WRONLY|
2636  O_CREAT|O_TRUNC|
2637  O_LARGEFILE,
2638  S_IRUSR|S_IWUSR|
2639  S_IRGRP|S_IWGRP|
2640  S_IROTH|S_IWOTH))
2641  < 0){
2642  perror("Error opening output file");
2643  exit(1);
2644  }
2645  LOG(VB_GENERAL, LOG_INFO,
2646  QString("Audio%1 output File is: %2")
2647  .arg(i).arg(fname));
2648  }
2649 
2650 
2651  for (i=0; i < rx.ac3n; i++){
2652  snprintf(fname,256,"%s%d.ac3",filename
2653  ,i);
2654  if ((rx.dmx_out[i+1+rx.apidn] =
2655  open(fname,O_WRONLY|
2656  O_CREAT|O_TRUNC|
2657  O_LARGEFILE,
2658  S_IRUSR|S_IWUSR|
2659  S_IRGRP|S_IWGRP|
2660  S_IROTH|S_IWOTH))
2661  < 0){
2662  perror("Error opening output file");
2663  exit(1);
2664  }
2665  LOG(VB_GENERAL, LOG_INFO,
2666  QString("AC3%1 output File is: %2")
2667  .arg(i).arg(fname));
2668  }
2669  do_demux(&rx);
2670  } else if (analyze){
2671  rx.demux=1;
2672  do_analyze(&rx);
2673  } else {
2674  do_replex(&rx);
2675  }
2676 
2677  return 0;
2678 }
ring_free
static unsigned int ring_free(ringbuffer *rbuf)
Definition: ringbuffer.h:101
pes_in_t::priv
void * priv
Definition: pes.h:89
replex::inflength
uint64_t inflength
Definition: replex.h:49
LIMIT
#define LIMIT
find_pes_ids
static void find_pes_ids(struct replex *rx)
Definition: replex.cpp:1564
PRIVATE_STREAM1
#define PRIVATE_STREAM1
Definition: pes.h:23
ring_posdiff
static int ring_posdiff(ringbuffer *rbuf, int pos1, int pos2)
Definition: ringbuffer.h:87
replex_tsp
static int replex_tsp(struct replex *rx, uint8_t *tsp)
Definition: replex.cpp:1163
index_unit::frame_start
uint8_t frame_start
Definition: mpg_common.h:48
replex::audio_state
int audio_state[N_AUDIO]
Definition: replex.h:106
avi_audio_s::fps
uint32_t fps
Definition: avi.h:51
ring_init
int ring_init(ringbuffer *rbuf, int size)
Definition: ringbuffer.cpp:38
CLOCK_MS
#define CLOCK_MS
Definition: element.h:78
sequence_t::current_frame
uint8_t current_frame
Definition: element.h:105
ptsdec
static void ptsdec(uint64_t *pts1, uint64_t pts2)
Definition: pes.h:122
avi_context::ai
avi_audio_info ai[MAX_TRACK]
Definition: avi.h:99
pes.h
error
static void error(const char *str,...)
Definition: vbi.cpp:42
REPLEX_PS
#define REPLEX_PS
Definition: replex.h:42
find_audio_sync
int find_audio_sync(ringbuffer *rbuf, audio_sync_buf &buf, int off, int type, int le)
Definition: element.cpp:327
MAX_PLENGTH
#define MAX_PLENGTH
Definition: pes.h:49
replex::extframe
audio_frame_t extframe[N_AUDIO]
Definition: replex.h:77
replex::current_vindex
index_unit current_vindex
Definition: replex.h:113
MAXVPID
#define MAXVPID
Definition: replex.cpp:1344
B_FRAME
#define B_FRAME
Definition: element.h:56
fill_buffers
static int fill_buffers(void *r, int finish)
Definition: replex.cpp:1835
replex::vdr
int vdr
Definition: replex.h:61
replex::demux
int demux
Definition: replex.h:57
ring_peek
int ring_peek(ringbuffer *rbuf, uint8_t *data, unsigned int count, uint32_t off)
Definition: ringbuffer.cpp:122
next_ptsdts_video
uint64_t next_ptsdts_video(uint64_t *pts, sequence_t *s, uint64_t fcount, uint64_t gcount)
Definition: element.cpp:76
find_audio_s
int find_audio_s(const uint8_t *rbuf, int off, int type, int le)
Definition: element.cpp:377
replex::ignore_pts
int ignore_pts
Definition: replex.h:46
ringbuffer
Definition: ringbuffer.h:39
index_unit::gop_off
uint8_t gop_off
Definition: mpg_common.h:46
sequence_t
Definition: element.h:87
SEC_PER
#define SEC_PER
Definition: element.h:80
find_any_header
int find_any_header(uint8_t *head, const uint8_t *buf, int length)
Definition: mpg_common.cpp:107
discid.disc.read
def read(device=None, features=[])
Definition: disc.py:35
get_video_info
int get_video_info(ringbuffer *rbuf, sequence_t *s, int off, int le)
Definition: element.cpp:195
get_pid
uint16_t get_pid(const uint8_t *pid)
Definition: ts.cpp:47
index_unit::seq_end
uint8_t seq_end
Definition: mpg_common.h:42
fix_audio
static void fix_audio(struct replex *rx, multiplex_t *mx)
Definition: replex.cpp:2068
replex::extrbuffer
ringbuffer extrbuffer[N_AUDIO]
Definition: replex.h:78
replex::audiobuf
int audiobuf
Definition: replex.h:70
fix_video_count
void fix_video_count(sequence_t *s, uint64_t *frame, uint64_t origpts, uint64_t pts, uint64_t origdts, uint64_t dts)
Definition: element.cpp:117
avi_context::movi_length
int64_t movi_length
Definition: avi.h:73
VIDEO_STREAM_S
#define VIDEO_STREAM_S
Definition: pes.h:28
init_index
void init_index(index_unit *iu)
Definition: replex.cpp:1845
get_next_video_unit
static int get_next_video_unit(struct replex *rx, index_unit *viu)
Definition: replex.cpp:2128
avi_es_out
static void avi_es_out(pes_in_t *p)
Definition: replex.cpp:1094
replex::ac
avi_context ac
Definition: replex.h:60
replex::exttype
int exttype[N_AUDIO]
Definition: replex.h:75
index_unit::dts
uint64_t dts
Definition: mpg_common.h:40
S_IWGRP
#define S_IWGRP
Definition: replex.cpp:56
pes_es_out
static void pes_es_out(pes_in_t *p)
Definition: replex.cpp:982
get_audio_info
int get_audio_info(ringbuffer *rbuf, audio_frame_t *af, int off, int le)
Definition: element.cpp:483
mythburn.write
def write(text, progress=True)
Definition: mythburn.py:308
audio_frame_t::bit_rate
uint32_t bit_rate
Definition: element.h:112
arg
arg(title).arg(filename).arg(doDelete))
INDEX_BUF
#define INDEX_BUF
Definition: replex.h:69
get_ac3_info
int get_ac3_info(ringbuffer *rbuf, audio_frame_t *af, int off, int le)
Definition: element.cpp:534
replex::first_iframe
int first_iframe
Definition: replex.h:111
replex::aframe_count
uint64_t aframe_count[N_AUDIO]
Definition: replex.h:103
finish_mpg
void finish_mpg(multiplex_t *mx)
Definition: multiplex.cpp:600
replex::fd_in
int fd_in
Definition: replex.h:54
PICTURE_START_CODE
#define PICTURE_START_CODE
Definition: element.h:35
replex::last_ac3pts
uint64_t last_ac3pts[N_AC3]
Definition: replex.h:93
replex::ac3_id
uint16_t ac3_id[N_AC3]
Definition: replex.h:83
MMAX_PLENGTH
#define MMAX_PLENGTH
Definition: pes.h:50
replex::vframe_count
uint64_t vframe_count
Definition: replex.h:117
read_avi_header
int read_avi_header(avi_context *ac, int fd)
Definition: avi.cpp:215
printpts
void printpts(int64_t pts)
Definition: pes.cpp:43
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
replex::video_state
int video_state
Definition: replex.h:121
find_pids_file
static void find_pids_file(struct replex *rx)
Definition: replex.cpp:1292
init_multiplex
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)
Definition: multiplex.cpp:678
fix_audio_count
void fix_audio_count(uint64_t *acount, audio_frame_t *aframe, uint64_t origpts, uint64_t pts)
Definition: element.cpp:65
ring_read_file
int ring_read_file(ringbuffer *rbuf, int fd, int count)
Definition: ringbuffer.cpp:300
REPLEX_HDTV
#define REPLEX_HDTV
Definition: multiplex.h:45
replex::current_ac3index
index_unit current_ac3index[N_AC3]
Definition: replex.h:85
I_FRAME
#define I_FRAME
Definition: element.h:54
avi_read_index
int avi_read_index(avi_context *ac, int fd)
Definition: avi.cpp:142
replex::vpes_abort
int vpes_abort
Definition: replex.h:114
replex::index_vrbuffer
ringbuffer index_vrbuffer
Definition: replex.h:116
replex::keep_pts
int keep_pts
Definition: replex.h:47
hardwareprofile.scan.scan
def scan(profile, smoonURL, gate)
Definition: scan.py:57
VIDEO_BUF
#define VIDEO_BUF
Definition: replex.h:66
sequence_t::set
int set
Definition: element.h:88
index_unit::seq_header
uint8_t seq_header
Definition: mpg_common.h:41
replex::avi_rest
int avi_rest
Definition: replex.h:52
MPEG_AUDIO
@ MPEG_AUDIO
Definition: element.h:84
replex::lastper
int lastper
Definition: replex.h:51
check_audio_header
int check_audio_header(ringbuffer *rbuf, audio_frame_t *af, int off, int le, int type)
Definition: element.cpp:419
P_FRAME
#define P_FRAME
Definition: element.h:55
ptsdiff
int64_t ptsdiff(uint64_t pts1, uint64_t pts2)
Definition: pes.cpp:78
do_replex
static void do_replex(struct replex *rx)
Definition: replex.cpp:2340
AVI_HASINDEX
#define AVI_HASINDEX
Definition: avi.h:37
replex::current_aindex
index_unit current_aindex[N_AUDIO]
Definition: replex.h:99
replex::ac3_state
int ac3_state[N_AUDIO]
Definition: replex.h:92
lseek
#define lseek
Definition: mythiowrapper.cpp:236
pes_id_out
static void pes_id_out(pes_in_t *p)
Definition: replex.cpp:1502
guess_fill
static int guess_fill(struct replex *rx)
Definition: replex.cpp:1247
multiplex_t::ext
ext_arr ext
Definition: multiplex.h:79
index_unit::frame_off
uint8_t frame_off
Definition: mpg_common.h:47
replex::last_vpts
uint64_t last_vpts
Definition: replex.h:122
AVFrame
struct AVFrame AVFrame
Definition: BorderDetector.h:15
avi_video_s::fps
uint32_t fps
Definition: avi.h:63
SEQUENCE_END_CODE
#define SEQUENCE_END_CODE
Definition: element.h:45
index_unit::active
uint8_t active
Definition: mpg_common.h:36
analyze_audio
static void analyze_audio(pes_in_t *p, struct replex *rx, int len, int num, int type)
Definition: replex.cpp:233
mythlogging.h
replex::ac3frame
audio_frame_t ac3frame[N_AC3]
Definition: replex.h:90
replex::vrbuffer
ringbuffer vrbuffer
Definition: replex.h:115
replex::fix_sync
int fix_sync
Definition: replex.h:48
trans_pts_dts
uint64_t trans_pts_dts(const uint8_t *pts)
Definition: mpg_common.cpp:143
replex::scan_found
int scan_found
Definition: replex.h:125
do_analyze
static void do_analyze(struct replex *rx)
Definition: replex.cpp:2160
replex::finish
int finish
Definition: replex.h:56
replex::index_arbuffer
ringbuffer index_arbuffer[N_AUDIO]
Definition: replex.h:102
FRAME_ERR
#define FRAME_ERR
Definition: mpg_common.h:67
hardwareprofile.config.p
p
Definition: config.py:33
audio_sync_buf
std::array< uint8_t, 7 > audio_sync_buf
Definition: element.h:123
index_unit::start
uint32_t start
Definition: mpg_common.h:38
hardwareprofile.i18n.t
t
Definition: i18n.py:36
PTS_ONLY
#define PTS_ONLY
Definition: pes.h:46
MAXAC3PID
#define MAXAC3PID
Definition: replex.cpp:1346
avi_context::done
int done
Definition: avi.h:75
N_AUDIO
#define N_AUDIO
Definition: multiplex.h:35
replex::itype
int itype
Definition: replex.h:44
replex::first_vpts
uint64_t first_vpts
Definition: replex.h:120
sequence_t::current_tmpref
uint8_t current_tmpref
Definition: element.h:106
AUDIO_BUF
#define AUDIO_BUF
Definition: replex.h:67
ADAPT_FIELD
#define ADAPT_FIELD
Definition: ts.h:42
REPLEX_DVD
#define REPLEX_DVD
Definition: multiplex.h:44
replex::last_apts
uint64_t last_apts[N_AUDIO]
Definition: replex.h:107
PAY_START
#define PAY_START
Definition: ts.h:35
replex::index_ac3rbuffer
ringbuffer index_ac3rbuffer[N_AC3]
Definition: replex.h:88
find_pids
int find_pids(uint16_t *vpid, uint16_t *apid, uint16_t *ac3pid, uint8_t *buf, int len)
Definition: ts.cpp:127
replex::vpid
uint16_t vpid
Definition: replex.h:110
replex::ac3buf
int ac3buf
Definition: replex.h:71
get_avi_from_index
int get_avi_from_index(pes_in_t *p, int fd, avi_context *ac, void(*func)(pes_in_t *p), uint32_t insize)
Definition: avi.cpp:426
filename
QString filename
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:637
avi_context::avih_flags
uint32_t avih_flags
Definition: avi.h:83
audio_frame_t::frequency
uint32_t frequency
Definition: element.h:113
get_next_audio_unit
static int get_next_audio_unit(struct replex *rx, index_unit *aiu, int i)
Definition: replex.cpp:2138
S_IWOTH
#define S_IWOTH
Definition: replex.cpp:58
S_SEARCH
@ S_SEARCH
Definition: replex.h:38
replex_fill_buffers
static int replex_fill_buffers(struct replex *rx, uint8_t *mbuf)
Definition: replex.cpp:1689
find_pids_pos
int find_pids_pos(uint16_t *vpid, uint16_t *apid, uint16_t *ac3pid, uint8_t *buf, int len, int *vpos, int *apos, int *ac3pos)
Definition: ts.cpp:57
check_times
void check_times(multiplex_t *mx, int *video_ok, aok_arr &ext_ok, int *start)
Definition: multiplex.cpp:485
audio_frame_t::set
int set
Definition: element.h:110
replex_all_set
static int replex_all_set(struct replex *rx)
Definition: replex.cpp:1851
audio_frame_t::frametime
uint32_t frametime
Definition: element.h:118
index_unit::frame
uint8_t frame
Definition: mpg_common.h:45
replex::otype
int otype
Definition: replex.h:45
replex::pac3
pes_in_t pac3[N_AC3]
Definition: replex.h:84
ringbuffer::size
uint32_t size
Definition: ringbuffer.h:42
ring_write
int ring_write(ringbuffer *rbuf, uint8_t *data, int count)
Definition: ringbuffer.cpp:90
add_pts_audio
uint64_t add_pts_audio(uint64_t pts, audio_frame_t *aframe, uint64_t frames)
Definition: element.cpp:56
AUDIO_STREAM_E
#define AUDIO_STREAM_E
Definition: pes.h:27
usage
static void usage(char *progname)
Definition: replex.cpp:2398
replex::priv
void * priv
Definition: replex.h:124
S_IRGRP
#define S_IRGRP
Definition: replex.cpp:55
replex::exttypcnt
int exttypcnt[N_AUDIO]
Definition: replex.h:76
do_scan
static void do_scan(struct replex *rx)
Definition: replex.cpp:2273
O_LARGEFILE
#define O_LARGEFILE
Definition: replex.cpp:46
sequence_t::ext_set
int ext_set
Definition: element.h:89
get_next_ac3_unit
static int get_next_ac3_unit(struct replex *rx, index_unit *aiu, int i)
Definition: replex.cpp:2148
encode_mp2_audio
static int encode_mp2_audio(audio_frame_t *aframe, uint8_t *buffer, int bufsize)
Definition: replex.cpp:174
MAX_TRIES
#define MAX_TRIES
replex::finread
uint64_t finread
Definition: replex.h:50
replex_check_id
static int replex_check_id(struct replex *rx, uint16_t id)
Definition: replex.cpp:69
N_AC3
#define N_AC3
Definition: multiplex.h:36
replex::ac3rbuffer
ringbuffer ac3rbuffer[N_AC3]
Definition: replex.h:87
ring_wpos
static int ring_wpos(ringbuffer *rbuf)
Definition: ringbuffer.h:77
es_out
static void es_out(pes_in_t *p)
Definition: replex.cpp:912
index_unit::err
uint8_t err
Definition: mpg_common.h:49
IN_SIZE
#define IN_SIZE
Definition: replex.cpp:1291
index_unit::framesize
uint32_t framesize
Definition: mpg_common.h:50
get_pes
void get_pes(pes_in_t *p, uint8_t *buf, int count, void(*func)(pes_in_t *p))
Definition: pes.cpp:164
replex::ac3n
int ac3n
Definition: replex.h:82
replex::index_extrbuffer
ringbuffer index_extrbuffer[N_AUDIO]
Definition: replex.h:79
replex::video_delay
uint64_t video_delay
Definition: replex.h:63
replex::videobuf
int videobuf
Definition: replex.h:72
index_unit::gop
uint8_t gop
Definition: mpg_common.h:43
uptsdiff
uint64_t uptsdiff(uint64_t pts1, uint64_t pts2)
Definition: pes.cpp:104
SEQUENCE_HDR_CODE
#define SEQUENCE_HDR_CODE
Definition: element.h:42
ring_read
int ring_read(ringbuffer *rbuf, uint8_t *data, int count)
Definition: ringbuffer.cpp:200
AC3_BUF
#define AC3_BUF
Definition: replex.h:68
replex::arbuffer
ringbuffer arbuffer[N_AUDIO]
Definition: replex.h:101
REPLEX_MPEG2
#define REPLEX_MPEG2
Definition: multiplex.h:43
write_out_packs
void write_out_packs(multiplex_t *mx, int video_ok, aok_arr &ext_ok)
Definition: multiplex.cpp:581
ring_find_any_header
int ring_find_any_header(ringbuffer *rbuf, uint8_t *head, int off, int le)
Definition: mpg_common.cpp:216
replex::apid
uint16_t apid[N_AUDIO]
Definition: replex.h:97
avi_context
Definition: avi.h:70
init_pes_in
void init_pes_in(pes_in_t *p, int t, ringbuffer *rb, int wi)
Definition: pes.cpp:146
check_stream_type
static int check_stream_type(struct replex *rx, uint8_t *buf, int len)
Definition: replex.cpp:1869
get_avi
void get_avi(pes_in_t *p, uint8_t *buf, int count, void(*func)(pes_in_t *p))
Definition: avi.cpp:525
replex::fd_out
int fd_out
Definition: replex.h:55
VIDEO_STREAM_E
#define VIDEO_STREAM_E
Definition: pes.h:29
avcodec_encode_audio
static int avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, const short *samples)
Definition: replex.cpp:87
find_pids_stdin
static void find_pids_stdin(struct replex *rx, uint8_t *buf, int len)
Definition: replex.cpp:1439
replex
Definition: replex.h:40
ring_avail
static unsigned int ring_avail(ringbuffer *rbuf)
Definition: ringbuffer.h:108
save_read
static ssize_t save_read(struct replex *rx, void *buf, size_t count)
Definition: replex.cpp:1212
replex::analyze
int analyze
Definition: replex.h:59
AUDIO_STREAM_S
#define AUDIO_STREAM_S
Definition: pes.h:26
replex::apes_abort
int apes_abort[N_AUDIO]
Definition: replex.h:100
ring_skip
int ring_skip(ringbuffer *rbuf, int count)
Definition: ringbuffer.cpp:233
AC3
@ AC3
Definition: element.h:84
PICTURE_CODING_EXTENSION
#define PICTURE_CODING_EXTENSION
Definition: element.h:50
replex::seq_head
sequence_t seq_head
Definition: replex.h:119
setup_multiplex
void setup_multiplex(multiplex_t *mx)
Definition: multiplex.cpp:837
replex::audio_delay
uint64_t audio_delay
Definition: replex.h:64
main
int main(int argc, char **argv)
Definition: replex.cpp:2421
check_riff
int check_riff(avi_context *ac, uint8_t *buf, int len)
Definition: avi.cpp:79
MAXAPID
#define MAXAPID
Definition: replex.cpp:1345
get_video_ext_info
int get_video_ext_info(ringbuffer *rbuf, sequence_t *s, int off, int le)
Definition: element.cpp:591
replex::apidn
int apidn
Definition: replex.h:96
do_demux
static void do_demux(struct replex *rx)
Definition: replex.cpp:2303
audio_frame_t::framesize
uint32_t framesize
Definition: element.h:117
uint16_t
unsigned short uint16_t
Definition: iso6937tables.h:3
ptscmp
int ptscmp(uint64_t pts1, uint64_t pts2)
Definition: pes.cpp:114
REPLEX_AVI
#define REPLEX_AVI
Definition: replex.h:43
audio_frame_t
Definition: element.h:109
replex::aframe
audio_frame_t aframe[N_AUDIO]
Definition: replex.h:104
TS_SIZE
#define TS_SIZE
Definition: hlsstreamhandler.cpp:19
replex::dmx_out
int dmx_out[N_AC3+N_AUDIO+1]
Definition: replex.h:58
printptss
void printptss(int64_t pts)
Definition: pes.cpp:60
replex::ac3pes_abort
int ac3pes_abort[N_AC3]
Definition: replex.h:86
avi_audio_s::initial_frames
uint32_t initial_frames
Definition: avi.h:53
multiplex_t
Definition: multiplex.h:41
pes_in_t
Definition: pes.h:70
analyze_video
static void analyze_video(pes_in_t *p, struct replex *rx, int len)
Definition: replex.cpp:509
PTS_DTS
#define PTS_DTS
Definition: pes.h:47
avi_context::vi
avi_video_info vi
Definition: avi.h:98
GROUP_START_CODE
#define GROUP_START_CODE
Definition: element.h:46
multiplex_t::priv
void * priv
Definition: multiplex.h:88
index_unit
Definition: mpg_common.h:35
REPLEX_TS
#define REPLEX_TS
Definition: replex.h:41
init_replex
static void init_replex(struct replex *rx)
Definition: replex.cpp:1918
samples
static const std::array< const uint64_t, 4 > samples
Definition: element.cpp:46
replex::first_apts
uint64_t first_apts[N_AUDIO]
Definition: replex.h:105
replex::vgroup_count
uint64_t vgroup_count
Definition: replex.h:118
show_buf
void show_buf(uint8_t *buf, int length)
Definition: mpg_common.cpp:37
replex::first_ac3pts
uint64_t first_ac3pts[N_AC3]
Definition: replex.h:91
replex.h
AVI_S
#define AVI_S
replex_finish
static void replex_finish(struct replex *rx)
Definition: replex.cpp:1673
index_unit::pts
uint64_t pts
Definition: mpg_common.h:39
aok_arr
std::array< bool, N_AUDIO > aok_arr
Definition: multiplex.h:39
replex::paudio
pes_in_t paudio[N_AUDIO]
Definition: replex.h:98
find_all_pids_file
static void find_all_pids_file(struct replex *rx)
Definition: replex.cpp:1347
S_IROTH
#define S_IROTH
Definition: replex.cpp:57
replex::pvideo
pes_in_t pvideo
Definition: replex.h:112
EXTENSION_START_CODE
#define EXTENSION_START_CODE
Definition: element.h:44
index_unit::length
uint32_t length
Definition: mpg_common.h:37
ring_rdiff
static int ring_rdiff(ringbuffer *rbuf, int pos)
Definition: ringbuffer.h:97
replex::ac3frame_count
uint64_t ac3frame_count[N_AC3]
Definition: replex.h:89