/***************************************************************************** * Demux: read packet and send them to decoders ***************************************************************************** * 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; vlc_tick_t i_date; p_block = vlc_stream_Block( p_demux->s, CDG_FRAME_SIZE ); if( p_block == NULL ) { msg_Dbg( p_demux, "cannot read data, eof" ); return VLC_DEMUXER_EOF; } i_date = PosToDate( p_demux ); if( i_date >= date_Get( &p_sys->pts ) + CDG_FRAME_DELTA ) { p_block->i_dts = p_block->i_pts = VLC_TICK_0 + i_date; date_Set( &p_sys->pts, VLC_TICK_0 + i_date ); } else { p_block->i_dts = VLC_TICK_0 + i_date; p_block->i_pts = date_Get( &p_sys->pts ); } es_out_SetPCR( p_demux->out, p_block->i_pts ); es_out_Send( p_demux->out, p_sys->p_es, p_block ); return VLC_DEMUXER_SUCCESS; }
/***************************************************************************** * Demux: read packet and send them to decoders ***************************************************************************** * 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; mtime_t i_date; mtime_t i_delta; i_delta = INT64_C(1000000) / CDG_FRAME_RATE; p_block = vlc_stream_Block( p_demux->s, CDG_FRAME_SIZE ); if( p_block == NULL ) { msg_Dbg( p_demux, "cannot read data, eof" ); return 0; } i_date = vlc_stream_Tell( p_demux->s ) / CDG_FRAME_SIZE * i_delta; if( i_date >= date_Get( &p_sys->pts ) + i_delta ) { p_block->i_dts = p_block->i_pts = i_date; date_Set( &p_sys->pts, i_date ); } else { p_block->i_dts = i_date; p_block->i_pts = date_Get( &p_sys->pts ); } es_out_SetPCR( p_demux->out, p_block->i_pts ); es_out_Send( p_demux->out, p_sys->p_es, p_block ); return 1; }
static int SendBlock( demux_t *p_demux, int i ) { demux_sys_t *p_sys = p_demux->p_sys; block_t *p_block; if( ( p_block = vlc_stream_Block( p_demux->s, i ) ) == NULL ) { msg_Warn( p_demux, "cannot read data" ); return 0; } if( p_sys->i_frame_length ) { p_block->i_pts = p_sys->i_time; p_sys->i_time += p_sys->i_frame_length; } else { p_block->i_pts = mdate(); } p_block->i_dts = p_block->i_pts; /* set PCR */ es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block->i_pts ); es_out_Send( p_demux->out, p_sys->p_es, p_block ); if( p_sys->b_still ) p_sys->i_still_end = mdate() + p_sys->i_frame_length; return 1; }
/***************************************************************************** * Demux: read packet and send them to decoders ***************************************************************************** * 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; int64_t i_offset = vlc_stream_Tell( p_demux->s ); unsigned i_frames = p_sys->i_block_frames; if( p_sys->i_data_size > 0 && (i_offset - HEADER_LENGTH) >= p_sys->i_data_size ) { return VLC_DEMUXER_EOF; } p_block = vlc_stream_Block( p_demux->s, p_sys->i_frame_size * i_frames ); if( p_block == NULL ) { msg_Warn( p_demux, "cannot read data" ); return VLC_DEMUXER_EOF; } i_frames = p_block->i_buffer / p_sys->i_frame_size; p_block->i_dts = p_block->i_pts = date_Get( &p_sys->pts ); es_out_SetPCR( p_demux->out, p_block->i_pts ); es_out_Send( p_demux->out, p_sys->p_es, p_block ); date_Increment( &p_sys->pts, i_frames * FRAME_LENGTH ); return VLC_DEMUXER_SUCCESS; }
/***************************************************************************** * Demux: read packet and send them to decoders ***************************************************************************** * 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; int64_t i_offset; unsigned i_frames = p_sys->i_block_frames; i_offset = vlc_stream_Tell( p_demux->s ); if( p_sys->i_data_size > 0 && i_offset >= p_sys->i_data_offset + p_sys->i_data_size ) { /* EOF */ return 0; } p_block = vlc_stream_Block( p_demux->s, p_sys->i_frame_size * i_frames ); if( p_block == NULL ) { msg_Warn( p_demux, "cannot read data" ); return 0; } i_frames = p_block->i_buffer / p_sys->i_frame_size; p_block->i_dts = p_block->i_pts = date_Get( &p_sys->pts ); es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block->i_pts ); es_out_Send( p_demux->out, p_sys->p_es, p_block ); date_Increment( &p_sys->pts, i_frames * FRAME_LENGTH ); return 1; }
static picture_t *ImageReadUrl( image_handler_t *p_image, const char *psz_url, video_format_t *p_fmt_in, video_format_t *p_fmt_out ) { block_t *p_block; picture_t *p_pic; stream_t *p_stream = NULL; uint64_t i_size; p_stream = vlc_stream_NewMRL( p_image->p_parent, psz_url ); if( !p_stream ) { msg_Dbg( p_image->p_parent, "could not open %s for reading", psz_url ); return NULL; } if( vlc_stream_GetSize( p_stream, &i_size ) || i_size > SSIZE_MAX ) { msg_Dbg( p_image->p_parent, "could not read %s", psz_url ); goto error; } p_block = vlc_stream_Block( p_stream, i_size ); if( p_block == NULL ) goto error; if( !p_fmt_in->i_chroma ) { char *psz_mime = stream_ContentType( p_stream ); if( psz_mime != NULL ) { p_fmt_in->i_chroma = image_Mime2Fourcc( psz_mime ); free( psz_mime ); } } vlc_stream_Delete( p_stream ); if( !p_fmt_in->i_chroma ) { /* Try to guess format from file name */ p_fmt_in->i_chroma = image_Ext2Fourcc( psz_url ); } p_pic = ImageRead( p_image, p_block, p_fmt_in, p_fmt_out ); return p_pic; error: vlc_stream_Delete( p_stream ); return NULL; }
static block_t *ps_pkt_read( stream_t *s ) { const uint8_t *p_peek; int i_peek = vlc_stream_Peek( s, &p_peek, 14 ); if( i_peek < 4 ) return NULL; int i_size = ps_pkt_size( p_peek, i_peek ); if( i_size <= 6 && p_peek[3] > PS_STREAM_ID_PACK_HEADER ) { /* Special case, search the next start code */ i_size = 6; for( ;; ) { i_peek = vlc_stream_Peek( s, &p_peek, i_size + 1024 ); if( i_peek <= i_size + 4 ) { return NULL; } while( i_size <= i_peek - 4 ) { if( p_peek[i_size] == 0x00 && p_peek[i_size+1] == 0x00 && p_peek[i_size+2] == 0x01 && p_peek[i_size+3] >= PS_STREAM_ID_END_STREAM ) { return vlc_stream_Block( s, i_size ); } i_size++; } } } else { /* Normal case */ return vlc_stream_Block( s, i_size ); } return NULL; }
/***************************************************************************** * 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_out; bool b_eof = false; if( p_sys->p_current_block == NULL ) { p_sys->p_current_block = vlc_stream_Block( p_demux->s, FLAC_PACKET_SIZE ); b_eof = (p_sys->p_current_block == NULL); } if ( p_sys->p_current_block ) { p_sys->p_current_block->i_flags = p_sys->i_next_block_flags; p_sys->i_next_block_flags = 0; p_sys->p_current_block->i_pts = p_sys->p_current_block->i_dts = p_sys->b_start ? VLC_TS_0 : VLC_TS_INVALID; } while( (p_block_out = p_sys->p_packetizer->pf_packetize( p_sys->p_packetizer, (p_sys->p_current_block) ? &p_sys->p_current_block : NULL )) ) { /* Only clear on output when packet is accepted as sync #17111 */ p_sys->b_start = false; while( p_block_out ) { block_t *p_next = p_block_out->p_next; p_block_out->p_next = NULL; /* set PCR */ if( unlikely(p_sys->i_pts == VLC_TS_INVALID) ) es_out_Control( p_demux->out, ES_OUT_SET_PCR, __MAX(p_block_out->i_dts - 1, VLC_TS_0) ); p_sys->i_pts = p_block_out->i_dts; es_out_Send( p_demux->out, p_sys->p_es, p_block_out ); es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pts ); p_block_out = p_next; } break; } return b_eof ? VLC_DEMUXER_EOF : VLC_DEMUXER_SUCCESS; }
/***************************************************************************** * 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; p_block = vlc_stream_Block( p_demux->s, p_sys->i_frame_size ); if( p_block == NULL ) return VLC_DEMUXER_EOF; p_block->i_dts = p_block->i_pts = date_Get( &p_sys->pts ); es_out_SetPCR( p_demux->out, p_block->i_pts ); es_out_Send( p_demux->out, p_sys->p_es, p_block ); date_Increment( &p_sys->pts, p_sys->i_frame_samples ); return VLC_DEMUXER_SUCCESS; }
static int Demux(demux_t *demux) { demux_sys_t *sys = demux->p_sys; while(sys->current < sys->count) { stl_entry_t *s = &sys->index[sys->current]; if (s->start > sys->next_date) break; block_t *b = vlc_stream_Block(demux->s, 128 * s->count); if (b) { b->i_dts = b->i_pts = VLC_TS_0 + s->start; if (s->stop > s->start) b->i_length = s->stop - s->start; es_out_Send(demux->out, sys->es, b); } sys->current++; } return sys->current < sys->count ? 1 : 0; }
/***************************************************************************** * Demux: read packet and send them to decoders ***************************************************************************** * 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; /* set PCR */ es_out_SetPCR( p_demux->out, VLC_TS_0 + p_sys->i_time ); p_block = vlc_stream_Block( p_demux->s, p_sys->i_frame_size ); if( p_block == NULL ) { msg_Warn( p_demux, "cannot read data" ); return 0; } p_block->i_dts = p_block->i_pts = VLC_TS_0 + p_sys->i_time; es_out_Send( p_demux->out, p_sys->es, p_block ); p_sys->i_time += p_sys->i_frame_length; return 1; }
/***************************************************************************** * 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; bool b_eof = false; if( ( p_block_in = vlc_stream_Block( p_demux->s, MPGV_PACKET_SIZE ) ) == NULL ) { b_eof = true; } if( p_block_in ) { p_block_in->i_pts = p_block_in->i_dts = ( p_sys->b_start ) ? VLC_TS_0 : VLC_TS_INVALID; } while( (p_block_out = p_sys->p_packetizer->pf_packetize( p_sys->p_packetizer, p_block_in ? &p_block_in : NULL )) ) { p_sys->b_start = false; while( p_block_out ) { block_t *p_next = p_block_out->p_next; es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block_out->i_dts ); p_block_out->p_next = NULL; es_out_Send( p_demux->out, p_sys->p_es, p_block_out ); p_block_out = p_next; } } return (b_eof) ? VLC_DEMUXER_EOF : VLC_DEMUXER_SUCCESS; }
static int RefineSeek( demux_t *p_demux, mtime_t i_time, double i_bytemicrorate, uint64_t i_lowpos, uint64_t i_highpos ) { demux_sys_t *p_sys = p_demux->p_sys; bool b_found = false; block_t *p_block_out; block_t *p_block_in; unsigned i_frame_size = FLAC_MIN_FRAME_SIZE; bool b_canfastseek = false; (int) vlc_stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b_canfastseek ); uint64_t i_start_pos = vlc_stream_Tell( p_demux->s ); while( !b_found ) { FlushPacketizer( p_sys->p_packetizer ); p_block_out = NULL; p_block_in = NULL; while( !p_block_out ) { if( !p_block_in ) { if( !(p_block_in = vlc_stream_Block( p_demux->s, i_frame_size )) ) break; } p_block_out = p_sys->p_packetizer->pf_packetize( p_sys->p_packetizer, &p_block_in ); } if( !p_block_out ) { if( p_block_in ) block_Release( p_block_in ); break; } if( p_block_out->i_buffer > i_frame_size ) i_frame_size = p_block_out->i_buffer; /* If we are further than wanted block */ if( p_block_out->i_dts >= i_time ) { mtime_t i_diff = p_block_out->i_dts - i_time; /* Not in acceptable approximation range */ if( i_diff > CLOCK_FREQ / 10 && i_diff / i_bytemicrorate > i_frame_size ) { i_highpos = i_start_pos; i_start_pos -= ( i_diff / i_bytemicrorate ); i_start_pos = __MAX(i_start_pos, i_lowpos + i_frame_size); } else b_found = true; } else if( p_block_out->i_dts < i_time ) { mtime_t i_diff = i_time - p_block_out->i_dts; /* Not in acceptable NEXT_TIME demux range */ if( i_diff >= ((b_canfastseek) ? FLAC_MAX_PREROLL : FLAC_MAX_SLOW_PREROLL) && i_diff / i_bytemicrorate > i_frame_size ) { i_lowpos = i_start_pos; i_start_pos += ( i_diff / i_bytemicrorate ); i_start_pos = __MIN(i_start_pos, i_highpos - i_frame_size); } else b_found = true; } if( p_block_out ) block_Release( p_block_out ); if( p_block_in ) block_Release( p_block_in ); if( !b_found ) { if( i_highpos < i_lowpos || i_highpos - i_lowpos < i_frame_size ) break; if( VLC_SUCCESS != vlc_stream_Seek( p_demux->s, i_start_pos ) ) break; } } return b_found ? VLC_SUCCESS : VLC_EGENERIC; }
/***************************************************************************** * 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; bool b_eof = false; p_block_in = vlc_stream_Block( p_demux->s, H26X_PACKET_SIZE ); if( p_block_in == NULL ) { b_eof = true; } else { p_block_in->i_dts = date_Get( &p_sys->dts ); } while( (p_block_out = p_sys->p_packetizer->pf_packetize( p_sys->p_packetizer, p_block_in ? &p_block_in : NULL )) ) { while( p_block_out ) { block_t *p_next = p_block_out->p_next; p_block_out->p_next = NULL; if( p_block_in ) { p_block_in->i_dts = date_Get( &p_sys->dts ); p_block_in->i_pts = VLC_TICK_INVALID; } if( p_sys->p_es == NULL ) { p_sys->p_packetizer->fmt_out.b_packetized = true; p_sys->p_es = es_out_Add( p_demux->out, &p_sys->p_packetizer->fmt_out ); if( !p_sys->p_es ) { block_ChainRelease( p_block_out ); return VLC_DEMUXER_EOF; } } /* h264 packetizer does merge multiple NAL into AU, but slice flag persists */ bool frame = p_block_out->i_flags & BLOCK_FLAG_TYPE_MASK; const vlc_tick_t i_frame_dts = p_block_out->i_dts; const vlc_tick_t i_frame_length = p_block_out->i_length; es_out_Send( p_demux->out, p_sys->p_es, p_block_out ); if( frame ) { if( !p_sys->frame_rate_den ) { /* Use packetizer's one */ if( p_sys->p_packetizer->fmt_out.video.i_frame_rate_base && p_sys->p_packetizer->fmt_out.video.i_frame_rate ) { p_sys->frame_rate_num = p_sys->p_packetizer->fmt_out.video.i_frame_rate; p_sys->frame_rate_den = p_sys->p_packetizer->fmt_out.video.i_frame_rate_base; } else { p_sys->frame_rate_num = 25000; p_sys->frame_rate_den = 1000; } date_Init( &p_sys->dts, 2 * p_sys->frame_rate_num, p_sys->frame_rate_den ); date_Set( &p_sys->dts, VLC_TICK_0 ); msg_Dbg( p_demux, "using %.2f fps", (double) p_sys->frame_rate_num / p_sys->frame_rate_den ); } es_out_SetPCR( p_demux->out, date_Get( &p_sys->dts ) ); unsigned i_nb_fields; if( i_frame_length > 0 ) { i_nb_fields = round( (double)i_frame_length * 2 * p_sys->frame_rate_num / ( p_sys->frame_rate_den * CLOCK_FREQ ) ); } else i_nb_fields = 2; if( i_nb_fields <= 6 ) /* in the legit range */ date_Increment( &p_sys->dts, i_nb_fields ); else /* Somehow some discontinuity */ date_Set( &p_sys->dts, i_frame_dts ); } p_block_out = p_next; } } return (b_eof) ? VLC_DEMUXER_EOF : VLC_DEMUXER_SUCCESS; }
static int Open (vlc_object_t *obj) { demux_t *demux = (demux_t *)obj; int64_t size = stream_Size (demux->s); if (size > LONG_MAX /* too big for GME */) return VLC_EGENERIC; /* Auto detection */ const uint8_t *peek; if (vlc_stream_Peek (demux->s, &peek, 4) < 4) return VLC_EGENERIC; const char *type = gme_identify_header (peek); if (!*type) return VLC_EGENERIC; msg_Dbg (obj, "detected file type %s", type); block_t *data = NULL; if (size <= 0) { data = vlc_stream_Block (demux->s, 1 << 24); if (data == NULL) return VLC_EGENERIC; } /* Initialization */ demux_sys_t *sys = malloc (sizeof (*sys)); if (unlikely(sys == NULL)) return VLC_ENOMEM; sys->emu = gme_new_emu (gme_identify_extension (type), RATE); if (sys->emu == NULL) { free (sys); return VLC_ENOMEM; } if (data) { gme_load_custom (sys->emu, ReaderBlock, data->i_buffer, data); block_Release(data); } else { gme_load_custom (sys->emu, ReaderStream, size, demux->s); } gme_start_track (sys->emu, sys->track_id = 0); es_format_t fmt; es_format_Init (&fmt, AUDIO_ES, VLC_CODEC_S16N); fmt.audio.i_rate = RATE; fmt.audio.i_bytes_per_frame = 4; fmt.audio.i_frame_length = 4; fmt.audio.i_channels = 2; fmt.audio.i_blockalign = 4; fmt.audio.i_bitspersample = 16; fmt.i_bitrate = RATE * 4; sys->es = es_out_Add (demux->out, &fmt); date_Init (&sys->pts, RATE, 1); date_Set (&sys->pts, 0); /* Titles */ unsigned n = gme_track_count (sys->emu); sys->titlev = malloc (n * sizeof (*sys->titlev)); if (unlikely(sys->titlev == NULL)) n = 0; sys->titlec = n; for (unsigned i = 0; i < n; i++) { input_title_t *title = vlc_input_title_New (); sys->titlev[i] = title; if (unlikely(title == NULL)) continue; gme_info_t *infos; if (gme_track_info (sys->emu, &infos, i)) continue; msg_Dbg (obj, "track %u: %s %d ms", i, infos->song, infos->length); if (infos->length != -1) title->i_length = infos->length * INT64_C(1000); if (infos->song[0]) title->psz_name = strdup (infos->song); gme_free_info (infos); } /* Callbacks */ demux->pf_demux = Demux; demux->pf_control = Control; demux->p_sys = sys; return VLC_SUCCESS; }
/***************************************************************************** * 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; p_block_in = vlc_stream_Block( p_demux->s, H26X_PACKET_SIZE ); if( p_block_in == NULL ) { return 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; p_block_in->i_dts = date_Get( &p_sys->dts ); p_block_in->i_pts = VLC_TS_INVALID; if( p_sys->p_es == NULL ) { p_sys->p_packetizer->fmt_out.b_packetized = true; p_sys->p_es = es_out_Add( p_demux->out, &p_sys->p_packetizer->fmt_out ); if( !p_sys->p_es ) return VLC_DEMUXER_EOF; } /* h264 packetizer does merge multiple NAL into AU, but slice flag persists */ bool frame = p_block_out->i_flags & BLOCK_FLAG_TYPE_MASK; es_out_Send( p_demux->out, p_sys->p_es, p_block_out ); if( frame ) { if( !p_sys->frame_rate_den ) { /* Use packetizer's one */ if( p_sys->p_packetizer->fmt_out.video.i_frame_rate_base ) { p_sys->frame_rate_num = p_sys->p_packetizer->fmt_out.video.i_frame_rate; p_sys->frame_rate_den = p_sys->p_packetizer->fmt_out.video.i_frame_rate_base; } else { p_sys->frame_rate_num = 25000; p_sys->frame_rate_den = 1000; } date_Init( &p_sys->dts, p_sys->frame_rate_num, p_sys->frame_rate_den ); date_Set( &p_sys->dts, VLC_TS_0 ); msg_Dbg( p_demux, "using %.2f fps", (double) p_sys->frame_rate_num / p_sys->frame_rate_den ); } es_out_Control( p_demux->out, ES_OUT_SET_PCR, date_Get( &p_sys->dts ) ); date_Increment( &p_sys->dts, 1 ); } p_block_out = p_next; } } return 1; }