Some further info, I am now getting segfaults from avcodec_decode_audio2.
What possible reasons could there be for this to happen?
For example, this is my initialize context function, called during
stream_open(like in ffplay.c), and then called at the beginning of every new
playback:
int initialize_context(PyMovie *movie, int threaded)
{
DECLAREGIL
AVFormatContext *ic;
AVFormatParameters params, *ap = ¶ms;
int ret, err;
memset(ap, 0, sizeof(*ap));
ap->width = 0;
ap->height= 0;
ap->time_base= (AVRational){1, 25};
ap->pix_fmt = PIX_FMT_NONE;
if (movie->ic) {
av_close_input_file(movie->ic);
movie->ic = NULL; /* safety */
}
err = av_open_input_file(&ic, movie->filename, movie->iformat, 0, ap);
if (err < 0) {
if(threaded)
GRABGIL
PyErr_Format(PyExc_IOError, "There was a problem opening up %s, due
to %i", movie->filename, err);
if(threaded)
RELEASEGIL
ret = -1;
goto fail;
}
err = av_find_stream_info(ic);
if (err < 0) {
if(threaded)
GRABGIL
PyErr_Format(PyExc_IOError, "%s: could not find codec parameters",
movie->filename);
if(threaded)
RELEASEGIL
ret = -1;
goto fail;
}
if(ic->pb)
ic->pb->eof_reached= 0; //FIXME hack, ffplay maybe should not use
url_feof() to test for the end
movie->ic = ic;
ret=0;
fail:
return ret;
}
Here is for example, the audio decoder function, up to the segfaulting call:
int audio_decoder(void *arg)
{
PyMovie *movie = arg;
DECLAREGIL
GRABGIL
Py_INCREF(movie);
RELEASEGIL
double pts;
AVPacket *pkt = &movie->audio_pkt;
AVCodecContext *dec= movie->audio_st->codec;
int n, len1, data_size;
int filled =0;
len1=0;
int co = 0;
for(;co<2;co++)
{
if (!movie->paused && movie->audio_paused)
{
pauseBuffer(movie->channel);
movie->audio_paused = 0;
}
else if (movie->paused && !movie->audio_paused)
{
pauseBuffer(movie->channel);
movie->audio_paused = 1;
goto closing;
}
//check if the movie has ended
if(movie->stop)
{
stopBuffer(movie->channel);
goto closing;
}
//fill up the buffer
while(movie->audio_pkt_size > 0)
{
data_size = sizeof(movie->audio_buf1);
len1 += avcodec_decode_audio2(dec, (int16_t *)movie->audio_buf1,
&data_size, movie->audio_pkt_data, movie->audio_pkt_size);
if (len1 < 0) {
/* if error, we skip the frame */
movie->audio_pkt_size = 0;
break;
}
movie->audio_pkt_data += len1;
movie->audio_pkt_size -= len1;
if (data_size <= 0)
continue;
//reformat_ctx here, but deleted
/* if no pts, then compute it */
pts = movie->audio_clock;
n = 2 * dec->channels;
movie->audio_clock += (double)data_size / (double)(n *
dec->sample_rate);
filled=1;
}
//either buffer filled or no packets yet
/* free the current packet */
if (pkt->data)
av_free_packet(pkt);
/* read next packet */
if (packet_queue_get(&movie->audioq, pkt, 1) < 0)
{
goto closing;
}
if(pkt->data == flush_pkt.data){
avcodec_flush_buffers(dec);
goto closing;
}
movie->audio_pkt_data = pkt->data;
movie->audio_pkt_size = pkt->size;
/* if update the audio clock with the pts */
if (pkt->pts != AV_NOPTS_VALUE) {
movie->audio_clock =
av_q2d(movie->audio_st->time_base)*pkt->pts;
}
if(filled)
{
SDL_LockMutex(movie->audio_mutex);
//SDL_CondWait(movie->audio_sig, movie->audio_mutex);
int chan = playBuffer(movie->audio_buf1, data_size,
movie->channel);
movie->channel = chan;
filled=0;
len1=0;
SDL_UnlockMutex(movie->audio_mutex);
goto closing;
}
else
{
filled=0;
}
}
closing:
GRABGIL
Py_DECREF(movie);
RELEASEGIL
return 0;
}
This only segfaults after one playback. Any ideas?
On Fri, Jun 26, 2009 at 2:24 PM, Tyler Laing <[email protected]> wrote:
> As a follow up on this, I determined the issue, which is that I needed to
> effectively restart my AVFormatContext object, with av_open_input_file, and
> switch the audio and video streams to the new streams allocated there. But
> is there any way to avoid this? Like being able to reset the audio and video
> streams back to the beginning, after eof has been reached?
>
>
> On Fri, Jun 26, 2009 at 12:39 PM, Tyler Laing <[email protected]> wrote:
>
>> Hello there,
>>
>> I am writing the pygame/Python movie module using ffmpeg. One of the
>> requirements I need to implement is to provide looping capability. What I
>> have is most of the video initialization stuff, like initializating an
>> AVFormatContext, etc is done once, then once one playthrough is done, and if
>> more playbacks are demanded, then its supposed to seek back to the beginning
>> of the stream(s). I use most of the same seeking code as ffplay does.
>> However, av_read_frame is returning a -32. Obviously, there's something I'm
>> forgetting to do with my AVFormatContext. Before, I went through the whole
>> initialization process every time I wanted to loop, but this isn't quite
>> satisfactory, and causes a few problems. So what am I missing?
>>
>> -Tyler
>>
>> --
>> Visit my blog at http://oddco.ca/zeroth/zblog
>>
>
>
>
> --
> Visit my blog at http://oddco.ca/zeroth/zblog
>
--
Visit my blog at http://oddco.ca/zeroth/zblog
_______________________________________________
libav-user mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/libav-user