Example #1
0
static demuxer_t* demux_ppbox_open(demuxer_t* demuxer) {
  ppbox_demux_priv_t * priv = (ppbox_demux_priv_t *)calloc(sizeof(ppbox_demux_priv_t), 1);
  priv->duration = PPBOX_GetDuration()();
  priv->stream_count = PPBOX_GetStreamCount()();

  mp_msg(MSGT_DEMUX, MSGL_ERR, "demux_ppbox_open duration %u\n", priv->duration);
  mp_msg(MSGT_DEMUX, MSGL_ERR, "demux_ppbox_open stream count %u\n", priv->stream_count);

  for (uint32_t idx = 0; idx < priv->stream_count; ++idx) {
    PPBOX_StreamInfoEx info;
    PPBOX_GetStreamInfoEx()(idx, &info);
    if (info.type == ppbox_video) {
      mp_msg(MSGT_DEMUX, MSGL_ERR, "video stream\n");
      sh_video_t* sh_video = new_sh_video(demuxer, idx);;
      BITMAPINFOHEADER *bih = calloc(sizeof(*bih) + info.format_size, 1);
      bih->biSize = sizeof(*bih) + info.format_size;
      bih->biCompression = mmioFOURCC('H', '2', '6', '4');
      bih->biWidth = info.video_format.width;
      bih->biHeight = info.video_format.height;
      memcpy(bih + 1, info.format_buffer, info.format_size);
      sh_video->format = bih->biCompression;
      sh_video->disp_w = info.video_format.width;
      sh_video->disp_h = info.video_format.height;
      sh_video->fps = info.video_format.frame_rate;
      sh_video->frametime = 1.0 / info.video_format.frame_rate;
      sh_video->bih = bih;
      demuxer->video->sh = sh_video;
      priv->streams[idx] = demuxer->video;
    } else if (info.type == ppbox_audio) {
      mp_msg(MSGT_DEMUX, MSGL_ERR, "audio stream\n");
#if STREAMTYPE_PPBOX == 21
      sh_audio_t* sh_audio = new_sh_audio(demuxer, idx);
#else
      sh_audio_t* sh_audio = new_sh_audio(demuxer, idx, NULL);
#endif
      WAVEFORMATEX *wf = calloc(sizeof(*wf) + info.format_size, 1);;
      wf->wFormatTag = 255;
      wf->nChannels = info.audio_format.channel_count;
      wf->nSamplesPerSec = info.audio_format.sample_rate;
      wf->wBitsPerSample = info.audio_format.sample_size;
      wf->cbSize = info.format_size;
      memcpy(wf + 1, info.format_buffer, info.format_size);
      sh_audio->wf = wf;
      sh_audio->format = mmioFOURCC('M', 'P', '4', 'A');
      sh_audio->samplerate = info.audio_format.sample_rate;
      sh_audio->samplesize = info.audio_format.sample_size;
      sh_audio->channels = info.audio_format.channel_count;
      demuxer->audio->sh = sh_audio;
      demuxer->audio->id = idx;
      priv->streams[idx] = demuxer->audio;
    }
  }
  demuxer->seekable = priv->duration > 0;
  demuxer->priv = priv;

  return demuxer;
}
Example #2
0
static demuxer_t* demux_open_y4m(demuxer_t* demuxer){
    y4m_priv_t* priv = demuxer->priv;
    sh_video_t* sh=new_sh_video(demuxer,0);

    priv->framenum = 0;
    priv->si = malloc(sizeof(y4m_stream_info_t));

    sh->bih=calloc(1, sizeof(*sh->bih));

    demuxer->video->sh=sh;
    sh->ds=demuxer->video;
    demuxer->video->id=0;

    read_streaminfo(demuxer);

    return demuxer;
}
static demuxer_t* demux_open_rawdv(demuxer_t* demuxer)
{
   unsigned char dv_frame[DV_PAL_FRAME_SIZE];
   sh_video_t *sh_video = NULL;
   rawdv_frames_t *frames = malloc(sizeof(rawdv_frames_t));
   dv_decoder_t *dv_decoder=NULL;

   mp_msg(MSGT_DEMUXER,MSGL_V,"demux_open_rawdv() end_pos %"PRId64"\n",(int64_t)demuxer->stream->end_pos);

   // go back to the beginning
   stream_reset(demuxer->stream);
   stream_seek(demuxer->stream, 0);

   //get the first frame
   stream_read(demuxer->stream, dv_frame, DV_PAL_FRAME_SIZE);

   //read params from this frame
   dv_decoder=dv_decoder_new(TRUE,TRUE,FALSE);
   dv_decoder->quality=DV_QUALITY_BEST;

   if (dv_parse_header(dv_decoder, dv_frame) == -1)
	   return NULL;

   // create a new video stream header
   sh_video = new_sh_video(demuxer, 0);
   if (!sh_video)
	   return NULL;

   // make sure the demuxer knows about the new video stream header
   // (even though new_sh_video() ought to take care of it)
   demuxer->seekable = 1;
   demuxer->video->sh = sh_video;

   // make sure that the video demuxer stream header knows about its
   // parent video demuxer stream (this is getting wacky), or else
   // video_read_properties() will choke
   sh_video->ds = demuxer->video;

   // custom fourcc for internal MPlayer use
//   sh_video->format = mmioFOURCC('R', 'A', 'D', 'V');
   sh_video->format = mmioFOURCC('D', 'V', 'S', 'D');

   sh_video->disp_w = dv_decoder->width;
   sh_video->disp_h = dv_decoder->height;
   mp_msg(MSGT_DEMUXER,MSGL_V,"demux_open_rawdv() frame_size: %d w: %d h: %d dif_seq: %d system: %d\n",dv_decoder->frame_size,dv_decoder->width, dv_decoder->height,dv_decoder->num_dif_seqs,dv_decoder->system);

   sh_video->fps= (dv_decoder->system==e_dv_system_525_60?29.97:25);
   sh_video->frametime = 1.0/sh_video->fps;

  // emulate BITMAPINFOHEADER for win32 decoders:
  sh_video->bih=malloc(sizeof(BITMAPINFOHEADER));
  memset(sh_video->bih,0,sizeof(BITMAPINFOHEADER));
  sh_video->bih->biSize=40;
  sh_video->bih->biWidth = dv_decoder->width;
  sh_video->bih->biHeight = dv_decoder->height;
  sh_video->bih->biPlanes=1;
  sh_video->bih->biBitCount=24;
  sh_video->bih->biCompression=sh_video->format; // "DVSD"
  sh_video->bih->biSizeImage=sh_video->bih->biWidth*sh_video->bih->biHeight*3;


   frames->current_filepos=0;
   frames->current_frame=0;
   frames->frame_size=dv_decoder->frame_size;
   frames->frame_number=demuxer->stream->end_pos/frames->frame_size;

   mp_msg(MSGT_DEMUXER,MSGL_V,"demux_open_rawdv() seek to %qu, size: %d, dv_dec->frame_size: %d\n",frames->current_filepos,frames->frame_size, dv_decoder->frame_size);
    if (dv_decoder->audio != NULL && demuxer->audio->id>=-1){
       sh_audio_t *sh_audio =  new_sh_audio(demuxer, 0);
	    demuxer->audio->sh = sh_audio;
	    sh_audio->ds = demuxer->audio;
       mp_msg(MSGT_DEMUXER,MSGL_V,"demux_open_rawdv() chan: %d samplerate: %d\n",dv_decoder->audio->num_channels,dv_decoder->audio->frequency );
       // custom fourcc for internal MPlayer use
       sh_audio->format = mmioFOURCC('R', 'A', 'D', 'V');

	sh_audio->wf = malloc(sizeof(WAVEFORMATEX));
	memset(sh_audio->wf, 0, sizeof(WAVEFORMATEX));
	sh_audio->wf->wFormatTag = sh_audio->format;
	sh_audio->wf->nChannels = dv_decoder->audio->num_channels;
	sh_audio->wf->wBitsPerSample = 16;
	sh_audio->wf->nSamplesPerSec = dv_decoder->audio->frequency;
	// info about the input stream:
	sh_audio->wf->nAvgBytesPerSec = sh_video->fps*dv_decoder->frame_size;
	sh_audio->wf->nBlockAlign = dv_decoder->frame_size;

//       sh_audio->context=(void*)dv_decoder;
    }
   stream_reset(demuxer->stream);
   stream_seek(demuxer->stream, 0);
   dv_decoder_free(dv_decoder);  //we keep this in the context of both stream headers
   demuxer->priv=frames;
   return demuxer;
}
Example #4
0
static demuxer_t* demux_open_tv(demuxer_t *demuxer)
{
    tvi_handle_t *tvh;
    sh_video_t *sh_video;
    sh_audio_t *sh_audio = NULL;
    const tvi_functions_t *funcs;

    demuxer->priv=NULL;
    if(!(tvh=tv_begin(demuxer->stream->priv))) return NULL;
    if (!tvh->functions->init(tvh->priv)) return NULL;

    tvh->demuxer = demuxer;
    tvh->functions->control(tvh->priv,TVI_CONTROL_VBI_INIT,
                            &(tvh->tv_param->teletext.device));
    tvh->functions->control(tvh->priv,TVI_CONTROL_GET_VBI_PTR,
                            &demuxer->teletext);

    if (!open_tv(tvh)) {
        tv_uninit(tvh);
        return NULL;
    }
    funcs = tvh->functions;
    demuxer->priv=tvh;

    sh_video = new_sh_video(demuxer, 0);

    /* get IMAGE FORMAT */
    funcs->control(tvh->priv, TVI_CONTROL_VID_GET_FORMAT, &sh_video->format);
//    if (IMGFMT_IS_RGB(sh_video->format) || IMGFMT_IS_BGR(sh_video->format))
//	sh_video->format = 0x0;

    /* set FPS and FRAMETIME */

    if(!sh_video->fps)
    {
        float tmp;
        if (funcs->control(tvh->priv, TVI_CONTROL_VID_GET_FPS, &tmp) != TVI_CONTROL_TRUE)
            sh_video->fps = 25.0f; /* on PAL */
        else sh_video->fps = tmp;
    }

    if (tvh->tv_param->fps != -1.0f)
        sh_video->fps = tvh->tv_param->fps;

    sh_video->frametime = 1.0f/sh_video->fps;

    /* If playback only mode, go to immediate mode, fail silently */
    if(tvh->tv_param->immediate == 1)
    {
        funcs->control(tvh->priv, TVI_CONTROL_IMMEDIATE, 0);
        tvh->tv_param->noaudio = 1;
    }

    /* disable TV audio if -nosound is present */
    if (!demuxer->audio || demuxer->audio->id == -2) {
        tvh->tv_param->noaudio = 1;
    }

    /* set width */
    funcs->control(tvh->priv, TVI_CONTROL_VID_GET_WIDTH, &sh_video->disp_w);

    /* set height */
    funcs->control(tvh->priv, TVI_CONTROL_VID_GET_HEIGHT, &sh_video->disp_h);

    demuxer->video->sh = sh_video;
    sh_video->ds = demuxer->video;
    demuxer->video->id = 0;
    demuxer->seekable = 0;

    /* here comes audio init */
    if (tvh->tv_param->noaudio == 0 && funcs->control(tvh->priv, TVI_CONTROL_IS_AUDIO, 0) == TVI_CONTROL_TRUE)
    {
        int audio_format;
        int sh_audio_format;
        char buf[128];

        /* yeah, audio is present */

        funcs->control(tvh->priv, TVI_CONTROL_AUD_SET_SAMPLERATE,
                       &tvh->tv_param->audiorate);

        if (funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_FORMAT, &audio_format) != TVI_CONTROL_TRUE)
            goto no_audio;

        switch(audio_format)
        {
        case AF_FORMAT_U8:
        case AF_FORMAT_S8:
        case AF_FORMAT_U16_LE:
        case AF_FORMAT_U16_BE:
        case AF_FORMAT_S16_LE:
        case AF_FORMAT_S16_BE:
        case AF_FORMAT_S32_LE:
        case AF_FORMAT_S32_BE:
            sh_audio_format = 0x1; /* PCM */
            break;
        case AF_FORMAT_IMA_ADPCM:
        case AF_FORMAT_MU_LAW:
        case AF_FORMAT_A_LAW:
        case AF_FORMAT_MPEG2:
        default:
            mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_UnsupportedAudioType,
                   af_fmt2str(audio_format, buf, 128), audio_format);
            goto no_audio;
        }

        sh_audio = new_sh_audio(demuxer, 0, NULL);

        funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_SAMPLERATE,
                       &sh_audio->samplerate);
        funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_SAMPLESIZE,
                       &sh_audio->samplesize);
        funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_CHANNELS,
                       &sh_audio->channels);

        sh_audio->format = sh_audio_format;
        sh_audio->sample_format = audio_format;

        sh_audio->i_bps = sh_audio->o_bps =
                              sh_audio->samplerate * sh_audio->samplesize *
                              sh_audio->channels;

        // emulate WF for win32 codecs:
        sh_audio->wf = malloc(sizeof(*sh_audio->wf));
        sh_audio->wf->wFormatTag = sh_audio->format;
        sh_audio->wf->nChannels = sh_audio->channels;
        sh_audio->wf->wBitsPerSample = sh_audio->samplesize * 8;
        sh_audio->wf->nSamplesPerSec = sh_audio->samplerate;
        sh_audio->wf->nBlockAlign = sh_audio->samplesize * sh_audio->channels;
        sh_audio->wf->nAvgBytesPerSec = sh_audio->i_bps;

        mp_msg(MSGT_DECVIDEO, MSGL_V, "  TV audio: %d channels, %d bits, %d Hz\n",
               sh_audio->wf->nChannels, sh_audio->wf->wBitsPerSample,
               sh_audio->wf->nSamplesPerSec);

        demuxer->audio->sh = sh_audio;
        sh_audio->ds = demuxer->audio;
        demuxer->audio->id = 0;
    }
no_audio:

    if(!(funcs->start(tvh->priv))) {
        // start failed :(
        tv_uninit(tvh);
        return NULL;
    }

    /* set color eq */
    tv_set_color_options(tvh, TV_COLOR_BRIGHTNESS, tvh->tv_param->brightness);
    tv_set_color_options(tvh, TV_COLOR_HUE, tvh->tv_param->hue);
    tv_set_color_options(tvh, TV_COLOR_SATURATION, tvh->tv_param->saturation);
    tv_set_color_options(tvh, TV_COLOR_CONTRAST, tvh->tv_param->contrast);

    if(tvh->tv_param->gain!=-1)
        if(funcs->control(tvh->priv,TVI_CONTROL_VID_SET_GAIN,&tvh->tv_param->gain)!=TVI_CONTROL_TRUE)
            mp_msg(MSGT_TV,MSGL_WARN,"Unable to set gain control!\n");

    teletext_control(demuxer->teletext,TV_VBI_CONTROL_RESET,
                     &tvh->tv_param->teletext);

    return demuxer;
}
void rtpCodecInitialize_video(demuxer_t* demuxer,
			      MediaSubsession* subsession,
			      unsigned& flags) {
  flags = 0;
  // Create a dummy video stream header
  // to make the main MPlayer code happy:
  sh_video_t* sh_video = new_sh_video(demuxer,0);
  BITMAPINFOHEADER* bih
    = (BITMAPINFOHEADER*)calloc(1,sizeof(BITMAPINFOHEADER));
  bih->biSize = sizeof(BITMAPINFOHEADER);
  sh_video->bih = bih;
  demux_stream_t* d_video = demuxer->video;
  d_video->sh = sh_video; sh_video->ds = d_video;
  
  // Map known video MIME types to the BITMAPINFOHEADER parameters
  // that this program uses.  (Note that not all types need all
  // of the parameters to be set.)
  if (strcmp(subsession->codecName(), "MPV") == 0) {
    flags |= RTPSTATE_IS_MPEG12_VIDEO;
  } else if (strcmp(subsession->codecName(), "MP1S") == 0 ||
	     strcmp(subsession->codecName(), "MP2T") == 0) {
    flags |= RTPSTATE_IS_MPEG12_VIDEO|RTPSTATE_IS_MULTIPLEXED;
  } else if (strcmp(subsession->codecName(), "H263") == 0 ||
	     strcmp(subsession->codecName(), "H263-2000") == 0 ||
	     strcmp(subsession->codecName(), "H263-1998") == 0) {
    bih->biCompression = sh_video->format
      = mmioFOURCC('H','2','6','3');
    needVideoFrameRate(demuxer, subsession);
  } else if (strcmp(subsession->codecName(), "H264") == 0) {
    bih->biCompression = sh_video->format
      = mmioFOURCC('H','2','6','4');
    unsigned int configLen = 0;
    unsigned char* configData
      = parseH264ConfigStr(subsession->fmtp_spropparametersets(), configLen);
    sh_video->bih = bih = insertVideoExtradata(bih, configData, configLen);
    delete[] configData;
#ifdef USE_LIBAVCODEC
    av_register_codec_parser(&h264_parser);
    h264parserctx = av_parser_init(CODEC_ID_H264);
#endif
    needVideoFrameRate(demuxer, subsession);
  } else if (strcmp(subsession->codecName(), "H261") == 0) {
    bih->biCompression = sh_video->format
      = mmioFOURCC('H','2','6','1');
    needVideoFrameRate(demuxer, subsession);
  } else if (strcmp(subsession->codecName(), "JPEG") == 0) {
    bih->biCompression = sh_video->format
      = mmioFOURCC('M','J','P','G');
    needVideoFrameRate(demuxer, subsession);
  } else if (strcmp(subsession->codecName(), "MP4V-ES") == 0) {
    bih->biCompression = sh_video->format
      = mmioFOURCC('m','p','4','v');
    // For the codec to work correctly, it may need a 'VOL Header' to be
    // inserted at the front of the data stream.  Construct this from the
    // "config" MIME parameter, which was present (hopefully) in the
    // session's SDP description:
    unsigned configLen;
    unsigned char* configData
      = parseGeneralConfigStr(subsession->fmtp_config(), configLen);
    sh_video->bih = bih = insertVideoExtradata(bih, configData, configLen);
    needVideoFrameRate(demuxer, subsession);
  } else if (strcmp(subsession->codecName(), "X-QT") == 0 ||
	     strcmp(subsession->codecName(), "X-QUICKTIME") == 0) {
    // QuickTime generic RTP format, as described in
    // http://developer.apple.com/quicktime/icefloe/dispatch026.html

    // We can't initialize this stream until we've received the first packet
    // that has QuickTime "sdAtom" information in the header.  So, keep
    // reading packets until we get one:
    unsigned char* packetData; unsigned packetDataLen; float pts;
    QuickTimeGenericRTPSource* qtRTPSource
      = (QuickTimeGenericRTPSource*)(subsession->rtpSource());
    unsigned fourcc;
    do {
      if (!awaitRTPPacket(demuxer, demuxer->video,
			  packetData, packetDataLen, pts)) {
	return;
      }
    } while (!parseQTState_video(qtRTPSource->qtState, fourcc));

    bih->biCompression = sh_video->format = fourcc;
    bih->biWidth = qtRTPSource->qtState.width;
    bih->biHeight = qtRTPSource->qtState.height;
      uint8_t *pos = (uint8_t*)qtRTPSource->qtState.sdAtom + 86;
      uint8_t *endpos = (uint8_t*)qtRTPSource->qtState.sdAtom
                        + qtRTPSource->qtState.sdAtomSize;
      while (pos+8 < endpos) {
        unsigned atomLength = pos[0]<<24 | pos[1]<<16 | pos[2]<<8 | pos[3];
        if (atomLength == 0 || atomLength > endpos-pos) break;
        if ((!memcmp(pos+4, "avcC", 4) && fourcc==mmioFOURCC('a','v','c','1') || 
             !memcmp(pos+4, "esds", 4) || 
             !memcmp(pos+4, "SMI ", 4) && fourcc==mmioFOURCC('S','V','Q','3')) &&
            atomLength > 8) {
          sh_video->bih = bih = 
              insertVideoExtradata(bih, pos+8, atomLength-8);
          break;
        }
        pos += atomLength;
      }
    needVideoFrameRate(demuxer, subsession);
  } else {
    fprintf(stderr,
	    "Unknown MPlayer format code for MIME type \"video/%s\"\n",
	    subsession->codecName());
  }
}
Example #6
0
/**
 * \brief MPlayer callback: Open MNG stream.
 * \param[in] demuxer demuxer structure
 * \return demuxer structure on success, \p NULL on error
 */
