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 = stream_Block( p_demux->s, i ) ) == NULL ) { msg_Warn( p_demux, "cannot read data" ); return 0; } if( !p_sys->i_frame_length || !p_sys->i_time ) { p_sys->i_time = p_block->i_dts = p_block->i_pts = mdate(); } else { p_block->i_dts = p_block->i_pts = VLC_TS_0 + p_sys->i_time; p_sys->i_time += p_sys->i_frame_length; } /* 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_still_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; unsigned i_frames = p_sys->i_block_frames; i_offset = 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 = stream_Block( p_demux->s, p_sys->fmt.audio.i_bytes_per_frame * i_frames ); if( p_block == NULL ) { msg_Warn( p_demux, "cannot read data" ); return 0; } i_frames = p_block->i_buffer / p_sys->fmt.audio.i_bytes_per_frame; p_block->i_dts = p_block->i_pts = VLC_TS_0 + 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 * p_sys->fmt.audio.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; 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; }
/***************************************************************************** * 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_block_in = stream_Block( p_demux->s, HEVC_BLOCK_SIZE ) ) == NULL ) { return 0; } p_block_in->i_dts = VLC_TS_INVALID; p_block_in->i_pts = VLC_TS_INVALID; 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_out->i_dts = p_sys->i_dts; p_block_out->i_pts = VLC_TS_INVALID; uint8_t nal_type = p_block_out->p_buffer[4] & 0x7E; /*Get fps from vps if available and not already forced*/ if( p_sys->f_fps == 0.0f && nal_type == 0x40 ) { if( getFPS( p_demux, p_block_out) ) { msg_Err(p_demux,"getFPS failed"); return 0; } } /* Update DTS only on VCL NAL*/ if( nal_type < 0x40 && p_sys->f_fps ) { es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_dts ); p_sys->i_dts += (int64_t)((float)CLOCK_FREQ / p_sys->f_fps); } es_out_Send( p_demux->out, p_sys->p_es, p_block_out ); p_block_out = p_next; } } return 1; }
static block_t *Load(demux_t *demux) { const int max_size = 4096 * 4096 * 8; const int64_t size = stream_Size(demux->s); if (size < 0 || size > max_size) { msg_Err(demux, "Rejecting image based on its size (%"PRId64" > %d)", size, max_size); return NULL; } if (size > 0) return stream_Block(demux->s, size); /* TODO */ 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_in, *p_block_out; if( ( p_block_in = stream_Block( p_demux->s, VC1_PACKET_SIZE ) ) == NULL ) return 0; /* */ p_block_in->i_dts = VLC_TS_0; p_block_in->i_pts = 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_packetizer->fmt_out.b_packetized = true; p_sys->p_es = es_out_Add( p_demux->out, &p_sys->p_packetizer->fmt_out); } es_out_Control( p_demux->out, ES_OUT_SET_PCR, VLC_TS_0 + p_sys->i_dts ); p_block_out->i_dts = VLC_TS_0 + p_sys->i_dts; p_block_out->i_pts = VLC_TS_0 + p_sys->i_dts; es_out_Send( p_demux->out, p_sys->p_es, p_block_out ); p_block_out = p_next; if( p_sys->p_packetizer->fmt_out.video.i_frame_rate > 0 && p_sys->p_packetizer->fmt_out.video.i_frame_rate_base > 0 ) p_sys->i_dts += INT64_C(1000000) * p_sys->p_packetizer->fmt_out.video.i_frame_rate_base / p_sys->p_packetizer->fmt_out.video.i_frame_rate; else if( p_sys->f_fps > 0.001 ) p_sys->i_dts += (int64_t)((double)1000000.0 / p_sys->f_fps); else p_sys->i_dts += INT64_C(1000000) / 25; } } 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; if( !( p_block_in = stream_Block( p_demux->s, FLAC_PACKET_SIZE ) ) ) return 0; p_block_in->i_pts = p_block_in->i_dts = p_sys->b_start ? VLC_TS_0 : VLC_TS_INVALID; p_sys->b_start = false; 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_packetizer->fmt_out.b_packetized = true; p_sys->p_packetizer->fmt_out.audio_replay_gain = p_sys->replay_gain; p_sys->p_es = es_out_Add( p_demux->out, &p_sys->p_packetizer->fmt_out); } p_sys->i_pts = p_block_out->i_dts - VLC_TS_0; /* Correct timestamp */ p_block_out->i_pts += p_sys->i_time_offset; p_block_out->i_dts += p_sys->i_time_offset; /* set PCR */ 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; }
/***************************************************************************** * 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; p_block = stream_Block( p_demux->s, CDG_FRAME_SIZE ); if( p_block == NULL ) { msg_Dbg( p_demux, "cannot read data, eof" ); return 0; } p_block->i_dts = p_block->i_pts = date_Increment( &p_sys->pts, 1 ); 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 ); 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; if( ( p_block_in = stream_Block( p_demux->s, H264_PACKET_SIZE ) ) == NULL ) { return 0; } /* m4v demuxer doesn't set pts/dts at all */ p_block_in->i_dts = 1; p_block_in->i_pts = 1; 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_packetizer->fmt_out.b_packetized = VLC_TRUE; p_sys->p_es = es_out_Add( p_demux->out, &p_sys->p_packetizer->fmt_out); } es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_dts ); p_block_out->i_dts = p_sys->i_dts; p_block_out->i_pts = p_sys->i_dts; es_out_Send( p_demux->out, p_sys->p_es, p_block_out ); p_block_out = p_next; p_sys->i_dts += (int64_t)((double)1000000.0 / p_sys->f_fps); } } 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 = !( p_block_in = stream_Block( p_demux->s, FLAC_PACKET_SIZE ) ); if ( p_block_in ) { p_block_in->i_pts = p_block_in->i_dts = p_sys->b_start ? VLC_TS_0 : VLC_TS_INVALID; p_sys->b_start = false; } 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_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); } p_sys->i_pts = p_block_out->i_dts; /* set PCR */ 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 !b_eof; }
/***************************************************************************** * 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_block_in = stream_Block( p_demux->s, MPGV_PACKET_SIZE ) ) == NULL ) { return 0; } if( p_sys->b_start ) { p_block_in->i_pts = p_block_in->i_dts = VLC_TS_0; } else { p_block_in->i_pts = p_block_in->i_dts = VLC_TS_INVALID; } while( (p_block_out = p_sys->p_packetizer->pf_packetize( p_sys->p_packetizer, &p_block_in )) ) { 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 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; mtime_t i_pcr = date_Get( &p_sys->pcr ); /* Call the pace control */ es_out_Control( p_demux->out, ES_OUT_SET_PCR, VLC_TS_0 + i_pcr ); if( p_sys->b_y4m ) { /* Skip the frame header */ /* Skip "FRAME" */ if( stream_Read( p_demux->s, NULL, 5 ) < 5 ) return 0; /* Find \n */ for( ;; ) { uint8_t b; if( stream_Read( p_demux->s, &b, 1 ) < 1 ) return 0; if( b == 0x0a ) break; } } if( ( p_block = stream_Block( p_demux->s, p_sys->frame_size ) ) == NULL ) { /* EOF */ return 0; } p_block->i_dts = p_block->i_pts = VLC_TS_0 + i_pcr; es_out_Send( p_demux->out, p_sys->p_es_video, p_block ); date_Increment( &p_sys->pcr, 1 ); 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; /* set PCR */ es_out_Control( p_demux->out, ES_OUT_SET_PCR, VLC_TS_0 + p_sys->i_time ); if( ( p_block = stream_Block( p_demux->s, p_sys->i_frame_size ) ) == 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; if( ( p_block_in = stream_Block( p_demux->s, M4A_PACKET_SIZE ) ) == NULL ) { return 0; } p_block_in->i_pts = p_block_in->i_dts = p_sys->b_start ? 1 : 0; p_sys->b_start = VLC_FALSE; 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; if( p_sys->p_es == NULL ) { p_sys->p_packetizer->fmt_out.b_packetized = VLC_TRUE; p_sys->p_es = es_out_Add( p_demux->out, &p_sys->p_packetizer->fmt_out); } 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 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; const int64_t i_pos = stream_Tell( p_demux->s ); if( p_sys->i_data_size > 0 && i_pos >= p_sys->i_data_pos + p_sys->i_data_size ) { /* EOF */ return 0; } if( ( p_block = stream_Block( p_demux->s, p_sys->i_frame_size ) ) == NULL ) { msg_Warn( p_demux, "cannot read data" ); return 0; } p_block->i_dts = p_block->i_pts = VLC_TS_0 + date_Get( &p_sys->pts ); /* set PCR */ es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block->i_pts ); /* Do the channel reordering */ if( p_sys->i_chans_to_reorder ) aout_ChannelReorder( p_block->p_buffer, p_block->i_buffer, p_sys->fmt.audio.i_channels, p_sys->pi_chan_table, p_sys->fmt.i_codec ); es_out_Send( p_demux->out, p_sys->p_es, p_block ); date_Increment( &p_sys->pts, p_sys->i_frame_samples ); 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; /* Align stream */ int64_t i_pos = stream_Tell( p_demux->s ); if( i_pos % 2 ) stream_Read( p_demux->s, NULL, 1 ); if( !( p_block_in = stream_Block( p_demux->s, A52_PACKET_SIZE ) ) ) { return 0; } if( !p_sys->b_big_endian && p_block_in->i_buffer ) { /* Convert to big endian */ #ifdef HAVE_SWAB swab(p_block_in->p_buffer, p_block_in->p_buffer, p_block_in->i_buffer); #else int i; byte_t *p_tmp, tmp; p_tmp = p_block_in->p_buffer; for( i = p_block_in->i_buffer / 2 ; i-- ; ) { tmp = p_tmp[0]; p_tmp[0] = p_tmp[1]; p_tmp[1] = tmp; p_tmp += 2; } #endif } if( p_sys->b_start ) p_block_in->i_pts = p_block_in->i_dts = 1; else p_block_in->i_pts = p_block_in->i_dts = 0; while( (p_block_out = p_sys->p_packetizer->pf_packetize( p_sys->p_packetizer, &p_block_in )) ) { p_sys->b_start = VLC_FALSE; while( p_block_out ) { block_t *p_next = p_block_out->p_next; /* We assume a constant bitrate */ if( p_block_out->i_length ) { p_sys->i_mux_rate = p_block_out->i_buffer * I64C(1000000)/p_block_out->i_length; } /* set PCR */ 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; }
/***************************************************************************** * 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_block_in = stream_Block( p_demux->s, H26X_PACKET_SIZE ) ) == 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; }
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 (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 = 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; }
static int HandleMessage (demux_t *p_demux, mtrk_t *tr) { stream_t *s = p_demux->s; block_t *block; uint8_t first, event; unsigned datalen; if (stream_Seek (s, tr->offset) || (stream_Read (s, &first, 1) != 1)) return -1; event = (first & 0x80) ? first : tr->running_event; switch (event & 0xf0) { case 0xF0: /* System Exclusive */ switch (event) { case 0xF0: /* System Specific start */ case 0xF7: /* System Specific continuation */ { /* Variable length followed by SysEx event data */ int32_t len = ReadVarInt (s); if (len == -1) return -1; block = stream_Block (s, len); if (block == NULL) return -1; block = block_Realloc (block, 1, len); if (block == NULL) return -1; block->p_buffer[0] = event; goto send; } case 0xFF: /* SMF Meta Event */ if (HandleMeta (p_demux, tr)) return -1; /* We MUST NOT pass this event forward. It would be * confused as a MIDI Reset real-time event. */ goto skip; case 0xF1: case 0xF3: datalen = 1; break; case 0xF2: datalen = 2; break; case 0xF4: case 0xF5: /* We cannot handle undefined "common" (non-real-time) * events inside SMF, as we cannot differentiate a * one byte delta-time (< 0x80) from event data. */ default: datalen = 0; break; } break; case 0xC0: case 0xD0: datalen = 1; break; default: datalen = 2; break; } /* FIXME: one message per block is very inefficient */ block = block_New (p_demux, 1 + datalen); if (block == NULL) goto skip; block->p_buffer[0] = event; if (first & 0x80) { stream_Read (s, block->p_buffer + 1, datalen); } else { if (datalen == 0) { msg_Err (p_demux, "malformatted MIDI event"); return -1; /* can't use implicit running status with empty payload! */ } block->p_buffer[1] = first; if (datalen > 1) stream_Read (s, block->p_buffer + 2, datalen - 1); } send: block->i_dts = block->i_pts = VLC_TS_0 + date_Get (&p_demux->p_sys->pts); es_out_Send (p_demux->out, p_demux->p_sys->es, block); skip: if (event < 0xF8) /* If event is not real-time, update running status */ tr->running_event = event; tr->offset = stream_Tell (s); return 0; }