/** @internal @This handles audio input. * * @param upipe description structure of the pipe * @param uref uref structure * @param upump_p reference to upump structure */ static void upipe_osx_audioqueue_sink_input_audio(struct upipe *upipe, struct uref *uref, struct upump **upump_p) { struct upipe_osx_audioqueue_sink *osx_audioqueue = upipe_osx_audioqueue_sink_from_upipe(upipe); struct AudioQueueBuffer *qbuf; size_t size = 0; if (unlikely(!ubase_check(uref_block_size(uref, &size)))) { upipe_warn(upipe, "could not get block size"); uref_free(uref); return; } /* TODO block ? */ #if 0 upump_mgr_use(upump->mgr); upump_mgr_sink_block(upump->mgr); #endif /* allocate queue buf, extract block, enqueue * Audioqueue has no support for "external" buffers */ AudioQueueAllocateBuffer(osx_audioqueue->queue, size, &qbuf); uref_block_extract(uref, 0, -1, qbuf->mAudioData); qbuf->mAudioDataByteSize = size; qbuf->mUserData = (*upump_p)->mgr; AudioQueueEnqueueBuffer(osx_audioqueue->queue, qbuf, 0, NULL); uref_free(uref); }
/** @internal @This handles packets. * * @param upipe description structure of the pipe * @param uref uref structure * @param upump upump structure */ static void upipe_avcdec_input_packet(struct upipe *upipe, struct uref *uref, struct upump *upump) { uint8_t *inbuf; size_t insize = 0; struct upipe_avcdec *upipe_avcdec = upipe_avcdec_from_upipe(upipe); assert(upipe); assert(uref); if (upipe_avcdec->upump_av_deal) { /* pending open_codec callback */ upipe_dbg(upipe, "Received packet while open_codec pending"); if (upump) { upump_mgr_sink_block(upump->mgr); upump_mgr_use(upump->mgr); upipe_avcdec->saved_upump_mgr = upump->mgr; } if (upipe_avcdec->saved_uref) { upipe_warn(upipe, "Dropping previously saved packet !"); uref_free(upipe_avcdec->saved_uref); } upipe_avcdec->saved_uref = uref; return; } else if (upipe_avcdec->saved_uref) { upipe_dbg(upipe, "Processing previously saved packet"); struct uref *prev_uref = upipe_avcdec->saved_uref; upipe_avcdec->saved_uref = NULL; /* Not a typo, using the current upump here */ upipe_avcdec_input_packet(upipe, prev_uref, upump); } if (!upipe_avcdec->context) { uref_free(uref); upipe_warn(upipe, "Received packet but decoder is not initialized"); return; } /* avcodec input buffer needs to be at least 4-byte aligned and FF_INPUT_BUFFER_PADDING_SIZE larger than actual input size. Thus, extract ubuf content in a properly allocated buffer. Padding must be zeroed. */ uref_block_size(uref, &insize); if (unlikely(!insize)) { upipe_warn(upipe, "Received packet with size 0, dropping"); uref_free(uref); return; } upipe_dbg_va(upipe, "Received packet %u - size : %u", upipe_avcdec->counter, insize); inbuf = malloc(insize + FF_INPUT_BUFFER_PADDING_SIZE); if (unlikely(!inbuf)) { upipe_throw_aerror(upipe); return; } memset(inbuf, 0, insize + FF_INPUT_BUFFER_PADDING_SIZE); uref_block_extract(uref, 0, insize, inbuf); ubuf_free(uref_detach_ubuf(uref)); uref_pic_set_number(uref, upipe_avcdec->counter); /* Track current uref in pipe structure - required for buffer allocation * in upipe_avcdec_get_buffer */ upipe_avcdec->uref = uref; upipe_avcdec_process_buf(upipe, inbuf, insize, upump); free(inbuf); uref_free(uref); upipe_avcdec->counter++; }