Browse Source

chromecast: always start video with a keyframe

pull/68/head
Thomas Guillem 9 years ago
parent
commit
dfd1709335
  1. 39
      modules/stream_out/chromecast/cast.cpp

39
modules/stream_out/chromecast/cast.cpp

@ -87,9 +87,11 @@ struct sout_stream_sys_t
, p_intf(intf)
, b_supports_video(has_video)
, i_port(port)
, first_video_keyframe_pts( -1 )
, es_changed( true )
, cc_has_input( false )
, cc_reload( false )
, has_video( false )
, out_force_reload( false )
, transcoding_state( TRANSCODING_NONE )
, out_streams_added( 0 )
@ -128,10 +130,13 @@ struct sout_stream_sys_t
const bool b_supports_video;
const int i_port;
sout_stream_id_sys_t * video_proxy_id;
mtime_t first_video_keyframe_pts;
bool es_changed;
bool cc_has_input;
bool cc_reload;
bool has_video;
bool out_force_reload;
int transcoding_state;
std::vector<sout_stream_id_sys_t*> streams;
@ -266,7 +271,11 @@ static sout_stream_id_sys_t *ProxyAdd(sout_stream_t *p_stream, const es_format_t
sout_stream_sys_t *p_sys = p_stream->p_sys;
sout_stream_id_sys_t *id = sout_StreamIdAdd(p_stream->p_next, p_fmt);
if (id)
{
if (p_fmt->i_cat == VIDEO_ES)
p_sys->video_proxy_id = id;
p_sys->out_streams_added++;
}
return id;
}
@ -274,6 +283,8 @@ static void ProxyDel(sout_stream_t *p_stream, sout_stream_id_sys_t *id)
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
p_sys->out_streams_added--;
if (id == p_sys->video_proxy_id)
p_sys->video_proxy_id = NULL;
return sout_StreamIdDel(p_stream->p_next, id);
}
@ -283,6 +294,25 @@ static int ProxySend(sout_stream_t *p_stream, sout_stream_id_sys_t *id,
sout_stream_sys_t *p_sys = p_stream->p_sys;
if (p_sys->cc_has_input || p_sys->out_streams_added >= p_sys->out_streams.size())
{
if (p_sys->has_video)
{
// In case of video, the first block must be a keyframe
if (id == p_sys->video_proxy_id)
{
if (p_sys->first_video_keyframe_pts == -1
&& p_buffer->i_flags & BLOCK_FLAG_TYPE_I)
p_sys->first_video_keyframe_pts = p_buffer->i_pts;
}
else // no keyframe for audio
p_buffer->i_flags &= ~BLOCK_FLAG_TYPE_I;
if (p_buffer->i_pts < p_sys->first_video_keyframe_pts
|| p_sys->first_video_keyframe_pts == -1)
{
block_Release(p_buffer);
return VLC_SUCCESS;
}
}
int ret = sout_StreamIdSend(p_stream->p_next, id, p_buffer);
if (ret == VLC_SUCCESS && !p_sys->cc_has_input)
{
@ -622,6 +652,8 @@ static void DelInternal(sout_stream_t *p_stream, sout_stream_id_sys_t *id,
p_sys->out_streams.erase(out_it);
p_sys->es_changed = reset_config;
p_sys->out_force_reload = reset_config;
if( p_sys_id->fmt.i_cat == VIDEO_ES )
p_sys->has_video = false;
break;
}
out_it++;
@ -728,6 +760,9 @@ bool sout_stream_sys_t::startSoutChain(sout_stream_t *p_stream,
msg_Dbg( p_stream, "Creating chain %s", sout.c_str() );
cc_has_input = false;
cc_reload = false;
first_video_keyframe_pts = -1;
video_proxy_id = NULL;
has_video = false;
out_streams = new_streams;
transcoding_state = new_transcoding_state;
@ -754,7 +789,11 @@ bool sout_stream_sys_t::startSoutChain(sout_stream_t *p_stream,
it = out_streams.erase( it );
}
else
{
if( p_sys_id->fmt.i_cat == VIDEO_ES )
has_video = true;
++it;
}
}
if (out_streams.empty())

Loading…
Cancel
Save