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  uint8_t buf[7];
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  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, (uint8_t *) buf, 7,
749  off+c+pos) < 0){
750  rx->vpes_abort = len -(c+pos-1);
751  return;
752  }
753 #ifdef IN_DEBUG
754  int hour = (int)((buf[4]>>2)& 0x1F);
755  int min = (int)(((buf[4]<<4)& 0x30)|
756  ((buf[5]>>4)& 0x0F));
757  int sec = (int)(((buf[5]<<3)& 0x38)|
758  ((buf[6]>>5)& 0x07));
759  LOG(VB_GENERAL, LOG_DEBUG,
760  QString(" gop %1:%2.%3 %4")
761  .arg(hour,2,10,QChar('0'))
762  .arg(min, 2,10,QChar('0'))
763  .arg(sec, 2,10,QChar('0'))
764  .arg((p->ini_pos+c+pos)%rx->videobuf));
765 #endif
766  rx->vgroup_count = 0;
767 
768  break;
769  }
770 
771  case PICTURE_START_CODE:{
772  if (len-(c+pos) < 14){
773  rx->vpes_abort = len - (pos-1+c);
774  return;
775  }
776 
777  if (ring_peek(rbuf, (uint8_t *) buf, 6,
778  off+c+pos) < 0) return;
779 
780 
781  frame = ((buf[5]&0x38) >>3);
782 
783  if (frame == I_FRAME){
784  if( !rx->first_iframe){
785  if (s->set){
786  rx->first_iframe = 1;
787  } else {
788  s->set=0;
789  flush = 0;
790  break;
791  }
792  }
793  }
794 
795  frame_off = c+pos - seq_p;
796  if (s->set){
797  if (!seq_h && !gop) flush = 1;
798  }
799  tempref = (buf[5]>>6) & 0x03;
800  tempref |= buf[4] << 2;
801 
802  switch (frame){
803  case I_FRAME:
804 #ifdef ANA
805  LOG(VB_GENERAL, LOG_DEBUG, "I");
806 #endif
807 #ifdef IN_DEBUG
808  LOG(VB_GENERAL, LOG_DEBUG,
809  QString(" I-frame %1")
810  .arg((p->ini_pos+c+pos)%rx->videobuf));
811 #endif
812  break;
813  case B_FRAME:
814 #ifdef ANA
815  LOG(VB_GENERAL, LOG_DEBUG, "B");
816 #endif
817 #ifdef IN_DEBUG
818  LOG(VB_GENERAL, LOG_DEBUG,
819  QString(" B-frame %1")
820  .arg((p->ini_pos+c+pos)%rx->videobuf));
821 #endif
822  break;
823  case P_FRAME:
824 #ifdef ANA
825  LOG(VB_GENERAL, LOG_DEBUG, "P");
826 #endif
827 #ifdef IN_DEBUG
828  LOG(VB_GENERAL, LOG_DEBUG,
829  QString(" P-frame %1")
830  .arg((p->ini_pos+c+pos)%rx->videobuf));
831 #endif
832  break;
833  }
834  s->current_frame = frame;
835  s->current_tmpref = tempref;
836 
837  break;
838  }
839  default:
840 #ifdef IN_DEBUG
841 #if 0
842  LOG(VB_GENERAL, LOG_ERR,
843  QString("other header 0x%1 (%2+%3)")
844  .arg(head, 2,16,QChar('0')).arg(c).arg(pos));
845 #endif
846 #endif
847  break;
848  }
849 
850  if (flush && s->set && rx->first_iframe){
851  if(iu->active){
852  rx->vframe_count++;
853  rx->vgroup_count++;
854 
855  iu->length = ring_posdiff(rbuf,
856  iu->start,
857  p->ini_pos+
858  pos+c-frame_off);
859 
860  if ( ring_write(index_buf, (uint8_t *)
861  &rx->current_vindex,
862  sizeof(index_unit))<0){
863  LOG(VB_GENERAL, LOG_ERR,
864  "video ring buffer overrun error");
865  exit(1);
866 
867  }
868  }
870  flush = 0;
871  iu->active = 1;
872  if (!rx->ignore_pts){
873  if ((p->flag2 & PTS_DTS) == PTS_DTS){
874  iu->pts = trans_pts_dts(p->pts);
875  iu->dts = trans_pts_dts(p->dts);
876  } else if (p->flag2 & PTS_ONLY){
877  iu->pts = trans_pts_dts(p->pts);
878  }
879  }
880  iu->start = (p->ini_pos+pos+c-frame_off)
881  %rx->videobuf;
882 #ifdef IN_DEBUG
883  LOG(VB_GENERAL, LOG_DEBUG,
884  QString("START %1").arg(iu->start));
885 #endif
886  }
887 
888  if (s->set){
889  if (frame)
890  iu->frame = (frame&0xFF);
891  if (seq_h)
892  iu->seq_header = 1;
893  if (seq_end)
894  iu->seq_end = 1;
895  if (gop)
896  iu->gop = 1;
897  if (gop_off)
898  iu->gop_off = gop_off;
899  if (frame_off)
900  iu->frame_off = frame_off;
901  }
902  c+=pos+4;
903  } else {
904  if (pos == -2){
905  rx->vpes_abort = 4;
906 
907  }
908  c = len;
909  }
910  }
911 }
912 
913 static void es_out(pes_in_t *p)
914 {
915 
916  struct replex *rx;
917  char t[80];
918  int len;
919 
920  len = p->plength-3-p->hlength;
921 
922  rx = (struct replex *) p->priv;
923 
924  switch(p->type)
925  {
926  case 0xE0: {
927  sprintf(t, "Video ");
928  if (rx->vpes_abort){
929  p->ini_pos = (p->ini_pos - rx->vpes_abort)%rx->vrbuffer.size;
930  len += rx->vpes_abort;
931  }
932  analyze_video(p, rx, len);
933  if (!rx->seq_head.set){
934  ring_skip(&rx->vrbuffer, len);
935  }
936  break;
937  }
938 
939  case 1 ... 32:{
940  int l;
941  l = p->type - 1;
942  sprintf(t, "Audio%d ", l);
943  if (rx->apes_abort[l]){
944  p->ini_pos = (p->ini_pos - rx->apes_abort[l])
945  %rx->arbuffer[l].size;
946  len += rx->apes_abort[l];
947  }
948  analyze_audio(p, rx, len, l, MPEG_AUDIO);
949  if (!rx->aframe[l].set)
950  ring_skip(&rx->arbuffer[l], len);
951 
952  break;
953  }
954 
955  case 0x80 ... 0x87:{
956  int l;
957  l = p->type - 0x80;
958  sprintf(t, "AC3 %d ", p->type);
959  if (rx->ac3pes_abort[l]){
960  p->ini_pos = (p->ini_pos - rx->ac3pes_abort[l])
961  %rx->ac3rbuffer[l].size;
962  len += rx->ac3pes_abort[l];
963  }
964  analyze_audio(p, rx, len, l, AC3);
965  if (!rx->ac3frame[l].set)
966  ring_skip(&rx->ac3rbuffer[l], len);
967  break;
968  }
969 
970  default:
971  LOG(VB_GENERAL, LOG_ERR,
972  QString("UNKNOWN AUDIO type %1").arg(p->type));
973  return;
974 
975 
976  }
977 
978 #ifdef IN_DEBUG
979  LOG(VB_GENERAL, LOG_DEBUG, QString("%1 PES").arg(t));
980 #endif
981 }
982 
983 static void pes_es_out(pes_in_t *p)
984 {
985 
986  struct replex *rx;
987  char t[80];
988  int len, i;
989  int l=0;
990 
991  len = p->plength-3-p->hlength;
992  rx = (struct replex *) p->priv;
993 
994  switch(p->cid){
996  if (rx->vpid != p->cid) break;
997  p->type = 0xE0;
998  p->ini_pos = ring_wpos(&rx->vrbuffer);
999 
1000  if (ring_write(&rx->vrbuffer, p->buf+9+p->hlength, len)<0){
1001  LOG(VB_GENERAL, LOG_ERR,
1002  "video ring buffer overrun error");
1003  exit(1);
1004  }
1005  if (rx->vpes_abort){
1006  p->ini_pos = (p->ini_pos - rx->vpes_abort)%rx->vrbuffer.size;
1007  len += rx->vpes_abort;
1008  }
1009  sprintf(t, "Video ");
1010  analyze_video(p, rx, len);
1011  if (!rx->seq_head.set){
1012  ring_skip(&rx->vrbuffer, len);
1013  }
1014  break;
1015 
1016  case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1017  p->type = p->cid - 0xc0 + 1;
1018  l = -1;
1019  for (i=0; i<rx->apidn; i++)
1020  if (p->cid == rx->apid[i])
1021  l = i;
1022  if (l < 0) break;
1023  p->ini_pos = ring_wpos(&rx->arbuffer[l]);
1024  if (ring_write(&rx->arbuffer[l], p->buf+9+p->hlength, len)<0){
1025  LOG(VB_GENERAL, LOG_ERR,
1026  "video ring buffer overrun error");
1027  exit(1);
1028  }
1029  if (rx->apes_abort[l]){
1030  p->ini_pos = (p->ini_pos - rx->apes_abort[l])
1031  %rx->arbuffer[l].size;
1032  len += rx->apes_abort[l];
1033  }
1034 
1035  sprintf(t, "Audio%d ", l);
1036  analyze_audio(p, rx, len, l, MPEG_AUDIO);
1037  if (!rx->aframe[l].set)
1038  ring_skip(&rx->arbuffer[l], len);
1039 
1040  break;
1041 
1042  case PRIVATE_STREAM1:{
1043  int hl=4;
1044  if (rx->vdr){
1045  hl=0;
1046  p->type=0x80;
1047  l = 0;
1048  } else {
1049  uint16_t fframe;
1050 
1051  fframe=0;
1052  fframe = p->buf[9+p->hlength+3];
1053  fframe |= (p->buf[9+p->hlength+2]<<8);
1054 
1055  if (fframe > p->plength) break;
1056 
1057  p->type = p->buf[9+p->hlength];
1058  l = -1;
1059  for (i=0; i<rx->ac3n; i++)
1060  if (p->type == rx->ac3_id[i])
1061  l = i;
1062  if (l < 0) break;
1063  }
1064  len -= hl;
1065  p->ini_pos = ring_wpos(&rx->ac3rbuffer[l]);
1066 
1067  if (ring_write(&rx->ac3rbuffer[l], p->buf+9+hl+p->hlength, len)<0){
1068  LOG(VB_GENERAL, LOG_ERR,
1069  "video ring buffer overrun error");
1070  exit(1);
1071  }
1072  if (rx->ac3pes_abort[l]){
1073  p->ini_pos = (p->ini_pos - rx->ac3pes_abort[l])
1074  %rx->ac3rbuffer[l].size;
1075  len += rx->ac3pes_abort[l];
1076  }
1077 
1078  sprintf(t, "AC3 %d ", p->type);
1079  analyze_audio(p, rx, len, l, AC3);
1080  sprintf(t,"%d",rx->ac3frame[l].set);
1081  if (!rx->ac3frame[l].set)
1082  ring_skip(&rx->ac3rbuffer[l], len);
1083  }
1084  break;
1085 
1086  default:
1087  return;
1088  }
1089 
1090 #ifdef IN_DEBUG
1091  LOG(VB_GENERAL, LOG_DEBUG, QString("%1 PES %2").arg(t).arg(len));
1092 #endif
1093 }
1094 
1095 static void avi_es_out(pes_in_t *p)
1096 {
1097 
1098  struct replex *rx;
1099  char t[80];
1100  int len;
1101 
1102  len = p->plength;
1103 
1104  rx = (struct replex *) p->priv;
1105 
1106 
1107  switch(p->type)
1108  {
1109  case 0xE0: {
1110  sprintf(t, "Video ");
1111  if (!len){
1112  rx->vframe_count++;
1113  break;
1114  }
1115  analyze_video(p, rx, len);
1116  if (!rx->seq_head.set){
1117  ring_skip(&rx->vrbuffer, len);
1118  }
1119  break;
1120  }
1121 
1122  case 1 ... 32:{
1123  int l;
1124  l = p->type - 1;
1125  sprintf(t, "Audio%d ", l);
1126  if (!len){
1127  rx->aframe_count[l]++;
1128  break;
1129  }
1130  analyze_audio(p, rx, len, l, MPEG_AUDIO);
1131  if (!rx->aframe[l].set)
1132  ring_skip(&rx->arbuffer[l], len);
1133 
1134  break;
1135  }
1136 
1137  case 0x80 ... 0x87:{
1138  int l;
1139 
1140  l = p->type - 0x80;
1141  sprintf(t, "AC3 %d ", p->type);
1142  if (!len){
1143  rx->ac3frame_count[l]++;
1144  break;
1145  }
1146  analyze_audio(p, rx, len, l, AC3);
1147  if (!rx->ac3frame[l].set)
1148  ring_skip(&rx->ac3rbuffer[l], len);
1149  break;
1150  }
1151 
1152  default:
1153  return;
1154 
1155 
1156  }
1157 #ifdef IN_DEBUG
1158  LOG(VB_GENERAL, LOG_DEBUG, QString("%1 PES").arg(t));
1159 #endif
1160 
1161 }
1162 
1163 
1164 static int replex_tsp(struct replex *rx, uint8_t *tsp)
1165 {
1166  uint16_t pid;
1167  int type;
1168  int off=0;
1169  pes_in_t *p=nullptr;
1170 
1171  pid = get_pid(tsp+1);
1172 
1173  if ((type=replex_check_id(rx, pid))<0)
1174  return 0;
1175 
1176  switch(type){
1177  case 0:
1178  p = &rx->pvideo;
1179  break;
1180 
1181  case 1 ... 32:
1182  p = &rx->paudio[type-1];
1183  break;
1184 
1185  case 0x80 ... 0x87:
1186  p = &rx->pac3[type-0x80];
1187  break;
1188  default:
1189  return 0;
1190 
1191  }
1192 
1193 
1194  if ( tsp[1] & PAY_START) {
1195  if (p->plength == MMAX_PLENGTH-6){
1196  p->plength = p->found-6;
1197  es_out(p);
1198  init_pes_in(p, p->type, nullptr, 0);
1199  }
1200  }
1201 
1202  if ( tsp[3] & ADAPT_FIELD) { // adaptation field?
1203  off = tsp[4] + 1;
1204  if (off+4 >= TS_SIZE) return 0;
1205  }
1206 
1207  get_pes(p, tsp+4+off, TS_SIZE-4-off, es_out);
1208 
1209  return 0;
1210 }
1211 
1212 
1213 static ssize_t save_read(struct replex *rx, void *buf, size_t count)
1214 {
1215  ssize_t neof = 1;
1216  size_t re = 0;
1217  int fd = rx->fd_in;
1218 
1219  if (rx->itype== REPLEX_AVI){
1220  int l = rx->inflength - rx->finread;
1221  if ( l <= 0) return 0;
1222  if ( (int) count > l) count = l;
1223  }
1224  while(neof >= 0 && re < count){
1225  neof = read(fd, ((char*)buf)+re, count - re);
1226  if (neof > 0) re += neof;
1227  else break;
1228  }
1229  rx->finread += re;
1230 #ifndef OUT_DEBUG
1231  if (rx->inflength){
1232  uint8_t per=0;
1233 
1234  per = (uint8_t)(rx->finread*100/rx->inflength);
1235  if (per % 10 == 0 && rx->lastper < per){
1236  LOG(VB_GENERAL, LOG_DEBUG, QString("read %1%%")
1237  .arg(per,3));
1238  rx->lastper = per;
1239  }
1240  } else
1241  LOG(VB_GENERAL, LOG_DEBUG, QString("read %1 MB")
1242  .arg(rx->finread/1024.0/1024.0, 0,'f',2,QChar('0')));
1243 #endif
1244  if (neof < 0 && re == 0) return neof;
1245  else return re;
1246 }
1247 
1248 static int guess_fill( struct replex *rx)
1249 {
1250  int vavail, aavail, ac3avail, i, fill;
1251 
1252  vavail = 0;
1253  ac3avail =0;
1254  aavail = 0;
1255  fill =0;
1256 
1257 #define LIMIT 3
1258  if ((vavail = ring_avail(&rx->index_vrbuffer)/sizeof(index_unit))
1259  < LIMIT)
1260  fill = ring_free(&rx->vrbuffer);
1261 
1262  for (i=0; i<rx->apidn;i++){
1263  if ((aavail = ring_avail(&rx->index_arbuffer[i])
1264  /sizeof(index_unit)) < LIMIT)
1265  if (fill < (int) ring_free(&rx->arbuffer[i]))
1266  fill = ring_free(&rx->arbuffer[i]);
1267  }
1268 
1269  for (i=0; i<rx->ac3n;i++){
1270  if ((ac3avail = ring_avail(&rx->index_ac3rbuffer[i])
1271  /sizeof(index_unit)) < LIMIT)
1272  if (fill < (int) ring_free(&rx->ac3rbuffer[i]))
1273  fill = ring_free(&rx->ac3rbuffer[i]);
1274  }
1275 
1276 #if 0
1277  LOG(VB_GENERAL, LOG_INFO,
1278  QString("free %1 %2 %3 %4")
1279  .arg(fill).arg(vavail).arg(aavail).arg(ac3avail));
1280 #endif
1281 
1282  if (!fill){
1283  if(vavail && (aavail || ac3avail)) return 0;
1284  else return -1;
1285  }
1286 
1287  return fill/2;
1288 }
1289 
1290 
1291 
1292 #define IN_SIZE (1000*TS_SIZE)
1293 static void find_pids_file(struct replex *rx)
1294 {
1295  uint8_t buf[IN_SIZE];
1296  int afound=0;
1297  int vfound=0;
1298  int count=0;
1299  int re=0;
1300  uint16_t vpid=0, apid=0, ac3pid=0;
1301 
1302  LOG(VB_GENERAL, LOG_INFO, "Trying to find PIDs");
1303  while (!afound && !vfound && count < (int) rx->inflength){
1304  if (rx->vpid) vfound = 1;
1305  if (rx->apidn) afound = 1;
1306  if ((re = save_read(rx,buf,IN_SIZE))<0)
1307  LOG(VB_GENERAL, LOG_ERR,
1308  QString("reading: %1").arg(strerror(errno)));
1309  else
1310  count += re;
1311  if ( (re = find_pids(&vpid, &apid, &ac3pid, buf, re))){
1312  if (!rx->vpid && vpid){
1313  rx->vpid = vpid;
1314  LOG(VB_GENERAL, LOG_INFO,QString("vpid 0x%1")
1315  .arg(rx->vpid, 4,16,QChar('0')));
1316  vfound++;
1317  }
1318  if (!rx->apidn && apid){
1319  rx->apid[0] = apid;
1320  LOG(VB_GENERAL, LOG_INFO, QString("apid 0x%1")
1321  .arg(rx->apid[0], 4,16,QChar('0')));
1322  rx->apidn++;
1323  afound++;
1324  }
1325  if (!rx->ac3n && ac3pid){
1326  rx->ac3_id[0] = ac3pid;
1327  LOG(VB_GENERAL, LOG_INFO, QString("ac3pid 0x%1")
1328  .arg(rx->ac3_id[0], 4,16,QChar('0')));
1329  rx->ac3n++;
1330  afound++;
1331  }
1332 
1333  }
1334 
1335  }
1336 
1337  lseek(rx->fd_in,0,SEEK_SET);
1338  if (!afound || !vfound){
1339  LOG(VB_GENERAL, LOG_ERR, "Couldn't find all pids");
1340  exit(1);
1341  }
1342 
1343 }
1344 
1345 #define MAXVPID 16
1346 #define MAXAPID 32
1347 #define MAXAC3PID 16
1348 static void find_all_pids_file(struct replex *rx)
1349 {
1350  uint8_t buf[IN_SIZE];
1351  int count=0;
1352  int j;
1353  int re=0;
1354  uint16_t vpid[MAXVPID], apid[MAXAPID], ac3pid[MAXAC3PID];
1355  int vn=0, an=0,ac3n=0;
1356  uint16_t vp,ap,cp;
1357  int vpos, apos, cpos;
1358 
1359  memset (vpid , 0 , MAXVPID*sizeof(uint16_t));
1360  memset (apid , 0 , MAXAPID*sizeof(uint16_t));
1361  memset (ac3pid , 0 , MAXAC3PID*sizeof(uint16_t));
1362 
1363  LOG(VB_GENERAL, LOG_INFO, "Trying to find PIDs");
1364  while (count < (int) rx->inflength-IN_SIZE){
1365  if ((re = save_read(rx,buf,IN_SIZE))<0)
1366  LOG(VB_GENERAL, LOG_ERR, QString("reading: %1")
1367  .arg(strerror(errno)));
1368  else
1369  count += re;
1370  if ( (re = find_pids_pos(&vp, &ap, &cp, buf, re,
1371  &vpos, &apos, &cpos))){
1372  if (vp){
1373  int old=0;
1374  for (j=0; j < vn; j++){
1375 #if 0
1376  LOG(VB_GENERAL, LOG_INFO,
1377  QString("%1. %2").arg(j+1).arg(vpid[j]));
1378 #endif
1379  if (vpid[j] == vp){
1380  old = 1;
1381  break;
1382  }
1383  }
1384  if (!old){
1385  vpid[vn]=vp;
1386 
1387  LOG(VB_GENERAL, LOG_INFO,
1388  QString("vpid %1: 0x%2 (%3) PES ID: 0x%4")
1389  .arg(vn+1)
1390  .arg(vpid[vn], 4,16,QChar('0'))
1391  .arg(vpid[vn])
1392  .arg(buf[vpos], 2,16,QChar('0')));
1393  if (vn+1 < MAXVPID) vn++;
1394  }
1395  }
1396 
1397  if (ap){
1398  int old=0;
1399  for (j=0; j < an; j++)
1400  if (apid[j] == ap){
1401  old = 1;
1402  break;
1403  }
1404  if (!old){
1405  apid[an]=ap;
1406  LOG(VB_GENERAL, LOG_INFO,
1407  QString("apid %1: 0x%2 (%3) PES ID: 0x%4")
1408  .arg(an +1)
1409  .arg(apid[an], 4,16,QChar('0'))
1410  .arg(apid[an])
1411  .arg(buf[apos], 2,16,QChar('0')));
1412  if (an+1 < MAXAPID) an++;
1413  }
1414  }
1415 
1416  if (cp){
1417  int old=0;
1418  for (j=0; j < ac3n; j++)
1419  if (ac3pid[j] == cp){
1420  old = 1;
1421  break;
1422  }
1423  if (!old){
1424  ac3pid[ac3n]=cp;
1425  LOG(VB_GENERAL, LOG_INFO,
1426  QString("ac3pid %1: 0x%2 (%3)")
1427  .arg(ac3n+1)
1428  .arg(ac3pid[ac3n], 4,16,QChar('0'))
1429  .arg(ac3pid[ac3n]));
1430  if (ac3n+1< MAXAC3PID) ac3n++;
1431  }
1432  }
1433  }
1434 
1435  }
1436 
1437  lseek(rx->fd_in,0,SEEK_SET);
1438 }
1439 
1440 static void find_pids_stdin(struct replex *rx, uint8_t *buf, int len)
1441 {
1442  int afound=0;
1443  int vfound=0;
1444  uint16_t vpid=0, apid=0, ac3pid=0;
1445 
1446  if (rx->vpid) vfound = 1;
1447  if (rx->apidn) afound = 1;
1448  LOG(VB_GENERAL, LOG_INFO, "Trying to find PIDs");
1449  if ( find_pids(&vpid, &apid, &ac3pid, buf, len) ){
1450  if (!rx->vpid && vpid){
1451  rx->vpid = vpid;
1452  vfound++;
1453  }
1454  if (!rx->apidn && apid){
1455  rx->apid[0] = apid;
1456  rx->apidn++;
1457  afound++;
1458  ring_init(&rx->arbuffer[0], rx->audiobuf);
1459  init_pes_in(&rx->paudio[0], 1, &rx->arbuffer[0], 0);
1460  rx->paudio[0].priv = (void *) rx;
1461  ring_init(&rx->index_arbuffer[0], INDEX_BUF);
1462  memset(&rx->aframe[0], 0, sizeof(audio_frame_t));
1463  init_index(&rx->current_aindex[0]);
1464  rx->aframe_count[0] = 0;
1465  rx->first_apts[0] = 0;
1466  }
1467 
1468  if (!rx->ac3n && ac3pid){
1469  rx->ac3_id[0] = ac3pid;
1470  rx->ac3n++;
1471  afound++;
1472  ring_init(&rx->ac3rbuffer[0], AC3_BUF);
1473  init_pes_in(&rx->pac3[0], 0x80, &rx->ac3rbuffer[0],0);
1474  rx->pac3[0].priv = (void *) rx;
1476  memset(&rx->ac3frame[0], 0, sizeof(audio_frame_t));
1477  init_index(&rx->current_ac3index[0]);
1478  rx->ac3frame_count[0] = 0;
1479  rx->first_ac3pts[0] = 0;
1480  }
1481 
1482  }
1483 
1484  if (afound && vfound){
1485  LOG(VB_GENERAL, LOG_INFO, "found");
1486  if (rx->vpid)
1487  LOG(VB_GENERAL, LOG_INFO, QString("vpid %1 (0x%2)")
1488  .arg(rx->vpid).arg(rx->vpid, 4,16,QChar('0')));
1489  if (rx->apidn)
1490  LOG(VB_GENERAL, LOG_INFO, QString("apid %1 (0x%2)")
1491  .arg(rx->apid[0]).arg(rx->apid[0], 4,16,QChar('0')));
1492  if (rx->ac3n)
1493  LOG(VB_GENERAL, LOG_INFO, QString("ac3pid %1 (0x%2)")
1494  .arg(rx->ac3_id[0]).arg(rx->ac3_id[0], 4,16,QChar('0')));
1495  } else {
1496  LOG(VB_GENERAL, LOG_ERR, "Couldn't find pids");
1497  exit(1);
1498  }
1499 
1500 }
1501 
1502 
1503 static void pes_id_out(pes_in_t *p)
1504 {
1505 
1506 // int len = p->plength-3-p->hlength;
1507  struct replex *rx = (struct replex *) p->priv;
1508 
1509  rx->scan_found=0;
1510  switch(p->cid){
1511  case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1512  rx->scan_found=p->cid;
1513  break;
1514 
1515  case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1516  rx->scan_found=p->cid;
1517  break;
1518 
1519  case PRIVATE_STREAM1:
1520  if (rx->vdr){
1521  rx->scan_found = 0x80;
1522  break;
1523  } else {
1524 
1525  uint8_t id = p->buf[9+p->hlength];
1526  switch(id){
1527  case 0x80 ... 0x8f:
1528  {
1529  int c=0;
1530  uint16_t fframe;
1531 
1532  fframe=0;
1533  fframe = p->buf[9+p->hlength+3];
1534  fframe |= (p->buf[9+p->hlength+2]<<8);
1535 
1536  if (fframe < p->plength){
1537  if ((c=find_audio_s(p->buf,
1538  9+p->hlength+4+fframe,
1539  AC3, p->plength+6)) >= 0){
1540  rx->scan_found = id;
1541 #if 0
1542  LOG(VB_GENERAL, LOG_INFO,
1543  QString("0x%1 0x%2 \n")
1544  .arg(c-9-p->hlength-4, 4,16,QChar('0'))
1545  .arg(fframe, 4,16,QChar('0')));
1546  if (id>0x80)show_buf(p->buf+9+p->hlength,8);
1547  if (id>0x80)show_buf(p->buf+c,8);
1548 #endif
1549  }
1550  }
1551  break;
1552  }
1553  }
1554  break;
1555  }
1556  default:
1557  p->cid = 0;
1558  p->type = 0;
1559  rx->scan_found=0;
1560  memset(p->buf,0,MAX_PLENGTH*sizeof(uint8_t));
1561  return;
1562  }
1563 }
1564 
1565 static void find_pes_ids(struct replex *rx)
1566 {
1567  uint8_t buf[IN_SIZE];
1568  int count=0;
1569  int j;
1570  int re=0;
1571  uint16_t vpid[MAXVPID], apid[MAXAPID], ac3pid[MAXAC3PID];
1572  int vn=0, an=0,ac3n=0;
1573 
1574  memset (vpid , 0 , MAXVPID*sizeof(uint16_t));
1575  memset (apid , 0 , MAXAPID*sizeof(uint16_t));
1576  memset (ac3pid , 0 , MAXAC3PID*sizeof(uint16_t));
1577 
1578  LOG(VB_GENERAL, LOG_INFO, "Trying to find PES IDs");
1579  rx->scan_found=0;
1580  rx->pvideo.priv = rx ;
1581  while (count < (int) rx->inflength-IN_SIZE){
1582  if ((re = save_read(rx,buf,IN_SIZE))<0)
1583  LOG(VB_GENERAL, LOG_ERR, QString("reading: %1")
1584  .arg(strerror(errno)));
1585  else
1586  count += re;
1587 
1588  get_pes(&rx->pvideo, buf, re, pes_id_out);
1589 
1590  if ( rx->scan_found ){
1591 
1592  switch (rx->scan_found){
1593 
1594  case VIDEO_STREAM_S ... VIDEO_STREAM_E:
1595  {
1596  int old=0;
1597  for (j=0; j < vn; j++){
1598 #if 0
1599  LOG(VB_GENERAL, LOG_INFO,
1600  QString("%1. %2").arg(j+1).arg(vpid[j]));
1601 #endif
1602  if (vpid[j] == rx->scan_found){
1603  old = 1;
1604  break;
1605  }
1606  }
1607  if (!old){
1608  vpid[vn]=rx->scan_found;
1609 
1610  LOG(VB_GENERAL, LOG_INFO,
1611  QString("MPEG VIDEO %1: 0x%2 (%3)")
1612  .arg(vn+1)
1613  .arg(vpid[vn], 2,16,QChar('0'))
1614  .arg(vpid[vn]));
1615  if (vn+1 < MAXVPID) vn++;
1616  }
1617  }
1618  break;
1619 
1620 
1621  case AUDIO_STREAM_S ... AUDIO_STREAM_E:
1622  {
1623  int old=0;
1624  for (j=0; j < an; j++)
1625  if (apid[j] == rx->scan_found){
1626  old = 1;
1627  break;
1628  }
1629  if (!old){
1630  apid[an]=rx->scan_found;
1631  LOG(VB_GENERAL, LOG_INFO,
1632  QString("MPEG AUDIO %1: 0x%2 (%3)")
1633  .arg(an +1)
1634  .arg(apid[an], 2,16,QChar('0'))
1635  .arg(apid[an]));
1636  if (an+1 < MAXAPID) an++;
1637  }
1638  }
1639  break;
1640 
1641  case 0x80 ... 0x8f:
1642  {
1643  int old=0;
1644  for (j=0; j < ac3n; j++)
1645  if (ac3pid[j] == rx->scan_found){
1646  old = 1;
1647  break;
1648  }
1649  if (!old){
1650  ac3pid[ac3n]=rx->scan_found;
1651  if (rx->vdr){
1652  LOG(VB_GENERAL, LOG_INFO,
1653  "possible AC3 AUDIO with private stream 1 pid (0xbd)");
1654  }else{
1655  LOG(VB_GENERAL, LOG_INFO,
1656  QString("AC3 AUDIO %1: 0x%2 (%3)")
1657  .arg(ac3n+1)
1658  .arg(ac3pid[ac3n], 2,16,QChar('0'))
1659  .arg(ac3pid[ac3n]));
1660  }
1661  if (ac3n+1< MAXAC3PID) ac3n++;
1662  }
1663  rx->scan_found = 0;
1664  }
1665  break;
1666  }
1667  rx->scan_found = 0;
1668  }
1669  }
1670 }
1671 
1672 
1673 
1674 static void replex_finish(struct replex *rx)
1675 {
1676  if (!replex_all_set(rx)){
1677  LOG(VB_GENERAL, LOG_ERR, "Can't find all required streams");
1678  if (rx->itype == REPLEX_PS){
1679  LOG(VB_GENERAL, LOG_ERR,
1680  "Please check if audio and video have standard IDs (0xc0 or 0xe0)");
1681  }
1682  exit(1);
1683  }
1684 
1685  if (!rx->demux)
1686  finish_mpg((multiplex_t *)rx->priv);
1687  exit(0);
1688 }
1689 
1690 static int replex_fill_buffers(struct replex *rx, uint8_t *mbuf)
1691 {
1692  uint8_t buf[IN_SIZE];
1693  int i,j;
1694  int count=0;
1695  int fill;
1696  int re;
1697  int rsize;
1698  int tries = 0;
1699 
1700  if (rx->finish) return 0;
1701  fill = guess_fill(rx);
1702 #if 0
1703  LOG(VB_GENERAL, LOG_INFO,
1704  QString("trying to fill buffers with %1").arg(fill));
1705 #endif
1706  if (fill < 0) return -1;
1707 
1708  memset(buf, 0, IN_SIZE);
1709 
1710  switch(rx->itype){
1711  case REPLEX_TS:
1712  if (fill < IN_SIZE){
1713  rsize = fill - (fill%188);
1714  } else rsize = IN_SIZE;
1715 
1716 #if 0
1717  LOG(VB_GENERAL, LOG_INFO, QString("filling with %1").arg(rsize));
1718 #endif
1719 
1720  if (!rsize) return 0;
1721 
1722  memset(buf, 0, IN_SIZE);
1723 
1724  if ( mbuf ){
1725  for ( i = 0; i < 188 ; i++){
1726  if ( mbuf[i] == 0x47 ) break;
1727  }
1728 
1729  if ( i == 188){
1730  LOG(VB_GENERAL, LOG_ERR, "Not a TS");
1731  return -1;
1732  } else {
1733  memcpy(buf,mbuf+i,2*TS_SIZE-i);
1734  if ((count = save_read(rx,mbuf,i))<0)
1735  LOG(VB_GENERAL, LOG_ERR, QString("reading: %1")
1736  .arg(strerror(errno)));
1737  memcpy(buf+2*TS_SIZE-i,mbuf,i);
1738  i = 188;
1739  }
1740  } else i=0;
1741 
1742 
1743 #define MAX_TRIES 5
1744  while (count < rsize && tries < MAX_TRIES){
1745  if ((re = save_read(rx,buf+i,rsize-i)+i)<0)
1746  LOG(VB_GENERAL, LOG_ERR, QString("reading: %1")
1747  .arg(strerror(errno)));
1748  else
1749  count += re;
1750  tries++;
1751 
1752  if (!rx->vpid || !(rx->apidn || rx->ac3n)){
1753  find_pids_stdin(rx, buf, re);
1754  }
1755 
1756  for( j = 0; j < re; j+= TS_SIZE){
1757 
1758  if ( re - j < TS_SIZE) break;
1759 
1760  if ( replex_tsp( rx, buf+j) < 0){
1761  LOG(VB_GENERAL, LOG_ERR,
1762  "Error reading TS");
1763  exit(1);
1764  }
1765  }
1766  i=0;
1767  }
1768 
1769  if (tries == MAX_TRIES)
1770  replex_finish(rx);
1771  return 0;
1772  break;
1773 
1774  case REPLEX_PS:
1775  rsize = fill;
1776  if (fill > IN_SIZE) rsize = IN_SIZE;
1777  if (mbuf)
1778  get_pes(&rx->pvideo, mbuf, 2*TS_SIZE, pes_es_out);
1779 
1780  while (count < rsize && tries < MAX_TRIES){
1781  if ((re = save_read(rx, buf, rsize))<0)
1782  LOG(VB_GENERAL, LOG_ERR, QString("reading PS: %1")
1783  .arg(strerror(errno)));
1784  else
1785  count += re;
1786 
1787  get_pes(&rx->pvideo, buf, re, pes_es_out);
1788 
1789  tries++;
1790 
1791  }
1792 
1793  if (tries == MAX_TRIES)
1794  replex_finish(rx);
1795  return 0;
1796  break;
1797 
1798 
1799  case REPLEX_AVI:
1800  rsize = fill;
1801  if (fill > IN_SIZE) rsize = IN_SIZE;
1802 
1803  if (!(rx->ac.avih_flags & AVI_HASINDEX)){
1804 
1805  if (mbuf){
1806  get_avi(&rx->pvideo, mbuf, rx->avi_rest, avi_es_out);
1807  }
1808 
1809  while (count < rsize && tries < MAX_TRIES){
1810  if ((re = save_read(rx, buf, rsize))<0)
1811  LOG(VB_GENERAL, LOG_ERR,
1812  QString("reading AVI: %1")
1813  .arg(strerror(errno)));
1814  else
1815  count += re;
1816 
1817  get_avi(&rx->pvideo, buf, re, avi_es_out);
1818 
1819  tries++;
1820  }
1821  } else {
1822  if (get_avi_from_index(&rx->pvideo, rx->fd_in,
1823  &rx->ac, avi_es_out, rsize) < 0)
1824  tries = MAX_TRIES;
1825  }
1826 
1827  if (tries == MAX_TRIES)
1828  replex_finish(rx);
1829  return 0;
1830  break;
1831  }
1832 
1833  return -1;
1834 }
1835 
1836 static int fill_buffers(void *r, int finish)
1837 {
1838  struct replex *rx = (struct replex *)r;
1839 
1840  rx->finish = finish;
1841 
1842  return replex_fill_buffers(rx, nullptr);
1843 }
1844 
1845 
1847 {
1848  memset(iu,0, sizeof(index_unit));
1849  iu->frame_start = 1;
1850 }
1851 
1852 static int replex_all_set(struct replex *rx)
1853 {
1854  int i;
1855  int set=0;
1856 
1857  for (i=0; i < rx->ac3n ;i++){
1858  set += rx->ac3frame[i].set;
1859  }
1860  for (i=0; i<rx->apidn;i++){
1861  set += rx->aframe[i].set;
1862  }
1863  set += rx->seq_head.set;
1864 
1865  if (set == (rx->ac3n+ rx->apidn + 1)) return 1;
1866  return 0;
1867 }
1868 
1869 
1870 static int check_stream_type(struct replex *rx, uint8_t * buf, int len)
1871 {
1872  int c=0;
1873  avi_context ac;
1874  uint8_t head;
1875 
1876  if (rx->itype != REPLEX_TS) return rx->itype;
1877 
1878  if (len< 2*TS_SIZE){
1879  LOG(VB_GENERAL, LOG_ERR, "cannot determine streamtype");
1880  exit(1);
1881  }
1882 
1883  LOG(VB_GENERAL, LOG_INFO, "Checking for TS: ");
1884  while (c < len && buf[c]!=0x47) c++;
1885  if (c<len && len-c>=TS_SIZE){
1886  if (buf[c+TS_SIZE] == 0x47){
1887  LOG(VB_GENERAL, LOG_INFO, "confirmed");
1888  return REPLEX_TS;
1889  } else LOG(VB_GENERAL, LOG_INFO, "failed");
1890  } else LOG(VB_GENERAL, LOG_INFO, "failed");
1891 
1892  LOG(VB_GENERAL, LOG_INFO, "Checking for AVI: ");
1893  if (check_riff(&ac, buf, len)>=0){
1894  LOG(VB_GENERAL, LOG_INFO, "confirmed");
1895  rx->itype = REPLEX_AVI;
1896  rx->vpid = 0xE0;
1897  rx->apidn = 1;
1898  rx->apid[0] = 0xC0;
1899  rx->ignore_pts =1;
1900  return REPLEX_AVI;
1901  } else LOG(VB_GENERAL, LOG_INFO, "failed");
1902 
1903  LOG(VB_GENERAL, LOG_INFO, "Checking for PS: ");
1904  if (find_any_header(&head, buf, len) >= 0){
1905  LOG(VB_GENERAL, LOG_INFO, "confirmed(maybe)");
1906  } else {
1907  LOG(VB_GENERAL, LOG_INFO,"failed, trying it anyway");
1908  }
1909  rx->itype=REPLEX_PS;
1910  if (!rx->vpid) rx->vpid = 0xE0;
1911  if (!(rx->apidn || rx->ac3n)){
1912  rx->apidn = 1;
1913  rx->apid[0] = 0xC0;
1914  }
1915  return REPLEX_PS;
1916 }
1917 
1918 
1919 static void init_replex(struct replex *rx)
1920 {
1921  int i;
1922  uint8_t mbuf[2*TS_SIZE];
1923 
1924  rx->analyze=0;
1925 
1926  if (save_read(rx, mbuf, 2*TS_SIZE)<0)
1927  LOG(VB_GENERAL, LOG_ERR,
1928  QString("reading: %1").arg(strerror(errno)));
1929 
1930  check_stream_type(rx, mbuf, 2*TS_SIZE);
1931  if (rx->itype == REPLEX_TS){
1932  if (!rx->vpid || !(rx->apidn || rx->ac3n)){
1933  if (rx->inflength){
1934  find_pids_file(rx);
1935  }
1936  }
1937  }
1938 
1939 
1940  if (rx->otype==REPLEX_HDTV){
1941  rx->videobuf = 4*VIDEO_BUF;
1942  } else {
1943  rx->videobuf = VIDEO_BUF;
1944  }
1945  rx->audiobuf = AUDIO_BUF;
1946  rx->ac3buf = AC3_BUF;
1947 
1948  if (rx->itype == REPLEX_AVI){
1949  rx->videobuf = 4*VIDEO_BUF;
1950  rx->audiobuf = 2*rx->videobuf;
1951  }
1952 
1953  rx->vpes_abort = 0;
1954  rx->first_iframe = 0;
1955  ring_init(&rx->vrbuffer, rx->videobuf);
1956  if (rx->itype == REPLEX_TS || rx->itype == REPLEX_AVI)
1957  init_pes_in(&rx->pvideo, 0xE0, &rx->vrbuffer, 0);
1958  else {
1959  init_pes_in(&rx->pvideo, 0, nullptr, 1);
1960  }
1961  rx->pvideo.priv = (void *) rx;
1963  memset(&rx->seq_head, 0, sizeof(sequence_t));
1964  init_index(&rx->current_vindex);
1965  rx->vgroup_count = 0;
1966  rx->vframe_count = 0;
1967  rx->first_vpts = 0;
1968  rx->video_state = S_SEARCH;
1969  rx->last_vpts = 0;
1970 
1971  for (i=0; i<rx->apidn;i++){
1972 
1973  rx->apes_abort[i] = 0;
1974  rx->audio_state[i] = S_SEARCH;
1975  ring_init(&rx->arbuffer[i], rx->audiobuf);
1976 
1977  if (rx->itype == REPLEX_TS){
1978  init_pes_in(&rx->paudio[i], i+1,
1979  &rx->arbuffer[i], 0);
1980  rx->paudio[i].priv = (void *) rx;
1981  }
1982  ring_init(&rx->index_arbuffer[i], INDEX_BUF);
1983  memset(&rx->aframe[i], 0, sizeof(audio_frame_t));
1984  init_index(&rx->current_aindex[i]);
1985  rx->aframe_count[i] = 0;
1986  rx->first_apts[i] = 0;
1987  rx->last_apts[i] = 0;
1988  }
1989 
1990  for (i=0; i<rx->ac3n;i++){
1991  rx->ac3pes_abort[i] = 0;
1992  rx->ac3_state[i] = S_SEARCH;
1993  ring_init(&rx->ac3rbuffer[i], AC3_BUF);
1994  if (rx->itype == REPLEX_TS){
1995  init_pes_in(&rx->pac3[i], 0x80+i,
1996  &rx->ac3rbuffer[i],0);
1997  rx->pac3[i].priv = (void *) rx;
1998  }
2000  memset(&rx->ac3frame[i], 0, sizeof(audio_frame_t));
2001  init_index(&rx->current_ac3index[i]);
2002  rx->ac3frame_count[i] = 0;
2003  rx->first_ac3pts[i] = 0;
2004  rx->last_ac3pts[i] = 0;
2005  }
2006 
2007  if (rx->itype == REPLEX_TS){
2008  if (replex_fill_buffers(rx, mbuf)< 0) {
2009  LOG(VB_GENERAL, LOG_ERR, "error filling buffer");
2010  exit(1);
2011  }
2012  } else if ( rx->itype == REPLEX_AVI){
2013 #define AVI_S 1024
2014  avi_context *ac;
2015  uint8_t buf[AVI_S];
2016  int re=0;
2017  ssize_t read_count = 0;
2018 
2019  lseek(rx->fd_in, 0, SEEK_SET);
2020  ac = &rx->ac;
2021  memset(ac, 0, sizeof(avi_context));
2022  if ((read_count = save_read(rx, buf, 12)) != 12) {
2023  LOG(VB_GENERAL, LOG_ERR,
2024  QString("Error reading in 12 bytes from replex. Read %1 bytes")
2025  .arg(read_count));
2026  exit(1);
2027  }
2028 
2029  if (check_riff(ac, buf, 12) < 0){
2030  LOG(VB_GENERAL, LOG_ERR, "Wrong RIFF header");
2031  exit(1);
2032  } else {
2033  LOG(VB_GENERAL, LOG_INFO, "Found RIFF header");
2034  }
2035 
2036  memset(ac, 0, sizeof(avi_context));
2037  re = read_avi_header(ac, rx->fd_in);
2038  if (avi_read_index(ac,rx->fd_in) < 0 || re < 0){
2039  LOG(VB_GENERAL, LOG_ERR, "Error reading index");
2040  exit(1);
2041  }
2042 // rx->aframe_count[0] = ac->ai[0].initial_frames;
2043  rx->vframe_count = ac->ai[0].initial_frames*ac->vi.fps/
2044  ac->ai[0].fps;
2045 
2046  rx->inflength = lseek(rx->fd_in, 0, SEEK_CUR)+ac->movi_length;
2047 
2048  LOG(VB_GENERAL, LOG_INFO, QString("AVI initial frames %1")
2049  .arg(rx->vframe_count));
2050  if (!ac->done){
2051  LOG(VB_GENERAL, LOG_ERR, "Error reading AVI header");
2052  exit(1);
2053  }
2054 
2055  if (replex_fill_buffers(rx, buf+re)< 0) {
2056  LOG(VB_GENERAL, LOG_ERR, "error filling buffer");
2057  exit(1);
2058  }
2059  } else {
2060  if (replex_fill_buffers(rx, mbuf)< 0) {
2061  LOG(VB_GENERAL, LOG_ERR, "error filling buffer");
2062  exit(1);
2063  }
2064  }
2065 
2066 }
2067 
2068 
2069 static void fix_audio(struct replex *rx, multiplex_t *mx)
2070 {
2071  int i;
2072  index_unit aiu;
2073  int size;
2074 
2075  size = sizeof(index_unit);
2076 
2077  for ( i = 0; i < rx->apidn; i++){
2078  do {
2079  while (ring_avail(&rx->index_arbuffer[i]) <
2080  sizeof(index_unit)){
2081  if (replex_fill_buffers(rx, nullptr)< 0) {
2082  LOG(VB_GENERAL, LOG_ERR,
2083  "error in fix audio");
2084  exit(1);
2085  }
2086  }
2087  ring_peek(&rx->index_arbuffer[i], (uint8_t *)&aiu, size, 0);
2088  if ( ptscmp(aiu.pts + rx->first_apts[i], rx->first_vpts) < 0){
2089  ring_skip(&rx->index_arbuffer[i], size);
2090  ring_skip(&rx->arbuffer[i], aiu.length);
2091  } else break;
2092 
2093  } while (1);
2094  mx->ext[i].pts_off = aiu.pts;
2095 
2096  LOG(VB_GENERAL, LOG_INFO, QString("Audio%1 offset: ").arg(i));
2097  printpts(mx->ext[i].pts_off);
2098  printpts(rx->first_apts[i]+mx->ext[i].pts_off);
2099  }
2100 
2101  for ( i = 0; i < rx->ac3n; i++){
2102  do {
2103  while (ring_avail(&rx->index_ac3rbuffer[i]) <
2104  sizeof(index_unit)){
2105  if (replex_fill_buffers(rx, nullptr)< 0) {
2106  LOG(VB_GENERAL, LOG_ERR,
2107  "error in fix audio");
2108  exit(1);
2109  }
2110  }
2111  ring_peek(&rx->index_ac3rbuffer[i], (uint8_t *)&aiu,
2112  size, 0);
2113  if ( ptscmp (aiu.pts+rx->first_ac3pts[i], rx->first_vpts) < 0){
2114  ring_skip(&rx->index_ac3rbuffer[i], size);
2115  ring_skip(&rx->ac3rbuffer[i], aiu.length);
2116  } else break;
2117  } while (1);
2118  mx->ext[i].pts_off = aiu.pts;
2119 
2120  LOG(VB_GENERAL, LOG_INFO, QString("AC3%1 offset: ").arg(i));
2121  printpts(mx->ext[i].pts_off);
2122  printpts(rx->first_ac3pts[i]+mx->ext[i].pts_off);
2123 
2124  }
2125 }
2126 
2127 
2128 
2129 static int get_next_video_unit(struct replex *rx, index_unit *viu)
2130 {
2131  if (ring_avail(&rx->index_vrbuffer)){
2132  ring_read(&rx->index_vrbuffer, (uint8_t *)viu,
2133  sizeof(index_unit));
2134  return 1;
2135  }
2136  return 0;
2137 }
2138 
2139 static int get_next_audio_unit(struct replex *rx, index_unit *aiu, int i)
2140 {
2141  if(ring_avail(&rx->index_arbuffer[i])){
2142  ring_read(&rx->index_arbuffer[i], (uint8_t *)aiu,
2143  sizeof(index_unit));
2144  return 1;
2145  }
2146  return 0;
2147 }
2148 
2149 static int get_next_ac3_unit(struct replex *rx, index_unit *aiu, int i)
2150 {
2151  if (ring_avail(&rx->index_ac3rbuffer[i])) {
2152  ring_read(&rx->index_ac3rbuffer[i], (uint8_t *)aiu,
2153  sizeof(index_unit));
2154 
2155  return 1;
2156  }
2157  return 0;
2158 }
2159 
2160 
2161 static void do_analyze(struct replex *rx)
2162 {
2163  index_unit dummy;
2164  index_unit dummy2;
2165  int i;
2166  uint64_t lastvpts;
2167  uint64_t lastvdts;
2168  uint64_t lastapts[N_AUDIO];
2169  uint64_t lastac3pts[N_AC3];
2170  int av;
2171 
2172  av = rx->analyze-1;
2173 
2174  lastvpts = 0;
2175  lastvdts = 0;
2176  memset(lastapts, 0, N_AUDIO*sizeof(uint64_t));
2177  memset(lastac3pts, 0, N_AC3*sizeof(uint64_t));
2178 
2179  LOG(VB_GENERAL, LOG_INFO, "STARTING ANALYSIS");
2180 
2181 
2182  while(!rx->finish){
2183  if (replex_fill_buffers(rx, nullptr)< 0) {
2184  LOG(VB_GENERAL, LOG_ERR,
2185  "error in get next video unit");
2186  return;
2187  }
2188  for (i=0; i< rx->apidn; i++){
2189  while(get_next_audio_unit(rx, &dummy2, i)){
2190  ring_skip(&rx->arbuffer[i],
2191  dummy2.length);
2192  if (av>=1){
2193  LOG(VB_GENERAL, LOG_INFO,
2194  QString("MPG2 Audio%1 unit: length %2 PTS ")
2195  .arg(i).arg(dummy2.length));
2196  printptss(dummy2.pts);
2197 
2198  if (lastapts[i]){
2199  LOG(VB_GENERAL, LOG_INFO,
2200  " diff:");
2201  printptss(ptsdiff(dummy2.pts,lastapts[i]));
2202  }
2203  lastapts[i] = dummy2.pts;
2204  }
2205  }
2206  }
2207 
2208  for (i=0; i< rx->ac3n; i++){
2209  while(get_next_ac3_unit(rx, &dummy2, i)){
2210  ring_skip(&rx->ac3rbuffer[i],
2211  dummy2.length);
2212  if (av>=1){
2213  LOG(VB_GENERAL, LOG_INFO,
2214  QString("AC3 Audio%1 unit: length %2 PTS ")
2215  .arg(i).arg(dummy2.length));
2216  printptss(dummy2.pts);
2217  if (lastac3pts[i]){
2218  LOG(VB_GENERAL, LOG_INFO,
2219  " diff:");
2220  printptss(ptsdiff(dummy2.pts, lastac3pts[i]));
2221  }
2222  lastac3pts[i] = dummy2.pts;
2223  }
2224  }
2225  }
2226 
2227  while (get_next_video_unit(rx, &dummy)){
2228  ring_skip(&rx->vrbuffer,
2229  dummy.length);
2230  if (av==0 || av==2){
2231  LOG(VB_GENERAL, LOG_INFO, "Video unit: ");
2232  if (dummy.seq_header){
2233  LOG(VB_GENERAL, LOG_INFO,
2234  "Sequence header ");
2235  }
2236  if (dummy.gop){
2237  LOG(VB_GENERAL, LOG_INFO,
2238  "GOP header ");
2239  }
2240  switch (dummy.frame){
2241  case I_FRAME:
2242  LOG(VB_GENERAL, LOG_INFO, "I-frame");
2243  break;
2244  case B_FRAME:
2245  LOG(VB_GENERAL, LOG_INFO, "B-frame");
2246  break;
2247  case P_FRAME:
2248  LOG(VB_GENERAL, LOG_INFO, "P-frame");
2249  break;
2250  }
2251  LOG(VB_GENERAL, LOG_INFO, QString(" length %1 PTS ")
2252  .arg(dummy.length));
2253  printptss(dummy.pts);
2254  if (lastvpts){
2255  LOG(VB_GENERAL, LOG_INFO," diff:");
2256  printptss(ptsdiff(dummy.pts, lastvpts));
2257  }
2258  lastvpts = dummy.pts;
2259 
2260  LOG(VB_GENERAL, LOG_INFO, " DTS ");
2261  printptss(dummy.dts);
2262  if (lastvdts){
2263  LOG(VB_GENERAL, LOG_INFO, " diff:");
2264  printptss(ptsdiff(dummy.dts,lastvdts));
2265  }
2266  lastvdts = dummy.dts;
2267  }
2268  }
2269  }
2270 
2271 
2272 }
2273 
2274 static void do_scan(struct replex *rx)
2275 {
2276  uint8_t mbuf[2*TS_SIZE];
2277 
2278  rx->analyze=0;
2279 
2280  if (save_read(rx, mbuf, 2*TS_SIZE)<0)
2281  LOG(VB_GENERAL, LOG_ERR, QString("reading: %1")
2282  .arg(strerror(errno)));
2283 
2284  LOG(VB_GENERAL, LOG_INFO, "STARTING SCAN");
2285 
2286  check_stream_type(rx, mbuf, 2*TS_SIZE);
2287 
2288  switch(rx->itype){
2289  case REPLEX_TS:
2290  find_all_pids_file(rx);
2291  break;
2292 
2293  case REPLEX_PS:
2294  init_pes_in(&rx->pvideo, 0, nullptr, 1);
2295  find_pes_ids(rx);
2296  break;
2297 
2298  case REPLEX_AVI:
2299  break;
2300  }
2301 
2302 }
2303 
2304 static void do_demux(struct replex *rx)
2305 {
2306  index_unit dummy;
2307  index_unit dummy2;
2308  int i;
2309  LOG(VB_GENERAL, LOG_INFO, "STARTING DEMUX");
2310 
2311  while(!rx->finish){
2312  if (replex_fill_buffers(rx, nullptr)< 0) {
2313  LOG(VB_GENERAL, LOG_ERR,
2314  "error in get next video unit");
2315  return;
2316  }
2317  for (i=0; i< rx->apidn; i++){
2318  while(get_next_audio_unit(rx, &dummy2, i)){
2319  ring_read_file(&rx->arbuffer[i],
2320  rx->dmx_out[i+1],
2321  dummy2.length);
2322  }
2323  }
2324 
2325  for (i=0; i< rx->ac3n; i++){
2326  while(get_next_ac3_unit(rx, &dummy2, i)){
2327  ring_read_file(&rx->ac3rbuffer[i],
2328  rx->dmx_out[i+1+rx->apidn],
2329  dummy2.length);
2330  }
2331  }
2332 
2333  while (get_next_video_unit(rx, &dummy)){
2334  ring_read_file(&rx->vrbuffer, rx->dmx_out[0],
2335  dummy.length);
2336  }
2337  }
2338 }
2339 
2340 
2341 static void do_replex(struct replex *rx)
2342 {
2343  int video_ok = 0;
2344  int ext_ok[N_AUDIO];
2345  int start=1;
2346  multiplex_t mx;
2347 
2348 
2349  LOG(VB_GENERAL, LOG_INFO, "STARTING REPLEX");
2350  memset(&mx, 0, sizeof(mx));
2351  memset(ext_ok, 0, N_AUDIO*sizeof(int));
2352 
2353  while (!replex_all_set(rx)){
2354  if (replex_fill_buffers(rx, nullptr)< 0) {
2355  LOG(VB_GENERAL, LOG_INFO, "error filling buffer");
2356  exit(1);
2357  }
2358  }
2359 
2360  int i;
2361  for (i = 0; i < rx->apidn; i++){
2362  rx->exttype[i] = 2;
2363  rx->extframe[i] = rx->aframe[i];
2364  rx->extrbuffer[i] = rx->arbuffer[i];
2365  rx->index_extrbuffer[i] = rx->index_arbuffer[i];
2366  rx->exttypcnt[i+1] = i;
2367  }
2368 
2369  int ac3Count = 1;
2370  for (i = rx->apidn; i < rx->apidn + rx->ac3n; i++){
2371  rx->exttype[i] = 1;
2372  rx->extframe[i] = rx->ac3frame[i];
2373  rx->extrbuffer[i] = rx->ac3rbuffer[i];
2374  rx->index_extrbuffer[i] = rx->index_ac3rbuffer[i];
2375  rx->exttypcnt[i] = ac3Count++;
2376  }
2377 
2378  mx.priv = (void *) rx;
2379  rx->priv = (void *) &mx;
2380  init_multiplex(&mx, &rx->seq_head, rx->extframe,
2381  rx->exttype, rx->exttypcnt, rx->video_delay,
2382  rx->audio_delay, rx->fd_out, fill_buffers,
2383  &rx->vrbuffer, &rx->index_vrbuffer,
2384  rx->extrbuffer, rx->index_extrbuffer,
2385  rx->otype);
2386 
2387  if (!rx->ignore_pts){
2388  fix_audio(rx, &mx);
2389  }
2390  setup_multiplex(&mx);
2391 
2392  while(1){
2393  check_times( &mx, &video_ok, ext_ok, &start);
2394 
2395  write_out_packs( &mx, video_ok, ext_ok);
2396  }
2397 }
2398 
2399 
2400 static void usage(char *progname)
2401 {
2402  printf ("usage: %s [options] <input files>\n\n",progname);
2403  printf ("options:\n");
2404  printf (" --help, -h: print help message\n");
2405  printf (" --type, -t: set output type (MPEG2, DVD, HDTV)\n");
2406  printf (" --of, -o: set output file\n");
2407  printf (" --input_stream, -i: set input stream type (TS(default), PS, AVI)\n");
2408  printf (" --audio_pid, -a: audio PID for TS stream (also used for PS id)\n");
2409  printf (" --ac3_id, -c: ID of AC3 audio for demux (also used for PS id)\n");
2410  printf (" --video_pid, -v: video PID for TS stream (also used for PS id)\n");
2411  printf (" --video_delay, -d: video delay in ms\n");
2412  printf (" --audio_delay, -e: audio delay in ms\n");
2413  printf (" --ignore_PTS, -f: ignore all PTS information of original\n");
2414  printf (" --keep_PTS, -k: keep and don't correct PTS information of original\n");
2415  printf (" --fix_sync, -n: try to fix audio sync while demuxing\n");
2416  printf (" --demux, -z: demux only (-o is basename)\n");
2417  printf (" --analyze, -y: analyze (0=video,1=audio, 2=both)\n");
2418  printf (" --scan, -s: scan for streams\n");
2419  printf (" --vdr, -x: handle AC3 for vdr input file\n");
2420  exit(1);
2421 }
2422 
2423 int main(int argc, char **argv)
2424 {
2425  int c;
2426  int analyze=0;
2427  int scan =0;
2428  char *filename = nullptr;
2429  const char *type = "SVCD";
2430  const char *inpt = "TS";
2431 
2432  struct replex rx;
2433 
2434  memset(&rx, 0, sizeof(struct replex));
2435 
2436  while (1) {
2437  int option_index = 0;
2438  static struct option long_options[] = {
2439  {"type", required_argument, nullptr, 't'},
2440  {"input_stream", required_argument, nullptr, 'i'},
2441  {"video_pid", required_argument, nullptr, 'v'},
2442  {"audio_pid", required_argument, nullptr, 'a'},
2443  {"audio_delay", required_argument, nullptr, 'e'},
2444  {"video_delay", required_argument, nullptr, 'd'},
2445  {"ac3_id", required_argument, nullptr, 'c'},
2446  {"of",required_argument, nullptr, 'o'},
2447  {"ignore_PTS",required_argument, nullptr, 'f'},
2448  {"keep_PTS",required_argument, nullptr, 'k'},
2449  {"fix_sync",no_argument, nullptr, 'n'},
2450  {"demux",no_argument, nullptr, 'z'},
2451  {"analyze",required_argument, nullptr, 'y'},
2452  {"scan",required_argument, nullptr, 's'},
2453  {"vdr",required_argument, nullptr, 'x'},
2454  {"help", no_argument , nullptr, 'h'},
2455  {nullptr, 0, nullptr, 0}
2456  };
2457  c = getopt_long (argc, argv,
2458  "t:o:a:v:i:hp:q:d:c:n:fkd:e:zy:sx",
2459  long_options, &option_index);
2460  if (c == -1)
2461  break;
2462 
2463  switch (c) {
2464  case 't':
2465  type = optarg;
2466  break;
2467  case 'i':
2468  inpt = optarg;
2469  break;
2470  case 'd':
2471  rx.video_delay = strtol(optarg,(char **)nullptr, 0)
2472  *CLOCK_MS;
2473  break;
2474  case 'e':
2475  rx.audio_delay = strtol(optarg,(char **)nullptr, 0)
2476  *CLOCK_MS;
2477  break;
2478  case 'a':
2479  if (rx.apidn==N_AUDIO){
2480  LOG(VB_GENERAL, LOG_ERR, "Too many audio PIDs");
2481  exit(1);
2482  }
2483  rx.apid[rx.apidn] = strtol(optarg,(char **)nullptr, 0);
2484  rx.apidn++;
2485  break;
2486  case 'v':
2487  rx.vpid = strtol(optarg,(char **)nullptr, 0);
2488  break;
2489  case 'c':
2490  if (rx.ac3n==N_AC3){
2491  LOG(VB_GENERAL, LOG_ERR, "Too many audio PIDs");
2492  exit(1);
2493  }
2494  rx.ac3_id[rx.ac3n] = strtol(optarg,(char **)nullptr, 0);
2495  rx.ac3n++;
2496  break;
2497  case 'o':
2498  filename = optarg;
2499  break;
2500  case 'f':
2501  rx.ignore_pts =1;
2502  break;
2503  case 'k':
2504  rx.keep_pts =1;
2505  break;
2506  case 'z':
2507  rx.demux =1;
2508  break;
2509  case 'n':
2510  rx.fix_sync =1;
2511  break;
2512  case 'y':
2513  analyze = strtol(optarg,(char **)nullptr, 0);
2514  if (analyze>2) usage(argv[0]);
2515  analyze++;
2516  break;
2517  case 's':
2518  scan = 1;
2519  break;
2520  case 'x':
2521  rx.vdr=1;
2522  break;
2523  case 'h':
2524  case '?':
2525  default:
2526  usage(argv[0]);
2527  }
2528  }
2529 
2530  if (optind == argc-1) {
2531  if ((rx.fd_in = open(argv[optind] ,O_RDONLY| O_LARGEFILE)) < 0) {
2532  perror("Error opening input file ");
2533  exit(1);
2534  }
2535  LOG(VB_GENERAL, LOG_INFO,
2536  QString("Reading from %1").arg(argv[optind]));
2537  rx.inflength = lseek(rx.fd_in, 0, SEEK_END);
2538  LOG(VB_GENERAL, LOG_INFO,
2539  QString("Input file length: %1 MB")
2540  .arg(rx.inflength/1024.0/1024.0, 0,'f',2,QChar('0')));
2541  lseek(rx.fd_in,0,SEEK_SET);
2542  rx.lastper = 0;
2543  rx.finread = 0;
2544  } else {
2545  LOG(VB_GENERAL, LOG_INFO, "using stdin as input");
2546  rx.fd_in = STDIN_FILENO;
2547  rx.inflength = 0;
2548  }
2549 
2550  if (!rx.demux){
2551  if (filename){
2552  if ((rx.fd_out = open(filename,O_WRONLY|O_CREAT
2553  |O_TRUNC|O_LARGEFILE,
2554  S_IRUSR|S_IWUSR|S_IRGRP|
2555  S_IWGRP|
2556  S_IROTH|S_IWOTH)) < 0){
2557  perror("Error opening output file");
2558  exit(1);
2559  }
2560  LOG(VB_GENERAL, LOG_INFO,
2561  QString("Output File is: %1").arg(filename));
2562  } else {
2563  rx.fd_out = STDOUT_FILENO;
2564  LOG(VB_GENERAL, LOG_INFO, "using stdout as output");
2565  }
2566  }
2567  if (scan){
2568  if (rx.fd_in == STDIN_FILENO){
2569  LOG(VB_GENERAL, LOG_ERR, "Can`t scan from pipe");
2570  exit(1);
2571  }
2572  do_scan(&rx);
2573  exit(0);
2574  }
2575 
2576  if (!strncmp(type,"MPEG2",6))
2577  rx.otype=REPLEX_MPEG2;
2578  else if (!strncmp(type,"DVD",4))
2579  rx.otype=REPLEX_DVD;
2580  else if (!strncmp(type,"HDTV",4))
2581  rx.otype=REPLEX_HDTV;
2582  else if (!rx.demux)
2583  usage(argv[0]);
2584 
2585  if (!strncmp(inpt,"TS",3)){
2586  rx.itype=REPLEX_TS;
2587  } else if (!strncmp(inpt,"PS",3)){
2588  rx.itype=REPLEX_PS;
2589  if (!rx.vpid) rx.vpid = 0xE0;
2590  if (!(rx.apidn || rx.ac3n)){
2591  rx.apidn = 1;
2592  rx.apid[0] = 0xC0;
2593  }
2594  } else if (!strncmp(inpt,"AVI",4)){
2595  rx.itype=REPLEX_AVI;
2596  rx.vpid = 0xE0;
2597  rx.apidn = 1;
2598  rx.apid[0] = 0xC0;
2599  rx.ignore_pts =1;
2600  } else {
2601  usage(argv[0]);
2602  }
2603 
2604  init_replex(&rx);
2605  rx.analyze= analyze;
2606 
2607  if (rx.demux) {
2608  int i;
2609  char fname[256];
2610  if (!filename){
2611  filename = static_cast<char*>(malloc(4));
2612  strcpy(filename,"out");
2613  }
2614  if (strlen(filename) > 250){
2615  LOG(VB_GENERAL, LOG_ERR, "Basename too long");
2616  exit(0);
2617  }
2618 
2619  snprintf(fname,256,"%s.mv2",filename);
2620  if ((rx.dmx_out[0] = open(fname,O_WRONLY|
2621  O_CREAT|O_TRUNC|
2622  O_LARGEFILE,
2623  S_IRUSR|S_IWUSR|
2624  S_IRGRP|S_IWGRP|
2625  S_IROTH|S_IWOTH))
2626  < 0){
2627  perror("Error opening output file");
2628  exit(1);
2629  }
2630  LOG(VB_GENERAL, LOG_INFO,
2631  QString("Video output File is: %1").arg(fname));
2632 
2633  for (i=0; i < rx.apidn; i++){
2634  snprintf(fname,256,"%s%d.mp2",filename
2635  ,i);
2636  if ((rx.dmx_out[i+1] =
2637  open(fname,O_WRONLY|
2638  O_CREAT|O_TRUNC|
2639  O_LARGEFILE,
2640  S_IRUSR|S_IWUSR|
2641  S_IRGRP|S_IWGRP|
2642  S_IROTH|S_IWOTH))
2643  < 0){
2644  perror("Error opening output file");
2645  exit(1);
2646  }
2647  LOG(VB_GENERAL, LOG_INFO,
2648  QString("Audio%1 output File is: %2")
2649  .arg(i).arg(fname));
2650  }
2651 
2652 
2653  for (i=0; i < rx.ac3n; i++){
2654  snprintf(fname,256,"%s%d.ac3",filename
2655  ,i);
2656  if ((rx.dmx_out[i+1+rx.apidn] =
2657  open(fname,O_WRONLY|
2658  O_CREAT|O_TRUNC|
2659  O_LARGEFILE,
2660  S_IRUSR|S_IWUSR|
2661  S_IRGRP|S_IWGRP|
2662  S_IROTH|S_IWOTH))
2663  < 0){
2664  perror("Error opening output file");
2665  exit(1);
2666  }
2667  LOG(VB_GENERAL, LOG_INFO,
2668  QString("AC3%1 output File is: %2")
2669  .arg(i).arg(fname));
2670  }
2671  do_demux(&rx);
2672  } else if (analyze){
2673  rx.demux=1;
2674  do_analyze(&rx);
2675  } else {
2676  do_replex(&rx);
2677  }
2678 
2679  return 0;
2680 }
extdata_t::pts_off
uint64_t pts_off
Definition: mpg_common.h:57
ring_free
static unsigned int ring_free(ringbuffer *rbuf)
Definition: ringbuffer.h:92
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:1565
PRIVATE_STREAM1
#define PRIVATE_STREAM1
Definition: pes.h:23
ring_posdiff
static int ring_posdiff(ringbuffer *rbuf, int pos1, int pos2)
Definition: ringbuffer.h:78
replex_tsp
static int replex_tsp(struct replex *rx, uint8_t *tsp)
Definition: replex.cpp:1164
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:77
sequence_t::current_frame
uint8_t current_frame
Definition: element.h:104
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
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
samples
static uint64_t samples[4]
Definition: element.cpp:45
MAXVPID
#define MAXVPID
Definition: replex.cpp:1345
B_FRAME
#define B_FRAME
Definition: element.h:55
fill_buffers
static int fill_buffers(void *r, int finish)
Definition: replex.cpp:1836
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:376
replex::ignore_pts
int ignore_pts
Definition: replex.h:46
ringbuffer
Definition: ringbuffer.h:36
index_unit::gop_off
uint8_t gop_off
Definition: mpg_common.h:46
sequence_t
Definition: element.h:86
SEC_PER
#define SEC_PER
Definition: element.h:79
find_any_header
int find_any_header(uint8_t *head, const uint8_t *buf, int length)
Definition: mpg_common.cpp:116
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:46
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:2069
replex::extrbuffer
ringbuffer extrbuffer[N_AUDIO]
Definition: replex.h:78
find_audio_sync
int find_audio_sync(ringbuffer *rbuf, uint8_t *buf, int off, int type, int le)
Definition: element.cpp:326
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:1846
get_next_video_unit
static int get_next_video_unit(struct replex *rx, index_unit *viu)
Definition: replex.cpp:2129
avi_es_out
static void avi_es_out(pes_in_t *p)
Definition: replex.cpp:1095
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:983
get_audio_info
int get_audio_info(ringbuffer *rbuf, audio_frame_t *af, int off, int le)
Definition: element.cpp:482
mythburn.write
def write(text, progress=True)
Definition: mythburn.py:308
AC3
@ AC3
Definition: element.h:83
audio_frame_t::bit_rate
uint32_t bit_rate
Definition: element.h:111
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:533
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:34
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:42
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:1293
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:679
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:280
REPLEX_HDTV
#define REPLEX_HDTV
Definition: multiplex.h:40
replex::current_ac3index
index_unit current_ac3index[N_AC3]
Definition: replex.h:85
I_FRAME
#define I_FRAME
Definition: element.h:53
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:87
index_unit::seq_header
uint8_t seq_header
Definition: mpg_common.h:41
replex::avi_rest
int avi_rest
Definition: replex.h:52
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:418
P_FRAME
#define P_FRAME
Definition: element.h:54
ptsdiff
int64_t ptsdiff(uint64_t pts1, uint64_t pts2)
Definition: pes.cpp:77
do_replex
static void do_replex(struct replex *rx)
Definition: replex.cpp:2341
write_out_packs
void write_out_packs(multiplex_t *mx, int video_ok, int *ext_ok)
Definition: multiplex.cpp:581
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:1503
guess_fill
static int guess_fill(struct replex *rx)
Definition: replex.cpp:1248
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:44
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:152
replex::scan_found
int scan_found
Definition: replex.h:125
do_analyze
static void do_analyze(struct replex *rx)
Definition: replex.cpp:2161
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
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:1347
avi_context::done
int done
Definition: avi.h:75
N_AUDIO
#define N_AUDIO
Definition: multiplex.h:33
S_SEARCH
@ S_SEARCH
Definition: replex.h:38
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:105
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:39
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:126
replex::vpid
uint16_t vpid
Definition: replex.h:110
av_free
void av_free(void *ptr)
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:634
avi_context::avih_flags
uint32_t avih_flags
Definition: avi.h:83
audio_frame_t::frequency
uint32_t frequency
Definition: element.h:112
get_next_audio_unit
static int get_next_audio_unit(struct replex *rx, index_unit *aiu, int i)
Definition: replex.cpp:2139
S_IWOTH
#define S_IWOTH
Definition: replex.cpp:58
replex_fill_buffers
static int replex_fill_buffers(struct replex *rx, uint8_t *mbuf)
Definition: replex.cpp:1690
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:56
audio_frame_t::set
int set
Definition: element.h:109
replex_all_set
static int replex_all_set(struct replex *rx)
Definition: replex.cpp:1852
audio_frame_t::frametime
uint32_t frametime
Definition: element.h:117
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:39
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:2400
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:2274
O_LARGEFILE
#define O_LARGEFILE
Definition: replex.cpp:46
sequence_t::ext_set
int ext_set
Definition: element.h:88
MPEG_AUDIO
@ MPEG_AUDIO
Definition: element.h:83
get_next_ac3_unit
static int get_next_ac3_unit(struct replex *rx, index_unit *aiu, int i)
Definition: replex.cpp:2149
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:34
replex::ac3rbuffer
ringbuffer ac3rbuffer[N_AC3]
Definition: replex.h:87
ring_wpos
static int ring_wpos(ringbuffer *rbuf)
Definition: ringbuffer.h:68
es_out
static void es_out(pes_in_t *p)
Definition: replex.cpp:913
index_unit::err
uint8_t err
Definition: mpg_common.h:49
IN_SIZE
#define IN_SIZE
Definition: replex.cpp:1292
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:163
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:103
SEQUENCE_HDR_CODE
#define SEQUENCE_HDR_CODE
Definition: element.h:41
ring_read
int ring_read(ringbuffer *rbuf, uint8_t *data, int count)
Definition: ringbuffer.cpp:180
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:38
ring_find_any_header
int ring_find_any_header(ringbuffer *rbuf, uint8_t *head, int off, int le)
Definition: mpg_common.cpp:220
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:145
check_stream_type
static int check_stream_type(struct replex *rx, uint8_t *buf, int len)
Definition: replex.cpp:1870
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:1440
replex
Definition: replex.h:40
ring_avail
static unsigned int ring_avail(ringbuffer *rbuf)
Definition: ringbuffer.h:99
save_read
static ssize_t save_read(struct replex *rx, void *buf, size_t count)
Definition: replex.cpp:1213
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:213
PICTURE_CODING_EXTENSION
#define PICTURE_CODING_EXTENSION
Definition: element.h:49
replex::seq_head
sequence_t seq_head
Definition: replex.h:119
setup_multiplex
void setup_multiplex(multiplex_t *mx)
Definition: multiplex.cpp:838
replex::audio_delay
uint64_t audio_delay
Definition: replex.h:64
main
int main(int argc, char **argv)
Definition: replex.cpp:2423
check_riff
int check_riff(avi_context *ac, uint8_t *buf, int len)
Definition: avi.cpp:79
MAXAPID
#define MAXAPID
Definition: replex.cpp:1346
get_video_ext_info
int get_video_ext_info(ringbuffer *rbuf, sequence_t *s, int off, int le)
Definition: element.cpp:590
replex::apidn
int apidn
Definition: replex.h:96
do_demux
static void do_demux(struct replex *rx)
Definition: replex.cpp:2304
audio_frame_t::framesize
uint32_t framesize
Definition: element.h:116
uint16_t
unsigned short uint16_t
Definition: iso6937tables.h:1
ptscmp
int ptscmp(uint64_t pts1, uint64_t pts2)
Definition: pes.cpp:113
REPLEX_AVI
#define REPLEX_AVI
Definition: replex.h:43
audio_frame_t
Definition: element.h:108
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:59
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:36
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
check_times
void check_times(multiplex_t *mx, int *video_ok, int *ext_ok, int *start)
Definition: multiplex.cpp:485
multiplex_t::ext
extdata_t ext[N_AUDIO]
Definition: multiplex.h:74
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:45
multiplex_t::priv
void * priv
Definition: multiplex.h:83
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:1919
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:1674
index_unit::pts
uint64_t pts
Definition: mpg_common.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:1348
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:43
index_unit::length
uint32_t length
Definition: mpg_common.h:37
ring_rdiff
static int ring_rdiff(ringbuffer *rbuf, int pos)
Definition: ringbuffer.h:88
replex::ac3frame_count
uint64_t ac3frame_count[N_AC3]
Definition: replex.h:89