Build Fix -- compatibility issue with newer autoconf
[sxemacs] / src / media / media-ffmpeg.c
index 94d0c15..e9e6710 100644 (file)
@@ -87,6 +87,10 @@ DEFINE_MEDIA_DRIVER_CUSTOM(new_media_ffmpeg,
                           new_media_ffmpeg_rewind, NULL);
 
 \f
+#ifndef AVCODEC_MAX_AUDIO_FRAME_SIZE
+#define AVCODEC_MAX_AUDIO_FRAME_SIZE 19200
+#endif
+
 static int
 media_ffmpeg_bitrate(AVCodecContext *enc)
 {
@@ -200,29 +204,18 @@ media_ffmpeg_print(Lisp_Object ms, Lisp_Object pcfun, int ef)
 static AVFormatContext*
 media_ffmpeg_open_file(const char *file)
 {
-#if defined HAVE_AVFORMAT_ALLOC_CONTEXT
-       AVFormatContext *avfc = avformat_alloc_context();
-#elif defined HAVE_AV_ALLOC_FORMAT_CONTEXT
-       /* deprecated already, but `people' like Horst still use this */
-       AVFormatContext *avfc = av_alloc_format_context();
-#else
-# error "Your ffmpeg library is too old.  Adopt a new one."
-#endif /* HAVE_AVFORMAT_ALLOC_CONTEXT */
+       AVFormatContext *avfc = NULL;
 
        /* open the file */
-       if (av_open_input_file(&avfc, file, NULL, 0, NULL) < 0) {
+       if (avformat_open_input(&avfc, file, NULL, NULL) < 0) {
                FFMPEG_DEBUG_AVF("opening file failed.\n");
-               if (avfc)
-                       xfree(avfc);
                return NULL;
        }
 
        /* Retrieve stream information */
-       if (av_find_stream_info(avfc) < 0) {
+       if (avformat_find_stream_info(avfc, NULL) < 0) {
                FFMPEG_DEBUG_AVS("opening stream inside file failed.\n");
-               av_close_input_file(avfc);
-               if (avfc)
-                       xfree(avfc);
+               avformat_close_input(&avfc);
                return NULL;
        }
 
@@ -231,15 +224,9 @@ media_ffmpeg_open_file(const char *file)
 
 \f
 static int
-media_ffmpeg_vio_open(URLContext *h, const char *filename, int flags)
-{
-       return 0;
-}
-
-static int
-media_ffmpeg_vio_read(URLContext *h, unsigned char *buf, int size)
+media_ffmpeg_vio_read(void *h, unsigned char *buf, int size)
 {
-       media_data *sd = (media_data*)h->priv_data;
+       media_data *sd = (media_data*)h;
 
        FFMPEG_DEBUG_AVS("reading %d bytes to 0x%x, respecting seek %ld\n",
                         size, (unsigned int)buf, sd->seek);
@@ -255,16 +242,10 @@ media_ffmpeg_vio_read(URLContext *h, unsigned char *buf, int size)
        return size;
 }
 
-static int
-media_ffmpeg_vio_write(URLContext *h, unsigned char *buf, int size)
-{
-       return -1;
-}
-
 static int64_t
-media_ffmpeg_vio_seek(URLContext *h, int64_t pos, int whence)
+media_ffmpeg_vio_seek(void *h, int64_t pos, int whence)
 {
-       media_data *sd = (media_data*)h->priv_data;
+       media_data *sd = (media_data*)h;
 
        FFMPEG_DEBUG_AVS("seeking to %ld via %d\n", (long int)pos, whence);
 
@@ -285,25 +266,6 @@ media_ffmpeg_vio_seek(URLContext *h, int64_t pos, int whence)
        return sd->seek;
 }
 
-static int
-media_ffmpeg_vio_close(URLContext *h)
-{
-       if (h->priv_data)
-               xfree(h->priv_data);
-       h->priv_data = NULL;
-       return 0;
-}
-
-/* this is a memory-i/o protocol in case we have to deal with string data */
-static URLProtocol media_ffmpeg_protocol = {
-       "SXEmff",
-       media_ffmpeg_vio_open,
-       media_ffmpeg_vio_read,
-       media_ffmpeg_vio_write,
-       media_ffmpeg_vio_seek,
-       media_ffmpeg_vio_close,
-};
-
 /** Size of probe buffer, for guessing file type from file contents. */
 #define PROBE_BUF_MIN 2048
 #define PROBE_BUF_MAX 131072
@@ -311,79 +273,61 @@ static URLProtocol media_ffmpeg_protocol = {
 AVFormatContext*
 media_ffmpeg_open_data(char *data, size_t size)
 {
-#if defined HAVE_AVFORMAT_ALLOC_CONTEXT
-       AVFormatContext *avfc = avformat_alloc_context();
-#elif defined HAVE_AV_ALLOC_FORMAT_CONTEXT
-       /* deprecated already, but `people' like Horst still use this */
-       AVFormatContext *avfc = av_alloc_format_context();
-#else
-# error "Your ffmpeg library is too old.  Adopt a new one."
-#endif /* HAVE_AVFORMAT_ALLOC_CONTEXT */
-       AVProbeData *pd = NULL;
-       ByteIOContext *bioctx = NULL;
-       AVInputFormat *fmt = NULL;
-       char file[] = "SXEmff:SXEmacs.mp3\000";
-       media_data *sd = NULL;
-
-       /* register our virtual i/o */
-#if defined HAVE_AV_REGISTER_PROTOCOL
-       av_register_protocol(&media_ffmpeg_protocol);
-#elif defined HAVE_REGISTER_PROTOCOL
-       register_protocol(&media_ffmpeg_protocol);
-#else
-# error "Get a recent ffmpeg or get a life."
-#endif
+        AVFormatContext *avfc    = NULL;
+       AVIOContext     *avio    = NULL;
+       media_data      *sd      = NULL;
+       unsigned char   *buffer  = NULL;
+       static const int bufsize = 65536;
+       
+       /* initialise our media_data. Note that we need to use
+        * ffmpeg's malloc because it will free it on cleaning of the
+        * context and we don't want allocators corrupting each other.
+        */
+       sd = av_malloc(sizeof(media_data));
+       if (!sd)
+             return NULL;
 
-       /* initialise our media_data */
-       sd = xnew_and_zero(media_data);
        sd->length = size;
        sd->seek = 0;
        sd->data = data;
 
-       /* register ffmpeg byteio */
-       bioctx = xnew_and_zero(ByteIOContext);
-#if defined FFMPEG_URL_FOPEN_BIOCTX_STAR_STAR
-       url_fopen(&bioctx, file, URL_RDONLY);
-#elif defined FFMPEG_URL_FOPEN_BIOCTX_STAR
-       url_fopen(bioctx, file, URL_RDONLY);
-#endif
-       /* erm, register us at the byteio context */
-       ((URLContext*)(bioctx->opaque))->priv_data = sd;
-
-       /* take a probe */
-       pd = xnew_and_zero(AVProbeData);
-       pd->filename = file;
-       pd->buf = NULL;
-       pd->buf_size = 0;
-
-       pd->buf = (void*)sd->data;
-       pd->buf_size = PROBE_BUF_MIN;
-       fmt = av_probe_input_format(pd, 1);
-
-       /* if still no format found, error */
-       if (!fmt) {
-               xfree(pd);
-               xfree(bioctx);
-               xfree(sd);
-               xfree(avfc);
+       /* allocate the buffer  */
+       buffer = av_malloc(bufsize);
+       if (!buffer)
                return NULL;
-       }
 
-       /* open the file */
-       if (av_open_input_stream(&avfc, bioctx, file, fmt, NULL) < 0) {
-               xfree(pd);
-               xfree(bioctx);
-               xfree(sd);
-               xfree(avfc);
+       /* create ffmpeg avio context. Note that at this point thea
+        * AVIOContext has lifetime control of the previously
+        * allocated sd and buffer.
+        */
+       avio = avio_alloc_context(buffer,
+                                 bufsize,
+                                 0, /* No writes */
+                                 sd,
+                                 media_ffmpeg_vio_read,
+                                 NULL,
+                                 media_ffmpeg_vio_seek);
+
+       /* create format context, and make it use the avio above.
+          Note that at this point avfc has lifetime control of avio,
+          through avformat_free_context */
+       avfc = avformat_alloc_context();
+       avfc->pb = avio;
+       avfc->flags = AVFMT_FLAG_CUSTOM_IO;
+
+       /* open the input */
+       if (avformat_open_input(&avfc, NULL, NULL, NULL) < 0) {
+               FFMPEG_DEBUG_AVF("opening file failed.\n");
+               /* Abundance of caution, as on failure open input
+                  should clear the context, but when it does it also
+                  sets avfc to NULL so this is safe. */
+               avformat_free_context(avfc);
                return NULL;
        }
-
+       
        /* Retrieve stream information */
-       if (av_find_stream_info(avfc) < 0) {
-               xfree(pd);
-               xfree(bioctx);
-               xfree(sd);
-               xfree(avfc);
+       if (avformat_find_stream_info(avfc,NULL) < 0) {
+               avformat_close_input(&avfc);
                return NULL;
        }
 
@@ -397,7 +341,7 @@ media_ffmpeg_close(ms_driver_data_t data)
        FFMPEG_DEBUG_AVF("closing AVFormatContext: 0x%lx\n",
                         (long unsigned int)avfc);
        if (avfc && avfc->iformat)
-               av_close_input_file(avfc);
+               avformat_close_input(&avfc);
 }
 
 static void
@@ -432,39 +376,47 @@ media_ffmpeg_analyse_audio(media_substream *mss, AVFormatContext *avfc, int st)
                mtap->samplerate = avcc->sample_rate;
                mtap->bitrate = media_ffmpeg_bitrate(avcc);
 
+               int sample_bytes =
+                       av_get_bytes_per_sample(avcc->sample_fmt);
+               mtap->samplewidth = 8 * sample_bytes;
+               mtap->framesize = mtap->channels * sample_bytes;
                /* samplewidth and framesize */
                switch (avcc->sample_fmt) {
-               case SAMPLE_FMT_U8:
-                       mtap->samplewidth = 8;
-                       mtap->framesize = mtap->channels * 1;
+               case AV_SAMPLE_FMT_U8:
+                       assert(sample_bytes == 1);
                        mtap->msf = sxe_msf_U8;
                        break;
-               case SAMPLE_FMT_S16:
-                       mtap->samplewidth = 16;
-                       mtap->framesize = mtap->channels * 2;
+               case AV_SAMPLE_FMT_S16:
+                       assert(sample_bytes == 2);
                        mtap->msf = sxe_msf_S16;
                        break;
-#if defined SAMPLE_FMT_S24
-               case SAMPLE_FMT_S24:
-                       mtap->samplewidth = 32;
-                       mtap->framesize = mtap->channels * 4;
-                       mtap->msf = sxe_msf_S24;
-                       break;
-#endif /* SAMPLE_FMT_S24 */
-               case SAMPLE_FMT_S32:
-                       mtap->samplewidth = 32;
-                       mtap->framesize = mtap->channels * 4;
+               case AV_SAMPLE_FMT_S32:
+                       assert(sample_bytes == 4);
                        mtap->msf = sxe_msf_S32;
                        break;
-               case SAMPLE_FMT_FLT:
-                       mtap->samplewidth = 8*sizeof(float);
-                       mtap->framesize = mtap->channels * sizeof(float);
+               case AV_SAMPLE_FMT_FLT:
+                       assert(sample_bytes == sizeof(float));
                        mtap->msf = sxe_msf_FLT;
                        break;
-               case SAMPLE_FMT_NONE:
-               default:
+               case AV_SAMPLE_FMT_DBL:
+                       assert(sample_bytes == sizeof(double));
+                       mtap->msf = sxe_msf_DBL;
+                       break;
+               case AV_SAMPLE_FMT_NONE:
                        mtap->samplewidth = 0;
                        break;
+               default:
+                       {
+                               char fmt_name[128];
+                               error(("Unsupported sample format: "
+                                      "%s (%d), %d bytes/sample"),
+                                     av_get_sample_fmt_string(
+                                                              fmt_name,
+                                                              sizeof(fmt_name),
+                                                              avcc->sample_fmt),
+                                     avcc->sample_fmt,
+                                     sample_bytes);
+                       }
                }
        }
        mtap->endianness = 0;
@@ -541,6 +493,8 @@ media_ffmpeg_open(Lisp_Media_Stream *ms)
                mkfp = media_stream_kind_properties(ms).fprops;
                TO_EXTERNAL_FORMAT(LISP_STRING, mkfp->filename,
                                   ALLOCA, (file, file_len), Qnil);
+               SXE_SET_UNUSED(file_len);
+
                avfc = media_ffmpeg_open_file(file);
                if (!avfc) {
                        media_stream_set_meths(ms, NULL);
@@ -549,7 +503,7 @@ media_ffmpeg_open(Lisp_Media_Stream *ms)
                }
 
                /* store the filesize */
-               mkfp->filesize = avfc->file_size;
+               mkfp->filesize = avio_size(avfc->pb);
                break;
        }
        case MKIND_STRING: {
@@ -585,27 +539,27 @@ media_ffmpeg_open(Lisp_Media_Stream *ms)
                        avcc = avst->codec;
                        if (avcc &&
                            avcc->codec_id != CODEC_ID_NONE &&
-                           avcc->codec_type != CODEC_TYPE_DATA &&
+                           avcc->codec_type != AVMEDIA_TYPE_DATA &&
                            (avc = avcodec_find_decoder(avcc->codec_id)) &&
-                           (avc && (avcodec_open(avcc, avc) >= 0))) {
+                           (avc && (avcodec_open2(avcc, avc, NULL) >= 0))) {
 
                                /* create a substream */
                                mss = make_media_substream_append(ms);
 
                                switch ((unsigned int)avcc->codec_type) {
-                               case CODEC_TYPE_VIDEO:
+                               case AVMEDIA_TYPE_VIDEO:
                                        /* assign substream props */
                                        media_substream_type(mss) = MTYPE_VIDEO;
                                        media_ffmpeg_analyse_video(mss, avfc, st);
                                        break;
-                               case CODEC_TYPE_AUDIO:
+                               case AVMEDIA_TYPE_AUDIO:
                                        /* assign substream props */
                                        media_substream_type(mss) = MTYPE_AUDIO;
                                        media_ffmpeg_analyse_audio(mss, avfc, st);
                                        /* set some stream handlers */
                                        media_stream_set_meths(ms, media_ffmpeg);
                                        break;
-                               case CODEC_TYPE_DATA:
+                               case AVMEDIA_TYPE_DATA:
                                        media_substream_type(mss) = MTYPE_IMAGE;
                                        break;
                                default:
@@ -669,7 +623,7 @@ media_ffmpeg_read(media_substream *mss, void *outbuf, size_t length)
        AVFormatContext *avfc;
        AVStream *avst;
        AVCodecContext *avcc;
-       AVCodec *avc;
+       const AVCodec *avc;
        AVPacket pkt;
        /* buffering */
        /* the size we present here, is _not_ the size we want, however
@@ -695,6 +649,7 @@ media_ffmpeg_read(media_substream *mss, void *outbuf, size_t length)
        avst = avfc->streams[si];
        avcc = avst->codec;
        avc = avcc->codec;
+       SXE_SET_UNUSED(avc);
 
        /* unpack the substream */
        if ((mtap = media_substream_type_properties(mss).aprops) == NULL) {
@@ -734,7 +689,13 @@ media_ffmpeg_read(media_substream *mss, void *outbuf, size_t length)
 
                dec = pkt.size;
                /* decode the demuxed packet */
-#ifdef HAVE_AVCODEC_DECODE_AUDIO2
+#ifdef HAVE_AVCODEC_DECODE_AUDIO3
+/* prefer decode_audio3() if available */
+               size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
+               declen = avcodec_decode_audio3(
+                       avcc, (void*)((char*)outbuf+bufseek),
+                       &size, &pkt);
+#elif HAVE_AVCODEC_DECODE_AUDIO2
 /* prefer decode_audio2() if available */
                size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
                declen = avcodec_decode_audio2(
@@ -753,6 +714,8 @@ media_ffmpeg_read(media_substream *mss, void *outbuf, size_t length)
                                         (long long int)pkt.pts,
                                         (long long int)pkt.dts,
                                         pkt.size, size, declen);
+                       /* Because FFMPEG_DEBUG_AVF may expand to nothing ... */
+                       SXE_SET_UNUSED(declen);
 
                        /* memcpy(outbuf+bufseek, (char*)buffer, size); */
                        bufseek += size;
@@ -941,7 +904,6 @@ typedef struct VideoState {
 
 /* since we have only one decoding thread, we can use a global
    variable instead of a thread local variable */
-static VideoState *global_video_state;
 AVPacket flush_pkt;
 
 /* packet queue handling */
@@ -1064,23 +1026,15 @@ packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
 static uint64_t global_video_pkt_pts = AV_NOPTS_VALUE;
 
 static int
-my_get_buffer(struct AVCodecContext *c, AVFrame *pic)
+my_get_buffer(struct AVCodecContext *c, AVFrame *pic, int flags)
 {
-       int ret= avcodec_default_get_buffer(c, pic);
+        int ret= avcodec_default_get_buffer2(c, pic, flags);
        uint64_t *pts= av_malloc(sizeof(uint64_t));
        *pts= global_video_pkt_pts;
        pic->opaque= pts;
        return ret;
 }
 
-static void
-my_release_buffer(struct AVCodecContext *c, AVFrame *pic)
-{
-       if(pic) av_freep(&pic->opaque);
-       avcodec_default_release_buffer(c, pic);
-}
-
-
 static int
 stream_component_open(VideoState *is, int stream_index, Lisp_Media_Stream *ms)
 {
@@ -1096,7 +1050,7 @@ stream_component_open(VideoState *is, int stream_index, Lisp_Media_Stream *ms)
        enc = ic->streams[stream_index]->codec;
 
        /* prepare audio output */
-       if (enc->codec_type == CODEC_TYPE_AUDIO) {
+       if (enc->codec_type == AVMEDIA_TYPE_AUDIO) {
 #if 0
                wanted_spec.freq = enc->sample_rate;
                wanted_spec.format = AUDIO_S16SYS;
@@ -1131,18 +1085,18 @@ stream_component_open(VideoState *is, int stream_index, Lisp_Media_Stream *ms)
        enc->error_resilience = FF_ER_CAREFUL; /* error_resilience; */
 #endif
        enc->error_concealment = 3; /* error_concealment; */
+       if (1 /* thread_count */ > 1)
+               enc->thread_count = 1 /* thread_count */;
+
        if (!codec ||
-           avcodec_open(enc, codec) < 0)
+           avcodec_open2(enc, codec, NULL) < 0)
                return -1;
-       if (1 /* thread_count */ > 1)
-               avcodec_thread_init(enc, 1 /*thread_count*/);
-       enc->thread_count= 1 /* thread_count */;
 
        /* create a substream */
        mss = make_media_substream_append(ms);
 
        switch ((unsigned int)enc->codec_type) {
-       case CODEC_TYPE_AUDIO:
+       case AVMEDIA_TYPE_AUDIO:
                is->audio_stream = stream_index;
                is->audio_st = ic->streams[stream_index];
                is->audio_buf_size = 0;
@@ -1162,7 +1116,7 @@ stream_component_open(VideoState *is, int stream_index, Lisp_Media_Stream *ms)
                media_substream_type(mss) = MTYPE_AUDIO;
                media_ffmpeg_analyse_audio(mss, is->ic, stream_index);
                break;
-       case CODEC_TYPE_VIDEO:
+       case AVMEDIA_TYPE_VIDEO:
                is->video_stream = stream_index;
                is->video_st = ic->streams[stream_index];
 
@@ -1176,13 +1130,12 @@ stream_component_open(VideoState *is, int stream_index, Lisp_Media_Stream *ms)
                packet_queue_init(&is->videoq);
                is->video_tid = 0 /* SDL_CreateThread(video_thread, is) */;
 
-               enc->    get_buffer=     my_get_buffer;
-               enc->release_buffer= my_release_buffer;
-
+               enc->get_buffer2          = my_get_buffer;
                media_substream_type(mss) = MTYPE_VIDEO;
+
                media_ffmpeg_analyse_video(mss, is->ic, stream_index);
                break;
-       case CODEC_TYPE_SUBTITLE:
+       case AVMEDIA_TYPE_SUBTITLE:
                is->subtitle_stream = stream_index;
                is->subtitle_st = ic->streams[stream_index];
                packet_queue_init(&is->subtitleq);
@@ -1207,14 +1160,14 @@ stream_component_close(VideoState *is, int stream_index)
        enc = ic->streams[stream_index]->codec;
 
        switch ((unsigned int)enc->codec_type) {
-       case CODEC_TYPE_AUDIO:
+       case AVMEDIA_TYPE_AUDIO:
                packet_queue_abort(&is->audioq);
 #if 0
                SDL_CloseAudio();
 #endif
                packet_queue_end(&is->audioq);
                break;
-       case CODEC_TYPE_VIDEO:
+       case AVMEDIA_TYPE_VIDEO:
                packet_queue_abort(&is->videoq);
 
                /* note: we also signal this mutex to make sure we deblock the
@@ -1227,7 +1180,7 @@ stream_component_close(VideoState *is, int stream_index)
 #endif
                packet_queue_end(&is->videoq);
                break;
-       case CODEC_TYPE_SUBTITLE:
+       case AVMEDIA_TYPE_SUBTITLE:
                packet_queue_abort(&is->subtitleq);
 
                /* note: we also signal this mutex to make sure we deblock the
@@ -1248,15 +1201,15 @@ stream_component_close(VideoState *is, int stream_index)
 
        avcodec_close(enc);
        switch ((unsigned int)enc->codec_type) {
-       case CODEC_TYPE_AUDIO:
+       case AVMEDIA_TYPE_AUDIO:
                is->audio_st = NULL;
                is->audio_stream = -1;
                break;
-       case CODEC_TYPE_VIDEO:
+       case AVMEDIA_TYPE_VIDEO:
                is->video_st = NULL;
                is->video_stream = -1;
                break;
-       case CODEC_TYPE_SUBTITLE:
+       case AVMEDIA_TYPE_SUBTITLE:
                is->subtitle_st = NULL;
                is->subtitle_stream = -1;
                break;
@@ -1299,9 +1252,9 @@ enum {
 static VideoState *
 stream_open(char *filename, size_t filelen)
 {
-       VideoState *is = xnew(VideoState);
-       AVFormatParameters params, *ap = &params;
-       int err = 0;
+       VideoState   *is      = xnew(VideoState);
+       AVDictionary *options = NULL;
+       int err               = 0;
 
        is->filename = filename;
        is->filelen = filelen;
@@ -1316,7 +1269,7 @@ stream_open(char *filename, size_t filelen)
        is->av_sync_type = AV_SYNC_AUDIO_MASTER;
        is->parse_tid = 0; /* SDL_CreateThread(decode_thread, is); */
 
-       memset(ap, 0, sizeof(*ap));
+#if 0
        /* we force a pause when starting an RTSP stream */
        ap->initial_pause = 1;
 
@@ -1324,8 +1277,9 @@ stream_open(char *filename, size_t filelen)
        ap->height= 0; /* frame_height; */
        ap->time_base= (AVRational){1, 25};
        ap->pix_fmt = PIX_FMT_NONE; /* frame_pix_fmt; */
+#endif
 
-       err = av_open_input_file(&is->ic, is->filename, is->iformat, 0, ap);
+       err = avformat_open_input(&is->ic, is->filename, is->iformat, &options);
        if (UNLIKELY(err < 0)) {
                FFMPEG_DEBUG_AVF("Could not open \"%s\" (errno %d)\n",
                                 is->filename, err);
@@ -1381,7 +1335,7 @@ new_media_ffmpeg_open(Lisp_Media_Stream *ms)
        }
 
        if (!use_play) {
-               err = av_find_stream_info(vs->ic);
+               err = avformat_find_stream_info(vs->ic, NULL);
                if (err < 0) {
                        FFMPEG_DEBUG_AVF("\"%s\": "
                                         "could not find codec parameters\n",
@@ -1390,18 +1344,14 @@ new_media_ffmpeg_open(Lisp_Media_Stream *ms)
                }
                /* FIXME hack,
                 * ffplay maybe should not use url_feof() to test for the end */
-#if defined FFMPEG_URL_FOPEN_BIOCTX_STAR_STAR
                vs->ic->pb->eof_reached = 0;
-#elif defined FFMPEG_URL_FOPEN_BIOCTX_STAR
-               vs->ic->pb.eof_reached = 0;
-#endif
        }
 
        /* now we can begin to play (RTSP stream only) */
        av_read_play(vs->ic);
 
        if (use_play) {
-               err = av_find_stream_info(vs->ic);
+               err = avformat_find_stream_info(vs->ic, NULL);
                if (err < 0) {
                        FFMPEG_DEBUG_AVF("\"%s\": "
                                         "could not find codec parameters\n",
@@ -1413,12 +1363,12 @@ new_media_ffmpeg_open(Lisp_Media_Stream *ms)
        for (size_t i = 0; i < vs->ic->nb_streams; i++) {
                AVCodecContext *enc = vs->ic->streams[i]->codec;
                switch ((unsigned int)enc->codec_type) {
-               case CODEC_TYPE_AUDIO:
+               case AVMEDIA_TYPE_AUDIO:
                        if ((audio_index < 0 || wanted_audio_stream-- > 0)) {
                                audio_index = i;
                        }
                        break;
-               case CODEC_TYPE_VIDEO:
+               case AVMEDIA_TYPE_VIDEO:
                        if ((video_index < 0 || wanted_video_stream-- > 0)) {
                                video_index = i;
                        }
@@ -1428,7 +1378,7 @@ new_media_ffmpeg_open(Lisp_Media_Stream *ms)
                }
        }
        if (1 /* show_status */) {
-               dump_format(vs->ic, 0, vs->filename, 0);
+               av_dump_format(vs->ic, 0, vs->filename, 0);
                dump_stream_info(vs->ic);
        }
 
@@ -1556,25 +1506,14 @@ new_media_ffmpeg_read(media_substream *mss, void *outbuf, size_t length)
                if (is->audioq.size > MAX_AUDIOQ_SIZE ||
                    is->videoq.size > MAX_VIDEOQ_SIZE ||
                    is->subtitleq.size > MAX_SUBTITLEQ_SIZE ||
-#if defined FFMPEG_URL_FOPEN_BIOCTX_STAR_STAR
-                   url_feof(is->ic->pb)
-#elif defined FFMPEG_URL_FOPEN_BIOCTX_STAR
-                   url_feof(&is->ic->pb)
-#endif
-                       ) {
+                   avio_feof(is->ic->pb)) {
                        /* wait 10 ms */
                        usleep(10);
                        continue;
                }
                ret = av_read_frame(is->ic, pkt);
                if (ret < 0) {
-                       if (url_ferror(
-#if defined FFMPEG_URL_FOPEN_BIOCTX_STAR_STAR
-                                   is->ic->pb
-#elif defined FFMPEG_URL_FOPEN_BIOCTX_STAR
-                                   &is->ic->pb
-#endif
-                                   ) == 0) {
+                       if (is->ic->pb->error == 0) {
                                usleep(100); /* wait for user event */
                                continue;
                        } else
@@ -1596,8 +1535,6 @@ new_media_ffmpeg_read(media_substream *mss, void *outbuf, size_t length)
        }
 
        ret = 0;
-       /* disable interrupting */
-       global_video_state = NULL;
 
        /* close each stream */
        if (is->audio_stream >= 0)
@@ -1607,10 +1544,13 @@ new_media_ffmpeg_read(media_substream *mss, void *outbuf, size_t length)
        if (is->subtitle_stream >= 0)
                stream_component_close(is, is->subtitle_stream);
        if (is->ic) {
-               av_close_input_file(is->ic);
+               avformat_close_input(&is->ic);
                is->ic = NULL; /* safety */
        }
+
+#if 0
        url_set_interrupt_cb(NULL);
+#endif
 
        if (ret != 0) {
 #if 0
@@ -1673,12 +1613,12 @@ Lisp_Object
 media_ffmpeg_available_formats(void)
 {
        Lisp_Object formats;
-       AVInputFormat *avif;
+       AVInputFormat *avif = NULL;
 
        formats = Qnil;
 
        av_register_all();
-       avif = first_iformat;
+       avif = av_iformat_next(avif);
 
        while (avif) {
                if (avif->name) {
@@ -1686,7 +1626,7 @@ media_ffmpeg_available_formats(void)
                                Fintern(build_string(avif->name), Qnil);
                        formats = Fcons(fmtname, formats);
                }
-               avif = avif->next;
+               avif = av_iformat_next(avif);
        }
 
        return formats;