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