コード例 #1
0
ファイル: record.c プロジェクト: AsamQi/vlc
static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
{
    sout_stream_sys_t *p_sys = p_stream->p_sys;

    if( !p_sys->p_out )
        OutputStart( p_stream );

    if( id->p_first )
        block_ChainRelease( id->p_first );

    assert( !id->id || p_sys->p_out );
    if( id->id )
        sout_StreamIdDel( p_sys->p_out, id->id );

    es_format_Clean( &id->fmt );

    TAB_REMOVE( p_sys->i_id, p_sys->id, id );

    if( p_sys->i_id <= 0 )
    {
        if( !p_sys->p_out )
            p_sys->b_drop = false;
    }

    free( id );

    return VLC_SUCCESS;
}
コード例 #2
0
ファイル: record.c プロジェクト: AsamQi/vlc
static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
                 block_t *p_buffer )
{
    sout_stream_sys_t *p_sys = p_stream->p_sys;

    if( p_sys->i_date_start < 0 )
        p_sys->i_date_start = mdate();
    if( !p_sys->p_out &&
        ( mdate() - p_sys->i_date_start > p_sys->i_max_wait ||
          p_sys->i_size > p_sys->i_max_size ) )
    {
        msg_Dbg( p_stream, "Starting recording, waited %ds and %dbyte",
                 (int)((mdate() - p_sys->i_date_start)/1000000), (int)p_sys->i_size );
        OutputStart( p_stream );
    }

    OutputSend( p_stream, id, p_buffer );

    return VLC_SUCCESS;
}
コード例 #3
0
ファイル: server-play-nms.c プロジェクト: gerboland/osd-nms
static void * avLoop( void * arg )
{
	int loc_frames = 0;
	int loc_bytes;
	int loc_quit = 1;
	
	NMS_SRV_STATUS_t loc_preState = NMS_STATUS_PLAYER_STOPPED;
	int loc_cur_t = 0;
	int loc_next_t = 0;
	int loc_prev_t = 0;
	int loc_first_time = 0;
	int loc_preload;
	int loc_ffrw_scan_step = 0;
	media_buf_t loc_buf;
	long loc_info_duration;

	LOCK_PLAYMUTEX();
	if(editmode)
	{
		playState = NMS_STATUS_PLAYER_VF;
		loc_preload = 1;
		frameByFrame = 1;
	}
	else
	{
		playState =NMS_STATUS_PLAYER_PLAY; 
		loc_preload = PRELOAD_FRAMES;
		frameByFrame = 0;
	}
	UNLOCK_PLAYMUTEX();
	
	do
	{
		DBGMSG("In avloop now.");	
		/* preload */
		while (loc_frames < loc_preload)
		{
			if (1 == OutputGetBuffer(&loc_buf, 0, 1))
			{
				WPRINT("GetBuffer failed.");
				break;
			}
			
			loc_bytes = InputGetData(&loc_buf);
			if (loc_bytes == 0) continue;
			if (loc_bytes <0 )
			{
				// hit EOF, set flag to flush.
				loc_quit = 0;
				
				LOCK_PLAYMUTEX();
				playing = 0;
				UNLOCK_PLAYMUTEX();
				break; 
			}
			//DBGMSG("input data returned. ");
			LOCK_PLAYMUTEX();
			playtime = OutputGetPlaytime();
			UNLOCK_PLAYMUTEX();

#ifdef LOG_TIME_STAMP__
			if (loc_buf.curbuf == &loc_buf.abuf)
				DBGLOG("   aT = %d\n", loc_buf.curbuf->tsms);
			else
				DBGLOG("---vT = %d\n", loc_buf.curbuf->tsms);
#endif
			
			OutputWrite(&loc_buf);
			if (loc_buf.curbuf == &loc_buf.abuf) loc_frames++;
		}
		DBGMSG("preload finished.");
		OutputStart();
		/* start output */
		DBGMSG("output started.");
	} while(0);
	
	LOCK_PLAYMUTEX();
	preloaded = 1;
	everPlayed = 1;
	UNLOCK_PLAYMUTEX();
	
 main_play_loop:
	// preloaded...
	while (1)
	{	
		int loc_playState;
		int loc_iSeekFlag;
		int loc_iBookMark;
		int loc_sfrwLevelFinal;

		LOCK_PLAYMUTEX();
		if (!playing)
		{
			UNLOCK_PLAYMUTEX();
			break;
		}
		loc_playState = playState;
		UNLOCK_PLAYMUTEX();
		
		switch (loc_playState)
		{
		case NMS_STATUS_PLAYER_PAUSE:
			if (loc_preState != NMS_STATUS_PLAYER_PAUSE)
			{
				OutputPause(1);
				LOCK_PLAYMUTEX();
				playedOrPaused = NMS_STATUS_PLAYER_PAUSE;
				UNLOCK_PLAYMUTEX();
				loc_preState = NMS_STATUS_PLAYER_PAUSE;
			}
			continue;

		case NMS_STATUS_PLAYER_PLAY:
			{
				LOCK_PLAYMUTEX();
				loc_iSeekFlag = iSeekFlag;
				loc_iBookMark = iBookMark;
				UNLOCK_PLAYMUTEX();

				if (loc_preState != NMS_STATUS_PLAYER_PLAY || loc_iSeekFlag)
				{
					LOCK_PLAYMUTEX();
					playedOrPaused = NMS_STATUS_PLAYER_PLAY;		
					loc_info_duration = info.duration;			
					UNLOCK_PLAYMUTEX();

					if (loc_preState == NMS_STATUS_PLAYER_PAUSE)
					{
						OutputPause(0);	

						LOCK_PLAYMUTEX();
						muted = 0;
						UNLOCK_PLAYMUTEX();
					}
					else if (loc_iSeekFlag)
					{
						if (loc_info_duration - loc_iBookMark > 100)
						{
							loc_next_t = InputSeek(loc_iBookMark);						
							OutputFlush(loc_next_t);
						}
						LOCK_PLAYMUTEX();
						iSeekFlag = 0;
						UNLOCK_PLAYMUTEX();
					}
					else
					{
						LOCK_PLAYMUTEX();
						if (muted)
						{
							muted = 0;
							OutputMute(muted);
						}
						loc_sfrwLevelFinal = sfrwLevelFinal;
						UNLOCK_PLAYMUTEX();

						if (loc_preState == NMS_STATUS_PLAYER_SF)
						{
							int loc_cur_tmp;

							LOCK_PLAYMUTEX();
							loc_cur_tmp = playtime;
							UNLOCK_PLAYMUTEX();

							loc_next_t = loc_first_time + (loc_cur_tmp - loc_first_time) / loc_sfrwLevelFinal;
							loc_next_t = InputSeek(loc_next_t);
							OutputFlush(loc_next_t);	
						}
					}
					loc_preState = NMS_STATUS_PLAYER_PLAY;					
					loc_prev_t = 0;
				}				
			}
			break;
		case NMS_STATUS_PLAYER_FF:
		case NMS_STATUS_PLAYER_RW:
			if (loc_preState != loc_playState)
			{
				LOCK_PLAYMUTEX();
				loc_cur_t = playtime;
				UNLOCK_PLAYMUTEX();

				OutputFlush(loc_cur_t);
				if (loc_preState == NMS_STATUS_PLAYER_PAUSE)
					OutputPause(0);
				
				LOCK_PLAYMUTEX();
				if (!muted)
				{
					muted = 1;
					OutputMute(muted);
				}
				loc_cur_t = playtime;
				loc_first_time = loc_cur_t;
				loc_next_t = loc_cur_t;
				loc_prev_t = loc_cur_t;
				loc_preState = playState;
				UNLOCK_PLAYMUTEX();
			}

			LOCK_PLAYMUTEX();
			if (ffrwLevel == 0)
			{
				UNLOCK_PLAYMUTEX();
				continue;
			}
			else if (ffrwLevel > 2)
				loc_ffrw_scan_step = SCAN_STEP2_MS;
			else 
				loc_ffrw_scan_step = SCAN_STEP1_MS;

 
		get_new_timestamp:
			if (loc_preState == NMS_STATUS_PLAYER_FF)
			{
				loc_info_duration = info.duration;
				if (loc_info_duration != 0 && (playtime + ffrwLevel * loc_ffrw_scan_step) >= loc_info_duration)
				{
					loc_next_t = loc_info_duration;
					loc_next_t = InputSeek(loc_next_t);
					OutputFlush(loc_next_t);
					
					if(editmode)
					{
						playState = NMS_STATUS_PLAYER_PLAY;
						UNLOCK_PLAYMUTEX();
						break;	
					}
					else
					{
						loc_quit = 0;
						UNLOCK_PLAYMUTEX();
						goto bail;
					}					
				}
				else
				{
					playtime += ffrwLevel * loc_ffrw_scan_step;
					loc_next_t = playtime;
					if (rptState == NMS_PLAYBACK_REPEAT_ON)
					{
						if (loc_next_t >= rptB)
						{
							loc_next_t = rptB;
							loc_next_t = InputSeek(loc_next_t);
							OutputFlush(loc_next_t);
							UNLOCK_PLAYMUTEX();
							continue;
						}
					}
				}
			}
			else
			{
				if (playtime +ffrwLevel * loc_ffrw_scan_step <= 0)
				{
					loc_next_t = 0;
					loc_next_t = InputSeek(loc_next_t);
					OutputFlush(loc_next_t);
					if(editmode)
					{
						playState = NMS_STATUS_PLAYER_VF;
						frameByFrame = 1;
						loc_preState = NMS_STATUS_PLAYER_PLAY;
						UNLOCK_PLAYMUTEX();
						break;
					}
					else
						playState = NMS_STATUS_PLAYER_PLAY;

					ffrwLevel = 0;
					UNLOCK_PLAYMUTEX();
					continue;
				}
				else
				{
					playtime += ffrwLevel * loc_ffrw_scan_step;
					loc_next_t = playtime;
					if (rptState == NMS_PLAYBACK_REPEAT_ON)
					{
						if (loc_next_t <= rptA)
						{
							loc_next_t = rptA;
							loc_next_t = InputSeek(loc_next_t);
							OutputFlush(loc_next_t);
							UNLOCK_PLAYMUTEX();
							continue;
						}
					}
				}
			}

			loc_next_t = InputSeek(loc_next_t);
			OutputFlush(loc_next_t);
			if ((loc_preState == NMS_STATUS_PLAYER_FF && loc_prev_t >= loc_next_t) ||
				(loc_preState == NMS_STATUS_PLAYER_RW && loc_prev_t <= loc_next_t))
			{
				goto get_new_timestamp;
			}
			loc_prev_t = loc_cur_t;
			loc_cur_t = loc_next_t;			
			UNLOCK_PLAYMUTEX();
			break;

		case NMS_STATUS_PLAYER_VF:
			LOCK_PLAYMUTEX();
			DBGLOG("!!!!!!!!!!!!!!!play VF,mute=%d\n",muted);
			if (frameByFrame == 1)
			{
				OutputPause(0);
				loc_cur_t = playtime;
				OutputFlush(loc_cur_t);
				if (!muted)
				{
					muted = 1;
		            OutputMute(muted);
				}
			}
			playState = NMS_STATUS_PLAYER_PAUSE;
			loc_cur_t = playtime;
			UNLOCK_PLAYMUTEX();

			loc_next_t = loc_cur_t;
			loc_prev_t = loc_cur_t;
			loc_first_time = loc_cur_t;
			
			break;

		case NMS_STATUS_PLAYER_SF:
			if (loc_preState != NMS_STATUS_PLAYER_SF)
			{
				LOCK_PLAYMUTEX();
				loc_cur_t = playtime;
				OutputFlush(loc_cur_t);
				if (loc_preState == NMS_STATUS_PLAYER_PAUSE)
					OutputPause(0);
				if (!muted)
				{
					muted = 1;
					OutputMute(muted);
				}
				loc_cur_t = playtime;
				UNLOCK_PLAYMUTEX();

				loc_next_t = loc_cur_t;
				loc_prev_t = loc_cur_t;
				loc_preState = NMS_STATUS_PLAYER_SF;				
			}
			break;

		case NMS_STATUS_PLAYER_STOPPED:
			if (loc_preState == NMS_STATUS_PLAYER_PAUSE)
				OutputPause(0);
			loc_preState = NMS_STATUS_PLAYER_STOPPED;
			loc_quit = 1;
			goto bail;

		default:
			LOCK_PLAYMUTEX();
			playState = loc_preState;
			UNLOCK_PLAYMUTEX();
			break;
		}

		LOCK_PLAYMUTEX();
		if (rptState == NMS_PLAYBACK_REPEAT_ON)
		{
			loc_cur_t = playtime;
			if (loc_cur_t > rptB)
			{				
				loc_cur_t = InputSeek(rptA);
				OutputFlush(loc_cur_t);
			}
		}
		UNLOCK_PLAYMUTEX();
		
		if ( 1 == OutputGetBuffer(&loc_buf, 1000, 0))
		{
			//DBGMSG("buffer full or playback paused!");
			continue;
		}

		loc_bytes = InputGetData(&loc_buf);
		if (loc_bytes == 0)
		{
			WPRINT("zero bytes returned!");
			continue;
		}

		LOCK_PLAYMUTEX();
		if (loc_bytes < 0) 
		{
			if(editmode)
			{
				UNLOCK_PLAYMUTEX();
				continue;	
			}
			else
			{
				WPRINT("EOF reached!");
				// hit EOF, set flag to flush.
				loc_quit = 0;
				UNLOCK_PLAYMUTEX();
				break;
			}
		}
		UNLOCK_PLAYMUTEX();

#ifdef LOG_TIME_STAMP__
		if (loc_buf.curbuf == &loc_buf.abuf)
			DBGLOG("   aT = %d\n", loc_buf.curbuf->tsms);
		else
			DBGLOG("---vT = %d\n", loc_buf.curbuf->tsms);
#endif

		LOCK_PLAYMUTEX();
		playtime = OutputGetPlaytime();
		if (loc_buf.curbuf == &loc_buf.abuf)
		{
			if (loc_preState != NMS_STATUS_PLAYER_PLAY && rptState != NMS_PLAYBACK_REPEAT_ON)
			{
				UNLOCK_PLAYMUTEX();
				continue;
			}
		}
		UNLOCK_PLAYMUTEX();

		if (loc_preState != NMS_STATUS_PLAYER_PLAY && loc_preState != NMS_STATUS_PLAYER_PAUSE)
		{
			if (loc_first_time == 0)
			{
				loc_first_time = loc_cur_t;
			}
			if (loc_preState == NMS_STATUS_PLAYER_SF)
			{
				loc_buf.vbuf.tsms = loc_buf.vbuf.tsms - loc_first_time;
				LOCK_PLAYMUTEX();
				loc_buf.vbuf.tsms *= sfrwLevel;
				UNLOCK_PLAYMUTEX();
				loc_buf.vbuf.tsms += loc_first_time;
			}		
			loc_prev_t = loc_cur_t;
		}
		
		OutputWrite(&loc_buf);
	}
	
	DBGMSG("Exit main playback loop.\n");
	// if quit, re-fetch the lock here
	
 bail:
	LOCK_PLAYMUTEX();
	ffrwLevel = 0;
	sfrwLevel = 0;
	UNLOCK_PLAYMUTEX();
	
	if (loc_preState == NMS_STATUS_PLAYER_PAUSE)
	{
		OutputPause(0);
	}

	LOCK_PLAYMUTEX();
	if (muted)
	{
		muted = 0;
		OutputMute(muted);
	}
	UNLOCK_PLAYMUTEX();
	
	// We used to call InputFinish here, but let's wait a while, because we may be asked to seek again later,
	// while draining the output buffer. And we'll need input to be active if we want to have something to seek into.
	
	if (loc_quit)
	{
		LOCK_PLAYMUTEX();
		InputFinish();
		// If we're quitting the server, we really don't want to wait that video output is drained.
		// We flush it down the toilet without sending it to the TV.
		OutputFinish(0);
		UNLOCK_PLAYMUTEX();
	}
	else
	{
		unsigned long remain;
		
		// We're at the EOF of a playback. We may have some data left in the dm320
		// gargantuan output buffers, and we need to properly make sure it goes all to TV before we're done.
		//
		// We can't really call a blocking flush here (like OutputFinish(1)).
		// This is because the server will freeze otherwise and be unable to process 
		// commands (like STOP or PAUSE) that come in during the final draining of the output buffer.
		//
		// This is an improvement over the old way of just waiting some time before calling the 
		// blocking flush: it instead keeps checking the amount of data in the dm320 video output buffer 
		// and doesn't call the blocking flush until it's all drained. It sleeps a small amount of time 
		// between checks, then before the next check it processes commands.
		//
		// HACK:
		// It works better than before, however it's still a bit of an hack, since this
		// polling is really not elegant at all. It is much better to setup a callback and 
		// have imedia call us when there's no more data in the output buffer. 
		// Or something like that. --nero

		LOCK_PLAYMUTEX();
		playing = 1; //Restore the playback flag, since we're still actually playing.
		UNLOCK_PLAYMUTEX();

		remain = OutputGetBufferedSize();
		WPRINT("Entering buffer drain loop (remain %lu bytes).\n", remain);
		
		while (remain > 0)
		{
			
			LOCK_PLAYMUTEX();
			if (!playing) 
			{
				UNLOCK_PLAYMUTEX();
				break;
			}
			
			DBGMSG("Draining output buffer. Bytes remaining: %lu\n", remain);
			if (playState == NMS_STATUS_PLAYER_PAUSE) OutputPause(1);
			else 
			{
				OutputPause(0);
				
				// If we're asked to seek (ffw, rew or point-seek), let's just return in the main loop.
				// The logic in the loop will take care of everything else, we don't need to do anything more here.
				if (playState == NMS_STATUS_PLAYER_FF || playState == NMS_STATUS_PLAYER_RW ||
					(playState == NMS_STATUS_PLAYER_PLAY && iSeekFlag != 0)) 
				{
					DBGMSG("Going back to main playback loop.\n");
					UNLOCK_PLAYMUTEX();
					goto main_play_loop;
				}
			}
			UNLOCK_PLAYMUTEX();

			usleep(DRAIN_POLL_TICK);
			remain = OutputGetBufferedSize();
		}
		DBGMSG("Exited drain loop. Playing: %d - Remain: %lu\n", playing, remain);
		
		LOCK_PLAYMUTEX();
		InputFinish();
		OutputPause(0); //before finish output must make sure pause flag is cleared
		
		//Let's always call a final non-blocking flush. Thus if there are bugs in the above logic, 
		//we notice a clip at end of video (due to flushing to kingdom come the last part of data), 
		//and hopefully we come here to look ;) --nero
		OutputFinish(0);
		UNLOCK_PLAYMUTEX();
	}

	// clear playing and ffrw flag, and release lock before
	// joining ffrw thread.
	LOCK_PLAYMUTEX();
	playing = 0;
	
	rptState = NMS_PLAYBACK_REPEAT_OFF;	
	if (playtype == NPT_FILE)
		playState = NMS_STATUS_PLAYER_STOPPED;
	else
		playState = NMS_STATUS_PLAYER_NEXT;	
	
	DBGMSG("input output finished.");
	
	// check to play next file.
	if ((0 == loc_quit) && (playtype != NPT_FILE))
	{
		DBGMSG("searching for next file.");
		//if repeat is single and the file is not played, stop nextfile loop
		if (!((repeat == RM_REPEAT) && (errorStatus == NMS_STATUS_NOT_PLAYABLE)))
			trackChange = TC_NORMAL;
		
		UNLOCK_PLAYMUTEX();
		pthread_cond_broadcast(&nextFileCond);
	}
	else UNLOCK_PLAYMUTEX();

	pthread_exit(NULL);
}