diff options
Diffstat (limited to 'src/demuxers/demux_elem.c')
-rw-r--r-- | src/demuxers/demux_elem.c | 284 |
1 files changed, 284 insertions, 0 deletions
diff --git a/src/demuxers/demux_elem.c b/src/demuxers/demux_elem.c new file mode 100644 index 000000000..855c22e17 --- /dev/null +++ b/src/demuxers/demux_elem.c @@ -0,0 +1,284 @@ +/* + * Copyright (C) 2000 the xine project + * + * This file is part of xine, a unix video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine 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 + * + * $Id: demux_elem.c,v 1.1 2001/04/18 22:33:58 f1rmb Exp $ + * + * demultiplexer for elementary mpeg streams + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdio.h> +#include <fcntl.h> +#include <unistd.h> +#include <pthread.h> +#include <string.h> + +#include "xine.h" +#include "monitor.h" +#include "demux.h" + +static uint32_t xine_debug; + +typedef struct _demux_mpeg_elem_globals { + fifo_buffer_t *mBufVideo; + fifo_buffer_t *mBufAudio; + + input_plugin_t *mInput; + pthread_t mThread; + int mnBlocksize; + + int mnStatus; +} demux_mpeg_elem_globals_t ; + +static demux_mpeg_elem_globals_t gDemuxMpegElem; +static fifobuf_functions_t *Ffb; + +/* + * + */ +static int demux_mpeg_elem_next (void) { + + buf_element_t *pBuf; + + pBuf = Ffb->buffer_pool_alloc (); + + pBuf->pContent = pBuf->pMem; + pBuf->nDTS = 0; + pBuf->nPTS = 0; + pBuf->nSize = gDemuxMpegElem.mInput->read(pBuf->pMem, + gDemuxMpegElem.mnBlocksize); + pBuf->nType = BUF_MPEGELEMENT; + pBuf->nInputPos = gDemuxMpegElem.mInput->seek (0, SEEK_CUR); + + Ffb->fifo_buffer_put (gDemuxMpegElem.mBufVideo, pBuf); + + return (pBuf->nSize==gDemuxMpegElem.mnBlocksize); +} + +/* + * + */ +static void *demux_mpeg_elem_loop (void *dummy) { + buf_element_t *pBuf; + + do { + + if (!demux_mpeg_elem_next()) + gDemuxMpegElem.mnStatus = DEMUX_FINISHED; + + } while (gDemuxMpegElem.mnStatus == DEMUX_OK) ; + + xprintf (VERBOSE|DEMUX, "demux loop finished (status: %d)\n", + gDemuxMpegElem.mnStatus); + + pBuf = Ffb->buffer_pool_alloc (); + pBuf->nType = BUF_STREAMEND; + Ffb->fifo_buffer_put (gDemuxMpegElem.mBufVideo, pBuf); + + pBuf = Ffb->buffer_pool_alloc (); + pBuf->nType = BUF_STREAMEND; + Ffb->fifo_buffer_put (gDemuxMpegElem.mBufAudio, pBuf); + + return NULL; +} + +/* + * + */ +static void demux_mpeg_elem_stop (void) { + void *p; + + gDemuxMpegElem.mnStatus = DEMUX_FINISHED; + + Ffb->fifo_buffer_clear(gDemuxMpegElem.mBufVideo); + Ffb->fifo_buffer_clear(gDemuxMpegElem.mBufAudio); + + pthread_join (gDemuxMpegElem.mThread, &p); +} + +/* + * + */ +static int demux_mpeg_elem_get_status (void) { + return gDemuxMpegElem.mnStatus; +} + +/* + * + */ +static void demux_mpeg_elem_start (input_plugin_t *input_plugin, + fifo_buffer_t *bufVideo, + fifo_buffer_t *bufAudio, + fifo_buffer_t *bufSPU, + off_t pos) +{ + buf_element_t *pBuf; + + gDemuxMpegElem.mInput = input_plugin; + gDemuxMpegElem.mBufVideo = bufVideo; + gDemuxMpegElem.mBufAudio = bufAudio; + + gDemuxMpegElem.mnStatus = DEMUX_OK; + /* + if ((gDemuxMpegElem.mInput->get_capabilities() & INPUT_CAP_SEEKABLE) != 0 ) { + xprintf (VERBOSE|DEMUX, "=>seek to %Ld\n",pos); + + gDemuxMpegElem.mInput->seek (pos, SEEK_SET); + } + else { */ + if((gDemuxMpegElem.mInput->get_capabilities() & INPUT_CAP_SEEKABLE) != 0) + gDemuxMpegElem.mInput->seek (pos, SEEK_SET); +/* } */ + + gDemuxMpegElem.mnBlocksize = 2048; + // pos /= (off_t) gDemuxMpegElem.mnBlocksize; + // pos *= (off_t) gDemuxMpegElem.mnBlocksize; + // xprintf (VERBOSE|DEMUX, "=>seek to %Ld\n",pos); + + // gDemuxMpegElem.mInput->seek (pos, SEEK_SET); + + /* + * send reset buffer + */ + + pBuf = Ffb->buffer_pool_alloc (); + pBuf->nType = BUF_RESET; + Ffb->fifo_buffer_put (gDemuxMpegElem.mBufVideo, pBuf); + + pBuf = Ffb->buffer_pool_alloc (); + pBuf->nType = BUF_RESET; + Ffb->fifo_buffer_put (gDemuxMpegElem.mBufAudio, pBuf); + + /* + * now start demuxing + */ + + pthread_create (&gDemuxMpegElem.mThread, NULL, demux_mpeg_elem_loop, NULL) ; +} + +/* + * + */ +static void demux_mpeg_elem_select_audio_channel (int nChannel) { +} + +/* + * + */ +static void demux_mpeg_elem_select_spu_channel (int nChannel) { +} + +/* + * + */ +static int demux_mpeg_elem_open(input_plugin_t *ip, + const char *MRL, int stage) { + + switch(stage) { + + case STAGE_BY_CONTENT: { + uint8_t buf[4096]; + int bs = 0; + + if(!ip) + return DEMUX_CANNOT_HANDLE; + + if((ip->get_capabilities() & INPUT_CAP_SEEKABLE) != 0) { + ip->seek(0, SEEK_SET); + + if(ip->get_blocksize) + bs = ip->get_blocksize(); + + bs = (bs > 4) ? bs : 4; + + if(ip->read(buf, bs)) { + + if(buf[0] || buf[1] || (buf[2] != 0x01)) + return DEMUX_CANNOT_HANDLE; + + switch(buf[3]) { + case 0xb3: + return DEMUX_CAN_HANDLE; + break; + } + } + } + return DEMUX_CANNOT_HANDLE; + } + break; + + case STAGE_BY_EXTENSION: { + char *suffix; + + suffix = strrchr(MRL, '.'); + xprintf(VERBOSE|DEMUX, "demux_pure_can_handle: suffix %s of %s\n", + suffix, MRL); + + if(suffix) { + if(!strcasecmp(suffix, ".mpv")) + return DEMUX_CAN_HANDLE; + } + + return DEMUX_CANNOT_HANDLE; + } + break; + + default: + return DEMUX_CANNOT_HANDLE; + break; + } + + return DEMUX_CANNOT_HANDLE; +} + +/* + * + */ +static char *demux_mpeg_elem_get_id(void) { + return "MPEG_ELEM"; +} + +/* + * + */ +static demux_functions_t demux_mpeg_elem_functions = { + NULL, + NULL, + demux_mpeg_elem_open, + demux_mpeg_elem_start, + demux_mpeg_elem_stop, + demux_mpeg_elem_get_status, + demux_mpeg_elem_select_audio_channel, + demux_mpeg_elem_select_spu_channel, + demux_mpeg_elem_get_id +}; + +/* + * + */ +demux_functions_t *init_demux_mpeg_elem(fifobuf_functions_t *f, uint32_t xd) { + + Ffb = f; + xine_debug = xd; + return &demux_mpeg_elem_functions; +} |