/** @internal @This tries to find TS packets in the buffered input urefs. * * @param upipe description structure of the pipe * @param uref uref structure * @param upump_p reference to pump that generated the buffer */ static void upipe_ts_check_input(struct upipe *upipe, struct uref *uref, struct upump **upump_p) { struct upipe_ts_check *upipe_ts_check = upipe_ts_check_from_upipe(upipe); size_t size; if (unlikely(!ubase_check(uref_block_size(uref, &size)))) { uref_free(uref); upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return; } while (size > upipe_ts_check->output_size) { struct uref *next = uref_block_split(uref, upipe_ts_check->output_size); if (unlikely(next == NULL)) { uref_free(uref); upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return; } if (!upipe_ts_check_check(upipe, uref, upump_p)) { uref_free(next); return; } size -= upipe_ts_check->output_size; uref = next; } if (size == upipe_ts_check->output_size) upipe_ts_check_check(upipe, uref, upump_p); }
static void upipe_rtp_h264_output_nalu(struct upipe *upipe, uint8_t nalu, struct uref *uref, struct upump **upump_p) { size_t size = 0; if (unlikely(!ubase_check(uref_block_size(uref, &size)))) { upipe_err(upipe, "fail to get block size"); return; } bool split = size > RTP_SPLIT_SIZE; uint32_t fragment = 0; while (size) { bool last_fragment = size <= RTP_SPLIT_SIZE; size_t split_size = last_fragment ? size : RTP_SPLIT_SIZE; uint8_t hdr[2] = { nalu, 0 }; size_t hdr_size = 1; if (split) { if (!fragment) hdr[1] = FU_START; else if (last_fragment) hdr[1] = FU_END; hdr[1] |= NALU_TYPE(hdr[0]); hdr[0] = NALU_F(hdr[0]) | NALU_NRI(hdr[0]) | FU_A; hdr_size++; } struct uref *next = NULL; if (!last_fragment) { next = uref_block_split(uref, split_size); if (unlikely(next == NULL)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return; } } /* FIXME should require a ubuf_mgr */ struct ubuf *header = ubuf_block_alloc(uref->ubuf->mgr, hdr_size * sizeof (hdr[0])); if (unlikely(header == NULL)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); uref_free(uref); uref_free(next); return; } uint8_t *buf = NULL; int buf_size = hdr_size; ubuf_block_write(header, 0, &buf_size, &buf); memcpy(buf, hdr, hdr_size * sizeof (hdr[0])); ubuf_block_unmap(header, 0); /* append payload (current ubuf) to header to form segmented ubuf */ struct ubuf *payload = uref_detach_ubuf(uref); if (unlikely(!ubase_check(ubuf_block_append(header, payload)))) { upipe_warn(upipe, "could not append payload to header"); ubuf_free(header); ubuf_free(payload); uref_free(uref); uref_free(next); return; } uref_attach_ubuf(uref, header); uref_clock_set_cr_dts_delay(uref, 0); upipe_rtp_h264_output(upipe, uref, upump_p); size -= split_size; fragment++; uref = next; } }