/* kills the data */ static void stream_send_bytearr(liChunkQueue *out, guint8 type, guint16 requestid, GByteArray *data) { if (data->len > G_MAXUINT16) { stream_send_data(out, type, requestid, (const gchar*) data->data, data->len); g_byte_array_free(data, TRUE); } else { guint8 padlen = stream_send_fcgi_record(out, type, requestid, data->len); append_padding(data, padlen); li_chunkqueue_append_bytearr(out, data); } }
/* Process a buffer (including reencoding or encoding, if desired). * Returns: >0 - success * 0 - shout error occurred * -1 - no data produced * -2 - fatal error occurred */ int process_and_send_buffer(stream_description *sdsc, ref_buffer *buffer) { if(sdsc->reenc) { unsigned char *buf; int buflen,ret; ret = reencode_page(sdsc->reenc, buffer, &buf, &buflen); if(ret > 0) { ret = stream_send_data(sdsc, buf, buflen); free(buf); return ret; } else if(ret==0) /* No data produced by reencode */ return -1; else { LOG_ERROR0("Fatal reencoding error encountered"); return -2; } } else if (sdsc->enc) { ogg_page og; int be = (sdsc->input->subtype == INPUT_PCM_BE_16)?1:0; int ret=1; /* We use critical as a flag to say 'start a new stream' */ if(buffer->critical) { if(sdsc->resamp) { resample_finish(sdsc->resamp); encode_data_float(sdsc->enc, sdsc->resamp->buffers, sdsc->resamp->buffill); resample_clear(sdsc->resamp); sdsc->resamp = resample_initialise (sdsc->stream->channels, sdsc->stream->resampleinrate, sdsc->stream->resampleoutrate); } encode_finish(sdsc->enc); while(encode_flush(sdsc->enc, &og) != 0) { if ((ret = stream_send_data(sdsc, og.header, og.header_len)) == 0) return 0; if ((ret = stream_send_data(sdsc, og.body, og.body_len)) == 0) return 0; } encode_clear(sdsc->enc); if(sdsc->input->metadata_update) { vorbis_comment_clear(&sdsc->vc); vorbis_comment_init(&sdsc->vc); sdsc->input->metadata_update(sdsc->input->internal, &sdsc->vc); } sdsc->enc = encode_initialise(sdsc->stream->channels, sdsc->stream->samplerate, sdsc->stream->managed, sdsc->stream->min_br, sdsc->stream->nom_br, sdsc->stream->max_br, sdsc->stream->quality, &sdsc->vc); if(!sdsc->enc) { LOG_ERROR0("Failed to initialise encoder"); return -2; } sdsc->enc->max_samples_ppage = sdsc->stream->max_samples_ppage; } if(sdsc->downmix) { downmix_buffer(sdsc->downmix, (signed char *)buffer->buf, buffer->len, be); if(sdsc->resamp) { resample_buffer_float(sdsc->resamp, &sdsc->downmix->buffer, buffer->len/4); encode_data_float(sdsc->enc, sdsc->resamp->buffers, sdsc->resamp->buffill); } else encode_data_float(sdsc->enc, &sdsc->downmix->buffer, buffer->len/4); } else if(sdsc->resamp) { resample_buffer(sdsc->resamp, (signed char *)buffer->buf, buffer->len, be); encode_data_float(sdsc->enc, sdsc->resamp->buffers, sdsc->resamp->buffill); } else { encode_data(sdsc->enc, (signed char *)(buffer->buf), buffer->len, be); } while(encode_dataout(sdsc->enc, &og) > 0) { if ((ret = stream_send_data(sdsc, og.header, og.header_len)) == 0) return 0; if ((ret = stream_send_data(sdsc, og.body, og.body_len)) == 0) return 0; } return ret; } else return stream_send_data(sdsc, buffer->buf, buffer->len); }