/***************************************************************************** * Block: read data (CDDA_DATA_ONCE) *****************************************************************************/ static block_t *Block( access_t *p_access ) { access_sys_t *p_sys = p_access->p_sys; int i_blocks = CDDA_BLOCKS_ONCE; block_t *p_block; if( p_sys->i_track < 0 ) p_access->info.b_eof = true; /* Check end of file */ if( p_access->info.b_eof ) return NULL; if( !p_sys->b_header ) { /* Return only the header */ p_block = block_Alloc( sizeof( WAVEHEADER ) ); memcpy( p_block->p_buffer, &p_sys->waveheader, sizeof(WAVEHEADER) ); p_sys->b_header = true; return p_block; } if( p_sys->i_sector >= p_sys->i_last_sector ) { p_access->info.b_eof = true; return NULL; } /* Don't read too far */ if( p_sys->i_sector + i_blocks >= p_sys->i_last_sector ) i_blocks = p_sys->i_last_sector - p_sys->i_sector; /* Do the actual reading */ if( !( p_block = block_Alloc( i_blocks * CDDA_DATA_SIZE ) ) ) { msg_Err( p_access, "cannot get a new block of size: %i", i_blocks * CDDA_DATA_SIZE ); return NULL; } if( ioctl_ReadSectors( VLC_OBJECT(p_access), p_sys->vcddev, p_sys->i_sector, p_block->p_buffer, i_blocks, CDDA_TYPE ) < 0 ) { msg_Err( p_access, "cannot read sector %i", p_sys->i_sector ); block_Release( p_block ); /* Try to skip one sector (in case of bad sectors) */ p_sys->i_sector++; p_access->info.i_pos += CDDA_DATA_SIZE; return NULL; } /* Update a few values */ p_sys->i_sector += i_blocks; p_access->info.i_pos += p_block->i_buffer; return p_block; }
static int Demux (demux_t *demux) { demux_sys_t *sys = demux->p_sys; block_t *block = block_Alloc( sys->block_size); if (unlikely(block==NULL)) return 0; if (!sys->tune->getStatus()) { block_Release (block); return 0; } int i_read = sys->player->play ((void*)block->p_buffer, block->i_buffer); if (i_read <= 0) { block_Release (block); return 0; } block->i_buffer = i_read; block->i_pts = block->i_dts = VLC_TS_0 + date_Get (&sys->pts); es_out_Control (demux->out, ES_OUT_SET_PCR, block->i_pts); es_out_Send (demux->out, sys->es, block); date_Increment (&sys->pts, i_read / sys->bytes_per_frame); return 1; }
static block_t *Load(demux_t *demux) { const unsigned max_size = 4096 * 4096 * 8; uint64_t size; if (stream_GetSize(demux->s, &size) == VLC_SUCCESS) { if (size > max_size) { msg_Err(demux, "image too large (%"PRIu64" > %u), rejected", size, max_size); return NULL; } } else size = max_size; block_t *block = block_Alloc(size); if (block == NULL) return NULL; ssize_t val = stream_Read(demux->s, block->p_buffer, size); if (val < 0) { block_Release(block); return NULL; } block->i_buffer = val; return block; }
/* Create the p_sys->p_csd that will be sent via PutInput */ static int CSDDup(decoder_t *p_dec, const struct csd *p_csd, size_t i_count) { decoder_sys_t *p_sys = p_dec->p_sys; CSDFree(p_dec); p_sys->pp_csd = malloc(i_count * sizeof(block_t *)); if (!p_sys->pp_csd) return VLC_ENOMEM; for (size_t i = 0; i < i_count; ++i) { p_sys->pp_csd[i] = block_Alloc(p_csd[i].i_size); if (!p_sys->pp_csd[i]) { CSDFree(p_dec); return VLC_ENOMEM; } p_sys->pp_csd[i]->i_flags = BLOCK_FLAG_CSD; memcpy(p_sys->pp_csd[i]->p_buffer, p_csd[i].p_buf, p_csd[i].i_size); p_sys->i_csd_count++; } p_sys->i_csd_send = 0; return VLC_SUCCESS; }
static block_t *Encode( encoder_t *enc, block_t *in ) { if( in == NULL ) return NULL; block_t *out = block_Alloc( in->i_nb_samples * enc->fmt_out.audio.i_bytes_per_frame ); if( unlikely(out == NULL) ) return NULL; out->i_flags = in->i_flags; out->i_nb_samples = in->i_nb_samples; out->i_dts = in->i_dts; out->i_pts = in->i_pts; out->i_length = in->i_length; void (*encode)(void *, const uint8_t *, unsigned) = (void *)enc->p_sys; if( encode != NULL ) encode( out->p_buffer, in->p_buffer, in->i_nb_samples * enc->fmt_out.audio.i_channels ); else { assert( out->i_buffer >= in->i_buffer ); memcpy( out->p_buffer, in->p_buffer, in->i_buffer ); } return out; }
/***************************************************************************** * Filter: *****************************************************************************/ static bool FilterInit( filter_t *p_filter, block_t *p_block, block_t **pp_out ) { if( !p_block || !p_block->i_nb_samples ) { if( p_block ) block_Release( p_block ); return false; } size_t i_out_size = p_block->i_nb_samples * p_filter->fmt_out.audio.i_bitspersample * p_filter->fmt_out.audio.i_channels / 8; block_t *p_out = block_Alloc( i_out_size ); if( !p_out ) { msg_Warn( p_filter, "can't get output buffer" ); block_Release( p_block ); return false; } p_out->i_nb_samples = p_block->i_nb_samples; p_out->i_dts = p_block->i_dts; p_out->i_pts = p_block->i_pts; p_out->i_length = p_block->i_length; int i_input_nb = aout_FormatNbChannels( &p_filter->fmt_in.audio ); int i_output_nb = aout_FormatNbChannels( &p_filter->fmt_out.audio ); p_out->i_buffer = p_block->i_buffer * i_output_nb / i_input_nb; *pp_out = p_out; return true; }
/***************************************************************************** * I/O wrappers for libavformat *****************************************************************************/ static int IOWrite( void *opaque, uint8_t *buf, int buf_size ) { sout_mux_t *p_mux = opaque; sout_mux_sys_t *p_sys = p_mux->p_sys; int i_ret; #ifdef AVFORMAT_DEBUG msg_Dbg( p_mux, "IOWrite %i bytes", buf_size ); #endif block_t *p_buf = block_Alloc( buf_size ); if( buf_size > 0 ) memcpy( p_buf->p_buffer, buf, buf_size ); if( p_sys->b_write_header ) p_buf->i_flags |= BLOCK_FLAG_HEADER; #if LIBAVFORMAT_VERSION_CHECK( 57, 7, 0, 40, 100 ) if( !p_sys->b_header_done ) p_buf->i_flags |= BLOCK_FLAG_HEADER; #endif if( p_sys->b_write_keyframe ) { p_buf->i_flags |= BLOCK_FLAG_TYPE_I; p_sys->b_write_keyframe = false; } i_ret = sout_AccessOutWrite( p_mux->p_access, p_buf ); return i_ret ? i_ret : -1; }
static block_t *BlockString( const char *psz ) { block_t *p = block_Alloc( strlen(psz) ); if( p ) memcpy( p->p_buffer, psz, p->i_buffer ); return p; }
/***************************************************************************** * Demux: *****************************************************************************/ static int Demux( demux_t *p_demux ) { demux_sys_t *p_sys = p_demux->p_sys; block_t *p_frame; const int i_bk = ( p_sys->fmt.audio.i_bitspersample / 8 ) * p_sys->fmt.audio.i_channels; p_frame = block_Alloc( p_sys->fmt.audio.i_rate / 10 * i_bk ); if( !p_frame ) return VLC_DEMUXER_EGENERIC; const int i_read = ModPlug_Read( p_sys->f, p_frame->p_buffer, p_frame->i_buffer ); if( i_read <= 0 ) { /* EOF */ block_Release( p_frame ); return VLC_DEMUXER_EOF; } p_frame->i_buffer = i_read; p_frame->i_dts = p_frame->i_pts = date_Get( &p_sys->pts ); es_out_SetPCR( p_demux->out, p_frame->i_pts ); es_out_Send( p_demux->out, p_sys->es, p_frame ); date_Increment( &p_sys->pts, i_read / i_bk ); return VLC_DEMUXER_SUCCESS; }
/***************************************************************************** * NewUDPPacket: allocate a new UDP packet of size p_sys->i_mtu *****************************************************************************/ static block_t *NewUDPPacket( sout_access_out_t *p_access, mtime_t i_dts) { sout_access_out_sys_t *p_sys = p_access->p_sys; block_t *p_buffer; while ( block_FifoCount( p_sys->p_empty_blocks ) > MAX_EMPTY_BLOCKS ) { p_buffer = block_FifoGet( p_sys->p_empty_blocks ); block_Release( p_buffer ); } if( block_FifoCount( p_sys->p_empty_blocks ) == 0 ) { p_buffer = block_Alloc( p_sys->i_mtu ); } else { p_buffer = block_FifoGet(p_sys->p_empty_blocks ); p_buffer->i_flags = 0; p_buffer = block_Realloc( p_buffer, 0, p_sys->i_mtu ); } p_buffer->i_dts = i_dts; p_buffer->i_buffer = 0; return p_buffer; }
static block_t *Extract( filter_t *p_filter, block_t *p_in_buf ) { size_t i_out_channels = aout_FormatNbChannels( &p_filter->fmt_out.audio ); size_t i_out_size = p_in_buf->i_nb_samples * p_filter->fmt_out.audio.i_bitspersample * i_out_channels / 8; block_t *p_out_buf = block_Alloc( i_out_size ); if( unlikely(p_out_buf == NULL) ) { block_Release( p_in_buf ); return NULL; } p_out_buf->i_nb_samples = p_in_buf->i_nb_samples; p_out_buf->i_dts = p_in_buf->i_dts; p_out_buf->i_pts = p_in_buf->i_pts; p_out_buf->i_length = p_in_buf->i_length; static const int pi_selections[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, }; static_assert(sizeof(pi_selections)/sizeof(int) == AOUT_CHAN_MAX, "channel max size mismatch!"); aout_ChannelExtract( p_out_buf->p_buffer, i_out_channels, p_in_buf->p_buffer, p_filter->fmt_in.audio.i_channels, p_in_buf->i_nb_samples, pi_selections, p_filter->fmt_out.audio.i_bitspersample ); return p_out_buf; }
static int Demux (demux_t *demux) { demux_sys_t *sys = demux->p_sys; /* Next track */ if (gme_track_ended (sys->emu)) { msg_Dbg (demux, "track %u ended", sys->track_id); if (++sys->track_id >= (unsigned)gme_track_count (sys->emu)) return 0; demux->info.i_update |= INPUT_UPDATE_TITLE; demux->info.i_title = sys->track_id; gme_start_track (sys->emu, sys->track_id); } block_t *block = block_Alloc (2 * 2 * SAMPLES); if (unlikely(block == NULL)) return 0; gme_err_t ret = gme_play (sys->emu, 2 * SAMPLES, (void *)block->p_buffer); if (ret != NULL) { block_Release (block); msg_Err (demux, "%s", ret); return 0; } block->i_pts = block->i_dts = VLC_TS_0 + date_Get (&sys->pts); es_out_Control (demux->out, ES_OUT_SET_PCR, block->i_pts); es_out_Send (demux->out, sys->es, block); date_Increment (&sys->pts, SAMPLES); return 1; }
/***************************************************************************** * SendFrame: send a video frame to the stream output. *****************************************************************************/ static block_t *SendFrame( decoder_t *p_dec, block_t *p_block ) { decoder_sys_t *p_sys = p_dec->p_sys; p_block->i_dts = p_block->i_pts = date_Get( &p_sys->pts ); if( p_sys->b_invert ) { block_t *out = block_Alloc( p_block->i_buffer ); if( likely(out != NULL) ) { block_CopyProperties( out, p_block ); const uint8_t *p_src = p_block->p_buffer; uint8_t *p_pixels = out->p_buffer; for( unsigned i = 0; i < PICTURE_PLANE_MAX; i++ ) { unsigned pitch = p_sys->pitches[i]; unsigned lines = p_sys->lines[i]; uint8_t *p_dst = p_pixels + (pitch * lines); for( unsigned x = 0; x < lines; x++ ) { p_dst -= p_sys->pitches[i]; memcpy( p_dst, p_src, p_sys->pitches[i] ); p_src += p_sys->pitches[i]; } } } block_Release( p_block ); } return p_block; }
static block_t *Block(access_t *access) { access_t *a = GetAccess(access); if (a == NULL) return NULL; if (likely(a->pf_block != NULL)) return vlc_access_Block(a); if (a->pf_read == NULL) { access->info.b_eof = true; return NULL; } /* Emulate pf_block in case of mixed pf_read and bf_block */ block_t *block = block_Alloc(4096); if (unlikely(block == NULL)) return NULL; ssize_t ret = vlc_access_Read(a, block->p_buffer, block->i_buffer); if (ret >= 0) { block->i_buffer = ret; access->info.i_pos += ret; } else { block_Release(block); block = NULL; } return block; }
static block_t *S16toFl32(filter_t *filter, block_t *bsrc) { block_t *bdst = block_Alloc(bsrc->i_buffer * 2); if (unlikely(bdst == NULL)) goto out; block_CopyProperties(bdst, bsrc); int16_t *src = (int16_t *)bsrc->p_buffer; float *dst = (float *)bdst->p_buffer; for (size_t i = bsrc->i_buffer / 2; i--;) #if 0 /* Slow version */ *dst++ = (float)*src++ / 32768.f; #else { /* This is Walken's trick based on IEEE float format. On my PIII * this takes 16 seconds to perform one billion conversions, instead * of 19 seconds for the above division. */ union { float f; int32_t i; } u; u.i = *src++ + 0x43c00000; *dst++ = u.f - 384.f; } #endif out: block_Release(bsrc); VLC_UNUSED(filter); return bdst; }
/***************************************************************************** * DoWork: process samples buffer ***************************************************************************** * This function queues the audio buffer to be processed by the goom thread *****************************************************************************/ static block_t *DoWork( filter_t *p_filter, block_t *p_in_buf ) { filter_sys_t *p_sys = p_filter->p_sys; block_t *p_block; /* Queue sample */ vlc_mutex_lock( &p_sys->p_thread->lock ); if( p_sys->p_thread->i_blocks == MAX_BLOCKS ) { vlc_mutex_unlock( &p_sys->p_thread->lock ); return p_in_buf; } p_block = block_Alloc( p_in_buf->i_buffer ); if( !p_block ) { vlc_mutex_unlock( &p_sys->p_thread->lock ); return p_in_buf; } memcpy( p_block->p_buffer, p_in_buf->p_buffer, p_in_buf->i_buffer ); p_block->i_pts = p_in_buf->i_pts; p_sys->p_thread->pp_blocks[p_sys->p_thread->i_blocks++] = p_block; vlc_cond_signal( &p_sys->p_thread->wait ); vlc_mutex_unlock( &p_sys->p_thread->lock ); return p_in_buf; }
static block_t *Read (access_t *access) { #define BUFSIZE (20*188) block_t *block = block_Alloc (BUFSIZE); if (unlikely(block == NULL)) return NULL; access_sys_t *sys = access->p_sys; ssize_t val = dvb_read (sys->dev, block->p_buffer, BUFSIZE); if (val <= 0) { if (val == 0) access->info.b_eof = true; block_Release (block); return NULL; } block->i_buffer = val; /* Fetch the signal levels every so often. Some devices do not like this * to be requested too frequently, e.g. due to low bandwidth I²C bus. */ if ((sys->signal_poll++) == 0) access->info.i_update |= INPUT_UPDATE_SIGNAL; return block; }
/** * Trivially upmixes */ static block_t *Upmix( filter_t *p_filter, block_t *p_in_buf ) { unsigned i_input_nb = aout_FormatNbChannels( &p_filter->fmt_in.audio ); unsigned i_output_nb = aout_FormatNbChannels( &p_filter->fmt_out.audio ); assert( i_input_nb < i_output_nb ); block_t *p_out_buf = block_Alloc( p_in_buf->i_buffer * i_output_nb / i_input_nb ); if( unlikely(p_out_buf == NULL) ) { block_Release( p_in_buf ); return NULL; } p_out_buf->i_nb_samples = p_in_buf->i_nb_samples; p_out_buf->i_dts = p_in_buf->i_dts; p_out_buf->i_pts = p_in_buf->i_pts; p_out_buf->i_length = p_in_buf->i_length; float *p_dest = (float *)p_out_buf->p_buffer; const float *p_src = (float *)p_in_buf->p_buffer; for( size_t i = 0; i < p_in_buf->i_nb_samples; i++ ) { for( unsigned j = 0; j < i_output_nb; j++ ) p_dest[j] = p_src[j % i_input_nb]; p_src += i_input_nb; p_dest += i_output_nb; } block_Release( p_in_buf ); return p_out_buf; }
static int Peek (stream_t *stream, const uint8_t **pbuf, unsigned int len) { stream_sys_t *p_sys = stream->p_sys; block_t *peeked = p_sys->peeked; size_t curlen = 0; int fd = p_sys->read_fd; if (peeked == NULL) peeked = block_Alloc (len); else if ((curlen = peeked->i_buffer) < len) peeked = block_Realloc (peeked, 0, len); if ((p_sys->peeked = peeked) == NULL) return 0; if (curlen < len) { ssize_t val = net_Read (stream, fd, NULL, peeked->p_buffer + curlen, len - curlen, true); if (val >= 0) { curlen += val; peeked->i_buffer = curlen; } } *pbuf = peeked->p_buffer; return curlen; }
static block_t *Convert( filter_t *p_filter, block_t *p_block ) { if( !p_block || !p_block->i_nb_samples ) { if( p_block ) block_Release( p_block ); return NULL; } size_t i_out_size = p_block->i_nb_samples * p_filter->fmt_out.audio.i_bitspersample * p_filter->fmt_out.audio.i_channels / 8; block_t *p_out = block_Alloc( i_out_size ); if( !p_out ) { msg_Warn( p_filter, "can't get output buffer" ); block_Release( p_block ); return NULL; } p_out->i_nb_samples = p_block->i_nb_samples; p_out->i_dts = p_block->i_dts; p_out->i_pts = p_block->i_pts; p_out->i_length = p_block->i_length; DoWork( p_filter, p_block, p_out ); block_Release( p_block ); return p_out; }
static block_t *Encode( encoder_t *p_enc, subpicture_t *p_spu ) { VLC_UNUSED( p_enc ); subpicture_region_t *p_region; block_t *p_block; size_t len; if( p_spu == NULL ) return NULL; p_region = p_spu->p_region; if( ( p_region == NULL ) || ( p_region->fmt.i_chroma != VLC_CODEC_TEXT ) || ( p_region->psz_text == NULL ) ) return NULL; /* This should already be UTF-8 encoded, so not much effort... */ len = strlen( p_region->psz_text ); p_block = block_Alloc( len ); memcpy( p_block->p_buffer, p_region->psz_text, len ); p_block->i_pts = p_block->i_dts = p_spu->i_start; if( !p_spu->b_ephemer && ( p_spu->i_stop > p_spu->i_start ) ) p_block->i_length = p_spu->i_stop - p_spu->i_start; return p_block; }
static block_t * ConvertAVFrame( decoder_t *p_dec, AVFrame *frame ) { decoder_sys_t *p_sys = p_dec->p_sys; AVCodecContext *ctx = p_sys->p_context; block_t *p_block; /* Interleave audio if required */ if( av_sample_fmt_is_planar( ctx->sample_fmt ) ) { p_block = block_Alloc(frame->linesize[0] * ctx->channels); if ( likely(p_block) ) { const void *planes[ctx->channels]; for (int i = 0; i < ctx->channels; i++) planes[i] = frame->extended_data[i]; aout_Interleave(p_block->p_buffer, planes, frame->nb_samples, ctx->channels, p_dec->fmt_out.audio.i_format); p_block->i_nb_samples = frame->nb_samples; } av_frame_free(&frame); } else { p_block = vlc_av_frame_Wrap(frame); frame = NULL; } if (p_sys->b_extract && p_block) { /* TODO: do not drop channels... at least not here */ block_t *p_buffer = block_Alloc( p_dec->fmt_out.audio.i_bytes_per_frame * p_block->i_nb_samples ); if( likely(p_buffer) ) { aout_ChannelExtract( p_buffer->p_buffer, p_dec->fmt_out.audio.i_channels, p_block->p_buffer, ctx->channels, p_block->i_nb_samples, p_sys->pi_extraction, p_dec->fmt_out.audio.i_bitspersample ); p_buffer->i_nb_samples = p_block->i_nb_samples; } block_Release( p_block ); p_block = p_buffer; } return p_block; }
/***************************************************************************** * Demux: reads and demuxes data packets ***************************************************************************** * Returns -1 in case of error, 0 in case of EOF, 1 otherwise *****************************************************************************/ static int Demux( demux_t *p_demux) { demux_sys_t *p_sys = p_demux->p_sys; block_t *p_block_in, *p_block_out; if( p_sys->i_state == DIRAC_DEMUX_DISCONT ) { p_sys->i_state++; p_block_in = block_Alloc( 128 ); if( p_block_in ) { p_block_in->i_flags = BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED; } } else { p_block_in = stream_Block( p_demux->s, DIRAC_PACKET_SIZE ); if( !p_block_in ) { return 0; } if ( p_sys->i_state == DIRAC_DEMUX_FIRST) { p_sys->i_state++; /* by default, timestamps are invalid. * Except when we need an anchor point */ p_block_in->i_dts = VLC_TS_0; } } while( (p_block_out = p_sys->p_packetizer->pf_packetize( p_sys->p_packetizer, &p_block_in )) ) { while( p_block_out ) { block_t *p_next = p_block_out->p_next; p_block_out->p_next = NULL; if( p_sys->p_es == NULL ) p_sys->p_es = es_out_Add( p_demux->out, &p_sys->p_packetizer->fmt_out); p_block_out->i_dts += p_sys->i_dtsoffset; p_sys->i_dts = p_block_out->i_dts; /* track low watermark for pts_offset -- can be used to show * when it is too large */ mtime_t i_delay = p_block_out->i_pts - p_block_out->i_dts; if( p_sys->i_pts_offset_lowtide > i_delay ) { p_sys->i_pts_offset_lowtide = i_delay; } es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block_out->i_dts ); es_out_Send( p_demux->out, p_sys->p_es, p_block_out ); p_block_out = p_next; } } return 1; }
block_t *screen_Capture( demux_t *p_demux ) { demux_sys_t *p_sys = p_demux->p_sys; screen_data_t *p_data = ( screen_data_t * )p_sys->p_data; block_t *p_block; int i_size; i_size = p_sys->fmt.video.i_height * p_sys->fmt.video.i_width * 4; if( !( p_block = block_Alloc( i_size ) ) ) { msg_Warn( p_demux, "cannot get block" ); return NULL; } CGPoint cursor_pos; CGError cursor_result; cursor_pos.x = 0; cursor_pos.y = 0; cursor_result = CGSGetCurrentCursorLocation( p_data->connection, &cursor_pos ); cursor_pos.x -= p_data->screen_left; cursor_pos.y -= p_data->screen_top; if( p_sys->b_follow_mouse && cursor_result == kCGErrorSuccess ) { FollowMouse( p_sys, cursor_pos.x, cursor_pos.y ); } screen_CaptureScreen( p_sys ); CGLSetCurrentContext( p_data->clipped ); glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); glClear( GL_COLOR_BUFFER_BIT ); glDrawPixels( p_data->width, p_data->height, GL_RGBA, GL_UNSIGNED_BYTE, p_data->screen_image ); if( cursor_result == kCGErrorSuccess ) { screen_DrawCursor( p_sys, &cursor_pos ); } glReadPixels( 0, 0, p_data->width, p_data->height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, p_block->p_buffer ); return p_block; }
static block_t *Encode( encoder_t *p_enc, picture_t *p_pict ) { encoder_sys_t *p_sys = p_enc->p_sys; ogg_packet oggpacket; block_t *p_block; od_img img; if( !p_pict ) return NULL; const int i_width = p_sys->di.pic_width; const int i_height = p_sys->di.pic_height; /* Sanity check */ if( p_pict->p[0].i_pitch < i_width || p_pict->p[0].i_lines < i_height ) { msg_Err( p_enc, "frame is smaller than encoding size" "(%ix%i->%ix%i) -> dropping frame", p_pict->p[0].i_pitch, p_pict->p[0].i_lines, i_width, i_height ); return NULL; } /* Daala is a one-frame-in, one-frame-out system. Submit a frame * for compression and pull out the packet. */ img.nplanes = p_sys->di.nplanes; img.width = i_width; img.height = i_height; for( int i = 0; i < img.nplanes; i++ ) { img.planes[i].data = p_pict->p[i].p_pixels; img.planes[i].xdec = p_sys->di.plane_info[i].xdec; img.planes[i].ydec = p_sys->di.plane_info[i].ydec; img.planes[i].xstride = 1; img.planes[i].ystride = p_pict->p[i].i_pitch; } if( daala_encode_img_in( p_sys->dcx, &img, 0 ) < 0 ) { msg_Warn( p_enc, "failed encoding a frame" ); return NULL; } daala_encode_packet_out( p_sys->dcx, 0, &oggpacket ); /* Ogg packet to block */ p_block = block_Alloc( oggpacket.bytes ); memcpy( p_block->p_buffer, oggpacket.packet, oggpacket.bytes ); p_block->i_dts = p_block->i_pts = p_pict->date; if( daala_packet_iskeyframe( oggpacket.packet, oggpacket.bytes ) ) p_block->i_flags |= BLOCK_FLAG_TYPE_I; return p_block; }
static block_t *EncodeFrame( encoder_t *p_enc, block_t *p_block ) { if (!p_block) /* TODO: flush */ return NULL; encoder_sys_t *p_sys = p_enc->p_sys; block_t *p_pcm_block; block_t *p_chain = NULL; unsigned int i_samples = p_block->i_buffer >> 2 /* s16l stereo */; mtime_t start_date = p_block->i_pts; start_date -= (mtime_t)i_samples * (mtime_t)1000000 / (mtime_t)p_enc->fmt_out.audio.i_rate; VLC_UNUSED(p_enc); do { p_pcm_block = GetPCM( p_enc, p_block ); if( !p_pcm_block ) break; p_block = NULL; /* we don't need it anymore */ int16_t pcm_planar_buf[SHINE_MAX_SAMPLES * 2]; int16_t *pcm_planar_buf_chans[2] = { &pcm_planar_buf[0], &pcm_planar_buf[p_sys->samples_per_frame], }; aout_Deinterleave( pcm_planar_buf, p_pcm_block->p_buffer, p_sys->samples_per_frame, p_enc->fmt_in.audio.i_channels, p_enc->fmt_in.i_codec); long written; unsigned char *buf = shine_encode_buffer(p_sys->s, pcm_planar_buf_chans, &written); block_Release( p_pcm_block ); if (written <= 0) break; block_t *p_mp3_block = block_Alloc( written ); if( !p_mp3_block ) break; memcpy( p_mp3_block->p_buffer, buf, written ); /* date management */ p_mp3_block->i_length = p_sys->samples_per_frame * 1000000 / p_enc->fmt_out.audio.i_rate; start_date += p_mp3_block->i_length; p_mp3_block->i_dts = p_mp3_block->i_pts = start_date; p_mp3_block->i_nb_samples = p_sys->samples_per_frame; block_ChainAppend( &p_chain, p_mp3_block ); } while( p_pcm_block ); return p_chain; }
static void beginPaintHandler( rdpContext *p_context ) { vlcrdp_context_t * p_vlccontext = (vlcrdp_context_t *) p_context; demux_sys_t *p_sys = p_vlccontext->p_demux->p_sys; rdpGdi *p_gdi = p_context->gdi; p_gdi->primary->hdc->hwnd->invalid->null = 1; p_gdi->primary->hdc->hwnd->ninvalid = 0; if ( ! p_sys->p_block && p_sys->i_framebuffersize ) p_sys->p_block = block_Alloc( p_sys->i_framebuffersize ); }
/***************************************************************************** * DoWork: convert a buffer *****************************************************************************/ static block_t *DoWork( filter_t * p_filter, block_t *p_in_buf ) { size_t i_length = p_in_buf->i_buffer; uint8_t * p_in = p_in_buf->p_buffer; block_t *p_out_buf = NULL; uint16_t i_data_type = get_data_type( p_filter, p_in_buf ); if( i_data_type == 0 || ( i_length + 8 ) > AOUT_SPDIF_SIZE ) goto out; size_t i_out_length = p_in_buf->i_nb_samples * 4; p_out_buf = block_Alloc( i_out_length ); if( !p_out_buf ) goto out; uint8_t *p_out = p_out_buf->p_buffer; /* Copy the S/PDIF headers. */ void (*write16)(void *, uint16_t) = ( p_filter->fmt_out.audio.i_format == VLC_CODEC_SPDIFB ) ? SetWBE : SetWLE; write16( &p_out[0], 0xf872 ); /* syncword 1 */ write16( &p_out[2], 0x4e1f ); /* syncword 2 */ write16( &p_out[4], i_data_type ); /* data type */ write16( &p_out[6], i_length * 8 ); /* length in bits */ bool b_input_big_endian = is_big_endian( p_filter, p_in_buf ); bool b_output_big_endian = p_filter->fmt_out.audio.i_format == VLC_CODEC_SPDIFB; if( b_input_big_endian != b_output_big_endian ) { swab( p_in, p_out + 8, i_length & ~1 ); /* If i_length is odd, we have to adjust swapping a bit... */ if( i_length & 1 && ( i_length + 9 ) <= i_out_length ) { p_out[8 + i_length - 1] = 0; p_out[8 + i_length] = p_in[i_length-1]; i_length++; } } else memcpy( p_out + 8, p_in, i_length ); if( 8 + i_length < i_out_length ) /* padding */ memset( p_out + 8 + i_length, 0, i_out_length - i_length - 8 ); p_out_buf->i_dts = p_in_buf->i_dts; p_out_buf->i_pts = p_in_buf->i_pts; p_out_buf->i_nb_samples = p_in_buf->i_nb_samples; p_out_buf->i_buffer = i_out_length; out: block_Release( p_in_buf ); return p_out_buf; }
static block_t *Resample (filter_t *filter, block_t *in) { block_t *out = NULL; const size_t framesize = filter->fmt_out.audio.i_bytes_per_frame; SRC_STATE *s = (SRC_STATE *)filter->p_sys; SRC_DATA src; src.src_ratio = (double)filter->fmt_out.audio.i_rate / (double)filter->fmt_in.audio.i_rate; int err = src_set_ratio (s, src.src_ratio); if (err != 0) { msg_Err (filter, "cannot update resampling ratio: %s", src_strerror (err)); goto error; } src.input_frames = in->i_nb_samples; src.output_frames = ceil (src.src_ratio * src.input_frames); src.end_of_input = 0; out = block_Alloc (src.output_frames * framesize); if (unlikely(out == NULL)) goto error; src.data_in = (float *)in->p_buffer; src.data_out = (float *)out->p_buffer; err = src_process (s, &src); if (err != 0) { msg_Err (filter, "cannot resample: %s", src_strerror (err)); block_Release (out); out = NULL; goto error; } if (src.input_frames_used < src.input_frames) msg_Err (filter, "lost %ld of %ld input frames", src.input_frames - src.input_frames_used, src.input_frames); out->i_buffer = src.output_frames_gen * framesize; out->i_nb_samples = src.output_frames_gen; out->i_pts = in->i_pts; out->i_length = src.output_frames_gen * CLOCK_FREQ / filter->fmt_out.audio.i_rate; error: block_Release (in); return out; }
static void aout_DecSilence (audio_output_t *aout, mtime_t length, mtime_t pts) { aout_owner_t *owner = aout_owner (aout); const audio_sample_format_t *fmt = &owner->mixer_format; size_t frames = (fmt->i_rate * length) / CLOCK_FREQ; block_t *block; if (AOUT_FMT_SPDIF(fmt)) block = block_Alloc (4 * frames); else block = block_Alloc (frames * fmt->i_bytes_per_frame); if (unlikely(block == NULL)) return; /* uho! */ msg_Dbg (aout, "inserting %zu zeroes", frames); memset (block->p_buffer, 0, block->i_buffer); block->i_nb_samples = frames; block->i_pts = pts; block->i_dts = pts; block->i_length = length; aout_OutputPlay (aout, block); }