static demuxer_t * demux_mng_open(demuxer_t * demuxer)
{
    mng_priv_t * mng_priv;
    mng_handle h_mng;
    mng_retcode mng_ret;
    sh_video_t * sh_video;

    // create private data structure
    mng_priv = calloc(1, sizeof(mng_priv_t));

    //stream pointer into private data
    mng_priv->stream = demuxer->stream;

    // initialize MNG image instance
    h_mng = mng_initialize((mng_ptr)mng_priv, demux_mng_alloc,
                           demux_mng_free, MNG_NULL);
    if (!h_mng) {
        mp_msg(MSGT_DEMUX, MSGL_ERR,
               "demux_mng: could not initialize MNG image instance\n");
        free(mng_priv);
        return NULL;
    }

    // MNG image handle into private data
    mng_priv->h_mng = h_mng;

    // set required MNG callbacks
    if (mng_setcb_openstream(h_mng, demux_mng_openstream) ||
        mng_setcb_closestream(h_mng, demux_mng_closestream) ||
        mng_setcb_readdata(h_mng, demux_mng_readdata) ||
        mng_setcb_processheader(h_mng, demux_mng_processheader) ||
        mng_setcb_getcanvasline(h_mng, demux_mng_getcanvasline) ||
        mng_setcb_refresh(h_mng, demux_mng_refresh) ||
        mng_setcb_gettickcount(h_mng, demux_mng_gettickcount) ||
        mng_setcb_settimer(h_mng, demux_mng_settimer) ||
        mng_set_canvasstyle(h_mng, MNG_CANVAS_RGBA8)) {
        mp_msg(MSGT_DEMUX, MSGL_ERR,
               "demux_mng: could not set MNG callbacks\n");
        mng_cleanup(&h_mng);
        free(mng_priv);
        return NULL;
    }

    // start reading MNG data
    mng_ret = mng_read(h_mng);
    if (mng_ret) {
        mp_msg(MSGT_DEMUX, MSGL_ERR,
               "demux_mng: could not start reading MNG data: "
               "mng_retcode %d\n", mng_ret);
        mng_cleanup(&h_mng);
        free(mng_priv);
        return NULL;
    }

    // check that MNG header is processed now
    if (!mng_priv->header_processed) {
        mp_msg(MSGT_DEMUX, MSGL_ERR,
               "demux_mng: internal error: header not processed\n");
        mng_cleanup(&h_mng);
        free(mng_priv);
        return NULL;
    }

    // create a new video stream header
    sh_video = new_sh_video(demuxer, 0);

    // Make sure the demuxer knows about the new video stream header
    // (even though new_sh_video() ought to take care of it).
    // (Thanks to demux_gif.c for this.)
    demuxer->video->sh = sh_video;

    // Make sure that the video demuxer stream header knows about its
    // parent video demuxer stream (this is getting wacky), or else
    // video_read_properties() will choke.
    // (Thanks to demux_gif.c for this.)
    sh_video->ds = demuxer->video;

    // set format of pixels in video packets
    sh_video->format = mmioFOURCC(32, 'B', 'G', 'R');

    // set framerate to some value (MNG does not have a fixed framerate)
    sh_video->fps       = 5.0f;
    sh_video->frametime = 1.0f / sh_video->fps;

    // set video frame parameters
    sh_video->bih                = malloc(sizeof(*sh_video->bih));
    sh_video->bih->biCompression = sh_video->format;
    sh_video->bih->biWidth       = mng_priv->width;
    sh_video->bih->biHeight      = mng_priv->height;
    sh_video->bih->biBitCount    = 32;
    sh_video->bih->biPlanes      = 1;

    // Set start time to something > 0.
    //  - This is required for the variable frame time mechanism
    //    (GIF, MATROSKA, MNG) in video.c to work for the first frame.
    sh_video->ds->pts = MNG_START_PTS;

    // set private data in demuxer and return demuxer
    demuxer->priv = mng_priv;
    return demuxer;
}
Example #7
0
static demuxer_t* demux_open_fli(demuxer_t* demuxer){
  sh_video_t *sh_video = NULL;
  fli_frames_t *frames = malloc(sizeof(fli_frames_t));
  int frame_number;
  int speed;
  unsigned int frame_size;
  int magic_number;
  unsigned char * header;

  // go back to the beginning
  stream_reset(demuxer->stream);
  stream_seek(demuxer->stream, 0);

  header = calloc(1, sizeof(BITMAPINFOHEADER) + 128);
  stream_read(demuxer->stream, header + sizeof(BITMAPINFOHEADER), 128);
  stream_seek(demuxer->stream, 0);

  demuxer->movi_start = 128;
  demuxer->movi_end = stream_read_dword_le(demuxer->stream);

  magic_number = stream_read_word_le(demuxer->stream);

  if ((magic_number != 0xAF11) && (magic_number != 0xAF12))
  {
    mp_msg(MSGT_DEMUX, MSGL_ERR, "Bad/unknown magic number (%04x)\n",
	magic_number);
    free(header);
    free(frames);
    return NULL;
  }

  // fetch the number of frames
  frames->num_frames = stream_read_word_le(demuxer->stream);
  frames->current_frame = 0;

  // allocate enough entries for the indices
  //   audit: num_frames is 16bit so it is safe against overflow
  frames->filepos = malloc(frames->num_frames * sizeof(off_t));
  frames->frame_size = malloc(frames->num_frames * sizeof(int));

  // create a new video stream header
  sh_video = new_sh_video(demuxer, 0);

  // make sure the demuxer knows about the new video stream header
  // (even though new_sh_video() ought to take care of it)
  demuxer->video->sh = sh_video;

  // make sure that the video demuxer stream header knows about its
  // parent video demuxer stream (this is getting wacky), or else
  // video_read_properties() will choke
  sh_video->ds = demuxer->video;

  // custom fourcc for internal MPlayer use
  sh_video->format = mmioFOURCC('F', 'L', 'I', 'C');

  sh_video->disp_w = stream_read_word_le(demuxer->stream);
  sh_video->disp_h = stream_read_word_le(demuxer->stream);

  // pass extradata to codec
  sh_video->bih = (BITMAPINFOHEADER*)header;
  sh_video->bih->biSize = sizeof(BITMAPINFOHEADER) + 128;
  sh_video->bih->biWidth = sh_video->disp_w;
  sh_video->bih->biHeight = sh_video->disp_h;

  // skip the video depth and flags
  stream_skip(demuxer->stream, 4);

  // get the speed
  speed = stream_read_word_le(demuxer->stream);
  if (speed == 0)
    speed = 1;
  if (magic_number == 0xAF11)
    speed *= 1000/70;
  sh_video->fps = 1000 / speed;
  sh_video->frametime = 1/sh_video->fps;

  // build the frame index
  stream_seek(demuxer->stream, demuxer->movi_start);
  frame_number = 0;
  while ((!stream_eof(demuxer->stream)) && (frame_number < frames->num_frames))
  {
    frames->filepos[frame_number] = stream_tell(demuxer->stream);
    frame_size = stream_read_dword_le(demuxer->stream);
    magic_number = stream_read_word_le(demuxer->stream);
    stream_skip(demuxer->stream, frame_size - 6);

    // if this chunk has the right magic number, index it
    if ((magic_number == 0xF1FA) || (magic_number == 0xF5FA))
    {
      frames->frame_size[frame_number] = frame_size;
      frame_number++;
    }
  }

  // save the actual number of frames indexed
  frames->num_frames = frame_number;

  demuxer->priv = frames;

  return demuxer;
}
Example #8
0
static demuxer_t* demux_open_avs(demuxer_t* demuxer)
{
    int found = 0;
    AVS_T *AVS = demuxer->priv;
    int audio_samplesize = 0;
    AVS->frameno = 0;
    AVS->sampleno = 0;

    mp_msg(MSGT_DEMUX, MSGL_V, "AVS: demux_open_avs()\n");
    demuxer->seekable = 1;

    AVS->clip = AVS->avs_take_clip(AVS->handler, AVS->avs_env);
    if(!AVS->clip)
    {
        mp_msg(MSGT_DEMUX, MSGL_V, "AVS: avs_take_clip() failed\n");
        return NULL;
    }

    AVS->video_info = AVS->avs_get_video_info(AVS->clip);
    if (!AVS->video_info)
    {
        mp_msg(MSGT_DEMUX, MSGL_V, "AVS: avs_get_video_info() call failed\n");
        return NULL;
    }

    if (!avs_is_yv12(AVS->video_info))
    {
        AVS->handler = AVS->avs_invoke(AVS->avs_env, "ConvertToYV12", avs_new_value_array(&AVS->handler, 1), 0);
        if (avs_is_error(AVS->handler))
        {
            mp_msg(MSGT_DEMUX, MSGL_V, "AVS: Cannot convert input video to YV12: %s\n", avs_as_string(AVS->handler));
            return NULL;
        }

        AVS->clip = AVS->avs_take_clip(AVS->handler, AVS->avs_env);

        if(!AVS->clip)
        {
            mp_msg(MSGT_DEMUX, MSGL_V, "AVS: avs_take_clip() failed\n");
            return NULL;
        }

        AVS->video_info = AVS->avs_get_video_info(AVS->clip);
        if (!AVS->video_info)
        {
            mp_msg(MSGT_DEMUX, MSGL_V, "AVS: avs_get_video_info() call failed\n");
            return NULL;
        }
    }

    // TODO check field-based ??

    /* Video */
    if (avs_has_video(AVS->video_info))
    {
        sh_video_t *sh_video = new_sh_video(demuxer, 0);
        found = 1;

        if (demuxer->video->id == -1) demuxer->video->id = 0;
        if (demuxer->video->id == 0)
        demuxer->video->sh = sh_video;
        sh_video->ds = demuxer->video;

        sh_video->disp_w = AVS->video_info->width;
        sh_video->disp_h = AVS->video_info->height;

        //sh_video->format = get_mmioFOURCC(AVS->video_info);
        sh_video->format = mmioFOURCC('Y', 'V', '1', '2');
        sh_video->fps = (double) AVS->video_info->fps_numerator / (double) AVS->video_info->fps_denominator;
        sh_video->frametime = 1.0 / sh_video->fps;

        sh_video->bih = malloc(sizeof(BITMAPINFOHEADER) + (256 * 4));
        sh_video->bih->biCompression = sh_video->format;
        sh_video->bih->biBitCount = avs_bits_per_pixel(AVS->video_info);
        //sh_video->bih->biPlanes = 2;

        sh_video->bih->biWidth = AVS->video_info->width;
        sh_video->bih->biHeight = AVS->video_info->height;
        sh_video->num_frames = 0;
        sh_video->num_frames_decoded = 0;
    }

    /* Audio */
    if (avs_has_audio(AVS->video_info))
      switch (AVS->video_info->sample_type) {
        case AVS_SAMPLE_INT8:  audio_samplesize = 1; break;
        case AVS_SAMPLE_INT16: audio_samplesize = 2; break;
        case AVS_SAMPLE_INT24: audio_samplesize = 3; break;
        case AVS_SAMPLE_INT32:
        case AVS_SAMPLE_FLOAT: audio_samplesize = 4; break;
        default:
          mp_msg(MSGT_DEMUX, MSGL_ERR, "AVS: unknown audio type, disabling\n");
      }
    if (audio_samplesize)
    {
        sh_audio_t *sh_audio = new_sh_audio(demuxer, 0);
        found = 1;
        mp_msg(MSGT_DEMUX, MSGL_V, "AVS: Clip has audio -> Channels = %d - Freq = %d\n", AVS->video_info->nchannels, AVS->video_info->audio_samples_per_second);

        if (demuxer->audio->id == -1) demuxer->audio->id = 0;
        if (demuxer->audio->id == 0)
        demuxer->audio->sh = sh_audio;
        sh_audio->ds = demuxer->audio;

        sh_audio->wf = malloc(sizeof(WAVEFORMATEX));
        sh_audio->wf->wFormatTag = sh_audio->format =
            (AVS->video_info->sample_type == AVS_SAMPLE_FLOAT) ? 0x3 : 0x1;
        sh_audio->wf->nChannels = sh_audio->channels = AVS->video_info->nchannels;
        sh_audio->wf->nSamplesPerSec = sh_audio->samplerate = AVS->video_info->audio_samples_per_second;
        sh_audio->samplesize = audio_samplesize;
        sh_audio->wf->nAvgBytesPerSec = sh_audio->channels * sh_audio->samplesize * sh_audio->samplerate;
        sh_audio->wf->nBlockAlign = sh_audio->channels * sh_audio->samplesize;
        sh_audio->wf->wBitsPerSample = sh_audio->samplesize * 8;
        sh_audio->wf->cbSize = 0;
        sh_audio->i_bps = sh_audio->wf->nAvgBytesPerSec;
    }

    AVS->init = 1;
    if (found)
        return demuxer;
    else
        return NULL;
}
Example #9
0
static demuxer_t* demux_open_rtp(demuxer_t* demuxer)
{
    nms_rtsp_hints hints;
    char * url = demuxer->stream->streaming_ctrl->url->url;
    rtsp_ctrl * ctl;
    RTSP_Error reply;
    rtsp_medium * media;
    Nemesi_DemuxerStreamData * ndsd = calloc(1, sizeof(Nemesi_DemuxerStreamData));

    memset(&hints,0,sizeof(hints));
    if (rtsp_port) hints.first_rtp_port = rtsp_port;
    if (rtsp_transport_tcp) {
        hints.pref_rtsp_proto = TCP;
        hints.pref_rtp_proto = TCP;
    }
    if (rtsp_transport_sctp) {
        hints.pref_rtsp_proto = SCTP;
        hints.pref_rtp_proto = SCTP;
    }

    mp_msg(MSGT_DEMUX, MSGL_INFO, "Initializing libNemesi\n");
    if ((ctl = rtsp_init(&hints)) == NULL) {
        free(ndsd);
        return STREAM_ERROR;
    }

    ndsd->rtsp = ctl;
    demuxer->priv = ndsd;
    //nms_verbosity_set(1);

    mp_msg(MSGT_DEMUX, MSGL_INFO, "Opening: %s\n", url);
    if (rtsp_open(ctl, url)) {
        mp_msg(MSGT_DEMUX, MSGL_ERR, "rtsp_open failed.\n");
        return demuxer;
    }

    reply = rtsp_wait(ctl);
    if (reply.got_error) {
        mp_msg(MSGT_DEMUX, MSGL_ERR,
               "OPEN Error from the server: %s\n",
               reply.message.reply_str);
        return demuxer;
    }

    rtsp_play(ctl, 0, 0);
    reply = rtsp_wait(ctl);
    if (reply.got_error) {
        mp_msg(MSGT_DEMUX, MSGL_ERR,
               "PLAY Error from the server: %s\n",
               reply.message.reply_str);
        return demuxer;
    }

    if (!ctl->rtsp_queue)
        return demuxer;

    media = ctl->rtsp_queue->media_queue;
    for (; media; media=media->next) {
        sdp_medium_info * info = media->medium_info;
        rtp_session * sess = media->rtp_sess;
        rtp_buff buff;

        int media_format = atoi(info->fmts);
        rtp_pt * ptinfo = rtp_get_pt_info(sess, media_format);
        char const * format_name = ptinfo ? ptinfo->name : NULL;

        memset(&buff, 0, sizeof(rtp_buff));

        if (sess->parsers[media_format] == NULL) {
            mp_msg(MSGT_DEMUX, MSGL_ERR,
                   "libNemesi unsupported media format: %s\n",
                   format_name ? format_name : info->fmts);
            continue;
        }
        else {
            mp_msg(MSGT_DEMUX, MSGL_INFO,
                   "libNemesi supported media: %s\n",
                   format_name);
        }

        if (ptinfo->type == AU) {
            if (ndsd->session[NEMESI_SESSION_AUDIO] == NULL) {
                sh_audio_t* sh_audio = new_sh_audio(demuxer,0, NULL);
                WAVEFORMATEX* wf;
                demux_stream_t* d_audio = demuxer->audio;
                demuxer->audio->id = 0;

                mp_msg(MSGT_DEMUX, MSGL_INFO, "Detected as AUDIO stream...\n");

                link_session_and_fetch_conf(ndsd, NEMESI_SESSION_AUDIO,
                                            sess, &buff, NULL);

                wf = calloc(1,sizeof(*wf)+buff.len);
                wf->cbSize = buff.len;
                memcpy(wf+1, buff.data, buff.len);

                sh_audio->wf = wf;
                d_audio->sh = sh_audio;
                wf->nSamplesPerSec = 0;

                wf->wFormatTag =
                sh_audio->format = get4CC(supported_audio, format_name);
                if ( !(wf->wFormatTag) )
                    mp_msg(MSGT_DEMUX, MSGL_WARN,
                           "Unknown MPlayer format code for MIME"
                           " type \"audio/%s\"\n", format_name);
            } else {
                mp_msg(MSGT_DEMUX, MSGL_ERR,
                       "There is already an audio session registered,"
                       " ignoring...\n");
            }
        } else if (ptinfo->type == VI) {
            if (ndsd->session[NEMESI_SESSION_VIDEO] == NULL) {
                sh_video_t* sh_video;
                BITMAPINFOHEADER* bih;
                demux_stream_t* d_video;
                int fps = 0;

                mp_msg(MSGT_DEMUX, MSGL_INFO, "Detected as VIDEO stream...\n");

                link_session_and_fetch_conf(ndsd, NEMESI_SESSION_VIDEO,
                                            sess, &buff, &fps);

                bih = calloc(1,sizeof(*bih)+buff.len);
                bih->biSize = sizeof(*bih)+buff.len;
                memcpy(bih+1, buff.data, buff.len);

                sh_video = new_sh_video(demuxer,0);
                sh_video->bih = bih;
                d_video = demuxer->video;
                d_video->sh = sh_video;

                if (fps) {
                    sh_video->fps = fps;
                    sh_video->frametime = 1.0/fps;
                }

                bih->biCompression =
                sh_video->format = get4CC(supported_video, format_name);
                if ( !(bih->biCompression) ) {
                    mp_msg(MSGT_DEMUX, MSGL_WARN,
                        "Unknown MPlayer format code for MIME"
                        " type \"video/%s\"\n", format_name);
                }
            } else {
                mp_msg(MSGT_DEMUX, MSGL_ERR,
                       "There is already a video session registered,"
                       " ignoring...\n");
            }
        } else {
            mp_msg(MSGT_DEMUX, MSGL_ERR, "Unsupported media type\n");
        }
    }

    demuxer->stream->eof = 0;

    return demuxer;
}
Example #10
0
static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i) {
    lavf_priv_t *priv= demuxer->priv;
    AVStream *st= avfc->streams[i];
    AVCodecContext *codec= st->codec;
    int g;

    switch(codec->codec_type){
        case CODEC_TYPE_AUDIO:{
            WAVEFORMATEX *wf= calloc(sizeof(WAVEFORMATEX) + codec->extradata_size, 1);
            sh_audio_t* sh_audio;
            if(priv->audio_streams >= MAX_A_STREAMS)
                break;
            sh_audio=new_sh_audio(demuxer, i);
            mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_AudioID, "lavf", i);
            if(!sh_audio)
                break;
            priv->astreams[priv->audio_streams] = i;
            priv->audio_streams++;
            // mp4a tag is used for all mp4 files no matter what they actually contain
            if(codec->codec_tag == MKTAG('m', 'p', '4', 'a'))
                codec->codec_tag= 0;
            if(codec->codec_id == CODEC_ID_ADPCM_IMA_AMV)
                codec->codec_tag= MKTAG('A','M','V','A');
            if(!codec->codec_tag)
                codec->codec_tag= av_codec_get_tag(mp_wav_taglists, codec->codec_id);
            wf->wFormatTag= codec->codec_tag;
            wf->nChannels= codec->channels;
            wf->nSamplesPerSec= codec->sample_rate;
            wf->nAvgBytesPerSec= codec->bit_rate/8;
            wf->nBlockAlign= codec->block_align ? codec->block_align : 1;
            wf->wBitsPerSample= codec->bits_per_sample;
            wf->cbSize= codec->extradata_size;
            if(codec->extradata_size)
                memcpy(wf + 1, codec->extradata, codec->extradata_size);
            sh_audio->wf= wf;
            sh_audio->audio.dwSampleSize= codec->block_align;
            if(codec->frame_size && codec->sample_rate){
                sh_audio->audio.dwScale=codec->frame_size;
                sh_audio->audio.dwRate= codec->sample_rate;
            }else{
                sh_audio->audio.dwScale= codec->block_align ? codec->block_align*8 : 8;
                sh_audio->audio.dwRate = codec->bit_rate;
            }
            g= ff_gcd(sh_audio->audio.dwScale, sh_audio->audio.dwRate);
            sh_audio->audio.dwScale /= g;
            sh_audio->audio.dwRate  /= g;
//          printf("sca:%d rat:%d fs:%d sr:%d ba:%d\n", sh_audio->audio.dwScale, sh_audio->audio.dwRate, codec->frame_size, codec->sample_rate, codec->block_align);
            sh_audio->ds= demuxer->audio;
            sh_audio->format= codec->codec_tag;
            sh_audio->channels= codec->channels;
            sh_audio->samplerate= codec->sample_rate;
            sh_audio->i_bps= codec->bit_rate/8;
            switch (codec->codec_id) {
                case CODEC_ID_PCM_S8:
                case CODEC_ID_PCM_U8:
                    sh_audio->samplesize = 1;
                    break;
                case CODEC_ID_PCM_S16LE:
                case CODEC_ID_PCM_S16BE:
                case CODEC_ID_PCM_U16LE:
                case CODEC_ID_PCM_U16BE:
                    sh_audio->samplesize = 2;
                    break;
                case CODEC_ID_PCM_ALAW:
                    sh_audio->format = 0x6;
                    break;
                case CODEC_ID_PCM_MULAW:
                    sh_audio->format = 0x7;
                    break;
            }
            if(mp_msg_test(MSGT_HEADER,MSGL_V) ) print_wave_header(sh_audio->wf, MSGL_V);
            if((audio_lang && st->language[0] && !strncmp(audio_lang, st->language, 3))
                || (demuxer->audio->id == i || demuxer->audio->id == -1)) {
                demuxer->audio->id = i;
                demuxer->audio->sh= demuxer->a_streams[i];
            } else
                st->discard= AVDISCARD_ALL;
            break;
        }
        case CODEC_TYPE_VIDEO:{
            sh_video_t* sh_video;
            BITMAPINFOHEADER *bih;
            if(priv->video_streams >= MAX_V_STREAMS)
                break;
            sh_video=new_sh_video(demuxer, i);
            mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_VideoID, "lavf", i);
            if(!sh_video) break;
            priv->vstreams[priv->video_streams] = i;
            priv->video_streams++;
            bih=calloc(sizeof(BITMAPINFOHEADER) + codec->extradata_size,1);

            if(!codec->codec_tag)
                codec->codec_tag= av_codec_get_tag(mp_bmp_taglists, codec->codec_id);
            bih->biSize= sizeof(BITMAPINFOHEADER) + codec->extradata_size;
            bih->biWidth= codec->width;
            bih->biHeight= codec->height;
            bih->biBitCount= codec->bits_per_sample;
            bih->biSizeImage = bih->biWidth * bih->biHeight * bih->biBitCount/8;
            bih->biCompression= codec->codec_tag;
            sh_video->bih= bih;
            sh_video->disp_w= codec->width;
            sh_video->disp_h= codec->height;
            if (st->time_base.den) { /* if container has time_base, use that */
                sh_video->video.dwRate= st->time_base.den;
                sh_video->video.dwScale= st->time_base.num;
            } else {
                sh_video->video.dwRate= codec->time_base.den;
                sh_video->video.dwScale= codec->time_base.num;
            }
            sh_video->fps=av_q2d(st->r_frame_rate);
            sh_video->frametime=1/av_q2d(st->r_frame_rate);
            sh_video->format=bih->biCompression;
            sh_video->aspect=codec->width * codec->sample_aspect_ratio.num 
                               / (float)(codec->height * codec->sample_aspect_ratio.den);
            sh_video->i_bps=codec->bit_rate/8;
            mp_msg(MSGT_DEMUX,MSGL_DBG2,"aspect= %d*%d/(%d*%d)\n", 
                codec->width, codec->sample_aspect_ratio.num,
                codec->height, codec->sample_aspect_ratio.den);

            sh_video->ds= demuxer->video;
            if(codec->extradata_size)
                memcpy(sh_video->bih + 1, codec->extradata, codec->extradata_size);
            if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_video_header(sh_video->bih, MSGL_V);
            /*
                short biPlanes;
                int  biXPelsPerMeter;
                int  biYPelsPerMeter;
                int biClrUsed;
                int biClrImportant;
            */
            if(demuxer->video->id != i && demuxer->video->id != -1)
                st->discard= AVDISCARD_ALL;
            else{
                demuxer->video->id = i;
                demuxer->video->sh= demuxer->v_streams[i];
            }
            break;
        }
        case CODEC_TYPE_SUBTITLE:{
            sh_sub_t* sh_sub;
            if(priv->sub_streams >= MAX_S_STREAMS)
                break;
            /* only support text subtitles for now */
            if(codec->codec_id != CODEC_ID_TEXT)
                break;
            sh_sub = new_sh_sub_sid(demuxer, i, priv->sub_streams);
            mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_SubtitleID, "lavf", priv->sub_streams);
            if(!sh_sub) break;
            priv->sstreams[priv->sub_streams] = i;
            sh_sub->type = 't';
            demuxer->sub->sh = demuxer->s_streams[priv->sub_streams++];
            break;
        }
        default:
            st->discard= AVDISCARD_ALL;
    }
}
Example #11
0
int read_asf_header(demuxer_t *demuxer,struct asf_priv* asf){
  int hdr_len = asf->header.objh.size - sizeof(asf->header);
  int hdr_skip = 0;
  char *hdr = NULL;
  char guid_buffer[16];
  int pos, start = stream_tell(demuxer->stream);
  uint32_t* streams = NULL;
  int audio_streams=0;
  int video_streams=0;
  uint16_t stream_count=0;
  int best_video = -1;
  int best_audio = -1;
  uint64_t data_len;
  ASF_stream_header_t *streamh;
  uint8_t *buffer;
  int audio_pos=0;

  if(hdr_len < 0) {
    mp_msg(MSGT_HEADER, MSGL_FATAL, "Header size is too small.\n");
    return 0;
  }

  if (hdr_len > 1024 * 1024) {
    mp_msg(MSGT_HEADER, MSGL_ERR, MSGTR_MPDEMUX_ASFHDR_HeaderSizeOver1MB,
			hdr_len);
    hdr_skip = hdr_len - 1024 * 1024;
    hdr_len = 1024 * 1024;
  }
  hdr = malloc(hdr_len);
  if (!hdr) {
    mp_msg(MSGT_HEADER, MSGL_FATAL, MSGTR_MPDEMUX_ASFHDR_HeaderMallocFailed,
            hdr_len);
    return 0;
  }
  stream_read(demuxer->stream, hdr, hdr_len);
  if (hdr_skip)
    stream_skip(demuxer->stream, hdr_skip);
  if (stream_eof(demuxer->stream)) {
    mp_msg(MSGT_HEADER, MSGL_FATAL, MSGTR_MPDEMUX_ASFHDR_EOFWhileReadingHeader);
    goto err_out;
  }

  if (is_drm(hdr, hdr_len))
    mp_msg(MSGT_HEADER, MSGL_FATAL, MSGTR_MPDEMUX_ASFHDR_DRMProtected);

  if ((pos = find_asf_guid(hdr, asf_ext_stream_audio, 0, hdr_len)) >= 0)
  {
    // Special case: found GUID for dvr-ms audio.
    // Now skip back to associated stream header.
    int sh_pos=0;

    sh_pos = find_backwards_asf_guid(hdr, asf_stream_header_guid, pos);

    if (sh_pos > 0) {
      sh_audio_t *sh_audio;

       mp_msg(MSGT_HEADER, MSGL_V, "read_asf_header found dvr-ms audio stream header pos=%d\n", sh_pos);
      // found audio stream header - following code reads header and
      // initializes audio stream.
      audio_pos = pos - 16 - 8;
      streamh = (ASF_stream_header_t *)&hdr[sh_pos];
      le2me_ASF_stream_header_t(streamh);
      audio_pos += 64; //16+16+4+4+4+16+4;
      buffer = &hdr[audio_pos];
      sh_audio=new_sh_audio(demuxer,streamh->stream_no & 0x7F, NULL);
      sh_audio->needs_parsing = 1;
      mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_AudioID, "asfheader", streamh->stream_no & 0x7F);
      ++audio_streams;
      if (!asf_init_audio_stream(demuxer, asf, sh_audio, streamh, &audio_pos, &buffer, hdr, hdr_len))
        goto len_err_out;
      if (!get_ext_stream_properties(hdr, hdr_len, streamh->stream_no, asf, 0))
        goto len_err_out;
    }
  }
  // find stream headers
  // only reset pos if we didnt find dvr_ms audio stream
  // if we did find it then we want to avoid reading its header twice
  if (audio_pos == 0)
    pos = 0;

  while ((pos = find_asf_guid(hdr, asf_stream_header_guid, pos, hdr_len)) >= 0)
  {
    streamh = (ASF_stream_header_t *)&hdr[pos];
    pos += sizeof(ASF_stream_header_t);
    if (pos > hdr_len) goto len_err_out;
    le2me_ASF_stream_header_t(streamh);
    mp_msg(MSGT_HEADER, MSGL_V, "stream type: %s\n",
            asf_chunk_type(streamh->type));
    mp_msg(MSGT_HEADER, MSGL_V, "stream concealment: %s\n",
            asf_chunk_type(streamh->concealment));
    mp_msg(MSGT_HEADER, MSGL_V, "type: %d bytes,  stream: %d bytes  ID: %d\n",
            (int)streamh->type_size, (int)streamh->stream_size,
            (int)streamh->stream_no);
    mp_msg(MSGT_HEADER, MSGL_V, "unk1: %lX  unk2: %X\n",
            (unsigned long)streamh->unk1, (unsigned int)streamh->unk2);
    mp_msg(MSGT_HEADER, MSGL_V, "FILEPOS=0x%X\n", pos + start);
    // type-specific data:
    buffer = &hdr[pos];
    pos += streamh->type_size;
    if (pos > hdr_len) goto len_err_out;
    switch(ASF_LOAD_GUID_PREFIX(streamh->type)){
      case ASF_GUID_PREFIX_audio_stream: {
        sh_audio_t* sh_audio=new_sh_audio(demuxer,streamh->stream_no & 0x7F, NULL);
        mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_AudioID, "asfheader", streamh->stream_no & 0x7F);
        ++audio_streams;
        if (!asf_init_audio_stream(demuxer, asf, sh_audio, streamh, &pos, &buffer, hdr, hdr_len))
          goto len_err_out;
	//if(demuxer->audio->id==-1) demuxer->audio->id=streamh.stream_no & 0x7F;
        break;
        }
      case ASF_GUID_PREFIX_video_stream: {
        unsigned int len;
        float asp_ratio;
        sh_video_t* sh_video=new_sh_video(demuxer,streamh->stream_no & 0x7F);
        mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_VideoID, "asfheader", streamh->stream_no & 0x7F);
        len=streamh->type_size-(4+4+1+2);
	++video_streams;
//        sh_video->bih=malloc(chunksize); memset(sh_video->bih,0,chunksize);
        sh_video->bih=calloc((len<sizeof(*sh_video->bih))?sizeof(*sh_video->bih):len,1);
        memcpy(sh_video->bih,&buffer[4+4+1+2],len);
	le2me_BITMAPINFOHEADER(sh_video->bih);
	if (sh_video->bih->biSize > len && sh_video->bih->biSize > sizeof(*sh_video->bih))
		sh_video->bih->biSize = len;
        if (sh_video->bih->biCompression == mmioFOURCC('D', 'V', 'R', ' ')) {
          //mp_msg(MSGT_DEMUXER, MSGL_WARN, MSGTR_MPDEMUX_ASFHDR_DVRWantsLibavformat);
          //sh_video->fps=(float)sh_video->video.dwRate/(float)sh_video->video.dwScale;
          //sh_video->frametime=(float)sh_video->video.dwScale/(float)sh_video->video.dwRate;
          asf->asf_frame_state=-1;
          asf->asf_frame_start_found=0;
          asf->asf_is_dvr_ms=1;
          asf->dvr_last_vid_pts=0.0;
        } else asf->asf_is_dvr_ms=0;
        if (!get_ext_stream_properties(hdr, hdr_len, streamh->stream_no, asf, 1))
            goto len_err_out;
        if (get_meta(hdr, hdr_len, streamh->stream_no, &asp_ratio)) {
          sh_video->aspect = asp_ratio * sh_video->bih->biWidth /
            sh_video->bih->biHeight;
        }
        sh_video->i_bps = asf->bps;

        if( mp_msg_test(MSGT_DEMUX,MSGL_V) ) print_video_header(sh_video->bih, MSGL_V);
        //asf_video_id=streamh.stream_no & 0x7F;
	//if(demuxer->video->id==-1) demuxer->video->id=streamh.stream_no & 0x7F;
        break;
        }
      }
      // stream-specific data:
      // stream_read(demuxer->stream,(char*) buffer,streamh.stream_size);
  }

  // find file header
  pos = find_asf_guid(hdr, asf_file_header_guid, 0, hdr_len);
  if (pos >= 0) {
      ASF_file_header_t *fileh = (ASF_file_header_t *)&hdr[pos];
      pos += sizeof(ASF_file_header_t);
      if (pos > hdr_len) goto len_err_out;
      le2me_ASF_file_header_t(fileh);
      mp_msg(MSGT_HEADER, MSGL_V, "ASF: packets: %d  flags: %d  "
              "max_packet_size: %d  min_packet_size: %d  max_bitrate: %d  "
              "preroll: %d\n",
              (int)fileh->num_packets, (int)fileh->flags,
              (int)fileh->min_packet_size, (int)fileh->max_packet_size,
              (int)fileh->max_bitrate, (int)fileh->preroll);
      asf->packetsize=fileh->max_packet_size;
      asf->packet=malloc(asf->packetsize); // !!!
      asf->packetrate=fileh->max_bitrate/8.0/(double)asf->packetsize;
      asf->movielength=(fileh->play_duration-10000*fileh->preroll)/10000000.0;
  }

  // find content header
  pos = find_asf_guid(hdr, asf_content_desc_guid, 0, hdr_len);
  if (pos >= 0) {
        ASF_content_description_t *contenth = (ASF_content_description_t *)&hdr[pos];
        char *string=NULL;
        uint16_t* wstring = NULL;
        uint16_t len;
        pos += sizeof(ASF_content_description_t);
        if (pos > hdr_len) goto len_err_out;
	le2me_ASF_content_description_t(contenth);
	mp_msg(MSGT_HEADER,MSGL_V,"\n");
        // extract the title
        if((len = contenth->title_size) != 0) {
          wstring = (uint16_t*)&hdr[pos];
          pos += len;
          if (pos > hdr_len) goto len_err_out;
          if ((string = get_ucs2str(wstring, len))) {
            mp_msg(MSGT_HEADER,MSGL_V," Title: %s\n", string);
            demux_info_add(demuxer, "title", string);
            free(string);
          }
        }
        // extract the author
        if((len = contenth->author_size) != 0) {
          wstring = (uint16_t*)&hdr[pos];
          pos += len;
          if (pos > hdr_len) goto len_err_out;
          if ((string = get_ucs2str(wstring, len))) {
            mp_msg(MSGT_HEADER,MSGL_V," Author: %s\n", string);
            demux_info_add(demuxer, "author", string);
            free(string);
          }
        }
        // extract the copyright
        if((len = contenth->copyright_size) != 0) {
          wstring = (uint16_t*)&hdr[pos];
          pos += len;
          if (pos > hdr_len) goto len_err_out;
          if ((string = get_ucs2str(wstring, len))) {
            mp_msg(MSGT_HEADER,MSGL_V," Copyright: %s\n", string);
            demux_info_add(demuxer, "copyright", string);
            free(string);
          }
        }
        // extract the comment
        if((len = contenth->comment_size) != 0) {
          wstring = (uint16_t*)&hdr[pos];
          pos += len;
          if (pos > hdr_len) goto len_err_out;
          if ((string = get_ucs2str(wstring, len))) {
            mp_msg(MSGT_HEADER,MSGL_V," Comment: %s\n", string);
            demux_info_add(demuxer, "comments", string);
            free(string);
          }
        }
        // extract the rating
        if((len = contenth->rating_size) != 0) {
          wstring = (uint16_t*)&hdr[pos];
          pos += len;
          if (pos > hdr_len) goto len_err_out;
          if ((string = get_ucs2str(wstring, len))) {
            mp_msg(MSGT_HEADER,MSGL_V," Rating: %s\n", string);
            free(string);
          }
        }
	mp_msg(MSGT_HEADER,MSGL_V,"\n");
  }

  // find content header
  pos = find_asf_guid(hdr, asf_stream_group_guid, 0, hdr_len);
  if (pos >= 0) {
        int max_streams = (hdr_len - pos - 2) / 6;
        uint16_t stream_id, i;
        uint32_t max_bitrate;
        char *ptr = &hdr[pos];
        mp_msg(MSGT_HEADER,MSGL_V,"============ ASF Stream group == START ===\n");
        if(max_streams <= 0) goto len_err_out;
        stream_count = AV_RL16(ptr);
        ptr += sizeof(uint16_t);
        if(stream_count > max_streams) stream_count = max_streams;
        if(stream_count > 0)
              streams = malloc(2*stream_count*sizeof(uint32_t));
        mp_msg(MSGT_HEADER,MSGL_V," stream count=[0x%x][%u]\n", stream_count, stream_count );
        for( i=0 ; i<stream_count ; i++ ) {
          stream_id = AV_RL16(ptr);
          ptr += sizeof(uint16_t);
          max_bitrate = AV_RL32(ptr);
          ptr += sizeof(uint32_t);
          mp_msg(MSGT_HEADER,MSGL_V,"   stream id=[0x%x][%u]\n", stream_id, stream_id );
          mp_msg(MSGT_HEADER,MSGL_V,"   max bitrate=[0x%x][%u]\n", max_bitrate, max_bitrate );
          streams[2*i] = stream_id;
          streams[2*i+1] = max_bitrate;
        }
        mp_msg(MSGT_HEADER,MSGL_V,"============ ASF Stream group == END ===\n");
  }
  free(hdr);
  hdr = NULL;
  start = stream_tell(demuxer->stream); // start of first data chunk
  stream_read(demuxer->stream, guid_buffer, 16);
  if (memcmp(guid_buffer, asf_data_chunk_guid, 16) != 0) {
    mp_msg(MSGT_HEADER, MSGL_FATAL, MSGTR_MPDEMUX_ASFHDR_NoDataChunkAfterHeader);
    free(streams);
    streams = NULL;
    return 0;
  }
  // read length of chunk
  data_len = stream_read_qword_le(demuxer->stream);
  demuxer->movi_start = stream_tell(demuxer->stream) + 26;
  demuxer->movi_end = start + data_len;
  mp_msg(MSGT_HEADER, MSGL_V, "Found movie at 0x%X - 0x%X\n",
          (int)demuxer->movi_start, (int)demuxer->movi_end);

