Final set of changes for a working ffmpeg.
authorNelson Ferreira <nelson.ferreira@ieee.org>
Thu, 31 Dec 2015 19:39:54 +0000 (14:39 -0500)
committerNelson Ferreira <nelson.ferreira@ieee.org>
Thu, 31 Dec 2015 19:39:54 +0000 (14:39 -0500)
There are a couple of edges to polish but "works for me" now.

* src/media/media-ffmpeg.c (media_ffmpeg_read): Use
avcodec_decode_audio3 if available. More work is needed to use
avcodec_decod_audio4 because it uses frames which would need to
then be copied to the output buffer.
(my_get_buffer): Use avcodec_default_get_buffer2.
(my_release_buffer): No longer needed.
(stream_component_open): Properly set the thread count and use
avcodec_open2. Set get_buffer2 to my_get_buffer since we
are using the new interface.
(media_ffmpeg_available_formats): Use av_iformat_next.
(stream_open): Defer setting codec options to a later better
understanding of ffmpeg (keep #if 0 the old).
(new_media_ffmpeg_open): Use only the most recent AVIOContext access
method to set eof_reached. If we get issues reported we'll
revisit.
(new_media_ffmpeg_read): Use avio_eof and the most error field of
AVIOContext instead of furl_feof.  Do not unset the interrupt
callback for now.  We may need to revisit the reset of the
callback later.

* m4/sxe-mm.m4 (SXE_CHECK_FFMPEG_LIBS): Properly check for the
avcodec_decode_audio* and define corresponding
HAVE_AVCODEC_AUDIO*.  Also check for av_iformat_next.
(SXE_MM_CHECK_FFMPEG): Check at least one avcodec_decode_audio is
available and av_iformat_next.

Signed-off-by: Nelson Ferreira <nelson.ferreira@ieee.org>
m4/sxe-mm.m4
src/media/media-ffmpeg.c

index ef8d3a8..92e873d 100644 (file)
@@ -366,7 +366,9 @@ AC_DEFUN([SXE_MM_CHECK_FFMPEG], [
        fi
 
         ## make sure either decode_audio is there
-       if test "$ac_cv_lib_avcodec_avcodec_decode_audio4" = "yes"; then
+       if test "$ac_cv_lib_avcodec_avcodec_decode_audio" = "yes" -o \
+               "$ac_cv_lib_avcodec_avcodec_decode_audio2" = "yes" -o \
+               "$ac_cv_lib_avcodec_avcodec_decode_audio3" = "yes"; then
                sxe_cv_feat_ffmpeg_decoders="yes"
        fi
 
@@ -381,6 +383,7 @@ AC_DEFUN([SXE_MM_CHECK_FFMPEG], [
                "$ac_cv_lib_avformat_avformat_close_input" = "yes" -a \
                "$ac_cv_lib_avformat_avformat_find_stream_info" = "yes" -a \
                "$ac_cv_lib_avformat_av_probe_input_format" = "yes" -a \
+               "$ac_cv_lib_avformat_av_iformat_next" = "yes" -a \
                "$ac_cv_lib_avformat_av_read_frame" = "yes" -a \
                "$ac_cv_lib_avformat_av_seek_frame" = "yes" -a \
                "$ac_cv_lib_avformat_av_register_all" = "yes" -a \
@@ -432,11 +435,15 @@ AC_DEFUN([SXE_CHECK_FFMPEG_LIBS], [dnl
 
        AC_CHECK_LIB([avcodec], [avcodec_find_decoder], [:], [:], [${FFMPEG_LIBS}])
        AC_CHECK_LIB([avcodec], [avcodec_open2], [:], [:], [${FFMPEG_LIBS}])
+       AC_CHECK_LIB([avcodec], [avcodec_decode_audio], [:], [:], [${FFMPEG_LIBS}])
+       AC_CHECK_LIB([avcodec], [avcodec_decode_audio2], [:], [:], [${FFMPEG_LIBS}])
+       AC_CHECK_LIB([avcodec], [avcodec_decode_audio3], [:], [:], [${FFMPEG_LIBS}])
        AC_CHECK_LIB([avcodec], [avcodec_decode_audio4], [:], [:], [${FFMPEG_LIBS}])
 
        AC_CHECK_LIB([avformat], [avformat_open_input], [:], [:], [${FFMPEG_LIBS}])
        AC_CHECK_LIB([avformat], [avformat_close_input], [:], [:], [${FFMPEG_LIBS}])
        AC_CHECK_LIB([avformat], [avformat_find_stream_info], [:], [:], [${FFMPEG_LIBS}])
+       AC_CHECK_LIB([avformat], [av_iformat_next], [:], [:], [${FFMPEG_LIBS}])
        AC_CHECK_LIB([avformat], [av_probe_input_format], [:], [:], [${FFMPEG_LIBS}])
        AC_CHECK_LIB([avformat], [av_read_frame], [:], [:], [${FFMPEG_LIBS}])
        AC_CHECK_LIB([avformat], [av_seek_frame], [:], [:], [${FFMPEG_LIBS}])
@@ -450,6 +457,22 @@ AC_DEFUN([SXE_CHECK_FFMPEG_LIBS], [dnl
 
        AC_CHECK_LIB([avutil], [av_dict_get], [:], [:], [${FFMPEG_LIBS}])
 
+       if test "$ac_cv_lib_avcodec_avcodec_decode_audio" = "yes"; then
+               AC_DEFINE([HAVE_AVCODEC_DECODE_AUDIO], [1],
+                         [Define to 1 if avcodec_decode_audio is usable.])
+       fi
+       if test "$ac_cv_lib_avcodec_avcodec_decode_audio2" = "yes"; then
+               AC_DEFINE([HAVE_AVCODEC_DECODE_AUDIO2], [1],
+                         [Define to 1 if avcodec_decode_audio2 is usable.])
+       fi
+       if test "$ac_cv_lib_avcodec_avcodec_decode_audio3" = "yes"; then
+               AC_DEFINE([HAVE_AVCODEC_DECODE_AUDIO3], [1],
+                         [Define to 1 if avcodec_decode_audio is usable.])
+       fi
+       if test "$ac_cv_lib_avcodec_avcodec_decode_audio4" = "yes"; then
+               AC_DEFINE([HAVE_AVCODEC_DECODE_AUDIO4], [1],
+                         [Define to 1 if avcodec_decode_audio is usable.])
+       fi
 
        ## restore configuration
        SXE_RESTORE_LIBS
index d7fa9f9..559b2e9 100644 (file)
@@ -681,7 +681,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(
@@ -1012,23 +1018,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)
 {
@@ -1079,12 +1077,12 @@ 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);
@@ -1124,10 +1122,9 @@ 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 AVMEDIA_TYPE_SUBTITLE:
@@ -1247,9 +1244,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;
@@ -1264,7 +1261,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;
 
@@ -1272,8 +1269,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 = avformat_open_input(&is->ic, is->filename, is->iformat, NULL /*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);
@@ -1338,11 +1336,7 @@ 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) */
@@ -1504,25 +1498,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
@@ -1556,7 +1539,10 @@ new_media_ffmpeg_read(media_substream *mss, void *outbuf, size_t length)
                avformat_close_input(&is->ic);
                is->ic = NULL; /* safety */
        }
+
+#if 0
        url_set_interrupt_cb(NULL);
+#endif
 
        if (ret != 0) {
 #if 0
@@ -1619,12 +1605,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) {
@@ -1632,7 +1618,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;