Hi guys-
enabling sound in a playing video when the video is not at the beginning
seems to result in the audio opening at a later pts in the video than where
the video itself is currently at, with the code I'm using (based heavily on
ffplay and others). If using audio syncing, this means that the video speeds
up to catch up with the current audio. Basically I've been trying to make a
function to toggle audio on and off by disabling and re-enabling the audio
(packet_queue_abort(¤t_videostate->audioq) and
packet_queue_init(¤t_videostate->audioq)).
Full code is here, can anybody tell me what I've gotten wrong (yes, it's
c++, but the C version of the same thing does exactly the same thing:
int libavinterface::stream_component_open(unsigned int stream_index)
{
AVFormatContext *ic = current_videostate->ic;
AVCodecContext *decoder_context;
AVCodec *codec;
SDL_AudioSpec wanted_spec, spec;
if (stream_index >= ic->nb_streams)
{
return -1;
}
decoder_context = ic->streams[stream_index]->codec;
/* prepare audio output */
if (decoder_context->codec_type == CODEC_TYPE_AUDIO)
{
if (decoder_context->channels > 0)
{
decoder_context->request_channels = FFMIN(2,
decoder_context->channels);
}
else
{
decoder_context->request_channels = 2;
}
}
codec = avcodec_find_decoder(decoder_context->codec_id);
decoder_context->debug_mv = DEBUG_MV;
decoder_context->debug = DEBUG;
decoder_context->workaround_bugs = WORKAROUND_BUGS;
decoder_context->lowres = lowres;
// This option drops video size by half and decreases cpu by a third:
if(lowres)
{
decoder_context->flags |= CODEC_FLAG_EMU_EDGE;
}
decoder_context->idct_algo= IDCT_ALGORITHM;
// This option makes mpeg2 video etc look extremely bad with virtually no
cpu-use decrease:
// if(fast) decoder_context->flags2 |= CODEC_FLAG2_FAST;
decoder_context->skip_frame= SKIP_FRAME;
decoder_context->skip_idct= SKIP_IDCT;
decoder_context->skip_loop_filter= SKIP_LOOP_FILTER;
decoder_context->error_resilience= ERROR_RESILIENCE;
decoder_context->error_concealment= ERROR_CONCEALMENT;
if (!codec || avcodec_open(decoder_context, codec) < 0)
{
return -1;
}
/* prepare audio output */
if (decoder_context->codec_type == CODEC_TYPE_AUDIO)
{
wanted_spec.freq = decoder_context->sample_rate;
wanted_spec.format = AUDIO_S16SYS;
wanted_spec.channels = decoder_context->channels;
wanted_spec.silence = 0;
wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
wanted_spec.callback = sdl_audio_callback;
wanted_spec.userdata = current_videostate;
if (SDL_OpenAudio(&wanted_spec, &spec) < 0)
{
#ifdef VIDEOVSTDEBUG
fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
#endif
return -1;
}
current_videostate->audio_hw_buf_size = spec.size;
}
#if THREAD_COUNT > 1
avcodec_thread_init(decoder_context, THREAD_COUNT);
#endif
decoder_context->thread_count= THREAD_COUNT;
switch(decoder_context->codec_type)
{
case CODEC_TYPE_AUDIO:
current_videostate->audio_stream = stream_index;
current_videostate->audio_st = ic->streams[stream_index];
current_videostate->audio_buf_size = 0;
current_videostate->audio_buf_index = 0;
/* init averaging filter */
current_videostate->audio_diff_avg_coef = exp(log(0.01) /
AUDIO_DIFF_AVG_NB);
current_videostate->audio_diff_avg_count = 0;
/* since we do not have a precise anough audio fifo fullness,
we correct audio sync only if larger than this threshold */
current_videostate->audio_diff_threshold = 2.0 *
SDL_AUDIO_BUFFER_SIZE / decoder_context->sample_rate;
memset(¤t_videostate->audio_pkt, 0,
sizeof(current_videostate->audio_pkt));
packet_queue_init(¤t_videostate->audioq);
SDL_PauseAudio(0);
// Used by get_audio_clock:
audio_bytes_per_second =
current_videostate->audio_st->codec->sample_rate
* 2 * current_videostate->audio_st->codec->channels;
break;
case CODEC_TYPE_VIDEO:
current_videostate->video_stream = stream_index;
current_videostate->video_st = ic->streams[stream_index];
current_videostate->frame_last_delay = 40e-3;
current_videostate->frame_timer = (double)av_gettime() /
1000000.0;
current_videostate->video_current_pts_time = av_gettime();
packet_queue_init(¤t_videostate->videoq);
current_videostate->video_tid = SDL_CreateThread(video_thread,
this);
decoder_context->get_buffer= my_get_buffer;
decoder_context->release_buffer= my_release_buffer;
break;
case CODEC_TYPE_SUBTITLE:
current_videostate->subtitle_stream = stream_index;
current_videostate->subtitle_st = ic->streams[stream_index];
packet_queue_init(¤t_videostate->subtitleq);
current_videostate->subtitle_tid =
SDL_CreateThread(subtitle_thread, this);
break;
default:
break;
}
return 0;
}
void libavinterface::stream_component_close(unsigned int stream_index)
{
AVFormatContext *ic = current_videostate->ic;
AVCodecContext *decoder_context;
if (stream_index >= ic->nb_streams)
{
return;
}
decoder_context = ic->streams[stream_index]->codec;
switch(decoder_context->codec_type)
{
case CODEC_TYPE_AUDIO:
packet_queue_abort(¤t_videostate->audioq);
SDL_CloseAudio();
packet_queue_end(¤t_videostate->audioq);
break;
case CODEC_TYPE_VIDEO:
packet_queue_abort(¤t_videostate->videoq);
/* note: we also signal this mutex to make sure we deblock the
video thread in all cases */
SDL_LockMutex(current_videostate->pictq_mutex);
SDL_CondSignal(current_videostate->pictq_cond);
SDL_UnlockMutex(current_videostate->pictq_mutex);
SDL_WaitThread(current_videostate->video_tid, NULL);
packet_queue_end(¤t_videostate->videoq);
break;
case CODEC_TYPE_SUBTITLE:
packet_queue_abort(¤t_videostate->subtitleq);
/* note: we also signal this mutex to make sure we deblock the
video thread in all cases */
SDL_LockMutex(current_videostate->subpq_mutex);
current_videostate->subtitle_stream_changed = 1;
SDL_CondSignal(current_videostate->subpq_cond);
SDL_UnlockMutex(current_videostate->subpq_mutex);
SDL_WaitThread(current_videostate->subtitle_tid, NULL);
packet_queue_end(¤t_videostate->subtitleq);
break;
default:
break;
}
avcodec_close(decoder_context);
switch(decoder_context->codec_type)
{
case CODEC_TYPE_AUDIO:
current_videostate->audio_st = NULL;
current_videostate->audio_stream = -1;
audio_bytes_per_second = -1;
break;
case CODEC_TYPE_VIDEO:
current_videostate->video_st = NULL;
current_videostate->video_stream = -1;
break;
case CODEC_TYPE_SUBTITLE:
current_videostate->subtitle_st = NULL;
current_videostate->subtitle_stream = -1;
break;
default:
break;
}
}
Using mingw32, latest build, latest cvs ffmpeg, everything else is working
fine in terms of video playback thus far;
M@
_______________________________________________
libav-user mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/libav-user