if(streams) {
  // stream selection is done in the network code, it shouldn't be done here
  // as the servers often do not care about what we requested.
#if 0
  uint32_t vr = 0, ar = 0,i;
#ifdef CONFIG_NETWORKING
  if( demuxer->stream->streaming_ctrl!=NULL ) {
	  if( demuxer->stream->streaming_ctrl->bandwidth!=0 && demuxer->stream->streaming_ctrl->data!=NULL ) {
		  best_audio = ((asf_http_streaming_ctrl_t*)demuxer->stream->streaming_ctrl->data)->audio_id;
		  best_video = ((asf_http_streaming_ctrl_t*)demuxer->stream->streaming_ctrl->data)->video_id;
	  }
  } else
#endif
  for(i = 0; i < stream_count; i++) {
    uint32_t id = streams[2*i];
    uint32_t rate = streams[2*i+1];
    if(demuxer->v_streams[id] && rate > vr) {
      vr = rate;
      best_video = id;
    } else if(demuxer->a_streams[id] && rate > ar) {
      ar = rate;
      best_audio = id;
    }
  }
#endif
  free(streams);
  streams = NULL;
}

mp_msg(MSGT_HEADER,MSGL_V,"ASF: %d audio and %d video streams found\n",audio_streams,video_streams);
if(!audio_streams) demuxer->audio->id=-2;  // nosound
else if(best_audio > 0 && demuxer->audio->id == -1) demuxer->audio->id=best_audio;
if(!video_streams){
    if(!audio_streams){
	mp_msg(MSGT_HEADER,MSGL_ERR,MSGTR_MPDEMUX_ASFHDR_AudioVideoHeaderNotFound);
	return 0;
    }
    demuxer->video->id=-2; // audio-only
} else if (best_video > 0 && demuxer->video->id == -1) demuxer->video->id = best_video;

