Example #1
0
void ds_free_packs(demux_stream_t *ds)
{
    demux_packet_t *dp = ds->first;
    while (dp) {
        demux_packet_t *dn = dp->next;
        free_demux_packet(dp);
        dp = dn;
    }
    if (ds->asf_packet) {
        // free unfinished .asf fragments:
        free(ds->asf_packet->buffer);
        free(ds->asf_packet);
        ds->asf_packet = NULL;
    }
    ds->first = ds->last = NULL;
    ds->packs = 0; // !!!!!
    ds->bytes = 0;
    if (ds->current)
        free_demux_packet(ds->current);
    ds->current = NULL;
    ds->buffer = NULL;
    ds->buffer_pos = ds->buffer_size;
    ds->pts = MP_NOPTS_VALUE;
    ds->pts_bytes = 0;
}
Example #2
0
// return value:
//     0 = EOF or no stream found
//     1 = successfully read a packet
static int demux_mf_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds){
  mf_t         * mf = demuxer->priv;
  struct stat    fs;
  FILE         * f;

  if ( mf->curr_frame >= mf->nr_of_files ) return 0;

  stat( mf->names[mf->curr_frame],&fs );
//  printf( "[demux_mf] frame: %d (%s,%d)\n",mf->curr_frame,mf->names[mf->curr_frame],fs.st_size );

  if ( !( f=fopen( mf->names[mf->curr_frame],"rb" ) ) ) return 0;
  {
   sh_video_t     * sh_video = demuxer->video->sh;
   demux_packet_t * dp = new_demux_packet( fs.st_size );
   if ( !fread( dp->buffer,fs.st_size,1,f ) ) {
        fclose(f);
        free_demux_packet(dp);
        return 0;
   }
   dp->pts=mf->curr_frame / sh_video->fps;
   dp->pos=mf->curr_frame;
   dp->flags=1;
   // append packet to DS stream:
   ds_add_packet( demuxer->video,dp );
  }
  fclose( f );

  demuxer->filepos=mf->curr_frame++;
  return 1;
}
Example #3
0
ReadBufferQueue::~ReadBufferQueue() {
  free((void *)fTag);

  // Free any pending buffers (that never got delivered):
  demux_packet_t* dp = pendingDPHead;
  while (dp != NULL) {
    demux_packet_t* dpNext = dp->next;
    dp->next = NULL;
    free_demux_packet(dp);
    dp = dpNext;
  }
}
Example #4
0
void free_demux_packet(struct demux_packet *dp)
{
    if (dp->master == NULL) {  //dp is a master packet
        dp->refcount--;
        if (dp->refcount == 0) {
            if (dp->avpacket)
                talloc_free(dp->avpacket);
            else
                free(dp->buffer);
            free(dp);
        }
        return;
    }
    // dp is a clone:
    free_demux_packet(dp->master);
    free(dp);
}
Example #5
0
extern "C" int demux_rtp_fill_buffer(demuxer_t* demuxer, demux_stream_t* ds) {
  // Get a filled-in "demux_packet" from the RTP source, and deliver it.
  // Note that this is called as a synchronous read operation, so it needs
  // to block in the (hopefully infrequent) case where no packet is
  // immediately available.

  while (1) {
    float ptsBehind;
    demux_packet_t* dp = getBuffer(demuxer, ds, False, ptsBehind); // blocking
    if (dp == NULL) return 0;

    if (demuxer->stream->eof) return 0; // source stream has closed down

    // Before using this packet, check to make sure that its presentation
    // time is not far behind the other stream (if any).  If it is,
    // then we discard this packet, and get another instead.  (The rest of
    // MPlayer doesn't always do a good job of synchronizing when the
    // audio and video streams get this far apart.)
    // (We don't do this when streaming over TCP, because then the audio and
    // video streams are interleaved.)
    // (Also, if the stream is *excessively* far behind, then we allow
    // the packet, because in this case it probably means that there was
    // an error in the source's timestamp synchronization.)
    const float ptsBehindThreshold = 1.0; // seconds
    const float ptsBehindLimit = 60.0; // seconds
    if (ptsBehind < ptsBehindThreshold ||
	ptsBehind > ptsBehindLimit ||
	rtsp_transport_tcp) { // packet's OK
      ds_add_packet(ds, dp);
      break;
    }

#ifdef DEBUG_PRINT_DISCARDED_PACKETS
    RTPState* rtpState = (RTPState*)(demuxer->priv);
    ReadBufferQueue* bufferQueue = ds == demuxer->video ? rtpState->videoBufferQueue : rtpState->audioBufferQueue;
    fprintf(stderr, "Discarding %s packet (%fs behind)\n", bufferQueue->tag(), ptsBehind);
#endif
    free_demux_packet(dp); // give back this packet, and get another one
  }

  return 1;
}
Example #6
0
static demux_packet_t* getBuffer(demuxer_t* demuxer, demux_stream_t* ds,
				 Boolean mustGetNewData,
				 float& ptsBehind) {
  // Begin by finding the buffer queue that we want to read from:
  // (Get this from the RTP state, which we stored in
  //  the demuxer's 'priv' field)
  RTPState* rtpState = (RTPState*)(demuxer->priv);
  ReadBufferQueue* bufferQueue = NULL;
  int headersize = 0;
  TaskToken task;

  if (demuxer->stream->eof) return NULL;

  if (ds == demuxer->video) {
    bufferQueue = rtpState->videoBufferQueue;
    if (((sh_video_t*)ds->sh)->format == mmioFOURCC('H','2','6','4'))
      headersize = 3;
  } else if (ds == demuxer->audio) {
    bufferQueue = rtpState->audioBufferQueue;
    if (bufferQueue->readSource()->isAMRAudioSource())
      headersize = 1;
  } else {
    fprintf(stderr, "(demux_rtp)getBuffer: internal error: unknown stream\n");
    return NULL;
  }

  if (bufferQueue == NULL || bufferQueue->readSource() == NULL) {
    fprintf(stderr, "(demux_rtp)getBuffer failed: no appropriate RTP subsession has been set up\n");
    return NULL;
  }

  demux_packet_t* dp = NULL;
  if (!mustGetNewData) {
    // Check whether we have a previously-saved buffer that we can use:
    dp = bufferQueue->getPendingBuffer();
    if (dp != NULL) {
      ptsBehind = 0.0; // so that we always accept this data
      return dp;
    }
  }

  // Allocate a new packet buffer, and arrange to read into it:
    if (!bufferQueue->nextpacket) {
  dp = new_demux_packet(MAX_RTP_FRAME_SIZE);
  bufferQueue->dp = dp;
  if (dp == NULL) return NULL;
    }

#ifdef CONFIG_LIBAVCODEC
  extern AVCodecParserContext * h264parserctx;
  int consumed, poutbuf_size = 1;
  const uint8_t *poutbuf = NULL;
  float lastpts = 0.0;

  do {
    if (!bufferQueue->nextpacket) {
#endif
  // Schedule the read operation:
  bufferQueue->blockingFlag = 0;
  bufferQueue->readSource()->getNextFrame(&dp->buffer[headersize], MAX_RTP_FRAME_SIZE - headersize,
					  afterReading, bufferQueue,
					  onSourceClosure, bufferQueue);
  // Block ourselves until data becomes available:
  TaskScheduler& scheduler
    = bufferQueue->readSource()->envir().taskScheduler();
  int delay = 10000000;
  if (bufferQueue->prevPacketPTS * 1.05 > rtpState->mediaSession->playEndTime())
    delay /= 10;
  task = scheduler.scheduleDelayedTask(delay, onSourceClosure, bufferQueue);
  scheduler.doEventLoop(&bufferQueue->blockingFlag);
  scheduler.unscheduleDelayedTask(task);
  if (demuxer->stream->eof) {
    free_demux_packet(dp);
    return NULL;
  }

  if (headersize == 1) // amr
    dp->buffer[0] =
        ((AMRAudioSource*)bufferQueue->readSource())->lastFrameHeader();
#ifdef CONFIG_LIBAVCODEC
    } else {
      bufferQueue->dp = dp = bufferQueue->nextpacket;
      bufferQueue->nextpacket = NULL;
    }
    if (headersize == 3 && h264parserctx) { // h264
      consumed = h264parserctx->parser->parser_parse(h264parserctx,
                               avcctx,
                               &poutbuf, &poutbuf_size,
                               dp->buffer, dp->len);

      if (!consumed && !poutbuf_size)
        return NULL;

      if (!poutbuf_size) {
        lastpts=dp->pts;
        free_demux_packet(dp);
        bufferQueue->dp = dp = new_demux_packet(MAX_RTP_FRAME_SIZE);
      } else {
        bufferQueue->nextpacket = dp;
        bufferQueue->dp = dp = new_demux_packet(poutbuf_size);
        memcpy(dp->buffer, poutbuf, poutbuf_size);
        dp->pts=lastpts;
      }
    }
  } while (!poutbuf_size);
#endif

  // Set the "ptsBehind" result parameter:
  if (bufferQueue->prevPacketPTS != 0.0
      && bufferQueue->prevPacketWasSynchronized
      && *(bufferQueue->otherQueue) != NULL
      && (*(bufferQueue->otherQueue))->prevPacketPTS != 0.0
      && (*(bufferQueue->otherQueue))->prevPacketWasSynchronized) {
    ptsBehind = (*(bufferQueue->otherQueue))->prevPacketPTS
		 - bufferQueue->prevPacketPTS;
  } else {
    ptsBehind = 0.0;
  }

  if (mustGetNewData) {
    // Save this buffer for future reads:
    bufferQueue->savePendingBuffer(dp);
  }

  return dp;
}
Example #7
0
void ASFGenerateParcel(Context_t *context, const demuxer_t *demuxer)
{

	demux_stream_t *video = demuxer->video;
	demux_stream_t *audio = demuxer->audio;

	unsigned long long int Pts = 0;

	//printf("P\n");
	if (audio->first != NULL)
	{
		//printf("A\n");
		demux_packet_t *current = audio->first;
		//printf("PTS: %f\n", current->pts);
		Pts = (current->pts * 90000);

		while (current != NULL)
		{
			context->output->audio->Write(context, current->buffer, current->len, Pts, STREAMHEADERBUFFER, STREAMHEADERBUFFERSIZE, 0, "audio");

			demux_packet_t *dn = current->next;
			free_demux_packet(current);
			current = dn;
			//current = current->next;

			Pts = INVALID_PTS_VALUE;
		}

		audio->first = audio->last = NULL;
		audio->packs = 0; // !!!!!
		audio->bytes = 0;
		if (audio->current)
			free_demux_packet(audio->current);
		audio->current = NULL;
		audio->buffer = NULL;
		audio->buffer_pos = audio->buffer_size;
		audio->pts = 0;
		audio->pts_bytes = 0;

	}

	if (video->first != NULL)
	{
		//printf("V\n");
		demux_packet_t *current = video->first;

		//if (!(current->flags&0x10)) {  //current frame isn't a keyframe
		//printf("\tNORMALFRAME,                 ");
		//	Pts = INVALID_PTS_VALUE;
		//} else {
		//	//printf("\tKEYFRAME,                    ");
		//	Pts = (current->pts * 90000);
		//}


		while (current != NULL)
		{
			Pts = (current->pts * 90000);
			//printf("PTS: %f (%u)\n", current->pts, Pts);

			sh_video = demuxer->video->sh;
			sh_video->ds = demuxer->video;

			bwmv_t *priv = (bwmv_t *)malloc(sizeof(bwmv_t));
			memcpy(priv->privateData, ASF_PRIVATE_DATA, 4);
			priv->width = sh_video->bih->biWidth;
			priv->height = sh_video->bih->biHeight;
			priv->framerate = 333667;

			context->output->video->Write(context, current->buffer, current->len, Pts, (unsigned char *) priv, sizeof(bwmv_t), 0, "video");

			free(priv);

			demux_packet_t *dn = current->next;
			free_demux_packet(current);
			current = dn;
			//current = current->next;
			//Pts = INVALID_PTS_VALUE;
		}

		video->first = video->last = NULL;
		video->packs = 0; // !!!!!
		video->bytes = 0;
		if (video->current)
			free_demux_packet(video->current);
		video->current = NULL;
		video->buffer = NULL;
		video->buffer_pos = video->buffer_size;
		video->pts = 0;
		video->pts_bytes = 0;

	}
}
Example #8
0
// return value:
//     0 = EOF
//     1 = successful
int ds_fill_buffer(demux_stream_t *ds)
{
    demuxer_t *demux = ds->demuxer;
    if (ds->current)
        free_demux_packet(ds->current);
    ds->current = NULL;
    mp_dbg(MSGT_DEMUXER, MSGL_DBG3, "ds_fill_buffer (%s) called\n",
           ds == demux->audio ? "d_audio" : ds == demux->video ? "d_video" :
           ds == demux->sub   ? "d_sub"   : "unknown");
    while (1) {
        if (ds->packs) {
            demux_packet_t *p = ds->first;
            // copy useful data:
            ds->buffer = p->buffer;
            ds->buffer_pos = 0;
            ds->buffer_size = p->len;
            ds->pos = p->pos;
            ds->dpos += p->len; // !!!
            ++ds->pack_no;
            if (p->pts != MP_NOPTS_VALUE) {
                ds->pts = p->pts;
                ds->pts_bytes = 0;
            }
            ds->pts_bytes += p->len;    // !!!
            if (p->stream_pts != MP_NOPTS_VALUE)
                demux->stream_pts = p->stream_pts;
            ds->keyframe = p->keyframe;
            // unlink packet:
            ds->bytes -= p->len;
            ds->current = p;
            ds->first = p->next;
            if (!ds->first)
                ds->last = NULL;
            --ds->packs;
            /* The code below can set ds->eof to 1 when another stream runs
             * out of buffer space. That makes sense because in that situation
             * the calling code should not count on being able to demux more
             * packets from this stream.
             * If however the situation improves and we're called again
             * despite the eof flag then it's better to clear it to avoid
             * weird behavior. */
            ds->eof = 0;
            return 1;
        }

#define MaybeNI _("Maybe you are playing a non-interleaved stream/file or the codec failed?\n" \
                "For AVI files, try to force non-interleaved mode with the -ni option.\n")

        if (demux->audio->packs >= MAX_PACKS
            || demux->audio->bytes >= MAX_PACK_BYTES) {
            mp_tmsg(MSGT_DEMUXER, MSGL_ERR, "\nToo many audio packets in the buffer: (%d in %d bytes).\n",
                   demux->audio->packs, demux->audio->bytes);
            mp_tmsg(MSGT_DEMUXER, MSGL_HINT, MaybeNI);
            break;
        }
        if (demux->video->packs >= MAX_PACKS
            || demux->video->bytes >= MAX_PACK_BYTES) {
            mp_tmsg(MSGT_DEMUXER, MSGL_ERR, "\nToo many video packets in the buffer: (%d in %d bytes).\n",
                   demux->video->packs, demux->video->bytes);
            mp_tmsg(MSGT_DEMUXER, MSGL_HINT, MaybeNI);
            break;
        }
        if (!demux_fill_buffer(demux, ds)) {
            mp_dbg(MSGT_DEMUXER, MSGL_DBG2,
                   "ds_fill_buffer()->demux_fill_buffer() failed\n");
            break; // EOF
        }
    }
    ds->buffer_pos = ds->buffer_size = 0;
    ds->buffer = NULL;
    mp_msg(MSGT_DEMUXER, MSGL_V,
           "ds_fill_buffer: EOF reached (stream: %s)  \n",
           ds == demux->audio ? "audio" : "video");
    ds->eof = 1;
    return 0;
}