/* XMPS - X MPEG Player System * Copyright (C) 1999 Damien Chavarria * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public Licensse as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* * dummy_system.c : dummy system plugin. * */ /********************************************************************* * INCLUDES * *********************************************************************/ /* * includes : local * */ #include "mpeg3_system.h" /********************************************************************* * VARIABLES * *********************************************************************/ typedef struct { xmps_media_plugin_t *our_media; xmps_data_t *video_stream; xmps_data_t *audio_stream; xmps_data_t *subtitles_stream; xmps_time_t *time_info; GList *output_list; unsigned int buffer_size; double frame_rate; mpeg3_t *mpeg3; int video_time; int sub_time; pthread_mutex_t mutex; } mpeg3_system_t; /********************************************************************* * FUNCTIONS * *********************************************************************/ /* * get_system_info : MANDATORY * * Used by the plugin_center to get a pointer to the system object. * */ xmps_system_plugin_t *get_system_info(void) { xmps_system_plugin_t *system; system = (xmps_system_plugin_t *) malloc(sizeof(xmps_system_plugin_t)); system->name = "MPEG3"; system->data = (void *) malloc(sizeof(mpeg3_system_t)); system->open = mpeg3_open; system->get = mpeg3_get; system->set = mpeg3_set; system->read = mpeg3_read; system->seek = mpeg3_seek; system->write = mpeg3_write; system->close = mpeg3_close; ((mpeg3_system_t *) system->data)->our_media = NULL; ((mpeg3_system_t *) system->data)->video_stream = (xmps_data_t *) malloc(sizeof(xmps_data_t)); ((mpeg3_system_t *) system->data)->audio_stream = (xmps_data_t *) malloc(sizeof(xmps_data_t)); ((mpeg3_system_t *) system->data)->subtitles_stream = (xmps_data_t *) malloc(sizeof(xmps_data_t)); ((mpeg3_system_t *) system->data)->time_info = (xmps_time_t *) malloc(sizeof(xmps_time_t)); ((mpeg3_system_t *) system->data)->output_list = NULL; ((mpeg3_system_t *) system->data)->buffer_size = 0; return system; } /* * mpeg3_open * * - try to open a media. * */ unsigned int mpeg3_open(xmps_system_plugin_t *system) //unsigned int flag, void *p_center, xmps_media_plugin *media) { mpeg3_system_t *data; if(system == NULL) { return 0; } data = (mpeg3_system_t *) system->data; if(data == NULL) { return 0; } pthread_mutex_init(&data->mutex, NULL); return 1; } /* * mpeg3_set_info * */ unsigned int mpeg3_set(xmps_system_plugin_t *system, unsigned int flag, void *arg) { mpeg3_system_t *data; if(system == NULL) { return 0; } data = (mpeg3_system_t *) system->data; if(data == NULL) { return 0; } switch(flag) { case XMPS_FLAG_INPUT: { xmps_data_t *data_stream; unsigned int bits, i; XMPS_DEBUG("setting input!"); data_stream = (xmps_data_t *) arg; if(data_stream != NULL && data_stream->type == XMPS_DATA_RAW && data_stream->plugin_type == XMPS_PLUGIN_MEDIA) { XMPS_DEBUG("we try to open %s media", ((xmps_media_plugin_t *) data_stream->plugin)->name); data->our_media = (xmps_media_plugin_t *) data_stream->plugin; data->mpeg3 = mpeg3_new(data->our_media); /* * read the first 32 bits * */ data->our_media->seek(data->our_media, 0, XMPS_SEEK_SET); bits = mpeg3io_read_int32(data->mpeg3->fs); XMPS_DEBUG("first 4 bytes = %d", bits); if(((bits >> 24) & 0xff) == MPEG3_SYNC_BYTE) { data->mpeg3->packet_size = MPEG3_TS_PACKET_SIZE; data->mpeg3->is_transport_stream = 1; } else if(bits == MPEG3_PACK_START_CODE) { data->mpeg3->packet_size = MPEG3_DVD_PACKET_SIZE; data->mpeg3->demuxer->packet_size = 2080; data->mpeg3->is_program_stream = 1; } else if((bits & 0xfff00000) == 0xfff00000 || ((bits >> 8) == MPEG3_ID3_PREFIX)) { data->mpeg3->packet_size = MPEG3_DVD_PACKET_SIZE; data->mpeg3->has_audio = 1; data->mpeg3->is_audio_stream = 1; } else if(bits == MPEG3_SEQUENCE_START_CODE || bits == MPEG3_PICTURE_START_CODE) { data->mpeg3->packet_size = MPEG3_DVD_PACKET_SIZE; data->mpeg3->is_video_stream = 1; } else { return 0; } XMPS_DEBUG("Media can be played by mpeg3 system layer!"); data->our_media->seek(data->our_media, 0, XMPS_SEEK_SET); /* * now see about the streams * insude the media * */ if(!data->mpeg3->demuxer->total_titles) { mpeg3demux_create_title(data->mpeg3->demuxer, 0, 0); } if(data->mpeg3->is_transport_stream || data->mpeg3->is_program_stream) { /* * scan for video streams */ for(i = 0; i < MPEG3_MAX_STREAMS; i++) { if(data->mpeg3->demuxer->vstream_table[i]) { data->mpeg3->vtrack[data->mpeg3->total_vstreams] = mpeg3_new_vtrack(data->mpeg3, i, data->mpeg3->demuxer); if(data->mpeg3->vtrack[data->mpeg3->total_vstreams]) { data->mpeg3->total_vstreams++; } } } /* * scan for audio streams */ for(i = 0; i < MPEG3_MAX_STREAMS; i++) { if(data->mpeg3->demuxer->astream_table[i]) { data->mpeg3->atrack[data->mpeg3->total_astreams] = mpeg3_new_atrack(data->mpeg3, i, data->mpeg3->demuxer->astream_table[i], data->mpeg3->demuxer); if(data->mpeg3->atrack[data->mpeg3->total_astreams]) { data->mpeg3->total_astreams++; } } } /* * scan for subtitles streams */ for(i = 0; i < MPEG3_MAX_STREAMS; i++) { if(data->mpeg3->demuxer->sstream_table[i] == 1) { data->mpeg3->strack[data->mpeg3->total_sstreams] = mpeg3_new_strack(data->mpeg3, i, data->mpeg3->demuxer); if(data->mpeg3->strack[data->mpeg3->total_sstreams]) { data->mpeg3->total_sstreams++; } } } } else { if(data->mpeg3->is_video_stream) { data->mpeg3->vtrack[0] = mpeg3_new_vtrack(data->mpeg3, -1, data->mpeg3->demuxer); if(data->mpeg3->vtrack[0]) { data->mpeg3->total_vstreams++; } } else { if(data->mpeg3->is_audio_stream) { data->mpeg3->atrack[0] = mpeg3_new_atrack(data->mpeg3, -1, AUDIO_UNKNOWN, data->mpeg3->demuxer); if(data->mpeg3->atrack[0]) { data->mpeg3->total_astreams++; } } } } if(data->mpeg3->total_vstreams) data->mpeg3->has_video = 1; if(data->mpeg3->total_astreams) data->mpeg3->has_audio = 1; if(data->mpeg3->total_sstreams) data->mpeg3->has_subtitles = 1; XMPS_DEBUG("media has %d video stream(s)", data->mpeg3->total_vstreams); XMPS_DEBUG("media has %d audio stream(s)", data->mpeg3->total_astreams); XMPS_DEBUG("media has %d subtitles stream(s)", data->mpeg3->total_sstreams); return 1; } return 0; } break; default: break; } return 0; } /* * mpeg3_get_info * * */ void *mpeg3_get(xmps_system_plugin_t *system, unsigned int flag, void *arg) { mpeg3_system_t *data; if(system == NULL) { return 0; } data = (mpeg3_system_t *) system->data; if(data == NULL) { return 0; } switch(flag) { case XMPS_FLAG_TIME_INFO: { if(data->mpeg3->total_vstreams >= 1) { data->time_info->current_time = mpeg3demux_get_time(data->mpeg3->vtrack[0]->demuxer); data->time_info->total_time = mpeg3demux_total_length(data->mpeg3->vtrack[0]->demuxer); return data->time_info; } else { if(data->mpeg3->total_astreams >= 1) { data->time_info->current_time = (int) ((double) mpeg3demux_tell_percentage(data->mpeg3->atrack[0]->demuxer) * 100); data->time_info->total_time = 100; return data->time_info; } else { return NULL; } } } case XMPS_FLAG_TIME: { int *stream_id; stream_id = (int *) arg; if(stream_id != NULL) { switch(*stream_id) { case 1: data->video_time = ((mpeg3_t *) data->mpeg3->strack[0]->demuxer->file)->video_time; return &data->video_time; break; case 3: data->sub_time = ((mpeg3_t *) data->mpeg3->strack[0]->demuxer->file)->subtitle_time; return &data->sub_time; break; } } } break; case XMPS_FLAG_FRAMERATE: if(data->frame_rate == 0) { data->frame_rate = 25.0; } data->frame_rate = 25.0; return (void *) &data->frame_rate; break; case XMPS_FLAG_VIDEO_BUFFER_SIZE: return &data->buffer_size; break; case XMPS_FLAG_OUTPUT_LIST: { if( data->our_media != NULL ) { /* * re-init output list * */ data->output_list = NULL; /* * fill data structures * */ if(data->mpeg3->total_vstreams >= 1) { data->video_stream->id = 1; data->video_stream->type = XMPS_DATA_VIDEO_COMP; data->video_stream->video_compression = "MPG3"; data->video_stream->audio_compression = NULL; data->video_stream->user_data = (void *) &data->frame_rate; data->video_stream->plugin_type = XMPS_PLUGIN_SYSTEM; data->video_stream->plugin = system; data->output_list = g_list_prepend(data->output_list, data->video_stream); } if(data->mpeg3->total_astreams >= 1) { data->audio_stream->id = 2; data->audio_stream->type = XMPS_DATA_AUDIO_COMP; data->audio_stream->audio_compression = "MPG3"; data->audio_stream->video_compression = NULL; data->audio_stream->user_data = (void *) data->mpeg3->atrack[0]; data->audio_stream->plugin_type = XMPS_PLUGIN_SYSTEM; data->audio_stream->plugin = system; data->output_list = g_list_prepend(data->output_list, data->audio_stream); } if(data->mpeg3->total_sstreams >= 1) { data->subtitles_stream->id = 3; data->subtitles_stream->type = XMPS_DATA_SUBTITLES; data->subtitles_stream->audio_compression = NULL; data->subtitles_stream->video_compression = NULL; data->subtitles_stream->total_subtitles = data->mpeg3->total_sstreams; data->subtitles_stream->plugin_type = XMPS_PLUGIN_SYSTEM; data->subtitles_stream->plugin = system; data->output_list = g_list_prepend(data->output_list, data->subtitles_stream); } return (void *) data->output_list; } } break; default: break; } return NULL; } /* * mpeg3_read * */ int mpeg3_read(xmps_system_plugin_t *system, unsigned int stream_id, void *buffer, long size) { mpeg3_system_t * data; data = (mpeg3_system_t *) system->data; switch(stream_id) { case 1: if(size == -1) { if( data->mpeg3->vtrack[0]->demuxer->data_position != 0) { *((char *)buffer) = data->mpeg3->vtrack[0]->demuxer->data_buffer[data->mpeg3->vtrack[0]->demuxer->data_position--]; } else { pthread_mutex_lock(&data->mutex); *((char *) buffer) = mpeg3demux_read_prev_char_packet(data->mpeg3->vtrack[0]->demuxer); pthread_mutex_unlock(&data->mutex); } } else { pthread_mutex_lock(&data->mutex); mpeg3demux_read_data(data->mpeg3->vtrack[0]->demuxer, buffer, size); pthread_mutex_unlock(&data->mutex); } break; case 2: pthread_mutex_lock(&data->mutex); mpeg3demux_read_data(data->mpeg3->atrack[0]->demuxer, buffer, size); pthread_mutex_unlock(&data->mutex); if(mpeg3demux_eof(data->mpeg3->atrack[0]->demuxer)) { return -1; } break; case 3: pthread_mutex_lock(&data->mutex); mpeg3demux_read_data(data->mpeg3->strack[0]->demuxer, buffer, size); pthread_mutex_unlock(&data->mutex); break; default: break; } return 1; } /* * mpeg3_seek * */ unsigned int mpeg3_seek(xmps_system_plugin_t *system, unsigned int stream_id, unsigned int pos, xmps_seeking_method_t method) { mpeg3_system_t * data; if(system == NULL) return 0; data = (mpeg3_system_t *) system->data; if(data == NULL) { return 0; } switch(method) { case XMPS_SEEK_PERCENT: { if(data->mpeg3 != NULL) { double f; f = ((double)pos) / 100; XMPS_DEBUG("seeking to %f", f); if(data->mpeg3->total_vstreams >= 1) { XMPS_DEBUG("seeking to %d for video -> %f", pos, f); pthread_mutex_lock(&data->mutex); f = mpeg3demux_seek_percentage(data->mpeg3->vtrack[0]->demuxer, f); pthread_mutex_unlock(&data->mutex); } XMPS_DEBUG("seeking audio to %f", f); if(data->mpeg3->total_astreams >= 1) { pthread_mutex_lock(&data->mutex); mpeg3demux_seek_percentage(data->mpeg3->atrack[0]->demuxer, f); pthread_mutex_unlock(&data->mutex); } return 1; } } break; case XMPS_SEEK_SET: switch(stream_id) { case 1: return mpeg3demux_seek_byte(data->mpeg3->vtrack[0]->demuxer, pos); break; case 2: return mpeg3demux_seek_byte(data->mpeg3->atrack[0]->demuxer, pos); break; default: break; } break; case XMPS_SEEK_CUR: { switch(stream_id) { case 1: if(pos == 0) { return mpeg3demux_tell(data->mpeg3->vtrack[0]->demuxer); } else { } break; case 2: if(pos == 0) { return mpeg3demux_tell(data->mpeg3->atrack[0]->demuxer); } else { } break; default: break; } } break; case XMPS_SEEK_END: { switch(stream_id) { case 1: mpeg3demux_seek_byte(data->mpeg3->vtrack[0]->demuxer, mpeg3demuxer_total_bytes(data->mpeg3->vtrack[0]->demuxer) - pos); break; case 2: mpeg3demux_seek_byte(data->mpeg3->atrack[0]->demuxer, mpeg3demuxer_total_bytes(data->mpeg3->atrack[0]->demuxer) - pos); break; default: break; } } break; default: return 0; break; } return 0; } /* * mpeg3_write * */ unsigned int mpeg3_write(xmps_system_plugin_t *system, unsigned int data_id, const void *buffer, unsigned int size) { return 0; } /* * mpeg3_close * */ unsigned int mpeg3_close(xmps_system_plugin_t *system) { if(system == NULL) { return 0; } if(((mpeg3_system_t *) system->data)->our_media != NULL) { ((mpeg3_system_t *) system->data)->our_media->close(((mpeg3_system_t *) system->data)->our_media); ((mpeg3_system_t *) system->data)->our_media = NULL; } return 1; }