#if 0
if( mp_msg_test(MSGT_HEADER,MSGL_V) ){
    printf("ASF duration: %d\n",(int)fileh.duration);
    printf("ASF start pts: %d\n",(int)fileh.start_timestamp);
    printf("ASF end pts: %d\n",(int)fileh.end_timestamp);
}
#endif

return 1;

len_err_out:
  mp_msg(MSGT_HEADER, MSGL_FATAL, MSGTR_MPDEMUX_ASFHDR_InvalidLengthInASFHeader);
err_out:
  if (hdr) free(hdr);
  if (streams) free(streams);
  return 0;
}
Example #12
0
static demuxer_t* demux_open_mf(demuxer_t* demuxer) {
    sh_video_t   *sh_video = NULL;
    mf_t         *mf = NULL;
    int i;

    if(!demuxer->stream->url) return NULL;
    if(strncmp(demuxer->stream->url, "mf://", 5)) return NULL;


    mf=open_mf(demuxer->stream->url + 5);
    if(!mf) return NULL;

    if(!mf_type) {
        char* p=strrchr(mf->names[0],'.');
        if(!p) {
            mp_msg(MSGT_DEMUX, MSGL_INFO, "[demux_mf] file type was not set! (try -mf type=xxx)\n" );
            free( mf );
            return NULL;
        }
        mf_type=strdup(p+1);
        mp_msg(MSGT_DEMUX, MSGL_INFO, "[demux_mf] file type was not set! trying 'type=%s'...\n", mf_type);
    }

    demuxer->filepos=mf->curr_frame=0;

    demuxer->movi_start = 0;
    demuxer->movi_end = mf->nr_of_files - 1;

    // create a new video stream header
    sh_video = new_sh_video(demuxer, 0);
    // make sure the demuxer knows about the new video stream header
    // (even though new_sh_video() ought to take care of it)
    demuxer->video->sh = sh_video;

    // make sure that the video demuxer stream header knows about its
    // parent video demuxer stream (this is getting wacky), or else
    // video_read_properties() will choke
    sh_video->ds = demuxer->video;

    for (i = 0; type2format[i].type; i++)
        if (strcasecmp(mf_type, type2format[i].type) == 0)
            break;
    if (!type2format[i].type) {
        mp_msg(MSGT_DEMUX, MSGL_INFO, "[demux_mf] unknown input file type.\n" );
        free(mf);
        return NULL;
    }
    sh_video->format = type2format[i].format;

    sh_video->disp_w = mf_w;
    sh_video->disp_h = mf_h;
    sh_video->fps = mf_fps;
    sh_video->frametime = 1 / sh_video->fps;

    // emulate BITMAPINFOHEADER:
    sh_video->bih=malloc(sizeof(BITMAPINFOHEADER));
    memset(sh_video->bih,0,sizeof(BITMAPINFOHEADER));
    sh_video->bih->biSize=40;
    sh_video->bih->biWidth = mf_w;
    sh_video->bih->biHeight = mf_h;
    sh_video->bih->biPlanes=1;
    sh_video->bih->biBitCount=24;
    sh_video->bih->biCompression=sh_video->format;
    sh_video->bih->biSizeImage=sh_video->bih->biWidth*sh_video->bih->biHeight*3;

    /* disable seeking */
//  demuxer->seekable = 0;

    demuxer->priv=(void*)mf;

    return demuxer;
}
Example #13
0
static demuxer_t* demux_open_lavf(demuxer_t *demuxer){
    AVFormatContext *avfc;
    AVFormatParameters ap;
    AVOption *opt;
    lavf_priv_t *priv= demuxer->priv;
    int i,g;
    char mp_filename[256]="mp:";

    memset(&ap, 0, sizeof(AVFormatParameters));

    stream_seek(demuxer->stream, 0);

    register_protocol(&mp_protocol);

    avfc = av_alloc_format_context();

    if (correct_pts)
        avfc->flags |= AVFMT_FLAG_GENPTS;
    if (index_mode == 0)
        avfc->flags |= AVFMT_FLAG_IGNIDX;

    ap.prealloced_context = 1;
    if(opt_probesize) {
        double d = (double) opt_probesize;
        opt = av_set_double(avfc, "probesize", opt_probesize);
        if(!opt) mp_msg(MSGT_HEADER,MSGL_ERR, "demux_lavf, couldn't set option probesize to %.3f\r\n", d);
    }

    if(demuxer->stream->url)
        strncpy(mp_filename + 3, demuxer->stream->url, sizeof(mp_filename)-3);
    else
        strncpy(mp_filename + 3, "foobar.dummy", sizeof(mp_filename)-3);
    
    url_fopen(&priv->pb, mp_filename, URL_RDONLY);
    
    ((URLContext*)(priv->pb.opaque))->priv_data= demuxer->stream;
        
    if(av_open_input_stream(&avfc, &priv->pb, mp_filename, priv->avif, &ap)<0){
        mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF_header: av_open_input_stream() failed\n");
        return NULL;
    }

    priv->avfc= avfc;

    if(av_find_stream_info(avfc) < 0){
        mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF_header: av_find_stream_info() failed\n");
        return NULL;
    }

    if(avfc->title    [0]) demux_info_add(demuxer, "name"     , avfc->title    );
    if(avfc->author   [0]) demux_info_add(demuxer, "author"   , avfc->author   );
    if(avfc->copyright[0]) demux_info_add(demuxer, "copyright", avfc->copyright);
    if(avfc->comment  [0]) demux_info_add(demuxer, "comments" , avfc->comment  );
    if(avfc->album    [0]) demux_info_add(demuxer, "album"    , avfc->album    );
//    if(avfc->year        ) demux_info_add(demuxer, "year"     , avfc->year     );
//    if(avfc->track       ) demux_info_add(demuxer, "track"    , avfc->track    );
    if(avfc->genre    [0]) demux_info_add(demuxer, "genre"    , avfc->genre    );

    for(i=0; i<avfc->nb_streams; i++){
        AVStream *st= avfc->streams[i];
        AVCodecContext *codec= st->codec;

        switch(codec->codec_type){
        case CODEC_TYPE_AUDIO:{
            WAVEFORMATEX *wf= calloc(sizeof(WAVEFORMATEX) + codec->extradata_size, 1);
            sh_audio_t* sh_audio;
            if(priv->audio_streams >= MAX_A_STREAMS)
                break;
            sh_audio=new_sh_audio(demuxer, i);
            if(!sh_audio)
                break;
            priv->astreams[priv->audio_streams] = i;
            priv->audio_streams++;
            if(!codec->codec_tag)
                codec->codec_tag= av_codec_get_tag(mp_wav_taglists, codec->codec_id);
            wf->wFormatTag= codec->codec_tag;
            wf->nChannels= codec->channels;
            wf->nSamplesPerSec= codec->sample_rate;
            wf->nAvgBytesPerSec= codec->bit_rate/8;
            wf->nBlockAlign= codec->block_align ? codec->block_align : 1;
            wf->wBitsPerSample= codec->bits_per_sample;
            wf->cbSize= codec->extradata_size;
            if(codec->extradata_size){
                memcpy(
                    wf + 1, 
                    codec->extradata,
                    codec->extradata_size);
            }
            sh_audio->wf= wf;
            sh_audio->audio.dwSampleSize= codec->block_align;
            if(codec->frame_size && codec->sample_rate){
                sh_audio->audio.dwScale=codec->frame_size;
                sh_audio->audio.dwRate= codec->sample_rate;
            }else{
                sh_audio->audio.dwScale= codec->block_align ? codec->block_align*8 : 8;
                sh_audio->audio.dwRate = codec->bit_rate;
            }
            g= ff_gcd(sh_audio->audio.dwScale, sh_audio->audio.dwRate);
            sh_audio->audio.dwScale /= g;
            sh_audio->audio.dwRate  /= g;
//            printf("sca:%d rat:%d fs:%d sr:%d ba:%d\n", sh_audio->audio.dwScale, sh_audio->audio.dwRate, codec->frame_size, codec->sample_rate, codec->block_align);
            sh_audio->ds= demuxer->audio;
            sh_audio->format= codec->codec_tag;
            sh_audio->channels= codec->channels;
            sh_audio->samplerate= codec->sample_rate;
            sh_audio->i_bps= codec->bit_rate/8;
            switch (codec->codec_id) {
              case CODEC_ID_PCM_S8:
              case CODEC_ID_PCM_U8:
                sh_audio->samplesize = 1;
                break;
              case CODEC_ID_PCM_S16LE:
              case CODEC_ID_PCM_S16BE:
              case CODEC_ID_PCM_U16LE:
              case CODEC_ID_PCM_U16BE:
                sh_audio->samplesize = 2;
                break;
              case CODEC_ID_PCM_ALAW:
                sh_audio->format = 0x6;
                break;
              case CODEC_ID_PCM_MULAW:
                sh_audio->format = 0x7;
                break;
            }
            if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_wave_header(sh_audio->wf, MSGL_V);
	    if((audio_lang && st->language[0] && !strncmp(audio_lang, st->language, 3))
	        || (demuxer->audio->id == i || demuxer->audio->id == -1)
	    ) {
	        demuxer->audio->id = i;
                demuxer->audio->sh= demuxer->a_streams[i];
	    }
            else
                st->discard= AVDISCARD_ALL;
            break;}
        case CODEC_TYPE_VIDEO:{
            sh_video_t* sh_video;
            BITMAPINFOHEADER *bih;
            if(priv->video_streams >= MAX_V_STREAMS)
                break;
            sh_video=new_sh_video(demuxer, i);
            if(!sh_video) break;
            priv->vstreams[priv->video_streams] = i;
            priv->video_streams++;
            bih=calloc(sizeof(BITMAPINFOHEADER) + codec->extradata_size,1);

            if(!codec->codec_tag)
                codec->codec_tag= av_codec_get_tag(mp_bmp_taglists, codec->codec_id);
            bih->biSize= sizeof(BITMAPINFOHEADER) + codec->extradata_size;
            bih->biWidth= codec->width;
            bih->biHeight= codec->height;
            bih->biBitCount= codec->bits_per_sample;
            bih->biSizeImage = bih->biWidth * bih->biHeight * bih->biBitCount/8;
            bih->biCompression= codec->codec_tag;
            sh_video->bih= bih;
            sh_video->disp_w= codec->width;
            sh_video->disp_h= codec->height;
            if (st->time_base.den) { /* if container has time_base, use that */
                sh_video->video.dwRate= st->time_base.den;
                sh_video->video.dwScale= st->time_base.num;
            } else {
            sh_video->video.dwRate= codec->time_base.den;
            sh_video->video.dwScale= codec->time_base.num;
            }
            sh_video->fps=av_q2d(st->r_frame_rate);
            sh_video->frametime=1/av_q2d(st->r_frame_rate);
            sh_video->format = bih->biCompression;
            sh_video->aspect=   codec->width * codec->sample_aspect_ratio.num 
                              / (float)(codec->height * codec->sample_aspect_ratio.den);
            sh_video->i_bps= codec->bit_rate/8;
            mp_msg(MSGT_DEMUX,MSGL_DBG2,"aspect= %d*%d/(%d*%d)\n", 
                codec->width, codec->sample_aspect_ratio.num,
                codec->height, codec->sample_aspect_ratio.den);

            sh_video->ds= demuxer->video;
            if(codec->extradata_size)
                memcpy(sh_video->bih + 1, codec->extradata, codec->extradata_size);
            if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_video_header(sh_video->bih, MSGL_V);
/*    short 	biPlanes;
    int  	biXPelsPerMeter;
    int  	biYPelsPerMeter;
    int 	biClrUsed;
    int 	biClrImportant;*/
            if(demuxer->video->id != i && demuxer->video->id != -1)
                st->discard= AVDISCARD_ALL;
            else{
                demuxer->video->id = i;
                demuxer->video->sh= demuxer->v_streams[i];
            }
            break;}
        default:
            st->discard= AVDISCARD_ALL;
        }
    }
    
    mp_msg(MSGT_HEADER,MSGL_V,"LAVF: %d audio and %d video streams found\n",priv->audio_streams,priv->video_streams);
    mp_msg(MSGT_HEADER,MSGL_V,"LAVF: build %d\n", LIBAVFORMAT_BUILD);
    if(!priv->audio_streams) demuxer->audio->id=-2;  // nosound
//    else if(best_audio > 0 && demuxer->audio->id == -1) demuxer->audio->id=best_audio;
    if(!priv->video_streams){
        if(!priv->audio_streams){
	    mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF: no audio or video headers found - broken file?\n");
            return NULL; 
        }
        demuxer->video->id=-2; // audio-only
    } //else if (best_video > 0 && demuxer->video->id == -1) demuxer->video->id = best_video;

    return demuxer;
}
Example #14
0
static demuxer_t* demux_open_y4m(demuxer_t* demuxer){
    y4m_priv_t* priv = demuxer->priv;
    y4m_ratio_t ratio;
    sh_video_t* sh=new_sh_video(demuxer,0);
    int err;

    priv->framenum = 0;
    priv->si = malloc(sizeof(y4m_stream_info_t));

    if (priv->is_older)
    {
	char buf[4];
	int frame_rate_code;

	stream_skip(demuxer->stream, 8); /* YUV4MPEG */
	stream_skip(demuxer->stream, 1); /* space */
	stream_read(demuxer->stream, (char *)&buf[0], 3);
	buf[3] = 0;
	sh->disp_w = atoi(buf);
	stream_skip(demuxer->stream, 1); /* space */
	stream_read(demuxer->stream, (char *)&buf[0], 3);
	buf[3] = 0;
	sh->disp_h = atoi(buf);
	stream_skip(demuxer->stream, 1); /* space */
	stream_read(demuxer->stream, (char *)&buf[0], 1);
	buf[1] = 0;
	frame_rate_code = atoi(buf);
	stream_skip(demuxer->stream, 1); /* new-line */
	
	if (!sh->fps)
	{
	    /* values from xawtv */
	    switch(frame_rate_code)
	    {
		case 1:
		    sh->fps = 23.976f;
		    break;
		case 2:
		    sh->fps = 24.0f;
		    break;
		case 3:
		    sh->fps = 25.0f;
		    break;
		case 4:
		    sh->fps = 29.97f;
		    break;
		case 5:
		    sh->fps = 30.0f;
		    break;
		case 6:
		    sh->fps = 50.0f;
		    break;
		case 7:
		    sh->fps = 59.94f;
		    break;
		case 8:
		    sh->fps = 60.0f;
		    break;
		default:
		    sh->fps = 25.0f;
	    }
	}
	sh->frametime = 1.0f/sh->fps;
    }
    else
    {
	y4m_init_stream_info(priv->si);
	if ((err=y4m_read_stream_header(demuxer->stream, priv->si)) != Y4M_OK) 
	    mp_msg(MSGT_DEMUXER, MSGL_FATAL, "error parsing YUV4MPEG header: %s\n", y4m_strerr(err));
	
	if(!sh->fps) {
    	    ratio = y4m_si_get_framerate(priv->si);
    	    if (ratio.d != 0)
        	sh->fps=(float)ratio.n/(float)ratio.d;
    	    else
        	sh->fps=15.0f;
	}
	sh->frametime=1.0f/sh->fps;
	
	ratio = y4m_si_get_sampleaspect(priv->si);

	sh->disp_w = y4m_si_get_width(priv->si);
	sh->disp_h = y4m_si_get_height(priv->si);

	if (ratio.d != 0 && ratio.n != 0)
	    sh->aspect = (float)(sh->disp_w*ratio.n)/(float)(sh->disp_h*ratio.d);

    	demuxer->seekable = 0;
    }

    sh->format = mmioFOURCC('Y', 'V', '1', '2');

    sh->bih=malloc(sizeof(BITMAPINFOHEADER));
    memset(sh->bih,0,sizeof(BITMAPINFOHEADER));
    sh->bih->biSize=40;
    sh->bih->biWidth = sh->disp_w;
    sh->bih->biHeight = sh->disp_h;
    sh->bih->biPlanes=3;
    sh->bih->biBitCount=12;
    sh->bih->biCompression=sh->format;
    sh->bih->biSizeImage=sh->bih->biWidth*sh->bih->biHeight*3/2; /* YV12 */

    demuxer->video->sh=sh;
    sh->ds=demuxer->video;
    demuxer->video->id=0;
		

    mp_msg(MSGT_DEMUX, MSGL_INFO, "YUV4MPEG2 Video stream %d size: display: %dx%d, codec: %ux%u\n",
            demuxer->video->id, sh->disp_w, sh->disp_h, sh->bih->biWidth,
            sh->bih->biHeight);

    return demuxer;
}
Example #15
0
static demuxer_t* demux_dshow_open (demuxer_t *demuxer)
{
	sh_video_t *sh_video;
	sh_audio_t *sh_audio;
	stream_pos = 0;
	last_vpts = 0;
	b_stopped = 0;
	b_vfinished = 0;
	b_afinished = 0;
	b_firstframe = 1;
	b_firstaframe = 1;
	g_vpkg.pData = NULL;
	g_apkg.pData = NULL;
	apkg_buf = NULL;
	apkg_buf_size = 0;

	if(AudioInfo.demuxer)
		demux_info_add(demuxer, "DShow Demuxer", AudioInfo.demuxer);

	if(VideoInfo.haveVideo) {
		if (VideoInfo.avgtimeperframe < 10000)
			VideoInfo.avgtimeperframe = 400000;

		sh_video = new_sh_video(demuxer, 0);

		if (demuxer->video->id == -1) demuxer->video->id = 0;
		if (demuxer->video->id == 0)
		demuxer->video->sh = sh_video;
		sh_video->ds = demuxer->video;

		sh_video->disp_w = VideoInfo.width;
		sh_video->disp_h = VideoInfo.height;
		sh_video->format = mmioFOURCC('Y', 'V', '1', '2');

		sh_video->frametime = (float)(VideoInfo.avgtimeperframe/1E7);
		sh_video->fps = 1.0 / sh_video->frametime;

		sh_video->bih = calloc (1, sizeof (BITMAPINFOHEADER));
		sh_video->bih->biSize = sizeof (BITMAPINFOHEADER);
		sh_video->bih->biWidth = VideoInfo.width;
		sh_video->bih->biHeight = VideoInfo.height;
		sh_video->bih->biBitCount = 12;
		sh_video->bih->biSizeImage = sh_video->bih->biWidth * sh_video->bih->biHeight * sh_video->bih->biBitCount/8;
		sh_video->bih->biCompression = sh_video->format;
		if(VideoInfo.videoDecoder)
			demux_info_add(demuxer, "DShow Video", VideoInfo.videoDecoder);

		if(VideoInfo.aspectX > 1 && VideoInfo.aspectY > 1)
			sh_video->aspect = (float)VideoInfo.width*(float)VideoInfo.aspectX/((float)VideoInfo.height*(float)VideoInfo.aspectY);
	}

	if(AudioInfo.haveAudio) {
		sh_audio = new_sh_audio_aid(demuxer, 0, 0, NULL);
		demuxer->audio->id = 0;
		demuxer->audio->sh = sh_audio;
		sh_audio->ds = demuxer->audio;
		sh_audio->wf = malloc (sizeof (WAVEFORMATEX));
		memset(sh_audio->wf, 0, sizeof (WAVEFORMATEX));

		if(AudioInfo.audioDecoder) {
			if(AudioInfo.wFormatTag == 0xfffe && !strcmp(AudioInfo.audioDecoder, "Microsoft DTV-DVD Audio Decoder"))
				AudioInfo.wFormatTag = 0x3;
			demux_info_add(demuxer, "DShow Audio", AudioInfo.audioDecoder);
		}
		sh_audio->format = sh_audio->wf->wFormatTag = AudioInfo.wFormatTag;
		sh_audio->channels = sh_audio->wf->nChannels = AudioInfo.nChannels;
		sh_audio->samplerate = sh_audio->wf->nSamplesPerSec = AudioInfo.nSamplesPerSec;
		sh_audio->wf->wBitsPerSample = AudioInfo.wBitsPerSample;
		sh_audio->wf->nBlockAlign = sh_audio->channels * sh_audio->wf->wBitsPerSample / 8;
		sh_audio->wf->nAvgBytesPerSec = sh_audio->wf->nBlockAlign * sh_audio->samplerate;
        sh_audio->i_bps = sh_audio->wf->nAvgBytesPerSec;

	}

	duration = GetGraphDuration(g_pdgi);

	hWaitVSend = CreateEventA(NULL, FALSE, FALSE, NULL);
	hWaitASend = CreateEventA(NULL, FALSE, FALSE, NULL);
	hWaitVDec = CreateEventA(NULL, FALSE, FALSE, NULL);
	hWaitADec = CreateEventA(NULL, FALSE, FALSE, NULL);

	StartGraph(g_pdgi);

    return demuxer;
}
Example #16
0
// return value:
//     0 = EOF or no stream found
//     1 = successfully read a packet
static int demux_lmlm4_fill_buffer(demuxer_t *demux, demux_stream_t *ds)
{
    FrameInfo frameInfo;
    double pts;
    int id=1;
    int ret;

//hdr:
    demux->filepos = stream_tell(demux->stream);
    mp_msg(MSGT_DEMUX, MSGL_DBG2, "fpos = %"PRId64"\n", (int64_t)demux->filepos);

    ret=getFrame(demux, &frameInfo);
    if(ret<=0) return ret; // EOF/error

    pts=demux->video->sh ? frames*((sh_video_t*)(demux->video->sh))->frametime : 0;

    switch(frameInfo.frameType) {
    case FRAMETYPE_AUDIO_MPEG1L2:
        mp_dbg(MSGT_DEMUX, MSGL_DBG2, "Audio Packet\n");
        if (!video)
        {
            stream_skip(demux->stream, frameInfo.frameSize + frameInfo.paddingSize);
            mp_msg(MSGT_DEMUX, MSGL_V, "Skip Audio Packet\n");
            return -1; //goto hdr;
        }
        if(demux->audio->id==-1) {
            if(!demux->a_streams[id]) new_sh_audio(demux,id, NULL);
            demux->audio->id=id;
            demux->audio->sh=demux->a_streams[id];
            ((sh_audio_t*)(demux->audio->sh))->format=0x50; // mpeg audio layer 1/2
        }
        if(demux->audio->id==id)
            ds_read_packet(demux->audio, demux->stream, frameInfo.frameSize,
                           pts, demux->filepos, 0);
        else
            stream_skip(demux->stream,frameInfo.frameSize);
        break;
    case FRAMETYPE_I:
        if (!video) {
            video = 1;
            mp_dbg(MSGT_DEMUX, MSGL_DBG2, "First Video Packet\n");
        }
    case FRAMETYPE_P:
        frames=(frames+1)&(1024*1024-1); // wrap around at 4 hrs to avoid inaccurate float calculations
        if (!video)
        {
            stream_skip(demux->stream, frameInfo.frameSize + frameInfo.paddingSize);
            mp_msg(MSGT_DEMUX, MSGL_V, "Skip Video P Packet\n");
            return -1; //goto hdr;
        }
        mp_dbg(MSGT_DEMUX, MSGL_DBG2, "Video Packet\n");
        if(demux->video->id==-1) {
            if(!demux->v_streams[id]) new_sh_video(demux,id);
            demux->video->id=id;
            demux->video->sh=demux->v_streams[id];
            ((sh_video_t*)(demux->video->sh))->format=0x10000004; // mpeg4-ES
        }
        if(demux->video->id==id)
            ds_read_packet(demux->video, demux->stream, frameInfo.frameSize,
                           pts, demux->filepos, 0);
        break;
    default:
        stream_skip(demux->stream,frameInfo.frameSize);
    }

    stream_skip(demux->stream, frameInfo.paddingSize);

    return 1;
}
Example #17
0
static demuxer_t* demux_open_smjpeg(demuxer_t* demuxer){
    sh_video_t* sh_video;
    sh_audio_t* sh_audio;
    unsigned int htype = 0, hleng;
    int i = 0;

    /* file header */
    stream_skip(demuxer->stream, 8); /* \x00\x0aSMJPEG */
    stream_skip(demuxer->stream, 4);
    
    mp_msg(MSGT_DEMUX, MSGL_INFO, "This clip is %d seconds\n",
	stream_read_dword(demuxer->stream));
    
    /* stream header */
    while (i < 3)
    {
	i++;
	htype = stream_read_dword_le(demuxer->stream);
	if (htype == mmioFOURCC('H','E','N','D'))
	    break;
	hleng = (stream_read_word(demuxer->stream)<<16)|stream_read_word(demuxer->stream);
	switch(htype)
	{
	case mmioFOURCC('_','V','I','D'):
	    sh_video = new_sh_video(demuxer, 0);
	    demuxer->video->sh = sh_video;
	    sh_video->ds = demuxer->video;
	    
	    sh_video->bih = malloc(sizeof(BITMAPINFOHEADER));
	    memset(sh_video->bih, 0, sizeof(BITMAPINFOHEADER));

	    stream_skip(demuxer->stream, 4); /* number of frames */
//	    sh_video->fps = 24;
//	    sh_video->frametime = 1.0f/sh_video->fps;
	    sh_video->disp_w = stream_read_word(demuxer->stream);
	    sh_video->disp_h = stream_read_word(demuxer->stream);
	    sh_video->format = stream_read_dword_le(demuxer->stream);

	    /* these are false values */
	    sh_video->bih->biSize = 40;
	    sh_video->bih->biWidth = sh_video->disp_w;
	    sh_video->bih->biHeight = sh_video->disp_h;
	    sh_video->bih->biPlanes = 3;
	    sh_video->bih->biBitCount = 12;
	    sh_video->bih->biCompression = sh_video->format;
	    sh_video->bih->biSizeImage = sh_video->disp_w*sh_video->disp_h;
	    break;
	case mmioFOURCC('_','S','N','D'):
	    sh_audio = new_sh_audio(demuxer, 0);
	    demuxer->audio->sh = sh_audio;
	    sh_audio->ds = demuxer->audio;

	    sh_audio->wf = malloc(sizeof(WAVEFORMATEX));
	    memset(sh_audio->wf, 0, sizeof(WAVEFORMATEX));
	    
	    sh_audio->samplerate = stream_read_word(demuxer->stream);
	    sh_audio->wf->wBitsPerSample = stream_read_char(demuxer->stream);
	    sh_audio->channels = stream_read_char(demuxer->stream);
	    sh_audio->format = stream_read_dword_le(demuxer->stream);
	    sh_audio->wf->wFormatTag = sh_audio->format;
	    sh_audio->wf->nChannels = sh_audio->channels;
	    sh_audio->wf->nSamplesPerSec = sh_audio->samplerate;
	    sh_audio->wf->nAvgBytesPerSec = sh_audio->wf->nChannels*
	    sh_audio->wf->wBitsPerSample*sh_audio->wf->nSamplesPerSec/8;
	    sh_audio->wf->nBlockAlign = sh_audio->channels *2;
	    sh_audio->wf->cbSize = 0;
	    break;
	case mmioFOURCC('_','T','X','T'):
	    stream_skip(demuxer->stream, stream_read_dword(demuxer->stream));
	    break;
	}
    }

    demuxer->seekable = 0;
    
    return demuxer;
}
Example #18
0
static demuxer_t* demux_open_lmlm4(demuxer_t* demuxer) {
    sh_audio_t *sh_audio=NULL;
    sh_video_t *sh_video=NULL;

#if 0
    sh_video_t* sh_video;
    sh_audio_t* sh_audio;
    unsigned int htype = 0, hleng;
    int i = 0;

    sh_video = new_sh_video(demuxer, 0);
    demuxer->video->sh = sh_video;
    sh_video->ds = demuxer->video;
    sh_video->disp_w = 640;
    sh_video->disp_h = 480;
    sh_video->format = mmioFOURCC('D','I','V','X');

    sh_video->bih = calloc(1, sizeof(*sh_video->bih));

    /* these are false values */
    sh_video->bih->biSize = 40;
    sh_video->bih->biWidth = sh_video->disp_w;
    sh_video->bih->biHeight = sh_video->disp_h;
    sh_video->bih->biPlanes = 3;
    sh_video->bih->biBitCount = 16;
    sh_video->bih->biCompression = sh_video->format;
    sh_video->bih->biSizeImage = sh_video->disp_w*sh_video->disp_h;

    sh_audio = new_sh_audio(demuxer, 0, NULL);
    demuxer->audio->sh = sh_audio;
    sh_audio->ds = demuxer->audio;

    sh_audio->wf = calloc(1, sizeof(*sh_audio->wf));

    sh_audio->samplerate = 48000;
    sh_audio->wf->wBitsPerSample = 16;
    sh_audio->channels = 2;
    sh_audio->format = 0x50;
    sh_audio->wf->wFormatTag = sh_audio->format;
    sh_audio->wf->nChannels = sh_audio->channels;
    sh_audio->wf->nSamplesPerSec = sh_audio->samplerate;
    sh_audio->wf->nAvgBytesPerSec = sh_audio->wf->nChannels*
                                    sh_audio->wf->wBitsPerSample*sh_audio->wf->nSamplesPerSec/8;
    sh_audio->wf->nBlockAlign = sh_audio->channels *2;
    sh_audio->wf->cbSize = 0;

#endif

    demuxer->seekable = 0;

    if(!ds_fill_buffer(demuxer->video)) {
        mp_msg(MSGT_DEMUXER,MSGL_INFO,"LMLM4: " MSGTR_MissingVideoStream);
        demuxer->video->sh=NULL;
    } else {
        sh_video=demuxer->video->sh;
        sh_video->ds=demuxer->video;
    }
    if(demuxer->audio->id!=-2) {
        if(!ds_fill_buffer(demuxer->audio)) {
            mp_msg(MSGT_DEMUXER,MSGL_INFO,"LMLM4: " MSGTR_MissingAudioStream);
            demuxer->audio->sh=NULL;
        } else {
            sh_audio=demuxer->audio->sh;
            sh_audio->ds=demuxer->audio;
        }
    }

    return demuxer;
}
Example #19
0
void read_avi_header(demuxer_t *demuxer,int index_mode){
sh_audio_t *sh_audio=NULL;
sh_video_t *sh_video=NULL;
int stream_id=-1;
int idxfix_videostream=0;
int idxfix_divx=0;
avi_priv_t* priv=demuxer->priv;
off_t list_end=0;

//---- AVI header:
priv->idx_size=0;
priv->audio_streams=0;
while(1){
  int id=stream_read_dword_le(demuxer->stream);
  unsigned chunksize,size2;
  static int last_fccType=0;
  static int last_fccHandler=0;
  char* hdr=NULL;
  //
  if(stream_eof(demuxer->stream)) break;
  // Imply -forceidx if -saveidx is specified
  if (index_file_save)
    index_mode = 2;
  //
  if(id==mmioFOURCC('L','I','S','T')){
    unsigned len=stream_read_dword_le(demuxer->stream);   // list size
    id=stream_read_dword_le(demuxer->stream);             // list type
    mp_msg(MSGT_HEADER,MSGL_DBG2,"LIST %.4s  len=%u\n",(char *) &id,len);
    if(len >= 4) {
	len -= 4;
	list_end=stream_tell(demuxer->stream)+((len+1)&(~1));
    } else {
	mp_msg(MSGT_HEADER,MSGL_WARN,MSGTR_MPDEMUX_AVIHDR_EmptyList);
	list_end = 0;
    }
    mp_msg(MSGT_HEADER,MSGL_V,"list_end=0x%X\n",(int)list_end);
    if(id==listtypeAVIMOVIE){
      // found MOVI header
      if(!demuxer->movi_start) demuxer->movi_start=stream_tell(demuxer->stream);
      demuxer->movi_end=stream_tell(demuxer->stream)+len;
      mp_msg(MSGT_HEADER,MSGL_V,MSGTR_MPDEMUX_AVIHDR_FoundMovieAt,(int)demuxer->movi_start,(int)demuxer->movi_end);
      if(demuxer->stream->end_pos>demuxer->movi_end) demuxer->movi_end=demuxer->stream->end_pos;
      if(index_mode==-2 || index_mode==2 || index_mode==0)
        break; // reading from non-seekable source (stdin) or forced index or no index forced
      if(list_end>0) stream_seek(demuxer->stream,list_end); // skip movi
      list_end=0;
    }
    continue;
  }
  size2=stream_read_dword_le(demuxer->stream);
  mp_msg(MSGT_HEADER,MSGL_DBG2,"CHUNK %.4s  len=%u\n",(char *) &id,size2);
  chunksize=(size2+1)&(~1);
  switch(id){

    // Indicates where the subject of the file is archived
    case mmioFOURCC('I','A','R','L'): hdr="Archival Location";break;
    // Lists the artist of the original subject of the file;
    // for example, "Michaelangelo."
    case mmioFOURCC('I','A','R','T'): hdr="Artist";break;
    // Lists the name of the person or organization that commissioned
    // the subject of the file; for example "Pope Julian II."
    case mmioFOURCC('I','C','M','S'): hdr="Commissioned";break;
    // Provides general comments about the file or the subject
    // of the file. If the comment is several sentences long, end each
    // sentence with a period. Do not include new-line characters.
    case mmioFOURCC('I','C','M','T'): hdr="Comments";break;
    // Records the copyright information for the file; for example,
    // "Copyright Encyclopedia International 1991." If there are multiple
    // copyrights, separate them by semicolon followed by a space.
    case mmioFOURCC('I','C','O','P'): hdr="Copyright";break;
    // Describes whether an image has been cropped and, if so, how it
    // was cropped; for example, "lower-right corner."
    case mmioFOURCC('I','C','R','D'): hdr="Creation Date";break;
    // Describes whether an image has been cropped and, if so, how it
    // was cropped; for example, "lower-right corner."
    case mmioFOURCC('I','C','R','P'): hdr="Cropped";break;
    // Specifies the size of the original subject of the file; for
    // example, "8.5 in h, 11 in w."
    case mmioFOURCC('I','D','I','M'): hdr="Dimensions";break;
    // Stores dots per inch setting of the digitizer used to
    // produce the file, such as "300."
    case mmioFOURCC('I','D','P','I'): hdr="Dots Per Inch";break;
    // Stores the of the engineer who worked on the file. If there are
    // multiple engineers, separate the names by a semicolon and a blank;
    // for example, "Smith, John; Adams, Joe."
    case mmioFOURCC('I','E','N','G'): hdr="Engineer";break;
    // Describes the original work, such as "landscape,", "portrait,"
    // "still liefe," etc.
    case mmioFOURCC('I','G','N','R'): hdr="Genre";break;
    // Provides a list of keywords that refer to the file or subject of the
    // file. Separate multiple keywords with a semicolon and a blank;
    // for example, "Seattle, aerial view; scenery."
    case mmioFOURCC('I','K','E','Y'): hdr="Keywords";break;
    // ILGT - Describes the changes in the lightness settings on the digitizer
    // required to produce the file. Note that the format of this information
    // depends on the hardware used.
    case mmioFOURCC('I','L','G','T'): hdr="Lightness";break;
    // IMED - Decribes the original subject of the file, such as
    // "computer image," "drawing," "lithograph," and so on.
    case mmioFOURCC('I','M','E','D'): hdr="Medium";break;
    // INAM - Stores the title of the subject of the file, such as
    // "Seattle from Above."
    case mmioFOURCC('I','N','A','M'): hdr="Title";break;
    // IPLT - Specifies the number of colors requested when digitizing
    // an image, such as "256."
    case mmioFOURCC('I','P','L','T'): hdr="Palette Setting";break;
    // IPRD - Specifies the name of title the file was originally intended
    // for, such as "Encyclopedia of Pacific Northwest Geography."
    case mmioFOURCC('I','P','R','D'): hdr="Product";break;
    // ISBJ - Decsribes the contents of the file, such as
    // "Aerial view of Seattle."
    case mmioFOURCC('I','S','B','J'): hdr="Subject";break;
    // ISFT - Identifies the name of the software packages used to create the
    // file, such as "Microsoft WaveEdit"
    case mmioFOURCC('I','S','F','T'): hdr="Software";break;
    // ISHP - Identifies the change in sharpness for the digitizer
    // required to produce the file (the format depends on the hardware used).
    case mmioFOURCC('I','S','H','P'): hdr="Sharpness";break;
    // ISRC - Identifies the name of the person or organization who
    // suplied the original subject of the file; for example, "Try Research."
    case mmioFOURCC('I','S','R','C'): hdr="Source";break;
    // ISRF - Identifies the original form of the material that was digitized,
    // such as "slide," "paper," "map," and so on. This is not necessarily
    // the same as IMED
    case mmioFOURCC('I','S','R','F'): hdr="Source Form";break;
    // ITCH - Identifies the technician who digitized the subject file;
    // for example, "Smith, John."
    case mmioFOURCC('I','T','C','H'): hdr="Technician";break;
    case mmioFOURCC('I','S','M','P'): hdr="Time Code";break;
    case mmioFOURCC('I','D','I','T'): hdr="Digitization Time";break;

    case ckidAVIMAINHDR:          // read 'avih'
      stream_read(demuxer->stream,(char*) &avih,FFMIN(size2,sizeof(avih)));
      le2me_MainAVIHeader(&avih); // swap to machine endian
      chunksize-=FFMIN(size2,sizeof(avih));
      if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_avih(&avih,MSGL_V); // else print_avih_flags(&avih,MSGL_V);
      break;
    case ckidSTREAMHEADER: {      // read 'strh'
      AVIStreamHeader h;
      stream_read(demuxer->stream,(char*) &h,FFMIN(size2,sizeof(h)));
      le2me_AVIStreamHeader(&h);  // swap to machine endian
      chunksize-=FFMIN(size2,sizeof(h));
      ++stream_id;
      if(h.fccType==streamtypeVIDEO){
        sh_video=new_sh_video(demuxer,stream_id);
        mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_VideoID, "aviheader", stream_id);
        memcpy(&sh_video->video,&h,sizeof(h));
        sh_video->stream_delay = (float)sh_video->video.dwStart * sh_video->video.dwScale/sh_video->video.dwRate;
      } else
      if(h.fccType==streamtypeAUDIO){
        sh_audio=new_sh_audio(demuxer,stream_id);
        mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_AudioID, "aviheader", stream_id);
        memcpy(&sh_audio->audio,&h,sizeof(h));
        sh_audio->stream_delay = (float)sh_audio->audio.dwStart * sh_audio->audio.dwScale/sh_audio->audio.dwRate;
      }
      last_fccType=h.fccType;
      last_fccHandler=h.fccHandler;
      if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_strh(&h,MSGL_V);
      break; }
    case mmioFOURCC('i', 'n', 'd', 'x'): {
      uint32_t i;
      avisuperindex_chunk *s;

      if(!index_mode) break;

      if(chunksize<=24){
        break;
      }
      priv->suidx_size++;
      priv->suidx = realloc_struct(priv->suidx, priv->suidx_size, sizeof (avisuperindex_chunk));
      s = &priv->suidx[priv->suidx_size-1];

      chunksize-=24;
      memcpy(s->fcc, "indx", 4);
      s->dwSize = size2;
      s->wLongsPerEntry = stream_read_word_le(demuxer->stream);
      s->bIndexSubType = stream_read_char(demuxer->stream);
      s->bIndexType = stream_read_char(demuxer->stream);
      s->nEntriesInUse = stream_read_dword_le(demuxer->stream);
      *(uint32_t *)s->dwChunkId = stream_read_dword_le(demuxer->stream);
      stream_read(demuxer->stream, (char *)s->dwReserved, 3*4);
      memset(s->dwReserved, 0, 3*4);

      print_avisuperindex_chunk(s,MSGL_V);

      // Check and fix this useless crap
      if(s->wLongsPerEntry != sizeof (avisuperindex_entry)/4) {
          mp_msg (MSGT_HEADER, MSGL_WARN, "Broken super index chunk size: %u\n",s->wLongsPerEntry);
          s->wLongsPerEntry = sizeof(avisuperindex_entry)/4;
      }
      if( ((chunksize/4)/s->wLongsPerEntry) < s->nEntriesInUse){
        mp_msg (MSGT_HEADER, MSGL_WARN, "Broken super index chunk\n");
        s->nEntriesInUse = (chunksize/4)/s->wLongsPerEntry;
      }

      s->aIndex = calloc(s->nEntriesInUse, sizeof (avisuperindex_entry));
      s->stdidx = calloc(s->nEntriesInUse, sizeof (avistdindex_chunk));

      // now the real index of indices
      for (i=0; i<s->nEntriesInUse; i++) {
	  chunksize-=16;
	  s->aIndex[i].qwOffset = stream_read_qword_le(demuxer->stream);
	  s->aIndex[i].dwSize = stream_read_dword_le(demuxer->stream);
	  s->aIndex[i].dwDuration = stream_read_dword_le(demuxer->stream);
	  mp_msg (MSGT_HEADER, MSGL_V, "ODML (%.4s): [%d] 0x%016"PRIx64" 0x%04x %u\n",
		  (s->dwChunkId), i,
		  (uint64_t)s->aIndex[i].qwOffset, s->aIndex[i].dwSize, s->aIndex[i].dwDuration);
      }

      break; }
    case ckidSTREAMFORMAT: {      // read 'strf'
      if(last_fccType==streamtypeVIDEO){
        sh_video->bih=calloc(FFMAX(chunksize, sizeof(BITMAPINFOHEADER)), 1);
//        sh_video->bih=malloc(chunksize); memset(sh_video->bih,0,chunksize);
        mp_msg(MSGT_HEADER,MSGL_V,MSGTR_MPDEMUX_AVIHDR_FoundBitmapInfoHeader,chunksize,sizeof(BITMAPINFOHEADER));
        stream_read(demuxer->stream,(char*) sh_video->bih,chunksize);
	le2me_BITMAPINFOHEADER(sh_video->bih);  // swap to machine endian
	if (sh_video->bih->biSize > chunksize && sh_video->bih->biSize > sizeof(BITMAPINFOHEADER))
		sh_video->bih->biSize = chunksize;
	// fixup MS-RLE header (seems to be broken for <256 color files)
	if(sh_video->bih->biCompression<=1 && sh_video->bih->biSize==40)
	    sh_video->bih->biSize=chunksize;
        if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_video_header(sh_video->bih,MSGL_V);
        chunksize=0;
        sh_video->fps=(float)sh_video->video.dwRate/(float)sh_video->video.dwScale;
        sh_video->frametime=(float)sh_video->video.dwScale/(float)sh_video->video.dwRate;
        sh_video->format = sh_video->bih->biCompression;
//        if(demuxer->video->id==-1) demuxer->video->id=stream_id;
        // IdxFix:
        idxfix_videostream=stream_id;
        switch(sh_video->bih->biCompression){
	case mmioFOURCC('M', 'P', 'G', '4'):
	case mmioFOURCC('m', 'p', 'g', '4'):
	case mmioFOURCC('D', 'I', 'V', '1'):
          idxfix_divx=3; // set index recovery mpeg4 flavour: msmpeg4v1
	  mp_msg(MSGT_HEADER,MSGL_V,MSGTR_MPDEMUX_AVIHDR_RegeneratingKeyfTableForMPG4V1);
	  break;
        case mmioFOURCC('D', 'I', 'V', '3'):
	case mmioFOURCC('d', 'i', 'v', '3'):
	case mmioFOURCC('D', 'I', 'V', '4'):
        case mmioFOURCC('d', 'i', 'v', '4'):
	case mmioFOURCC('D', 'I', 'V', '5'):
	case mmioFOURCC('d', 'i', 'v', '5'):
	case mmioFOURCC('D', 'I', 'V', '6'):
        case mmioFOURCC('d', 'i', 'v', '6'):
	case mmioFOURCC('M', 'P', '4', '3'):
	case mmioFOURCC('m', 'p', '4', '3'):
	case mmioFOURCC('M', 'P', '4', '2'):
	case mmioFOURCC('m', 'p', '4', '2'):
	case mmioFOURCC('D', 'I', 'V', '2'):
        case mmioFOURCC('A', 'P', '4', '1'):
          idxfix_divx=1; // set index recovery mpeg4 flavour: msmpeg4v3
	  mp_msg(MSGT_HEADER,MSGL_V,MSGTR_MPDEMUX_AVIHDR_RegeneratingKeyfTableForDIVX3);
	  break;
        case mmioFOURCC('D', 'I', 'V', 'X'):
        case mmioFOURCC('d', 'i', 'v', 'x'):
        case mmioFOURCC('D', 'X', '5', '0'):
        case mmioFOURCC('X', 'V', 'I', 'D'):
        case mmioFOURCC('x', 'v', 'i', 'd'):
        case mmioFOURCC('F', 'M', 'P', '4'):
        case mmioFOURCC('f', 'm', 'p', '4'):
          idxfix_divx=2; // set index recovery mpeg4 flavour: generic mpeg4
	  mp_msg(MSGT_HEADER,MSGL_V,MSGTR_MPDEMUX_AVIHDR_RegeneratingKeyfTableForMPEG4);
	  break;
        }
      } else
      if(last_fccType==streamtypeAUDIO){
	unsigned wf_size = chunksize<sizeof(WAVEFORMATEX)?sizeof(WAVEFORMATEX):chunksize;
        sh_audio->wf=calloc(wf_size,1);
//        sh_audio->wf=malloc(chunksize); memset(sh_audio->wf,0,chunksize);
        mp_msg(MSGT_HEADER,MSGL_V,MSGTR_MPDEMUX_AVIHDR_FoundWaveFmt,chunksize,sizeof(WAVEFORMATEX));
        stream_read(demuxer->stream,(char*) sh_audio->wf,chunksize);
	le2me_WAVEFORMATEX(sh_audio->wf);
	if (sh_audio->wf->cbSize != 0 &&
	    wf_size < sizeof(WAVEFORMATEX)+sh_audio->wf->cbSize) {
	    sh_audio->wf=realloc(sh_audio->wf, sizeof(WAVEFORMATEX)+sh_audio->wf->cbSize);
	}
	sh_audio->format=sh_audio->wf->wFormatTag;
	if (sh_audio->format == 1 &&
	    last_fccHandler == mmioFOURCC('A', 'x', 'a', 'n'))
	    sh_audio->format = last_fccHandler;
	sh_audio->i_bps=sh_audio->wf->nAvgBytesPerSec;
        chunksize=0;
        if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_wave_header(sh_audio->wf,MSGL_V);
	++priv->audio_streams;
//        if(demuxer->audio->id==-1) demuxer->audio->id=stream_id;
      }
      break;
    }
    case mmioFOURCC('v', 'p', 'r', 'p'): {
	VideoPropHeader *vprp = malloc(chunksize);
	unsigned int i;
	stream_read(demuxer->stream, (void*)vprp, chunksize);
	le2me_VideoPropHeader(vprp);
	chunksize -= sizeof(*vprp)-sizeof(vprp->FieldInfo);
	chunksize /= sizeof(VIDEO_FIELD_DESC);
	if (vprp->nbFieldPerFrame > chunksize) {
	    vprp->nbFieldPerFrame = chunksize;
	}
	chunksize = 0;
	for (i=0; i<vprp->nbFieldPerFrame; i++) {
		le2me_VIDEO_FIELD_DESC(&vprp->FieldInfo[i]);
	}
	if (sh_video) {
		sh_video->aspect = GET_AVI_ASPECT(vprp->dwFrameAspectRatio);
	}
	if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_vprp(vprp,MSGL_V);
	free(vprp);
	break;
    }
    case mmioFOURCC('d', 'm', 'l', 'h'): {
	// dmlh 00 00 00 04 frms
	unsigned int total_frames = stream_read_dword_le(demuxer->stream);
	mp_msg(MSGT_HEADER,MSGL_V,MSGTR_MPDEMUX_AVIHDR_FoundAVIV2Header, chunksize, total_frames);
	stream_skip(demuxer->stream, chunksize-4);
	chunksize = 0;
    }
    break;
    case ckidAVINEWINDEX:
    if(demuxer->movi_end>stream_tell(demuxer->stream))
	demuxer->movi_end=stream_tell(demuxer->stream); // fixup movi-end
    if(index_mode && !priv->isodml){
      int i;
      priv->idx_size=size2>>4;
      mp_msg(MSGT_HEADER,MSGL_V,MSGTR_MPDEMUX_AVIHDR_ReadingIndexBlockChunksForFrames,
        priv->idx_size,avih.dwTotalFrames, (int64_t)stream_tell(demuxer->stream));
      priv->idx=malloc(priv->idx_size<<4);
//      printf("\nindex to %p !!!!! (priv=%p)\n",priv->idx,priv);
      stream_read(demuxer->stream,(char*)priv->idx,priv->idx_size<<4);
      for (i = 0; i < priv->idx_size; i++) {	// swap index to machine endian
	AVIINDEXENTRY *entry=(AVIINDEXENTRY*)priv->idx + i;
	le2me_AVIINDEXENTRY(entry);
	/*
	 * We (ab)use the upper word for bits 32-47 of the offset, so
	 * we'll clear them here.
	 * FIXME: AFAIK no codec uses them, but if one does it will break
	 */
	entry->dwFlags&=0xffff;
      }
      chunksize-=priv->idx_size<<4;
      if( mp_msg_test(MSGT_HEADER,MSGL_DBG2) ) print_index(priv->idx,priv->idx_size,MSGL_DBG2);
    }
    break;
    /* added May 2002 */
    case mmioFOURCC('R','I','F','F'): {
	char riff_type[4];

	mp_msg(MSGT_HEADER, MSGL_V, MSGTR_MPDEMUX_AVIHDR_AdditionalRIFFHdr);
	stream_read(demuxer->stream, riff_type, sizeof riff_type);
	if (strncmp(riff_type, "AVIX", sizeof riff_type))
	    mp_msg(MSGT_HEADER, MSGL_WARN, MSGTR_MPDEMUX_AVIHDR_WarnNotExtendedAVIHdr);
	else {
		/*
		 * We got an extended AVI header, so we need to switch to
		 * ODML to get seeking to work, provided we got indx chunks
		 * in the header (suidx_size > 0).
		 */
		if (priv->suidx_size > 0)
			priv->isodml = 1;
	}
	chunksize = 0;
	list_end = 0; /* a new list will follow */
	break; }
    case ckidAVIPADDING:
	stream_skip(demuxer->stream, chunksize);
	chunksize = 0;
	break;
  }
  if(hdr){
    mp_msg(MSGT_HEADER,MSGL_V,"hdr=%s  size=%u\n",hdr,size2);
    if(size2==3)
      chunksize=1; // empty
    else {
      char buf[256];
      int len=(size2<250)?size2:250;
      stream_read(demuxer->stream,buf,len);
      chunksize-=len;
      buf[len]=0;
      mp_msg(MSGT_HEADER,MSGL_V,"%-10s: %s\n",hdr,buf);
      demux_info_add(demuxer, hdr, buf);
    }
  }
  mp_msg(MSGT_HEADER,MSGL_DBG2,"list_end=0x%"PRIX64"  pos=0x%"PRIX64"  chunksize=0x%"PRIX64"  next=0x%"PRIX64"\n",
      (int64_t)list_end, (int64_t)stream_tell(demuxer->stream),
      (int64_t)chunksize, (int64_t)chunksize+(int64_t)stream_tell(demuxer->stream));
  if(list_end>0 &&
     chunksize+stream_tell(demuxer->stream) == list_end) list_end=0;
  if(list_end>0 && chunksize+stream_tell(demuxer->stream)>list_end){
      mp_msg(MSGT_HEADER,MSGL_V,MSGTR_MPDEMUX_AVIHDR_BrokenChunk,chunksize,(char *) &id);
      stream_seek(demuxer->stream,list_end);
      list_end=0;
  } else
  if(chunksize>0) stream_skip(demuxer->stream,chunksize); else
  if((int)chunksize<0) mp_msg(MSGT_HEADER,MSGL_WARN,"chunksize=%u  (id=%.4s)\n",chunksize,(char *) &id);

}
Example #20
0
static demuxer_t* demux_open_roq(demuxer_t* demuxer)
{
  sh_video_t *sh_video = NULL;
  sh_audio_t *sh_audio = NULL;

  roq_data_t *roq_data = malloc(sizeof(roq_data_t));
  int chunk_id;
  int chunk_size;
  int chunk_arg;
  int last_chunk_id = 0;
  int largest_audio_chunk = 0;
  int fps;

  roq_data->total_chunks = 0;
  roq_data->current_chunk = 0;
  roq_data->total_video_chunks = 0;
  roq_data->chunks = NULL;

  // position the stream and start traversing
  stream_seek(demuxer->stream, 6);
  fps = stream_read_word_le(demuxer->stream);
  while (!stream_eof(demuxer->stream))
  {
    chunk_id = stream_read_word_le(demuxer->stream);
    chunk_size = stream_read_dword_le(demuxer->stream);
    chunk_arg = stream_read_word_le(demuxer->stream);

    // this is the only useful header info in the file
    if (chunk_id == RoQ_INFO)
    {
      // there should only be one RoQ_INFO chunk per file
      if (sh_video)
      {
        mp_msg(MSGT_DECVIDEO, MSGL_WARN, "Found more than one RoQ_INFO chunk\n");
        stream_skip(demuxer->stream, 8);
      }
      else
      {
        // this is a good opportunity to create a video stream header
        sh_video = new_sh_video(demuxer, 0);
        // make sure the demuxer knows about the new stream header
        demuxer->video->sh = sh_video;
        // make sure that the video demuxer stream header knows about its
        // parent video demuxer stream
        sh_video->ds = demuxer->video;

        sh_video->disp_w = stream_read_word_le(demuxer->stream);
        sh_video->disp_h = stream_read_word_le(demuxer->stream);
        stream_skip(demuxer->stream, 4);

        // custom fourcc for internal MPlayer use
        sh_video->format = mmioFOURCC('R', 'o', 'Q', 'V');

        // constant frame rate
        sh_video->fps = fps;
        sh_video->frametime = 1 / sh_video->fps;
      }
    }
    else if ((chunk_id == RoQ_SOUND_MONO) ||
      (chunk_id == RoQ_SOUND_STEREO))
    {
      // create the audio stream header if it hasn't been created it
      if (sh_audio == NULL)
      {
        // make the header first
        sh_audio = new_sh_audio(demuxer, 0);
        // make sure the demuxer knows about the new stream header
        demuxer->audio->id = 0;
        demuxer->audio->sh = sh_audio;
        // make sure that the audio demuxer stream header knows about its
        // parent audio demuxer stream
        sh_audio->ds = demuxer->audio;

        // go through the bother of making a WAVEFORMATEX structure
        sh_audio->wf = malloc(sizeof(*sh_audio->wf));

        // custom fourcc for internal MPlayer use
        sh_audio->format = mmioFOURCC('R', 'o', 'Q', 'A');
        if (chunk_id == RoQ_SOUND_STEREO)
          sh_audio->wf->nChannels = 2;
        else
          sh_audio->wf->nChannels = 1;
        // always 22KHz, 16-bit
        sh_audio->wf->nSamplesPerSec = 22050;
        sh_audio->wf->wBitsPerSample = 16;
      }

      // index the chunk
      roq_data->chunks = realloc(roq_data->chunks,
        (roq_data->total_chunks + 1) * sizeof (roq_chunk_t));
      roq_data->chunks[roq_data->total_chunks].chunk_type = CHUNK_TYPE_AUDIO;
      roq_data->chunks[roq_data->total_chunks].chunk_offset =
        stream_tell(demuxer->stream) - 8;
      roq_data->chunks[roq_data->total_chunks].chunk_size = chunk_size + 8;
      roq_data->chunks[roq_data->total_chunks].running_audio_sample_count =
        roq_data->total_audio_sample_count;

      // audio housekeeping
      if (chunk_size > largest_audio_chunk)
        largest_audio_chunk = chunk_size;
      roq_data->total_audio_sample_count +=
        (chunk_size / sh_audio->wf->nChannels);

      stream_skip(demuxer->stream, chunk_size);
      roq_data->total_chunks++;
    }
    else if ((chunk_id == RoQ_QUAD_CODEBOOK) ||
      ((chunk_id == RoQ_QUAD_VQ) && (last_chunk_id != RoQ_QUAD_CODEBOOK)))
    {
      // index a new chunk if it's a codebook or quad VQ not following a
      // codebook
      roq_data->chunks = realloc(roq_data->chunks,
        (roq_data->total_chunks + 1) * sizeof (roq_chunk_t));
      roq_data->chunks[roq_data->total_chunks].chunk_type = CHUNK_TYPE_VIDEO;
      roq_data->chunks[roq_data->total_chunks].chunk_offset =
        stream_tell(demuxer->stream) - 8;
      roq_data->chunks[roq_data->total_chunks].chunk_size = chunk_size + 8;
      roq_data->chunks[roq_data->total_chunks].video_chunk_number =
        roq_data->total_video_chunks++;

      stream_skip(demuxer->stream, chunk_size);
      roq_data->total_chunks++;
    }
    else if ((chunk_id == RoQ_QUAD_VQ) && (last_chunk_id == RoQ_QUAD_CODEBOOK))
    {
      // if it's a quad VQ chunk following a codebook chunk, extend the last
      // chunk
      roq_data->chunks[roq_data->total_chunks - 1].chunk_size += (chunk_size + 8);
      stream_skip(demuxer->stream, chunk_size);
    }
    else if (!stream_eof(demuxer->stream))
    {
        mp_msg(MSGT_DECVIDEO, MSGL_WARN, "Unknown RoQ chunk ID: %04X\n", chunk_id);
    }

    last_chunk_id = chunk_id;
  }

  // minimum output buffer size = largest audio chunk * 2, since each byte
  // in the DPCM encoding effectively represents 1 16-bit sample
  // (store it in wf->nBlockAlign for the time being since init_audio() will
  // step on it anyway)
  if (sh_audio)
    sh_audio->wf->nBlockAlign = largest_audio_chunk * 2;

  roq_data->current_chunk = 0;

  demuxer->priv = roq_data;

  stream_reset(demuxer->stream);

  return demuxer;
}
static demuxer_t * demux_open_pva (demuxer_t * demuxer)
{
	sh_video_t *sh_video = new_sh_video(demuxer,0);
        sh_audio_t *sh_audio = new_sh_audio(demuxer,0, NULL);


	pva_priv_t * priv;

	stream_reset(demuxer->stream);
	stream_seek(demuxer->stream,0);



	priv=malloc(sizeof(pva_priv_t));

	if(demuxer->stream->type!=STREAMTYPE_FILE) demuxer->seekable=0;
	else demuxer->seekable=1;

	demuxer->priv=priv;
	memset(demuxer->priv,0,sizeof(pva_priv_t));

	if(!pva_sync(demuxer))
	{
		mp_msg(MSGT_DEMUX,MSGL_ERR,"Not a PVA file.\n");
		return NULL;
	}

	//printf("priv->just_synced %s after initial sync!\n",priv->just_synced?"set":"UNSET");

	demuxer->video->sh=sh_video;

	//printf("demuxer->stream->end_pos= %d\n",demuxer->stream->end_pos);


	mp_msg(MSGT_DEMUXER,MSGL_INFO,"Opened PVA demuxer...\n");

	/*
	 * Audio and Video codecs:
	 * the PVA spec only allows MPEG2 video and MPEG layer II audio. No need to check the formats then.
	 * Moreover, there would be no way to do that since the PVA stream format has no fields to describe
	 * the used codecs.
	 */

	sh_video->format=0x10000002;
	sh_video->ds=demuxer->video;

	/*
	printf("demuxer->video->id==%d\n",demuxer->video->id);
	printf("demuxer->audio->id==%d\n",demuxer->audio->id);
	*/

	demuxer->audio->id = 0;
	demuxer->audio->sh=sh_audio;
	sh_audio->format=0x50;
	sh_audio->ds=demuxer->audio;

	demuxer->movi_start=0;
	demuxer->movi_end=demuxer->stream->end_pos;

	priv->last_video_pts=-1;
	priv->last_audio_pts=-1;

	return demuxer;
}
Example #22
0
static demuxer_t* demux_open_vivo(demuxer_t* demuxer){
    vivo_priv_t* priv=demuxer->priv;

  if(!ds_fill_buffer(demuxer->video)){
    mp_msg(MSGT_DEMUX,MSGL_ERR,"VIVO: " MSGTR_MissingVideoStreamBug);
    return NULL;
  }

    audio_pos=0;
  
  h263_decode_picture_header(demuxer->video->buffer);
  
  if (vivo_param_version != -1)
    priv->version = '0' + vivo_param_version;

{		sh_video_t* sh=new_sh_video(demuxer,0);

		/* viv1, viv2 (for better codecs.conf) */    
		sh->format = mmioFOURCC('v', 'i', 'v', priv->version);
		if(!sh->fps)
		{
		    if (priv->fps)
			sh->fps=priv->fps;
		    else
			sh->fps=15.0f;
		}
		sh->frametime=1.0f/sh->fps;

		/* XXX: FIXME: can't scale image. */
		/* hotfix to disable: */
		priv->disp_width = priv->width;
		priv->disp_height = priv->height;

		if (vivo_param_width != -1)
		    priv->disp_width = priv->width = vivo_param_width;

		if (vivo_param_height != -1)
		    priv->disp_height = priv->height = vivo_param_height;
		
		if (vivo_param_vformat != -1)
		{
		    priv->disp_width = priv->width = h263_format[vivo_param_vformat][0];
		    priv->disp_height = priv->height = h263_format[vivo_param_vformat][1];
		}

		if (priv->disp_width)
		    sh->disp_w = priv->disp_width;
		else
		    sh->disp_w = width;
		if (priv->disp_height)
		    sh->disp_h = priv->disp_height;
		else
		    sh->disp_h = height;

		// emulate BITMAPINFOHEADER:
		sh->bih=malloc(sizeof(BITMAPINFOHEADER));
		memset(sh->bih,0,sizeof(BITMAPINFOHEADER));
		sh->bih->biSize=40;
		if (priv->width)
		    sh->bih->biWidth = priv->width;
		else
		    sh->bih->biWidth = width;
		if (priv->height)
		    sh->bih->biHeight = priv->height;
		else
		    sh->bih->biHeight = height;
		sh->bih->biPlanes=1;
		sh->bih->biBitCount=24;
		sh->bih->biCompression=sh->format;
		sh->bih->biSizeImage=sh->bih->biWidth*sh->bih->biHeight*3;

		/* insert as stream */
		demuxer->video->sh=sh;
		sh->ds=demuxer->video;
		demuxer->video->id=0;
		
		/* disable seeking */
		demuxer->seekable = 0;

		mp_msg(MSGT_DEMUX,MSGL_V,"VIVO Video stream %d size: display: %dx%d, codec: %ux%u\n",
		    demuxer->video->id, sh->disp_w, sh->disp_h, sh->bih->biWidth,
		    sh->bih->biHeight);
}

/* AUDIO init */
if (demuxer->audio->id >= -1){
  if(!ds_fill_buffer(demuxer->audio)){
    mp_msg(MSGT_DEMUX,MSGL_ERR,"VIVO: " MSGTR_MissingAudioStream);
  } else
{		sh_audio_t* sh=new_sh_audio(demuxer,1);

		/* Select audio codec */
		if (priv->audio_codec == 0)
		{
		    if (priv->version == '2')
			priv->audio_codec = VIVO_AUDIO_SIREN;
		    else
			priv->audio_codec = VIVO_AUDIO_G723;
		}
		if (vivo_param_acodec != NULL)
		{
		    if (!strcasecmp(vivo_param_acodec, "g723"))
			priv->audio_codec = VIVO_AUDIO_G723;
		    if (!strcasecmp(vivo_param_acodec, "siren"))
			priv->audio_codec = VIVO_AUDIO_SIREN;
		}

		if (priv->audio_codec == VIVO_AUDIO_G723)
		    sh->format = 0x111;
		else if (priv->audio_codec == VIVO_AUDIO_SIREN)
		    sh->format = 0x112;
		else
		{
		    mp_msg(MSGT_DEMUX, MSGL_ERR, "VIVO: Not support audio codec (%d)\n",
			priv->audio_codec);
		    free_sh_audio(demuxer, 1);
		    goto nosound;
		}

		// Emulate WAVEFORMATEX struct:
		sh->wf=malloc(sizeof(WAVEFORMATEX));
		memset(sh->wf,0,sizeof(WAVEFORMATEX));
		sh->wf->wFormatTag=sh->format;
		sh->wf->nChannels=1; /* 1 channels for both Siren and G.723 */

		/* Set bits per sample */
		if (priv->audio_codec == VIVO_AUDIO_SIREN)
		    sh->wf->wBitsPerSample = 16;
		else
		if (priv->audio_codec == VIVO_AUDIO_G723)
		    sh->wf->wBitsPerSample = 8;

		/* Set sampling rate */
		if (priv->audio_samplerate) /* got from header */
		    sh->wf->nSamplesPerSec = priv->audio_samplerate;
		else
		{
		    if (priv->audio_codec == VIVO_AUDIO_SIREN)
			sh->wf->nSamplesPerSec = 16000;
		    if (priv->audio_codec == VIVO_AUDIO_G723)
			sh->wf->nSamplesPerSec = 8000;
		}
		if (vivo_param_samplerate != -1)
		    sh->wf->nSamplesPerSec = vivo_param_samplerate;

		/* Set audio bitrate */
		if (priv->audio_bitrate) /* got from header */
		    sh->wf->nAvgBytesPerSec = priv->audio_bitrate;
		else
		{
		    if (priv->audio_codec == VIVO_AUDIO_SIREN)
			sh->wf->nAvgBytesPerSec = 2000;
		    if (priv->audio_codec == VIVO_AUDIO_G723)
			sh->wf->nAvgBytesPerSec = 800;
		}
		if (vivo_param_abitrate != -1)
		    sh->wf->nAvgBytesPerSec = vivo_param_abitrate;
		audio_rate=sh->wf->nAvgBytesPerSec;

		if (!priv->audio_bytesperblock)
		{
		    if (priv->audio_codec == VIVO_AUDIO_SIREN)
			sh->wf->nBlockAlign = 40;
		    if (priv->audio_codec == VIVO_AUDIO_G723)
			sh->wf->nBlockAlign = 24;
		}
		else
		    sh->wf->nBlockAlign = priv->audio_bytesperblock;
		if (vivo_param_bytesperblock != -1)
		    sh->wf->nBlockAlign = vivo_param_bytesperblock;
		
/*sound_ok:*/
		/* insert as stream */
		demuxer->audio->sh=sh;
		sh->ds=demuxer->audio;
		demuxer->audio->id=1;
nosound:
		return demuxer;
}
}
    return demuxer;
}
static int demux_ty_fill_buffer( demuxer_t *demux, demux_stream_t *dsds )
{
   int              invalidType = 0;
   int              errorHeader = 0;
   int              recordsDecoded = 0;

   int              readSize;

   int              numberRecs;
   unsigned char    *recPtr;
   int              offset;

   int              counter;

   int              aid;

   TiVoInfo         *tivo = demux->priv;
   unsigned char    *chunk = tivo->chunk;

   if ( demux->stream->type == STREAMTYPE_DVD )
      return 0;

   mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:ty processing\n" );

   if( demux->stream->eof ) return 0;

   // ======================================================================
   // If we haven't figured out the size of the stream, let's do so
   // ======================================================================
   if ( demux->stream->type == STREAMTYPE_VSTREAM )
   {
      // The vstream code figures out the exact size of the stream
      demux->movi_start = 0;
      demux->movi_end = demux->stream->end_pos;
      tivo->size = demux->stream->end_pos;
   }
   else
   {
      // If its a local file, try to find the Part Headers, so we can
      // calculate the ACTUAL stream size
      // If we can't find it, go off with the file size and hope the
      // extract program did the "right thing"
      if ( tivo->readHeader == 0 )
      {
         loff_t filePos;
         tivo->readHeader = 1;

         filePos = demux->filepos;
         stream_seek( demux->stream, 0 );

         readSize = stream_read( demux->stream, chunk, CHUNKSIZE );

         if ( memcmp( chunk, TMF_SIG, sizeof( TMF_SIG ) ) == 0 )
         {
            mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Detected a tmf\n" );
            tivo->tmf = 1;
            ty_tmf_filetoparts( demux, tivo );
            readSize = tmf_load_chunk( demux, tivo, chunk, 0 );
         }

         if ( readSize == CHUNKSIZE && AV_RB32(chunk) == TIVO_PES_FILEID )
         {
               loff_t numberParts;

               readSize = 0;

               if ( tivo->tmf != 1 )
               {
                  loff_t offset;

                  numberParts = demux->stream->end_pos / TIVO_PART_LENGTH;
                  offset = numberParts * TIVO_PART_LENGTH;

                  mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:ty/ty+Number Parts %"PRId64"\n",
                    (int64_t)numberParts );

                  if ( offset + CHUNKSIZE < demux->stream->end_pos )
                  {
                     stream_seek( demux->stream, offset );
                     readSize = stream_read( demux->stream, chunk, CHUNKSIZE );
                  }
               }
               else
               {
                  numberParts = tivo->tmf_totalparts;
                  offset = numberParts * TIVO_PART_LENGTH;
                  readSize = tmf_load_chunk( demux, tivo, chunk,
                     numberParts * ( TIVO_PART_LENGTH - CHUNKSIZE ) /
                     CHUNKSIZE );
               }

               if ( readSize == CHUNKSIZE && AV_RB32(chunk) == TIVO_PES_FILEID )
               {
                     int size = AV_RB24(chunk + 12);
                     size -= 4;
                     size *= CHUNKSIZE;
                     tivo->size = numberParts * TIVO_PART_LENGTH;
                     tivo->size += size;
                     mp_msg( MSGT_DEMUX, MSGL_DBG3,
                        "ty:Header Calc Stream Size %"PRId64"\n", tivo->size );
               }
         }

         if ( demux->stream->start_pos > 0 )
            filePos = demux->stream->start_pos;
         stream_seek( demux->stream, filePos );
         demux->filepos = stream_tell( demux->stream );
         tivo->whichChunk = filePos / CHUNKSIZE;
      }
      demux->movi_start = 0;
      demux->movi_end = tivo->size;
   }

   // ======================================================================
   // Give a clue as to where we are in the stream
   // ======================================================================
   mp_msg( MSGT_DEMUX, MSGL_DBG3,
      "ty:ty header size %"PRIx64"\n", (int64_t)tivo->size );
   mp_msg( MSGT_DEMUX, MSGL_DBG3,
      "ty:ty which Chunk %d\n", tivo->whichChunk );
   mp_msg( MSGT_DEMUX, MSGL_DBG3,
      "ty:file end_pos   %"PRIx64"\n", (int64_t)demux->stream->end_pos );
   mp_msg( MSGT_DEMUX, MSGL_DBG3,
      "\nty:wanted current offset %"PRIx64"\n", (int64_t)stream_tell( demux->stream ) );

   if ( tivo->size > 0 && stream_tell( demux->stream ) > tivo->size )
   {
         demux->stream->eof = 1;
         return 0;
   }

   do {
   if ( tivo->tmf != 1 )
   {
      // Make sure we are on a 128k boundary
      if ( demux->filepos % CHUNKSIZE != 0 )
      {
         int whichChunk = demux->filepos / CHUNKSIZE;
         if ( demux->filepos % CHUNKSIZE > CHUNKSIZE / 2 )
            whichChunk++;
         stream_seek( demux->stream, whichChunk * CHUNKSIZE );
      }

      demux->filepos = stream_tell( demux->stream );
      tivo->whichChunk = demux->filepos / CHUNKSIZE;
      readSize = stream_read( demux->stream, chunk, CHUNKSIZE );
      if ( readSize != CHUNKSIZE )
         return 0;
   }
   else
   {
      readSize = tmf_load_chunk( demux, tivo, chunk, tivo->whichChunk );
      if ( readSize != CHUNKSIZE )
         return 0;
      tivo->whichChunk++;
   }
   if (AV_RB32(chunk) == TIVO_PES_FILEID)
      mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Skipping PART Header\n" );
   } while (AV_RB32(chunk) == TIVO_PES_FILEID);

   mp_msg( MSGT_DEMUX, MSGL_DBG3,
      "\nty:actual current offset %"PRIx64"\n", stream_tell( demux->stream ) -
      CHUNKSIZE );


   // Let's make a Video Demux Stream for MPlayer
   aid = 0x0;
   if( !demux->v_streams[ aid ] ) new_sh_video( demux, aid );
   if( demux->video->id == -1 ) demux->video->id = aid;
   if( demux->video->id == aid )
   {
      demux_stream_t *ds = demux->video;
      if( !ds->sh ) ds->sh = demux->v_streams[ aid ];
   }

   // ======================================================================
   // Finally, we get to actually parse the chunk
   // ======================================================================
   mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:ty parsing a chunk\n" );
   numberRecs = chunk[ 0 ];
   recPtr = &chunk[ 4 ];
   offset = numberRecs * 16 + 4;
   for ( counter = 0 ; counter < numberRecs ; counter++ )
   {
      int size = AV_RB24(recPtr) >> 4;
      int type = recPtr[ 3 ];
      int nybbleType = recPtr[ 2 ] & 0x0f;
      recordsDecoded++;

      mp_msg( MSGT_DEMUX, MSGL_DBG3,
         "ty:Record Type %x/%x %d\n", nybbleType, type, size );

      // ================================================================
      // Video Parsing
      // ================================================================
      if ( type == 0xe0 )
      {
         if ( size > 0 && size + offset <= CHUNKSIZE )
         {
            int esOffset1 = demux_ty_FindESHeader( VIDEO_NAL, &chunk[ offset ],
               size);
            if ( esOffset1 != -1 )
               tivo->lastVideoPTS = get_ty_pts(
                  &chunk[ offset + esOffset1 + 9 ] );

            // Do NOT Pass the PES Header onto the MPEG2 Decode
            if( nybbleType != 0x06 )
               demux_ty_CopyToDemuxPacket( demux->video,
                  &chunk[ offset ], size, demux->filepos + offset,
                  tivo->lastVideoPTS );
            offset += size;
         }
         else
            errorHeader++;
      }
      // ================================================================
      // Audio Parsing
      // ================================================================
      else if ( type == 0xc0 )
      {
         if ( size > 0 && size + offset <= CHUNKSIZE )
         {
            if( demux->audio->id == -1 )
            {
               if ( nybbleType == 0x02 )
                  continue;    // DTiVo inconclusive, wait for more
               else if ( nybbleType == 0x09 )
               {
                  mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Setting AC-3 Audio\n" );
                  aid = 0x80;  // AC-3
               }
               else
               {
                  mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:Setting MPEG Audio\n" );
                  aid = 0x0;   // MPEG Audio
               }

               demux->audio->id = aid;
               if( !demux->a_streams[ aid ] ) new_sh_audio( demux, aid, NULL );
               if( demux->audio->id == aid )
               {
                  demux_stream_t *ds = demux->audio;
                  if( !ds->sh ) {
                    sh_audio_t* sh_a;
                    ds->sh = demux->a_streams[ aid ];
                    sh_a = (sh_audio_t*)ds->sh;
                    switch(aid & 0xE0){  // 1110 0000 b  (high 3 bit: type  low 5: id)
                      case 0x00: sh_a->format=0x50;break; // mpeg
                      case 0xA0: sh_a->format=0x10001;break;  // dvd pcm
                      case 0x80: if((aid & 0xF8) == 0x88) sh_a->format=0x2001;//dts
                                  else sh_a->format=0x2000;break; // ac3
                    }
                 }
               }
            }

            aid = demux->audio->id;


            // SA DTiVo Audio Data, no PES
            // ================================================
            if ( nybbleType == 0x02 || nybbleType == 0x04 )
            {
               if ( nybbleType == 0x02 && tivo->tivoType == 2 )
                  demux_ty_AddToAudioBuffer( tivo, &chunk[ offset ], size );
               else
               {

                  mp_msg( MSGT_DEMUX, MSGL_DBG3,
                     "ty:Adding Audio Packet Size %d\n", size );
                  demux_ty_CopyToDemuxPacket( demux->audio,
                     &chunk[ offset ], size, ( demux->filepos + offset ),
                     tivo->lastAudioPTS );
               }
            }

            // 3 - MPEG Audio with PES Header, either SA or DTiVo
            // 9 - DTiVo AC3 Audio Data with PES Header
            // ================================================
            if ( nybbleType == 0x03 || nybbleType == 0x09 )
            {
               int esOffset1, esOffset2;
               if ( nybbleType == 0x03 )
               esOffset1 = demux_ty_FindESHeader( AUDIO_NAL, &chunk[ offset ],
                  size);

               // SA PES Header, No Audio Data
               // ================================================
               if ( nybbleType == 0x03 && esOffset1 == 0 && size == 16 )
               {
                  tivo->tivoType = 1;
                  tivo->lastAudioPTS = get_ty_pts( &chunk[ offset +
                     SERIES2_PTS_OFFSET ] );
               }
               else
               // DTiVo Audio with PES Header
               // ================================================
               {
                  tivo->tivoType = 2;

                  demux_ty_AddToAudioBuffer( tivo, &chunk[ offset ], size );
                  demux_ty_FindESPacket( nybbleType == 9 ? AC3_NAL : AUDIO_NAL,
                     tivo->lastAudio, tivo->lastAudioEnd, &esOffset1,
                     &esOffset2 );

                  if ( esOffset1 != -1 && esOffset2 != -1 )
                  {
                     int packetSize = esOffset2 - esOffset1;
                     int headerSize;
                     int ptsOffset;

                     if ( IsValidAudioPacket( packetSize, &ptsOffset,
                           &headerSize ) )
                     {
                        mp_msg( MSGT_DEMUX, MSGL_DBG3,
                           "ty:Adding DTiVo Audio Packet Size %d\n",
                           packetSize );

                        tivo->lastAudioPTS = get_ty_pts(
                           &tivo->lastAudio[ esOffset1 + ptsOffset ] );

                        if (nybbleType == 9) headerSize = 0;
                        demux_ty_CopyToDemuxPacket
                        (
                           demux->audio,
                           &tivo->lastAudio[ esOffset1 + headerSize ],
                           packetSize - headerSize,
                           demux->filepos + offset,
                           tivo->lastAudioPTS
                        );

                     }

                     // Collapse the Audio Buffer
                     tivo->lastAudioEnd -= esOffset2;
                     memmove( &tivo->lastAudio[ 0 ],
                        &tivo->lastAudio[ esOffset2 ],
                        tivo->lastAudioEnd );
                  }
               }
            }

            offset += size;
         }
         else
            errorHeader++;
      }
      // ================================================================
      // 1 = Closed Caption
      // 2 = Extended Data Services
      // ================================================================
      else if ( type == 0x01 || type == 0x02 )
      {
                        unsigned char lastXDS[ 16 ];
         int b = AV_RB24(recPtr) >> 4;
         b &= 0x7f7f;

         mp_msg( MSGT_DEMUX, MSGL_DBG3, "ty:%s %04x\n", type == 1 ? "CC" : "XDS", b);

         lastXDS[ 0x00 ] = 0x00;
         lastXDS[ 0x01 ] = 0x00;
         lastXDS[ 0x02 ] = 0x01;
         lastXDS[ 0x03 ] = 0xb2;
         lastXDS[ 0x04 ] = 'T';
         lastXDS[ 0x05 ] = 'Y';
         lastXDS[ 0x06 ] = type;
         lastXDS[ 0x07 ] = b >> 8;
         lastXDS[ 0x08 ] = b;
         if ( subcc_enabled )
            demux_ty_CopyToDemuxPacket( demux->video, lastXDS, 0x09,
               demux->filepos + offset, tivo->lastVideoPTS );
      }
      // ================================================================
      // Unknown
      // ================================================================
      else
      {
         if ( size > 0 && size + offset <= CHUNKSIZE )