diff --git a/mythtv/programs/mythtranscode/mpeg2fix.cpp b/mythtv/programs/mythtranscode/mpeg2fix.cpp
index c7214d3..d5f161f 100644
a
|
b
|
int MPEG2replex::WaitBuffers() |
495 | 495 | if (done) |
496 | 496 | { |
497 | 497 | finish_mpg(mplex); |
498 | | pthread_exit(NULL); |
| 498 | static int errorcount = 0; // thread exit must return static, not stack |
| 499 | errorcount = mplex->error; |
| 500 | if (mplex->error) { |
| 501 | LOG(VB_GENERAL, LOG_ERR, |
| 502 | QString("twitham: thread finished with %1 write errors") |
| 503 | .arg(mplex->error)); |
| 504 | } |
| 505 | pthread_exit(&errorcount); |
499 | 506 | } |
500 | 507 | |
501 | 508 | return 0; |
… |
… |
void MPEG2replex::Start() |
554 | 561 | while (1) |
555 | 562 | { |
556 | 563 | check_times( &mx, &video_ok, ext_ok, &start); |
557 | | write_out_packs( &mx, video_ok, ext_ok); |
| 564 | if (write_out_packs( &mx, video_ok, ext_ok)) { |
| 565 | // exiting here blocks the reading thread indefinitely; |
| 566 | // maybe there is a way to fail it also? |
| 567 | // LOG(VB_GENERAL, LOG_ERR, // or comment all this to fail until close |
| 568 | // QString("twitham: exiting thread after %1 write errors") |
| 569 | // .arg(mplex->error)); |
| 570 | // pthread_exit(&mplex->error); |
| 571 | } |
558 | 572 | } |
559 | 573 | } |
560 | 574 | |
… |
… |
int MPEG2fixup::Start() |
2555 | 2569 | pthread_mutex_lock( &rx.mutex ); |
2556 | 2570 | pthread_cond_signal(&rx.cond); |
2557 | 2571 | pthread_mutex_unlock( &rx.mutex ); |
2558 | | pthread_join(thread, NULL); |
| 2572 | int ex = REENCODE_OK; |
| 2573 | void *errors; // return error if any write or close failures |
| 2574 | pthread_join(thread, &errors); |
| 2575 | if (*(int *)errors > 0) { |
| 2576 | LOG(VB_GENERAL, LOG_ERR, |
| 2577 | QString("twitham: joined thread failed with %1 write errors") |
| 2578 | .arg(*(int *)errors)); |
| 2579 | ex = REENCODE_ERROR; |
| 2580 | } |
2559 | 2581 | |
2560 | 2582 | avformat_close_input(&inputFC); |
2561 | 2583 | inputFC = NULL; |
2562 | | return REENCODE_OK; |
| 2584 | return ex; |
2563 | 2585 | } |
2564 | 2586 | |
2565 | 2587 | #ifdef NO_MYTH |
diff --git a/mythtv/programs/mythtranscode/replex/multiplex.c b/mythtv/programs/mythtranscode/replex/multiplex.c
index d6cf1a3..09516f6 100644
a
|
b
|
static void writeout_video(multiplex_t *mx) |
295 | 295 | //estimate next pts based on bitrate of this stream and data written |
296 | 296 | viu->dts = uptsdiff(viu->dts + ((nlength*viu->ptsrate)>>8), 0); |
297 | 297 | |
298 | | write(mx->fd_out, outbuf, written); |
| 298 | if (write(mx->fd_out, outbuf, written) != written) { |
| 299 | if (mx->error++ < 10) /* log only first few failures */ |
| 300 | LOG(VB_GENERAL, LOG_ERR, "twitham: %d write failed: %s", |
| 301 | mx->error, strerror(errno)); |
| 302 | } |
299 | 303 | |
300 | 304 | #ifdef OUT_DEBUG |
301 | 305 | LOG(VB_GENERAL, LOG_DEBUG, "VPTS"); |
… |
… |
void check_times( multiplex_t *mx, int *video_ok, int *ext_ok, int *start) |
571 | 575 | } |
572 | 576 | #endif |
573 | 577 | } |
574 | | void write_out_packs( multiplex_t *mx, int video_ok, int *ext_ok) |
| 578 | int write_out_packs( multiplex_t *mx, int video_ok, int *ext_ok) |
575 | 579 | { |
576 | 580 | int i; |
577 | 581 | |
… |
… |
void write_out_packs( multiplex_t *mx, int video_ok, int *ext_ok) |
589 | 593 | writeout_padding(mx); |
590 | 594 | } |
591 | 595 | } |
592 | | |
| 596 | return mx->error || 0; |
593 | 597 | } |
594 | 598 | |
595 | | void finish_mpg(multiplex_t *mx) |
| 599 | int finish_mpg(multiplex_t *mx) |
596 | 600 | { |
597 | 601 | int start=0; |
598 | 602 | int video_ok = 0; |
… |
… |
void finish_mpg(multiplex_t *mx) |
637 | 641 | if (mx->otype == REPLEX_MPEG2) |
638 | 642 | write(mx->fd_out, mpeg_end,4); |
639 | 643 | |
| 644 | if (close(mx->fd_out) < 0) { |
| 645 | mx->error++; |
| 646 | LOG(VB_GENERAL, LOG_ERR, "twitham: %d close failed: %s", |
| 647 | mx->error, strerror(errno)); |
| 648 | } |
| 649 | |
640 | 650 | dummy_destroy(&mx->vdbuf); |
641 | 651 | for (i=0; i<mx->extcnt;i++) |
642 | 652 | dummy_destroy(&mx->ext[i].dbuf); |
| 653 | return mx->error || 0; |
643 | 654 | } |
644 | 655 | |
645 | 656 | static int get_ts_video_overhead(int pktsize, sequence_t *seq) |
… |
… |
void init_multiplex( multiplex_t *mx, sequence_t *seq_head, |
684 | 695 | int i; |
685 | 696 | uint32_t data_rate; |
686 | 697 | |
| 698 | mx->error = 0; |
687 | 699 | mx->fill_buffers = fill_buffers; |
688 | 700 | mx->video_delay = video_delay; |
689 | 701 | mx->audio_delay = audio_delay; |
diff --git a/mythtv/programs/mythtranscode/replex/multiplex.h b/mythtv/programs/mythtranscode/replex/multiplex.h
index 56e2a69..cf4dac3 100644
a
|
b
|
typedef struct multiplex_s{ |
81 | 81 | |
82 | 82 | int (*fill_buffers)(void *p, int f); |
83 | 83 | void *priv; |
| 84 | int error; |
84 | 85 | } multiplex_t; |
85 | 86 | |
86 | 87 | void check_times( multiplex_t *mx, int *video_ok, int *ext_ok, int *start); |
87 | | void write_out_packs( multiplex_t *mx, int video_ok, int *ext_ok); |
88 | | void finish_mpg(multiplex_t *mx); |
| 88 | int write_out_packs( multiplex_t *mx, int video_ok, int *ext_ok); |
| 89 | int finish_mpg(multiplex_t *mx); |
89 | 90 | void init_multiplex( multiplex_t *mx, sequence_t *seq_head, |
90 | 91 | audio_frame_t *extframe, int *exttype, int *exttypcnt, |
91 | 92 | uint64_t video_delay, uint64_t audio_delay, int fd, |