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 = &params;
    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

Reply via email to