int redundancy_encoder_reset(u_char *state) { red_enc_state *re = (red_enc_state*)state; pb_flush(re->media_buffer); re->units_ready = 0; return TRUE; }
int pb_destroy (pb_t **ppb) { pb_t *pb = *ppb; pb_validate(pb); pb_flush(pb); #ifdef DEBUG if (pb->n_iterators != 0) { debug_msg("Iterators dangling from buffer. Release first.\n"); abort(); } #endif assert(pb->n_iterators == 0); xfree(pb); *ppb = NULL; return TRUE; }
int proc_err(pb_t *ppb, int pc, paramv_t *pv) { register func_t *f; register int i; register ctx_t *ctx; #ifdef xCTR2 if (tTf(6, 8)) lprintf("proc_err: new = %d\n", Ctx.ctx_new); #endif pb_prime(ppb, PB_ERR); /* ** Scan back on the list of context dependencies. ** If we come to someone who can process this message, ** we go ahead and do it. We also take this ** opportunity to unwind the context list & call the ** cleanup functions. */ for (ctx = &Ctx; ctx != NULL; ctx = ctx->ctx_link) { setprocname(ctx->ctx_name); f = ctx->ctx_fn; #ifdef xCTR2 if (tTf(6, 9)) lprintf("proc_err: unwinding %s: errfn=%x, ppb=%x, link=%x, resp=%d, fn=%x\n", getprocname(), ctx->ctx_errfn, ctx->ctx_ppb, ctx->ctx_link, ctx->ctx_resp, f); #endif /* Do the actual error processing. */ ppb->pb_proc = ctx->ctx_resp; if (ctx->ctx_errfn != NULL) i = (*ctx->ctx_errfn)(pc, pv); else i = -1; #ifdef xCTR2 if (tTf(6, 11)) lprintf("proc_err: errcode %d\n", i); #endif if (i == 0) break; else if (i > 0) { /* turn into nonfatal error */ ppb->pb_stat |= PB_INFO; ppb->pb_proc = PB_FRONT; } else { /* call the cleanup function */ if (f != NULL && f->fn_active > 0) { (*f->fn_cleanup)(1); } } /* arrange to leave if parent not in this process */ if (ppb->pb_proc != Cm.cm_myproc) { send_off(ppb, pc, pv); pb_flush(ppb); /* throw away dead contexts and exit */ break; } } if (ctx == NULL) { syserr("proc_err: no parent"); } #ifdef xCTR3 MonPpb = getmonppb(); if (tTf(6, 12)) { lprintf("proc_err: cleanup: ctx=%x, ->_link=%x, MonPpb = ", ctx, ctx->ctx_link); pb_dump(MonPpb, TRUE); } #endif /* pop contexts down to ctx and exit */ ctx = ctx->ctx_link; while (Ctx.ctx_link != ctx) { if (Ctx.ctx_link == NULL) syserr("proc_err: underflow"); Ctx.ctx_new = TRUE; resetp(); } /* ** Flush input pipe. ** THIS CODE IS ONLY NEEDED TO MAKE READMON WORK, AND ** SHOULD BE REMOVED WHEN READMON GOES AWAY!! */ if (ctx == NULL) { Cm.cm_input = Cm.cm_rinput; MonPpb = getmonppb(); while (!BITISSET(PB_EOF, MonPpb->pb_stat)) { pb_read(MonPpb); } MonPpb->pb_st = PB_UNKNOWN; } longjmp(Ctx.ctx_jbuf, 1); }
int redundancy_encoder_encode (u_char *state, struct s_pb *in, struct s_pb *out, uint32_t upp) { uint32_t m_len; timestamp_t playout; struct s_pb_iterator *pi; u_char *m_get; media_data *m; red_enc_state *re = (red_enc_state*)state; assert(upp != 0 && upp <= MAX_UNITS_PER_PACKET); pb_iterator_create(in, &pi); assert(pi != NULL); pb_iterator_advance(pi); while(pb_iterator_detach_at(pi, &m_get, &m_len, &playout)) { m = (media_data*)m_get; /* Remove element from playout buffer - it belongs to * the redundancy encoder now. */ #ifdef DEBUG_REDUNDANCY debug_msg("claimed %d, prev %d\n", playout.ticks, re->last_in.ticks); #endif /* DEBUG_REDUNDANCY */ assert(m != NULL); if (re->units_ready == 0) { re->last_in = playout; re->last_in.ticks--; } assert(ts_gt(playout, re->last_in)); re->last_in = playout; if (m->nrep > 0) { pb_add(re->media_buffer, (u_char*)m, m_len, playout); re->units_ready++; } else { /* Incoming unit has no data so transmission is * not happening. */ #ifdef DEBUG_REDUNDANCY debug_msg("No incoming data\n"); #endif /* DEBUG_REDUNDANCY */ media_data_destroy(&m, sizeof(media_data)); pb_flush(re->media_buffer); re->units_ready = 0; continue; } if (re->units_ready && (re->units_ready % upp) == 0) { channel_data *cd; int s; cd = redundancy_encoder_output(re, upp); assert(cd != NULL); s = pb_add(out, (u_char*)cd, sizeof(channel_data), playout); #ifdef DEBUG_REDUNDANCY debug_msg("Ready %d, Added %d\n", re->units_ready, playout.ticks); #endif /* DEBUG_REDUNDANCY */ assert(s); } } pb_iterator_destroy(in, &pi); return TRUE; }